GLB import error - only on Quest or phone

Hi,

I cant reproduce this on a PG yet but I starting to investigate WebXR and I have a weird problem affecting one of my models. I am using the helpers to generate an XR environment and everything works fine on a PC browser but when running on a Quest or a Samsung Galaxy S7 I get an error in the ImportMesh function that says “unable to import… invalid index into function table”. This is before I switch to XR mode so it is probably nothing to do with XR but something with the model itself. Another model works fine in XR and the problematic model works fine on PC. Perhaps this is more to do with whether it is running Pollyfill or not???
Any ideas on how I can troubleshoot this? The model is Draco compressed so I could try without (but the other model that works is also Draco compressed).

Pinging @RaananW

Hi,

as you say - this is probably not XR related, especially if it happens prior to actually using XR. You say you can’t reproduce this on the playground - does loading the model on the playground using android/quest works well?

Sorry for the tardiness in my reply. The inability to reproduce it in PG was because I didn’t know how to reproduce it (rather than it not being reproducable).

Anyway, I do now. I have setup a site with CORS enabled so I can load the model from there as I beleive it is to do with the model - perhaps it is too big (too many verts) for a mobile version? The PG below works fine on a desktop but not on a mobile device (Samsun Galaxy S7). If you comment out the model and enable another one instead it works. The problem model was originally created in SolidWorks and then via STL into Blender (simplified as much as possible) then exported to GLB with Draco. The other models were FBX->Blender->GLB+Draco.

Am I hiting a size problem or has the original file got some combination of left over mess that is causing a problem?

(I have tested this from multiple servers so confident it is not caused by server environment)

PG: Babylon.js Playground

I can reproduce this, thanks a lot for the playground.

@bghgary - this is the error shown when trying to load on mobile:

Any idea why this would happen?

I can’t repro this on my Android phone (OnePlus 6). From the callstack, it looks like something deep within Draco that is failing. It might be good to ask the Draco team? Issues · google/draco (github.com)

1 Like

Hi Mark,

just catching up on updates - have you tried contacting the draco team on github? were they able to help further?

Hi Raanan, thanks for the prompt. I got pulled onto another project and then had to attend a conference (virtually) so I ran out of data, power and time and had not yet contacted the draco team. However, I just checked again on both my phone and on the Quest and it is now working, so perhaps an update from them has resolved the issue.

The frame rate drops dramatically once the model is loaded (it is a large model) so perhaps it is too detailed and I will need to sacrific some detail or find out specifically is dropping the frame rate…but that’'s another problem. I think we can say the issue iI iniitally raised is no longer a problem.
Thanks.

1 Like

Hmm, I may have spoken too soon. I was just testing the local version of my test model viewer and I noticed that if I drag the model into sandbox it has about 5M indices but in my viewer it was 11M. I was using environment helper to create the ground and had enabled mirror on the ground - this was adding 6M indices. That might be part of the problem as the ground is also set to enable collisions for the camera movement (and later WebXR teleport). So I updated the script to not include the mirror and now when I run it on the phone I get the same error as before!! Weird. Have to go now but will test again tomorrow and if still an issue I will pass up to draco team.

1 Like

Ugh, I think I need to spend more time investigating this as it is not consistently reproducable. First thing today on my phone it worked, then I did a refresh and now it doesn’t work (with the same import error)! Furthermore, the floor reflections were still showing which means it is using a cached version of the script so I need to be sure of what I am running. I can’t seem to force Android Chrome to do a hard refresh. If I go to an incognito tab then the reflections are not there (ie using non-cached script…but still with import error). I have been into Chrome settings/Site Settings/Data Stored and deleted data for the site but it is still using a cached version (reflections on floor) so I don’t know how to force it to refresh.

I suspect the original import error is somehow timing related and may depend on whether it is downloading the model or getting it from cache…except I still got the error with an incognito tab. Currently it seems to work on first try of the day but not thereafter! Until I can reliably isolate it I do not feel comfortable passing it onto draco team and think I need to dig more.

The best way to do a hard reset is to connect your device to a pc and start a debug session. Then in the network tab you can force it to ignore cache.

Incognito, as opposed to what you might think, does use the main browser’s cache. It just doesn’t add additional items to it. So if it was there before - you will still be able to access it.

Thanks Raanan, I had tried a debug session and thought a shift-reload there would have done it but maybe not. I have now tried what you suggested and disabled the cache. The problem persists. I did notice that the draco decoder is coming from preview whereas my code is using cdn - maybe that is related? I will investigate that later (I have to go to more conferences today and am co-presenting at one so will be later). Thanks.

@bghgary will be able to answer this question better than me :slight_smile:

That can certainly cause issues, but I don’t know if it’s related to your current issue.

If you want to be sure, you can configure Draco to be the cdn version instead of the preview:
DracoCompression | Babylon.js Documentation

    DracoCompression.Configuration = {
        decoder: {
            wasmUrl: "https://cdn.babylonjs.com/draco_wasm_wrapper_gltf.js",
            wasmBinaryUrl: "https://cdn.babylonjs.com/draco_decoder_gltf.wasm",
            fallbackUrl: "https://cdn.babylonjs.com/draco_decoder_gltf.js"
        }
    };

You were right @bghgary it wasn’t related. I noticed that on the PC it was using the preview version as well…but I tried anyway and even with cdn versions I still get the error. I also tried setting animationStartMode to NONE as the model that has the problem has an animation whereas the models that don’t throw the error don’t have an animation. I still get the error.

The error is being throw by this code (lines 92-101 of KHR_draco_mesh_compression.ts)

            bufferView._dracoBabylonGeometry = this._loader.loadBufferViewAsync(`/bufferViews/${bufferView.index}`, bufferView).then((data) => {
                const dracoCompression = this.dracoCompression || DracoCompression.Default;
                return dracoCompression.decodeMeshAsync(data, attributes).then((babylonVertexData) => {
                    const babylonGeometry = new Geometry(babylonMesh.name, this._loader.babylonScene);
                    babylonVertexData.applyToGeometry(babylonGeometry);
                    return babylonGeometry;
                }).catch((error) => {
                    throw new Error(`${context}: ${error.message}`);
                });
            });

My interpretation is that it could be being thrown by the decodeMeshAsync function or the lambda function inside the then, but it is unclear which. Am I right in assuming that if it thrown by decodeMeshAsync then it is an issue for the draco team but if it is inside the lambda function then it is an issue for Babylon?

decodeMeshAsync is still a Babylon.js function which still has a bit of code underneath. Are you still getting the same error as you noted previously?

Yes, but only on an android (Samsung Galaxy S7) and a Quest. The stack trace is

000be69e:0x9000 Uncaught RuntimeError: invalid index into function table
at emscripten_bind_PointCloud___destroy___0 (:wasm-function[77]:0x9000)
at a._emscripten_bind_Mesh___destroy___0 (https://cdn.babylonjs.com/draco_wasm_wrapper_gltf.js:58:482)
at y.destroy.y.destroy (https://cdn.babylonjs.com/draco_wasm_wrapper_gltf.js:101:170)
at Object.a.destroy (https://cdn.babylonjs.com/draco_wasm_wrapper_gltf.js:74:3)
at fh (blob:https://outreach.ozgrav.org/d43fce0f-7ae4-484a-91f0-4bd664caca68:1:1306)
at blob:https://outreach.ozgrav.org/d43fce0f-7ae4-484a-91f0-4bd664caca68:1:1644
at Object.a.then (https://cdn.babylonjs.com/draco_wasm_wrapper_gltf.js:72:516)
at onmessage (blob:https://outreach.ozgrav.org/d43fce0f-7ae4-484a-91f0-4bd664caca68:1:1626)
emscripten_bind_PointCloud___destroy___0 @ 000be69e:0x9000
a._emscripten_bind_Mesh___destroy___0 @ draco_wasm_wrapper_gltf.js:58
y.destroy.y.destroy @ draco_wasm_wrapper_gltf.js:101
a.destroy @ draco_wasm_wrapper_gltf.js:74
fh @ d43fce0f-7ae4-484a-91f0-4bd664caca68:1
(anonymous) @ d43fce0f-7ae4-484a-91f0-4bd664caca68:1
a.then @ draco_wasm_wrapper_gltf.js:72
onmessage @ d43fce0f-7ae4-484a-91f0-4bd664caca68:1
KHR_draco_mesh_compression.ts:99 Uncaught (in promise) Error: /meshes/2/primitives/0: Uncaught RuntimeError: invalid index into function table
at KHR_draco_mesh_compression.ts:99
at async Promise.all (/WebXR/index 0)
at async Promise.all (/WebXR/index 0)
at async Promise.all (/WebXR/index 2)
at async Promise.all (/WebXR/index 0)
at async Promise.all (/WebXR/index 0)
at async Promise.all (/WebXR/index 0)

This call stack is deep in some emscripten (compiler for WebAssembly) function. Maybe try using the JS fallback version (null out the wasm urls)? Other than that, I think the Draco team can probably help better.

Ok I will try that and see if it sheds any light and then I think I will call in the Draco team anyway.

Thanks.

1 Like