Generate gltf using Cesium geometry

Hi everyone

I want to write a large amount of gltf models with different attributes using Cesium Geometry.

Previously, I succeeded in generate gltf using Three.js.

What I did is to modify the gltf’s accessors, bufferviews, buffers and other related attributes to match the geometry that created by Three.js. And I created a lot of Cylinder gltf.

But some of the geometry is created more convient by Cesium Geometry than Three.js, e.g. polygon on the surface of the ellipsoid.

But I met problem when I try to generate a sample gltf. my code in nodejs is below:

var Cesium = require(‘Cesium’);

var fs = require(‘fs’);

/* Create a extruded triangle */

var polygon = new Cesium.PolygonGeometry({

polygonHierarchy : new Cesium.PolygonHierarchy(

Cesium.Cartesian3.fromDegreesArray([

0,90,

72,74.2421,

0,74.2421

])

),

extrudedHeight: 10000

});

var geometry = Cesium.PolygonGeometry.createGeometry(polygon);

//load a gltf template, the template itselt works

var templ = fs.readFileSync(‘box.gltf’);

var templobj = JSON.parse(templ);

var obj = templobj;

//write indices accessor and bufferview

var accessor_21 = obj.accessors.accessor_21;

accessor_21.count = geometry.indices.length;

var bufferView_29 = obj.bufferViews.bufferView_29;

bufferView_29.byteLength = geometry.indices.buffer.byteLength;

bufferView_29.byteOffset = 0;

var indexBuffer = new Buffer(geometry.indices.buffer);

var indexBase64 = indexBuffer.toString(‘base64’);

//write position

var accessor_23 = obj.accessors.accessor_23;

accessor_23.count = geometry.attributes.position.values.length;

var positionBuffer = new Buffer(geometry.attributes.position.values.buffer);

var positionBase64 = positionBuffer.toString(‘base64’);

//write normal

var accessor_25 = obj.accessors.accessor_25;

accessor_25.count = geometry.attributes.normal.values.length;

accessor_25.byteOffset = positionBuffer.length;

var normalBuffer = new Buffer(geometry.attributes.normal.values.buffer);

var normalBase64 = normalBuffer.toString(‘base64’);

//write positions and normals bufferView
var bufferView_30 = obj.bufferViews.bufferView_30;

bufferView_30.byteOffset = indexBuffer.length;

bufferView_30.byteLength = positionBuffer.length+normalBuffer.length;

//write Buffer

var buffer = Buffer.concat([indexBuffer,positionBuffer,normalBuffer]);

var bufferBase64 = buffer.toString(‘base64’);

var boxBuffer = obj.buffers.Box;

boxBuffer.byteLength = buffer.length;

boxBuffer.uri = “data:application/octet-stream;base64,”+bufferBase64;

//write into a file

var newgltf = JSON.stringify(obj);

fs.writeFileSync(‘triangle.gltf’, newgltf);

``

My code can generate a gltf file, but it can’t be optimized by gltf-pipeline, and show the errors below:

Unhandled rejection RangeError: Index out of range

at checkOffset (buffer.js:817:11)

at Buffer.readFloatLE (buffer.js:994:5)

at readBufferComponent (G:\host\3d-tiles-creator\gltf-pipeline\lib\readBufferComponent.js:29:27)

at findAccessorMinMax (G:\host\3d-tiles-creator\gltf-pipeline\lib\findAccessorMinMax.js:46:33)

at accessorDefaults (G:\host\3d-tiles-creator\gltf-pipeline\lib\addDefaults.js:27:30)

at addDefaults (G:\host\3d-tiles-creator\gltf-pipeline\lib\addDefaults.js:537:5)

at Function.Pipeline.processJSONWithExtras (G:\host\3d-tiles-creator\gltf-pipeline\lib\Pipeline.js:89:5)

at G:\host\3d-tiles-creator\gltf-pipeline\lib\Pipeline.js:219:29

at tryCatcher (G:\host\3d-tiles-creator\gltf-pipeline\node_modules.3.4.7@bluebird\js\release\util.js:16:23)

at Promise._settlePromiseFromHandler (G:\host\3d-tiles-creator\gltf-pipeline\node_modules.3.4.7@bluebird\js\release\promise.js:510:31)

at Promise._settlePromise (G:\host\3d-tiles-creator\gltf-pipeline\node_modules.3.4.7@bluebird\js\release\promise.js:567:18)

at Promise._settlePromise0 (G:\host\3d-tiles-creator\gltf-pipeline\node_modules.3.4.7@bluebird\js\release\promise.js:612:10)

at Promise._settlePromises (G:\host\3d-tiles-creator\gltf-pipeline\node_modules.3.4.7@bluebird\js\release\promise.js:691:18)

at Async._drainQueue (G:\host\3d-tiles-creator\gltf-pipeline\node_modules.3.4.7@bluebird\js\release\async.js:133:16)

at Async._drainQueues (G:\host\3d-tiles-creator\gltf-pipeline\node_modules.3.4.7@bluebird\js\release\async.js:143:10)

at Immediate.Async.drainQueues (G:\host\3d-tiles-creator\gltf-pipeline\node_modules.3.4.7@bluebird\js\release\async.js:17:14)

Hi guys,

I found the solution now:

It seems I misunderstand the count property in position accessor. In fact, 3 elements should be one count to describe position.

Now I met a new problem,

I create a gltf file containing a polygon on surface of the globe.

I want to load it into Cesium using the code below.

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

var entity = viewer.entities.add({

name : ‘…/…/SampleData/models/triangle.gltf’,

position : new Cesium.Cartesian3(0,0,0),

model : {

uri : ‘…/…/SampleData/models/triangle.gltf’

}

});

``

I asume the origin of the gltf is the center of the earth.

But I got error like this:

An error occurred while rendering. Rendering has stopped.

RuntimeError: matrix is not invertible because its determinate is zero.

Error

at new RuntimeError (http://localhost/cesium/Source/Core/RuntimeError.js:43:19)

at Function.Matrix4.inverse (http://localhost/cesium/Source/Core/Matrix4.js:2519:19)

at cleanInverseModelView (http://localhost/cesium/Source/Renderer/UniformState.js:990:21)

at UniformState.get (http://localhost/cesium/Source/Renderer/UniformState.js:456:17)

at cleanNormal (http://localhost/cesium/Source/Renderer/UniformState.js:1080:45)

at UniformState.get (http://localhost/cesium/Source/Renderer/UniformState.js:553:17)

at Object.u_normalMatrix (http://localhost/cesium/Source/Scene/Model.js:2657:36)

at ShaderProgram._setUniforms (http://localhost/cesium/Source/Renderer/ShaderProgram.js:484:47)

at continueDraw (http://localhost/cesium/Source/Renderer/Context.js:924:36)

at Context.draw (http://localhost/cesium/Source/Renderer/Context.js:965:9)

``

Any help appreciated.

Chris

Hi guys,

I made the gltf into 3d-tiles, and load it into Cesium successfully.

Though I need to modify the matrix of rootnode in gltf. It works well anyway.

Are there any other procedures in handling gltf models than 3d-tiles?

Chris

Hi Chris,

Glad you were able to figure out your problems.

I’m not really sure what your asking here: “Are there any other procedures in handling gltf models than 3d-tiles?”

Can you please elaborate?

Best,

Hannah

Hi,

I am following this post since I am interested in obtaining a similar result to the one presented by Chris.

Would it be possible to receive a working example so that I can also generate gltf models using Cesium Geometries?

I thank you in advance.

Best regards,
Andrea

Hi Andrea,

Can I get more information about your use case? In what contexts would you need to use the gltf models?

Thanks,

  • Rachel