GLTF loader API question

HI, Im trying to use the importMeshAsync method from the gltfLoader.

I was able to split my glb data to obtain an object with the two property like this:

const gltfData = {
					json: jsonObject,
					bin: chunkBinaryData,
				};

But the chunkBinaryData is an ArrayBuffer and the importMeshAsync method expect the bin to be an IDataBuffer.

export interface IDataBuffer {
    /**
     * Reads bytes from the data buffer.
     * @param byteOffset The byte offset to read
     * @param byteLength The byte length to read
     * @returns A promise that resolves when the bytes are read
     */
    readAsync(byteOffset: number, byteLength: number): Promise<ArrayBufferView>;
    /**
     * The byte length of the buffer.
     */
    readonly byteLength: number;
}

Im a bit confuse here about how to prepare the bin data to be proceed in the importMeshAsync method. Im using Typescript.

Thank you!

Marc-Andre.

I am wondering why would you directly use those functions instead of the default provided ones?

@bghgary might be able to help regarding the setup.

My project is a little bit tricky , I have already try the default provided import Mesh function without any success and I have already use the stl, obj and vtp loader with success but I am struggling with the gltf one.

It would be great if you can explain what you are doing. These interfaces are not intended to be directly called by users.

The IDataBuffer interface was introduced to support http range requests for progressively loading a self-contained GLB .This required loading data asynchronously from the JSON/BIN chunks.

Hello,
thank you for your answer, I have found that the issue I got is that the file load in my scene but the position are incorrect and that is why I didn’t see it.

So im now able to load my imported gltf file extension from a base64 string using the SceneLoader.Append method.

I just need to found the proper position to set the mesh in front of my camera.

But for a glb file format, Im not sure how I can do it and I need to be able to load both gltf and glb format.

Do you have some exemple of loading a glb file?
I need to get the mesh result and pass it to other method I have, to set the position of the camera, create light and many other actions.

Thank you Marc-Andre

SceneLoader.Append should accept both .gltf and .glb. Are you specifically trying to load a base64 encoded GLB? The loader will accept base64 encoded strings for GLBs that start with:

            || StringTools.StartsWith(data, "data:base64," + GLTFFileLoader.magicBase64Encoded) // this is technically incorrect, but will continue to support for backcompat.
            || StringTools.StartsWith(data, "data:;base64," + GLTFFileLoader.magicBase64Encoded)
            || StringTools.StartsWith(data, "data:application/octet-stream;base64," + GLTFFileLoader.magicBase64Encoded)
            || StringTools.StartsWith(data, "data:model/gltf-binary;base64," + GLTFFileLoader.magicBase64Encoded);

Im loading the file from a fileReader like this:

fileReader.readAsText(file, 'binary');
			fileReader.onload = function (e) {
				const gltfString: string = e.target.result as string;
				console.log('GltfString ', gltfString);

				SceneLoader.Append('', `data:${gltfString}`, self.scene, (success) => {
					console.log('Success:::::', success);
					self.improveMeshAndPositionCamera(success.meshes);
				});
			};

I think the issue come from the file Im trying to load, he had some strange characters at the beginning of the file:

logger.js:43 BJS - [15:38:28]: Unable to load from data:glTFx��JSON{“accessors” : [{“bufferView” : 0, “byteOffset” : 0, “componentType” : 5125, “count” : 1622061, “type” : “SCALAR”, “max” : [1318107], “min” : [0]}, {“bufferView” : 1, “byteOffset” : 0, “componentType” : 5126, “count” : 1318108, “type” : “VEC3”, “max” : [257.4779968261719, 284.7049865722656, 165.04400634765625], “min” : [-184.63600158691406, -186.2949981689453, -161.95799255371094], “name” : “POSITION”}], “asset” : {“generator” : “Aspose.3D 21.8.1”, “version” : “2.0”}, “buffers” : [{“byteLength” : 25952984}], “bufferViews” : [{“buffer” : 0, “byteOffset” : 0, “byteLength” : 6488244, “target” : 34963}, {“buffer” : 0, “byteOffset” : 6488248, “byteLength” : 19464732, “byteStride” : 12, “target” : 34962}], “meshes” : [{“primitives” : [{“attributes” : {“POSITION” : 1}, “indices” : 0, “mode” : 4}], “name” : “”}], “nodes” : [{“mesh” : 0, “name” : “”}], “scene” : 0, “scenes” : [{“nodes” : [0]}]} ��BINa

Well, the problem is you are calling readAsText. The AsText part is the problem. :slight_smile:

You probably should be calling ReadAsArrayBuffer.

GLB is a binary format not text.

Ha yeah make a lot of sense :sweat_smile: But how do I pass the arrayBuffer to be loaded in the SceneLoader.Append method next im still confuse.

There are two options.

  1. Create a Blob URL and pass that in.
  2. Create a File object and pass that in.

See Add support for loading glb from a base64-encoded string or arraybuffer · Issue #5579 · BabylonJS/Babylon.js (github.com) for some discussion on the support for this.

Perhaps some more documentation would be useful. @PirateJC

EDIT: looks like you already have a file object. Maybe bypass the file reader completely. :slight_smile:

Nice I should be able to make it work from this.
A big thank to you for your time!
Really appreciated! Have a good day and thank you again!

2 Likes