GLTF loader can't parse compressed GLB string?

I have a simple GLB file compressed using “glTF-Transform”, which loads fine in GLTF Viewer. I’ve attached the model for reference.

But when I extract the contents into a string and attempt to parse it using “loader.parse”, I get the following error:

Error: Malformed buffer data: -1

The code I’m using is:

var enc = new TextEncoder().encode(glb_string);

loader.parse(enc.buffer, '', function(object){
	console.log(object);
}, function(error){
	console.log(error);
});

When loading the GLB model directly with the loader, it also loads fine.
So is it the case that the GLTF loader’s parse function is unable to load compressed GLB models?

Thank You!

model.glb (149.3 KB)

1 Like

The ArrayBuffer passed to GLTFLoader.parse cannot be an encoded string; the underlying data must be binary. When you “extract the contents into a string”, how are you doing that? If it’s Base64 encoding, you must decode it before use. If it’s any other string encoding then that’s probably a mistake.

If you want a string representation of a GLB then Base64 in a Data URI is probably the way to go – you can pass that Data URI directly to the load function. But be aware than Base64 is less efficient than a binary representation and will add ~33% size, and some additional parsing time.

1 Like

At the moment I’m simply opening the GLB file in my code editor, copying the contents into my database and save it as a string, without any encoding just to test.

What would you recommend as the correct way to convert GLB files into Base64 in a Data URI in Node JS?

1 Like

Ah yeah, copy/paste won’t work for binary data. If you’re on a macOS or Linux system you can do something like:

base64 -i input.glb -o output.txt

Or in Node.js:

import fs from 'fs/promises';
const glb = await fs.readFile('input.glb');
const base64 = glb.toString('base64');

That’s raw base64 encoding. To make it into a valid URL you’d prepend the (exact) string below:

data:application/octet-stream;base64,
2 Likes

I tried both methods and the outputted results are the same. So I prepended:

data:application/octet-stream;base64,

to the raw base64 encoding and then pasted the whole string to loader.parse(). But I get the following error:

JSON Parse error: Unexpected identifier "data"

model.txt (199.0 KB)

1 Like

Sorry I missed it where you said to pass the the Data URI directly to the load() function. Now it’s working great :slight_smile:

Thank You!!

1 Like

I don’t understand. Please, share this working code example with with us . I am beginner that lib and programing.

My code:


const Scene = async () => {
    const loader = new GLTFLoader()
    var enc = new TextEncoder().encode(glbJSON.data);
    
    loader.parse(enc.buffer, '', function (object) {
        console.log(object);
    }, function (error) {
        console.log(error);
    });

    return (
        <Suspense fallback={null}>
            <primitive object={loader.scene} />
        </Suspense>
    )
}

sitedeneme.json (1.6 KB)