error when passing gtlf to model.fromGltf()

Hey everyone,

I'm trying to pass a gltf object directly to the function model.fromGltf() instead of loading it from a file as suggested in the tutorial.
When loading the model from a file everything works just fine, so my model seems to be valid. However when I try to pass the same gltf directly I get the following error from Cesium.js:401:
"Uncaught TypeError: Cannot read property 'lastIndexOf' of undefined"

here is a snippet of my code:

var gltf = {<some gltf code>}
var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(-75.62898254394531, 40.02804946899414, 10.0))

var viewer = new Cesium.Viewer('cesiumContainer'),
    scene = viewer.scene

scene.primitives.removeAll()

var model = scene.primitives.add(Cesium.Model.fromGltf({
  gtlf: gltf,
  modelMatrix : modelMatrix,
  minimumPixelSize : 128,
  scale: 20000.0
}))

Does anyone have a suggestion what I am doing wrong here? Or might there actually be a bug in Cesium?

If you have the JSON for glTF, use “new Model” instead of Model.fromGltf, which is only for loading from a file. For example:

https://github.com/AnalyticalGraphicsInc/cesium/blob/master/Specs/Scene/ModelSpec.js#L149

Patrick

Thanks for your help.
I am wondering what the "gltf" option in Model.fromGltf actually is for?

Using "new Model()" I got rid of the error. However nothing seems to be rendered now.
Also I try to use the readyToRender event to zoom in to the model. Which seems not to get fired now. Is this event only for loading from file too?

Stephan

I am wondering what the “gltf” option in Model.fromGltf actually is for?

I don’t think fromGltf has a gltf option, only new Model does.

Also I try to use the readyToRender event to zoom in to the model. Which seems not to get fired now. Is this event only for loading from file too?

Are you using Cesium 1.6? Try Model.readyPromise.

Patrick

So I updated to Cesium 1.6 and tried to use the readyPromise.
I found two different notations in the model documentation, the first one beeing:

Cesium.when(model.readyPromise).then(function(model) {...})
(https://cesiumjs.org/Cesium/Build/Documentation/Model.html#readyPromise)

and the second:
model.readyPromise.then(function(model) {...})
(https://cesiumjs.org/Cesium/Build/Documentation/Model.html#fromGltf)

I tried both without success, the first one passes an undefined model to my anonymous function and the second one gives me an error, that readyPromise is not defined. Which approach is the right one?

They are both correct. “when” works with or without a promise while then is only available on an existing promises. Basically you can use “when” in cases where you are not sure if you are getting a value or a promise to a value. Here’s a complete example that you can copy/paste into Sandcastle.

var viewer = new Cesium.Viewer(‘cesiumContainer’);

var scene = viewer.scene;

var height = 5000.0;

var heading = 0.0;

var pitch = Cesium.Math.toRadians(10.0);

var roll = Cesium.Math.toRadians(-20.0);

var origin = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, height);

var modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(origin, heading, pitch, roll);

var model = scene.primitives.add(Cesium.Model.fromGltf({

url : ‘…/…/SampleData/models/CesiumAir/Cesium_Air.gltf’,

modelMatrix : modelMatrix,

minimumPixelSize : 128

}));

model.readyPromise.then(function(model) {

// Play and loop all animations at half-speed

model.activeAnimations.addAll({

speedup : 0.5,

loop : Cesium.ModelAnimationLoop.REPEAT

});

var camera = viewer.camera;

// Zoom to model

var controller = scene.screenSpaceCameraController;

var r = 2.0 * Math.max(model.boundingSphere.radius, camera.frustum.near);

controller.minimumZoomDistance = r * 0.5;

var center = Cesium.Matrix4.multiplyByPoint(model.modelMatrix, model.boundingSphere.center, new Cesium.Cartesian3());

var heading = Cesium.Math.toRadians(230.0);

var pitch = Cesium.Math.toRadians(-20.0);

camera.lookAt(center, new Cesium.HeadingPitchRange(heading, pitch, r * 2.0));

}).otherwise(function(error){

window.alert(error);

});

thanks a lot. this helped me solve my issue. :slight_smile: