Giving Model a frozen GLTF object crashes Cesium

I made a Sandcastle demo.

I get a different error in my case:

TypeError: Cannot read property 'pendingBufferLoads' of undefined
Model.update
../../../Source/Scene/Model.js:5210:22

5207 | if (this._state === ModelState.LOADING) {  
5208 |   // Transition from LOADING -> LOADED once resources are downloaded and created.
5209 |   // Textures may continue to stream in while in the LOADED state.> 
5210 |   if (loadResources.pendingBufferLoads === 0) {       |                    ^  
5211 |     if (!loadResources.initialized) {  
5212 |       frameState.brdfLutGenerator.update(frameState);
...

Inspecting the actual model primitive, it appears that the model never finishes loading.

This issue arose because I am using ImmerJS, which freezes objects.

Sandcastle code in case it disappears:

const viewer = new Cesium.Viewer("cesiumContainer");

// copied from https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/1.0/Box/glTF-Embedded/Box.gltf
const gltf = {
"accessors": {
"accessor_21": {
"bufferView": "bufferView_29",
"byteOffset": 0,
"byteStride": 0,
"componentType": 5123,
"count": 36,
"type": "SCALAR"
},
"accessor_23": {
"bufferView": "bufferView_30",
"byteOffset": 0,
"byteStride": 12,
"componentType": 5126,
"count": 24,
"max": [
0.5,
0.5,
0.5
],
"min": [
-0.5,
-0.5,
-0.5
],
"type": "VEC3"
},
"accessor_25": {
"bufferView": "bufferView_30",
"byteOffset": 288,
"byteStride": 12,
"componentType": 5126,
"count": 24,
"max": [
1,
1,
1
],
"min": [
-1,
-1,
-1
],
"type": "VEC3"
}
},
"animations": {},
"asset": {
"generator": "collada2gltf@027f74366341d569dea42e9a68b7104cc3892054",
"premultipliedAlpha": true,
"profile": {
"api": "WebGL",
"version": "1.0.2"
},
"version": "1.0"
},
"bufferViews": {
"bufferView_29": {
"buffer": "Box",
"byteLength": 72,
"byteOffset": 0,
"target": 34963
},
"bufferView_30": {
"buffer": "Box",
"byteLength": 576,
"byteOffset": 72,
"target": 34962
}
},
"buffers": {
"Box": {
"byteLength": 648,
"type": "arraybuffer",
"uri": "data:application/octet-stream;base64,AAABAAIAAwACAAEABAAFAAYABwAGAAUACAAJAAoACwAKAAkADAANAA4ADwAOAA0AEAARABIAEwASABEAFAAVABYAFwAWABUAAAAAvwAAAL8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAL8AAAA/AAAAPwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAA/AAAAPwAAAD8AAAC/AAAAPwAAAL8AAAC/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAvwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAvwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAvwAAAL8AAAC/AAAAvwAAAD8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAD8AAAC/AAAAPwAAAL8AAAC/AAAAPwAAAD8AAAC/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/"
}
},
"materials": {
"Effect-Red": {
"name": "Red",
"technique": "technique0",
"values": {
"diffuse": [
0.8,
0,
0,
1
],
"shininess": 256,
"specular": [
0.2,
0.2,
0.2,
1
]
}
}
},
"meshes": {
"Geometry-mesh002": {
"name": "Mesh",
"primitives": [
{
"attributes": {
"NORMAL": "accessor_25",
"POSITION": "accessor_23"
},
"indices": "accessor_21",
"material": "Effect-Red",
"mode": 4
}
]
}
},
"nodes": {
"Geometry-mesh002Node": {
"children": [],
"matrix": [
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1
],
"meshes": [
"Geometry-mesh002"
],
"name": "Mesh"
},
"node_1": {
"children": [
"Geometry-mesh002Node"
],
"matrix": [
1,
0,
0,
0,
0,
0,
-1,
0,
0,
1,
0,
0,
0,
0,
0,
1
],
"name": "Y_UP_Transform"
}
},
"programs": {
"program_0": {
"attributes": [
"a_normal",
"a_position"
],
"fragmentShader": "Box0FS",
"vertexShader": "Box0VS"
}
},
"scene": "defaultScene",
"scenes": {
"defaultScene": {
"nodes": [
"node_1"
]
}
},
"shaders": {
"Box0FS": {
"type": 35632,
"uri": "data:text/plain;base64,cHJlY2lzaW9uIGhpZ2hwIGZsb2F0Owp2YXJ5aW5nIHZlYzMgdl9ub3JtYWw7CnVuaWZvcm0gdmVjNCB1X2RpZmZ1c2U7CnVuaWZvcm0gdmVjNCB1X3NwZWN1bGFyOwp1bmlmb3JtIGZsb2F0IHVfc2hpbmluZXNzOwp2b2lkIG1haW4odm9pZCkgewp2ZWMzIG5vcm1hbCA9IG5vcm1hbGl6ZSh2X25vcm1hbCk7CnZlYzQgY29sb3IgPSB2ZWM0KDAuLCAwLiwgMC4sIDAuKTsKdmVjNCBkaWZmdXNlID0gdmVjNCgwLiwgMC4sIDAuLCAxLik7CnZlYzQgc3BlY3VsYXI7CmRpZmZ1c2UgPSB1X2RpZmZ1c2U7CnNwZWN1bGFyID0gdV9zcGVjdWxhcjsKZGlmZnVzZS54eXogKj0gbWF4KGRvdChub3JtYWwsdmVjMygwLiwwLiwxLikpLCAwLik7CmNvbG9yLnh5eiArPSBkaWZmdXNlLnh5ejsKY29sb3IgPSB2ZWM0KGNvbG9yLnJnYiAqIGRpZmZ1c2UuYSwgZGlmZnVzZS5hKTsKZ2xfRnJhZ0NvbG9yID0gY29sb3I7Cn0K"
},
"Box0VS": {
"type": 35633,
"uri": "data:text/plain;base64,cHJlY2lzaW9uIGhpZ2hwIGZsb2F0OwphdHRyaWJ1dGUgdmVjMyBhX3Bvc2l0aW9uOwphdHRyaWJ1dGUgdmVjMyBhX25vcm1hbDsKdmFyeWluZyB2ZWMzIHZfbm9ybWFsOwp1bmlmb3JtIG1hdDMgdV9ub3JtYWxNYXRyaXg7CnVuaWZvcm0gbWF0NCB1X21vZGVsVmlld01hdHJpeDsKdW5pZm9ybSBtYXQ0IHVfcHJvamVjdGlvbk1hdHJpeDsKdm9pZCBtYWluKHZvaWQpIHsKdmVjNCBwb3MgPSB1X21vZGVsVmlld01hdHJpeCAqIHZlYzQoYV9wb3NpdGlvbiwxLjApOwp2X25vcm1hbCA9IHVfbm9ybWFsTWF0cml4ICogYV9ub3JtYWw7CmdsX1Bvc2l0aW9uID0gdV9wcm9qZWN0aW9uTWF0cml4ICogcG9zOwp9Cg=="
}
},
"skins": {},
"techniques": {
"technique0": {
"attributes": {
"a_normal": "normal",
"a_position": "position"
},
"parameters": {
"diffuse": {
"type": 35666
},
"modelViewMatrix": {
"semantic": "MODELVIEW",
"type": 35676
},
"normal": {
"semantic": "NORMAL",
"type": 35665
},
"normalMatrix": {
"semantic": "MODELVIEWINVERSETRANSPOSE",
"type": 35675
},
"position": {
"semantic": "POSITION",
"type": 35665
},
"projectionMatrix": {
"semantic": "PROJECTION",
"type": 35676
},
"shininess": {
"type": 5126
},
"specular": {
"type": 35666
}
},
"program": "program_0",
"states": {
"enable": [
2929,
2884
]
},
"uniforms": {
"u_diffuse": "diffuse",
"u_modelViewMatrix": "modelViewMatrix",
"u_normalMatrix": "normalMatrix",
"u_projectionMatrix": "projectionMatrix",
"u_shininess": "shininess",
"u_specular": "specular"
}
}
}
};

const origin = Cesium.Cartesian3.fromDegrees(-122, 38, 100);
const modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(origin);
const hpr = new Cesium.HeadingPitchRoll(0, -1, 0);

// Uncomment this line and rerun
//Object.freeze(gltf);

const model = new Cesium.Model({
  gltf: gltf,
  minimumPixelSize: 64,
  modelMatrix: modelMatrix,
  scale: 10,
});

viewer.scene.primitives.add(model);
viewer.camera.setView({destination: origin, orientation: hpr});
viewer.camera.moveBackward(1000);

Hello @Rachel,

Yes, it looks like Model attempts to add properties to the gltf param if they are missing. I opened an issue here for us to fix this: Model mutates the gltf object parameter · Issue #9303 · CesiumGS/cesium · GitHub

In the meantime, you can try cloning your gltf before passing it in. We have a clone helper function for this: Global - Cesium Documentation

Best regards,

Hannah
Cesium Staff

1 Like