Documentation

April 25, 2019 ยท View on GitHub


Background

Threebox works by adding a Three.js scene to Mapbox GL, via a custom layer. The custom layer API takes a fair amount of finessing to be useful, and Threebox tackles several hurdles to getting THREE and Mapbox to work together.


Setup

var tb = new Threebox(map, mapboxGLContext[, options])

Sets up a threebox scene inside a Mapbox GL custom layer's onAdd function, which provides both inputs for this method. Automatically synchronizes the camera movement and events between Three.js and Mapbox GL JS.

optionrequireddefaulttypepurpose
defaultLightsnofalsebooleanWhether to add some default lighting to the scene. If no lighting added, most objects in the scene will render as black
passiveRenderingnotruebooleanColor of line. Unlike other Threebox objects, this color will render on screen precisely as specified, regardless of scene lighting

tb.update()

Rerender the threebox scene. Fired in the custom layer's render function.


Objects

Threebox offers convenience functions to construct meshes of various Three.js meshes, as well asl . Under the hood, they invoke a subclass of THREE.Object3D.

Objects in Threebox fall under two broad varieties. Static objects don't move or change once they're placed, and used usually to display background or geographical features. They may have complex internal geometry, which are expressed primarily in lnglat coordinates.

In contrast, dynamic objects can move around the map, positioned by a single lnglat point. Their internal geometries are produced mainly in local scene units, whether through external obj files, or these convenience methods below.

##Static objects

###Line

tb.line(options)

Adds a line to the map, in full 3D space. Color renders independently of scene lighting. Internally, calls a custom line shader.

optionrequireddefaulttypepurpose
geometryyesNAlineGeometryArray of lnglat coordinates to draw the line
colornoblackcolorColor of line. Unlike other Threebox objects, this color will render on screen precisely as specified, regardless of scene lighting
widthno1numberLine width. Unlike other Threebox objects, this width is in units of display pixels, rather than meters or scene units.
opacityno1NumberLine opacity

###Tube

tb.tube(options)

Extrude a tube along a specific lineGeometry, with an equilateral polygon as cross section. Internally uses a custom tube geometry generator.

optionrequireddefaulttypedescription
geometryyesNAlineGeometryLine coordinates forming the tube backbone
radiusno20numberRadius of the tube cross section, or half of tube width.
sidesno8numberNumber of facets along the tube. The higher, the more closely the tube will approximate a smooth cylinder.
materialnoMeshLambertMaterialthreeMaterialTHREE material to use. Can be invoked with a text string, or a predefined material object via THREE itself.
colornoblackcolorTube color. Ignored if material is a predefined THREE.Material object.
opacityno1NumberTube opacity

##Dynamic objects

###Sphere

tb.sphere(options)

Add a sphere to the map. Internally, calls THREE.Mesh with a THREE.SphereGeometry.

optionrequireddefaulttypedescription
radiusno50numberRadius of sphere.
unitsnoscenestring ("scene" or "meters")Units with which to interpret radius. If meters, Threebox will also rescale the object with changes in latitude, to appear to scale with objects and geography nearby.
sidesno8numberNumber of width and height segments. The higher the number, the smoother the sphere.
colornoblackcolorColor of sphere.
materialnoMeshLambertMaterialthreeMaterialTHREE material to use. Can be invoked with a text string, or a predefined material object via THREE itself.

###External OBJ object

threebox.loadObj(options, callback(obj))

Loads an object via an external .obj and .mtl file. Note that unlike all the other object classes, this is asynchronous, and returns the object as an argument of the callback function. Internally, uses THREE.OBJLoader to fetch the .obj assets.

optionrequireddefaulttypedescription
objyesNAstringURL path to asset's .obj file
mtlyesNAstringURL path to asset's .mtl file
unitsnoscenestring ("scene" or "meters")Units with which to interpret the object's vertices. If meters, Threebox will also rescale the object with changes in latitude, to appear to scale with objects and geography nearby.
rotationno0rotationTransformRotation of the object along the three axes, to align it to desired orientation before future rotations. Note that future rotations apply atop this transformation, and do not overwrite it.
scaleno1scaleTransformScale of the object along the three axes, to size it appropriately before future transformations. Note that future scaling applies atop this transformation, rather than overwriting it.
callbackyesNAfunctionA function to run after the object loads. The first argument will be the successfully loaded object.

###Object3D

threebox.Object3D(obj)

Add a THREE.Object3D instantiated elsewhere in THREE, to empower it with Threebox methods below. Unnecessary for objects instantiated with any methods above.

optionrequireddefaulttypedescription
unitsnoscenestring ("scene" or "meters")Units with which to interpret the object's vertices. If meters, Threebox will also rescale the object with changes in latitude, to appear to scale with objects and geography nearby.

###Shared methods between dynamic objects

obj.setCoords(lnglat)

Positions the object at the desired coordinate, and resizes it appropriately if it was instantiated with units: "meters". Can be called before adding object to the map.

obj.set(options)

Broad method to update object's position, rotation, and scale. Check out the Threebox Types section below for details

Options

optionrequireddefaulttypedescription
coordsnoNAlnglatPosition to which to move the object
rotationnoNArotationTransformRotation(s) to set the object, in units of degrees
scalenoNAscaleTransformScale(s) to set the object, where 1 is the default scale

obj.followPath(options(, callback) )

Translate object along a specified path. Optional callback function to execute when animation finishes

optionrequireddefaulttypedescription
pathyesNAlineGeometryPath for the object to follow
durationno1000numberDuration to travel the path, in milliseconds
trackHeadingnotruebooleanRotate the object so that it stays aligned with the direction of travel, throughout the animation

####obj.stop()

Stops all of object's current animations.

####obj.duplicate()

Returns a clone of the object. Greatly improves performance when handling many identical objects, by reusing materials and geometries.


##Utilities

tb.projectToWorld(lnglat)

Calculate the corresponding Vector3 for a given lnglat.

tb.unprojectFromWorld(Vector3)

Calculate the corresponding lnglat for a given Vector3.

tb.queryRenderedFeatures({x: number, y: number})

Takes an input of xy as an object with values representing screen coordinates (as returned by mapboxgl mouse events as e.point). Returns an array of threebox objects at that screen position.


Threebox types

pointGeometry [longitude, latitude(, meters altitude)]

An array of 2-3 numbers representing longitude, latitude, and optionally altitude (in meters). When altitude is omitted, it is assumed to be 0. When populating this from a GeoJSON Point, this array can be accessed at point.geometry.coordinates.

While altitude is not standardized in the GeoJSON specification, Threebox will accept it as such to position objects along the z-axis.


####lineGeometry

[pointGeometry, pointGeometry ... pointGeometry]

An array of at least two lnglat's, forming a line. When populating this from a GeoJSON Linestring, this array can be accessed at linestring.geometry.coordinates.


####rotationTransform

number or {x: number, y: number, z: number}

Angle(s) in degrees to rotate object. Can be expressed as either an object or number.

The object form takes three optional parameters along the three major axes: x is parallel to the equator, y parallel to longitudinal lines, and z perpendicular to the ground plane.

The number form rotates along the z axis, and equivalent to {z: number}.


####scaleTransform

number or {x: number, y: number, z: number}

Amount to scale the object, where 1 is the default size. Can be expressed as either an object or number.

The three axes are identical to those of rotationTransform. However, expressing as number form scales all three axes by that amount.

####threeMaterial

string or instance of THREE.Material()

Denotes the material used for an object. This can usually be customized further with color and opacity parameters in the same

Can be expressed as a string to the corresponding material type (e.g. "MeshPhysicalMaterial" for THREE.MeshPhysicalMaterial()), or a prebuilt THREE material directly.

##Using vanilla Three.js in Threebox

Threebox implements many small affordances to make mapping run in Three.js quickly and precisely on a global scale. Whenever possible, use threebox methods to add, change, manage, and remove elements of the scene. Otherwise, here are some best practices:

  • Use threebox.Object3D to add custom objects to the scene
  • If you must interact directly with the THREE scene, add all objects to threebox.world.
  • tb.projectToWorld to convert lnglat to the corresponding Vector3()

#Performance considerations

  • Use obj.clone() when adding many identical objects.