Using GLTFLoader.parse as opposed to GLTFLoader.load

I’m using

Linux PAULINE 5.19.0-41-generic #42~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Apr 18 17:40:00 UTC 2 x86_64 x86_64 x86_64 GNU/Linux

I’m running apache2 and I can easily use GLTFLoader.load(…) to load a (binary) ‘.glb’ file from the filesystem. I can even use TWEEN to make the model bob up/down in/out and it generally looks really smart.

I like to make things difficult for myself though, so I used MYSQL’s LOAD_FILE function to load the models I use into a BLOB datatype with the intention of SELECTing them using PHP and passing them on to GLTFLoader.parse(…).

I’ve tried all kind of things but I’m not really sure (even after having looked at the source code of GLTFLoader.load(…) what I’m doing wrong. Is there a tutorial somewhere on using GLTFLoader.parse(…) with BLOBS from MYSQL.

My latest attempt was along these lines but I’m definitely barking up some wrong tree.

var data = <?=$data?>;
    const obj = { data };
const blob = new Blob(
	[JSON.Stringify(obj, null, 2)], {
	type: "application/json";
});

I’m aware that you’re probably gonna use more in the way of code and specific errors but I have so many of both I thought I’d be as general as possible to start with.

Regards,
Søren

The input to the parse method should be the ArrayBuffer contents of a .glb, or the JSON contents of a .gltf file. Can’t be sure what your data variable is, but if it looks something like this…

{
  "asset": {"version": "2.0", "generator": "Blender vX.Y.Z"},
  ...
}

… then you could skip the rest of that and just pass it directly into the parse method.

Thank you. I’ll try that.

Here’s the intermediate result I talked about:

https://103.45.246.231/index6.php

It’s a self-signed certificate. No malicious code. Work in progress…

I’m probably doing a lot of stuff wrong but as I said I just started playing with this stuff, and Javascript is new to me.

So, I’m gonna answer my own question. You answer - donmccurdy - wasn’t entirely uncorrect, and it put me on the right path. The problem in a nutshell is that GLTFLoader handles 2 formats. The clean text (JSON) one, with the extension .gltf, and the binary format called .glb.

What I have is the binary one. .glb files, which GLFTLoader.load(…) will handle just fine, but the GLTFLoader.parse(…) function will only handle clean text versions (JSON presumably).

I’m thus left with a number of choices:

1.) Convert the binary GLB files to clean GLFT data on the server once and for all.

2.) Use nodejs’ (installed using “npm”) “glTF-Pipeline” to convert the data after download to the client’s computer using javascript.

3.) Do it using PHP on the server before serving the page.

That took me quite a while to figure out. If I’m wrong I’d love to be told.

FYI:

GLTFLoader.parse is able to parse the binary contents of a .glb, as well. But it needs to actually be binary data, and any string encoding would need to be decoded to a Uint8Array or ArrayBuffer, before you pass that data into the parse() method. Where <?=$data?> exists in an HTML file for binary data, PHP is certainly doing some kind of string encoding, but that’s not much help to us if we don’t know what encoding is used.

Of the choices —

  1. Converting your binary GLB files to glTF on the server, or in advance, is an option. This will increase downloaded size by +33% and add some parsing time on the client, but for small glTF files it may not be a noticeable problem.

  2. glTF Pipeline cannot run clientside. Something like glTF Transform can do the conversion client side, but you still have the same problem you started with – you need to get the binary data from the server to the client, intact, to do anything with it. If that part were solved there’d be no need for conversion anyway, so this is not a solution.

  3. Same result as (1), but higher complexity.


My advice here would somewhat depend on the scope and goals of what you’re building. In order of my own preference:

For professional work, I would not store large binary files in a SQL database. Instead use a dedicated Blob storage service, like Amazon S3 or Google Cloud Storage, which can handle serving binary files efficiently without extra load on your database. The database would only store pointers to the Blob storage.

Alternatively, a dedicated path on disk, which Apache2 (not your PHP server) will serve as static content with proper binary content headers.

Alternatively, have PHP serve the GLBs on a separate path from your HTML, being careful to write the binary data with a correct “Content-Type: application/octet-stream” header.

As a final option, you could base64 encode the binary data in PHP, then decode base64 to a binary ArrayBuffer in JavaScript. This option incurs the +33% size penalty, and additional encode/decode time.