Load from String - Length in Header does not match

I looked deeper into the ArrayBuffer generated with this line

var raw_content = BABYLON.Tools.DecodeBase64(base64_model_content);

and I can see that the single characters are being interpreted all as different bytes.
For example at the beginning of the string glTF 4 the is having two different bytes inside the ArrayBuffer in the Int8Array. I understand that, that the string is still having the right characters. Is this correct?

The Blob size after creating the blob shows aswell the correct length of the header. Where exactly could that errror occur.

In your repro PG, the string and string2 variables are wrong, they don’t hold valid glb data: string.charCodeAt(5), string.charCodeAt(6) and string.charCodeAt(7) should return 0 but it’s not the case.

Here’s one PG that works:

https://playground.babylonjs.com/#9HMFDW

It uses fetch to get the glb file from the server in binary form.

It converts the data to base 64 and back to binary before creating the blob: note it is not needed. Set dontConvertToBase64 to true to avoid this conversion (I did it only to match your repro).

I have looked a bit deeper into our data and realized that our binary data is not in a correct format sent from the backend.
So now in realization of that I need to agree on the points you have mentioned. Thank you for your help so far, it helped understand the whole process a lot better. I will put this topic to the side for now and if we have solved our problem I will take it up again and try to master the loading process.

So we continued working on the the function to load our data from string. The Error with the wrong base64 String we have been able to solve. We know receive the base64 String in a correct Format. The loading from String works fine with the following method:

return BABYLON.SceneLoader.ImportMeshAsync(null, "", base64_model_content, scene, undefined, undefined, undefined, ".glb")
  .then(function (result) {

	let bimProducts = geometryMap[checksum];
	positionMesh(result.meshes[1], bimProducts[0].position, bimProducts[0].rotation, bimProducts[0].ifc_guid);
	assetContainer.meshes.push(result.meshes[1]);

	for (let i = 1; i < bimProducts.length; i++) {
		let clone = result.meshes[1].clone(bimProducts[i].ifc_guid);
		positionMesh(clone, bimProducts[i].position, bimProducts[i].rotation, bimProducts[i].ifc_guid);
		assetContainer.meshes.push(clone);
	}
  });

Now we implemented Babylonjs into React. The loading function and everything remains the same. Also the base64 Strings are in correct format. Here is one for example:

Z2xURgIAAAAcBQAAEAQAAEpTT057ImFzc2V0Ijp7InZlcnNpb24iOiIyLjAiLCJnZW5lcmF0b3IiOiJPcGVuIEFzc2V0IEltcG9ydCBMaWJyYXJ5IChhc3NpbXAgdjUuMC4wKSJ9LCJhY2Nlc3NvcnMiOlt7ImJ1ZmZlclZpZXciOjAsImJ5dGVPZmZzZXQiOjAsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50Ijo4LCJ0eXBlIjoiVkVDMyIsIm1heCI6WzI0NzUuMCwtNTkuMTI1LDI4NDAuMF0sIm1pbiI6WzU5LjEyNSwtNzUuMCwwLjBdfSx7ImJ1ZmZlclZpZXciOjEsImJ5dGVPZmZzZXQiOjAsImNvbXBvbmVudFR5cGUiOjUxMjUsImNvdW50IjozNiwidHlwZSI6IlNDQUxBUiIsIm1heCI6WzcuMF0sIm1pbiI6WzAuMF19XSwiYnVmZmVycyI6W3siYnl0ZUxlbmd0aCI6MjQwfV0sImJ1ZmZlclZpZXdzIjpbeyJidWZmZXIiOjAsImJ5dGVPZmZzZXQiOjAsImJ5dGVMZW5ndGgiOjk2LCJ0YXJnZXQiOjM0OTYyfSx7ImJ1ZmZlciI6MCwiYnl0ZU9mZnNldCI6OTYsImJ5dGVMZW5ndGgiOjE0NCwidGFyZ2V0IjozNDk2M31dLCJtYXRlcmlhbHMiOlt7Im5hbWUiOiJJZmNTdXJmYWNlU3R5bGVfVW5uYW1lZCIsInBick1ldGFsbGljUm91Z2huZXNzIjp7ImJhc2VDb2xvckZhY3RvciI6WzAuNzA1ODgyMDEyODQ0MDg1NywwLjc1Mjk0MTAxMjM4MjUwNzMsMC43NTI5NDEwMTIzODI1MDczLDEuMF0sIm1ldGFsbGljRmFjdG9yIjowLjB9fV0sIm1lc2hlcyI6W3sicHJpbWl0aXZlcyI6W3sibW9kZSI6NCwibWF0ZXJpYWwiOjAsImluZGljZXMiOjEsImF0dHJpYnV0ZXMiOnsiUE9TSVRJT04iOjB9fV19XSwibm9kZXMiOlt7Im5hbWUiOiJJZmNXYWxsX1VubmFtZWRfMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCIsIm1hdHJpeCI6WzAuMDAxMDAwMDAwMDQ3NDk3NDUxNCwwLjAsMC4wLDAuMCwwLjAsLTQuMzcxMTM4ODY3NTMxNTk5ZS0xMSwtMC4wMDEwMDAwMDAwNDc0OTc0NTE0LDAuMCwwLjAsMC4wMDEwMDAwMDAwNDc0OTc0NTE0LC00LjM3MTEzODg2NzUzMTU5OWUtMTEsMC4wLDAuMCwwLjAsMC4wLDEuMF0sIm1lc2giOjB9XSwic2NlbmVzIjpbeyJub2RlcyI6WzBdfV0sInNjZW5lIjowffAAAABCSU4AAIBsQgCAbMIAAAAAAACWQgAAlsIAAAAAAACWQgAAlsIAgDFFAIBsQgCAbMIAgDFFALAaRQAAlsIAAAAAALAaRQAAlsIAgDFFALAaRQCAbMIAAAAAALAaRQCAbMIAgDFFAAAAAAEAAAACAAAAAAAAAAIAAAADAAAAAQAAAAQAAAAFAAAAAQAAAAUAAAACAAAABAAAAAYAAAAHAAAABAAAAAcAAAAFAAAABgAAAAAAAAADAAAABgAAAAMAAAAHAAAABgAAAAQAAAABAAAABgAAAAEAAAAAAAAAAwAAAAIAAAAFAAAAAwAAAAUAAAAHAAAA

This base64 String loads in our non React Solution and also on the playground examples you guys provided us with. Now in our React Solution we get following error:

image

We implemented babylonjs into react like this: How to use Babylon.js with ReactJS - Babylon.js Documentation

I think it could be something with the version of the loader or imports…
Here is what we import:

import React from 'react';
import { Scene, ArcRotateCamera, Color3, Engine, SceneLoader, AssetContainer, Vector3, 
HemisphericLight, SceneOptimizerOptions, SceneOptimizer } from '@babylonjs/core';
import { AdvancedDynamicTexture } from '@babylonjs/gui';
import SceneComponent from '../SceneComponent'; // ^^ point to file we created above or 
'babylonjs-hook' NPM.
import '../../App.css';
import { HOST, METADATA_URL, GEOMETRY_URL, postData, streamData } from "../api/dsbim.js";
import "@babylonjs/loaders";
import { addMenu } from './functions/menu.js';

Loading from a .glb in base64 format is supported only in 4.2, so you should try to use the preview versions of the npm (append “@preview” to the name of your npm packages).

Thank You now it runs successfully. Two open questions from my side.

  • When will the current preview Version realesed?
  • How is it possible loading from an ArrayBuffer -> Blob -> Url into the scene via ImportMeshAsync?

I don’t think there’s a definite date, it’s for this fall.

Just use your url like any other url and pass it as the 3rd parameter.

I used it like that https://playground.babylonjs.com/#7F6S08#21 but it doesnt work. Loading it from data:base64,base64String instead of url does work.

Your parameters to ImportMeshAsync are wrong:

https://playground.babylonjs.com/#7F6S08#22

1 Like

is here a limit to encoding to base64? or appending my model? Appends work if they are around 1gb or below otherwise with larger ones I get bytelength error or invalid array header size.

In the beginigng I was just using FileReader but wondered if there was a limitation there too with 4GB files, so have refactored it to chuck the data so it doesnt use up all the RAM in the browser

There is a size limit a string can have in javascript, and it depends on the browser: Javascript string size limit: 256 MB for me - is it the same for all browsers? - Stack Overflow

Try to run the code snippet given in one of the answer. On my computer, Chrome has a limit of 530Mb and Firefox of 1Gb.

1 Like