Cesium 3D Models Tutorial


Cesium supports 3D models, including key-frame animation, skinning, and individual node picking, using glTF, an emerging industry-standard format for 3D models on the web by the Khronos Group, the consortium behind WebGL and COLLADA. Cesium also provides a web-based tool to convert COLLADA models to glTF for optimized use with Cesium.

Quick start

Cesium includes a few ready-to-use glTF models: an aircraft with animated propellers, a ground vehicle with animated wheels, and a character with a skinned walk cycle.

These models each have their own directory in Apps/Sandcastle/models. Each has the original COLLADA file (.dae) and the glTF file (.json) along with its geometry (.bin), textures (usually .png or .jpg), and shaders (.glsl). The original COLLADA file is not needed for use in Cesium apps, but is still included.

Let’s write code to load these models. Open the Hello World example in Sandcastle. Under var viewer = ... on Line 4, add a scene variable.

var scene = viewer.scene;

Next, load the ground vehicle model using Cesium.Model.fromGltf by adding the following code.

var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(
    Cesium.Cartesian3.fromDegrees(-75.62898254394531, 40.02804946899414, 0.0));
var model = scene.primitives.add(Cesium.Model.fromGltf({
    url : '../models/CesiumGround/Cesium_Ground.json',
    modelMatrix : modelMatrix,
    scale : 200.0
}));

Hit F8, then use the geocoder tool in the upper right to zoom to Exton, PA.

We are now looking straight down at the ground vehicle. We can zoom in closer with right-mouse drag and tilt the view with middle-mouse drag.

Cesium.Model.fromGltf asynchronously loads the glTF model, including its external files, and renders it once it is completely loaded, which fires the readyToRender event. Just the url to the .json file is required, which is ../models/CesiumGround/Cesium_Ground.json in this example.

An optional scale is also provided to fromGltf to enlarge the model. Many true-scale models can be small, so it can help to use a large scale when first testing a model, even something very large like 200000.0. For example:

A modelMatrix is also provided to fromGltf to position and rotate the model. This creates a local coordinate system for the model. Here, Cesium.Transforms.eastNorthUpToFixedFrame is used to create a local east-north-up coordinate system with an origin of -75.62898254394531 degrees longitude and 40.02804946899414 degrees latitude. The model’s modelMatrix property can be changed at any time to move the model.

To visualize the coordinate system, use the Cesium Inspector by adding the following line of code anywhere under var viewer = ... on Line 4.

viewer.extend(Cesium.viewerCesiumInspectorMixin);

Hi F8 and now the inspector UI is shown in the upper left. Expand Primitives, click Pick a Primitive, click on the ground vehicle model, and then check show reference frame.

Here, the x axis (east) is red, the y axis (north) is green, and z (up) is blue.

We can use the same code to load the aircraft or character model by just changing the url passed to fromGltf to '../models/CesiumAir/Cesium_Air.json' or '../models/CesiumMan/Cesium_Man.json', respectively. See the reference documentation for Cesium.Model.fromGltf for all its options.

Animations

Each of these models have animations built into them that were key-framed by an artist, i.e., an artist created an animation by defining several key poses, which Cesium interpolates at runtime to create a smooth animation.

To play the animations, add the following code after calling Cesium.Model.fromGltf.

model.readyToRender.addEventListener(function(model) {
    model.activeAnimations.addAll({
        loop : Cesium.ModelAnimationLoop.REPEAT
    });
});

Since animations are stored in the glTF model, we need to wait for the readyToRender event before accessing them. addAll is used to play all animations in the model. Cesium.ModelAnimationLoop.REPEAT loops the animation until it is removed from the activeAnimations collection. To play a particular animation, use add instead, and provide the animation’s id (glTF JSON property name).

Animation is synced with the Cesium clock so increasing or decreasing the clock speed or reversing the direction using the timeline and playback widgets also affects model animations.

In addition to the loop option, addAll and add provide a number of options to control when the animation starts and stops, its speed, and its direction. For example, the following animates at half-speed (relative to the Cesium clock) and in reverse.

model.activeAnimations.addAll({
    loop : Cesium.ModelAnimationLoop.REPEAT,
    speedup : 0.5,
    reverse : true
});

add returns a ModelAnimation object (addAll returns an array of these), which has events for when the animation starts, stops, and updates each frame. This allows, for example, starting one animation relative to another. See the start, stop, and update events.

Picking

Like all Cesium primitives, Scene.pick will return a Model as part of its result if a model is selected. In addition, the glTF id (JSON property name) for the glTF node and glTF mesh are also returned, which allows precise picking of different model parts. The following example displays node and mesh name under the mouse cursor in the console window.

var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
handler.setInputAction(
    function (movement) {
        var pick = scene.pick(movement.endPosition);
        if (Cesium.defined(pick) && Cesium.defined(pick.node) && Cesium.defined(pick.mesh)) {
            console.log('node: ' + pick.node.name + '. mesh: ' + pick.mesh.name);
        }
    },
    Cesium.ScreenSpaceEventType.MOUSE_MOVE
);

For a complete Sandcastle example showing model loading, animation, and picking, see the 3D models example.

Converting COLLADA to glTF

To convert a COLLADA model to glTF for use with Cesium, use the web-based COLLADA-to-glTF converter. This will convert the .dae file to glTF files (.json, .bin, and .glsl) and convert image files to .png if they are not in a web-browser-friendly format.

Troubleshooting

If there is an issue loading a 3D model in Cesium, first pinpoint where the problem is. It will be either in

  • the COLLADA exporter of the modeling tool, e.g., Maya, Modo, SketchUp, etc., or
  • the COLLADA-to-glTF converter, or
  • the Cesium glTF renderer.

On Mac, to determine if a COLLADA file was exported correctly, double-click on the .dae file and it should appear in the Preview window. If the model has animations, mousing over the bottom of the window will bring up a toolbar to play them.

If the COLLADA file is not valid, Preview will display an error. This usually indicates that there is a bug in the COLLADA exporter used to create the COLLADA file.

To try to workaround this, install Xcode, then right-click on the .dae file and select Open With -> Xcode.

Xcode displays the model similar to Preview but has more features like the ability to select individual nodes. Xcode also implements many workarounds for invalid COLLADA files so it can often load a COLLADA file that Preview can’t. If the model loads in Xcode, select File - Save to save the model with the workarounds, and then it should load in Preview OK.

If it still doesn’t load in Preview, then there is a problem with the COLLADA exporter. Make sure you have the latest version and submit a bug to the modeling tool (not Cesium). It can also be worth trying exporting as .fbx or another format and then import into another modeling tool with a better COLLADA exporter like 3ds Max.

Once we have a valid COLLADA file, run it through the COLLADA-to-glTF converter, and then try to load it in Cesium. If it doesn’t load in Cesium or it displays incorrectly, there is either a bug in the converter or in Cesium. To get more details, open the browser’s developer tools (Ctrl-Shift-I in Chrome) and enable Pause on all exceptions (in the Sources tab in Chrome), and then reload the Cesium app.

Post a message to the Cesium forum and we can often provide a workaround until a fix is available. In your post, please include:

  • The original COLLADA and converted glTF files. We recognize that not everyone can share their models, but if you can, it dramatically increases our ability to help.
  • The browser’s console window and any exceptions that were thrown when the model was loaded, e.g.

Resources

Check out the 3D models example in Sandcastle and the reference documentation for Model and ModelAnimationCollection.

If you have questions, post them on the forum.


Back to top

blog comments powered by Disqus
Fork Cesium on GitHub