I assume data is already string from axios response? Why do you call JSON.stringify on it again? It would give different base64 string.
I did a test like this:
const s = 'abc'
btoa(JSON.stringify(s)) // output 'ImFiYyI='
btoa(s) // output 'YWJj'
I assume data is already string from axios response? Why do you call JSON.stringify on it again? It would give different base64 string.
I did a test like this:
const s = 'abc'
btoa(JSON.stringify(s)) // output 'ImFiYyI='
btoa(s) // output 'YWJj'
With fs.readFileSync
, I got this message.
importMesh of undefined from undefined version: undefined, exporter version: undefinedimportMesh has failed JSON parse
this message is very devastating
I assume data is already string from axios response? Why do you call JSON.stringify on it again? It would give different base64 string.
ah~ oops. I see I see
Correct. This wonât work with remote assets. You can use axios as you did. But you already running babylon.js on server, so I assumed you have assets on the same server or you can read from a dfs.
Right Right. Good point. I was just trying to import in both ways in despair
Both ways seem to not work and throwing below error.
BJS - [12:25:14]: Unable to load from data:base64,ewogICAgImFzc2V0IiA6IHsKICAgICAgICAiZ2VuZXJhdG9yIiA6ICJLaHJvbm9zIGdsVEYgQmxlbmRlciBJL08gdjEuOC4xOSIsCiAgICAgICAgInZlcnNpb24iIDogIjIuMCIKICAgIH0sCiAgICAic2NlbmUiIDogMCwKICAgICJzY2VuZXMiIDogWwogICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiIDogIlNjZW5lIiwKICAgICAgICAgICAgIm5vZGVzIiA6IFsKICAgICAgICAgICAgICAgIDAKICAgICAgICAgICAgXQogICAgICAgIH0KICAgIF0sCiAgICAibm9kZXMiIDogWwogICAgICAgIHsKICAgICAgICAgICAgIm1lc2giIDogMCwKICAgICAgICAgICAgIm5hbWUiIDogIkN1YmUiCiAgICAgICAgfQogICAgXSwKICAgICJtZXNoZXMiIDogWwogICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiIDogIkN1YmUiLAogICAgICAgICAgICAicHJpbWl0aXZlcyIgOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgImF0dHJpYnV0ZXMiIDogewogICAgICAgICAgICAgICAgICAgICAgICAiUE9TSVRJT04iIDogMCwKICAgICAgICAgICAgICAgICAgICAgICAgIk5PUk1BTCIgOiAxLAogICAgICAgICAgICAgICAgICAgICAgICAiVEVYQ09PUkRfMCIgOiAyCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAiaW5kaWNlcyIgOiAzCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0KICAgICAgICB9CiAgICBdLAogICAgImFjY2Vzc29ycyIgOiBbCiAgICAgICAgewogICAgICAgICAgICAiYnVmZmVyVmlldyIgOiAwLAogICAgICAgICAgICAiY29tcG9uZW50VHlwZSIgOiA1MTI2LAogICAgICAgICAgICAiY291bnQiIDogMjQsCiAgICAgICAgICAgICJtYXgiIDogWwogICAgICAgICAgICAgICAgMC4wMDk5OTk5OTk3NzY0ODI1ODIsCiAgICAgICAgICAgICAgICAwLjAwOTk5OTk5OTc3NjQ4MjU4MiwKICAgICAgICAgICAgICAgIDAuMDA5OTk5OTk5Nzc2NDgyNTgyCiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJtaW4iIDogWwogICAgICAgICAgICAgICAgLTAuMDA5OTk5OTk5Nzc2NDgyNTgyLAogICAgICAgICAgICAgICAgLTAuMDA5OTk5OTk5Nzc2NDgyNTgyLAogICAgICAgICAgICAgICAgLTAuMDA5OTk5OTk5Nzc2NDgyNTgyCiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJ0eXBlIiA6ICJWRUMzIgogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgICAiYnVmZmVyVmlldyIgOiAxLAogICAgICAgICAgICAiY29tcG9uZW50VHlwZSIgOiA1MTI2LAogICAgICAgICAgICAiY291bnQiIDogMjQsCiAgICAgICAgICAgICJ0eXBlIiA6ICJWRUMzIgogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgICAiYnVmZmVyVmlldyIgOiAyLAogICAgICAgICAgICAiY29tcG9uZW50VHlwZSIgOiA1MTI2LAogICAgICAgICAgICAiY291bnQiIDogMjQsCiAgICAgICAgICAgICJ0eXBlIiA6ICJWRUMyIgogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgICAiYnVmZmVyVmlldyIgOiAzLAogICAgICAgICAgICAiY29tcG9uZW50VHlwZSIgOiA1MTIzLAogICAgICAgICAgICAiY291bnQiIDogMzYsCiAgICAgICAgICAgICJ0eXBlIiA6ICJTQ0FMQVIiCiAgICAgICAgfQogICAgXSwKICAgICJidWZmZXJWaWV3cyIgOiBbCiAgICAgICAgewogICAgICAgICAgICAiYnVmZmVyIiA6IDAsCiAgICAgICAgICAgICJieXRlTGVuZ3RoIiA6IDI4OCwKICAgICAgICAgICAgImJ5dGVPZmZzZXQiIDogMAogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgICAiYnVmZmVyIiA6IDAsCiAgICAgICAgICAgICJieXRlTGVuZ3RoIiA6IDI4OCwKICAgICAgICAgICAgImJ5dGVPZmZzZXQiIDogMjg4CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAgICJidWZmZXIiIDogMCwKICAgICAgICAgICAgImJ5dGVMZW5ndGgiIDogMTkyLAogICAgICAgICAgICAiYnl0ZU9mZnNldCIgOiA1NzYKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICAgImJ1ZmZlciIgOiAwLAogICAgICAgICAgICAiYnl0ZUxlbmd0aCIgOiA3MiwKICAgICAgICAgICAgImJ5dGVPZmZzZXQiIDogNzY4CiAgICAgICAgfQogICAgXSwKICAgICJidWZmZXJzIiA6IFsKICAgICAgICB7CiAgICAgICAgICAgICJieXRlTGVuZ3RoIiA6IDg0MCwKICAgICAgICAgICAgInVyaSIgOiAiZGF0YTphcHBsaWNhdGlvbi9vY3RldC1zdHJlYW07YmFzZTY0LEN0Y2p2QXJYSTd3SzF5TThDdGNqdkFyWEk3d0sxeU04Q3RjanZBclhJN3dLMXlNOEN0Y2p2QXJYSXp3SzF5TThDdGNqdkFyWEl6d0sxeU04Q3RjanZBclhJendLMXlNOEN0Y2p2QXJYSTd3SzF5TzhDdGNqdkFyWEk3d0sxeU84Q3RjanZBclhJN3dLMXlPOEN0Y2p2QXJYSXp3SzF5TzhDdGNqdkFyWEl6d0sxeU84Q3RjanZBclhJendLMXlPOEN0Y2pQQXJYSTd3SzF5TThDdGNqUEFyWEk3d0sxeU04Q3RjalBBclhJN3dLMXlNOEN0Y2pQQXJYSXp3SzF5TThDdGNqUEFyWEl6d0sxeU04Q3RjalBBclhJendLMXlNOEN0Y2pQQXJYSTd3SzF5TzhDdGNqUEFyWEk3d0sxeU84Q3RjalBBclhJN3dLMXlPOEN0Y2pQQXJYSXp3SzF5TzhDdGNqUEFyWEl6d0sxeU84Q3RjalBBclhJendLMXlPOEFBQ0F2d0FBQUFBQUFBQ0FBQUFBQUFBQWdMOEFBQUNBQUFBQUFBQUFBQUFBQUlBL0FBQ0F2d0FBQUFBQUFBQ0FBQUFBQUFBQUFBQUFBSUEvQUFBQUFBQUFnRDhBQUFDQUFBQ0F2d0FBQUFBQUFBQ0FBQUFBQUFBQWdMOEFBQUNBQUFBQUFBQUFBQUFBQUlDL0FBQ0F2d0FBQUFBQUFBQ0FBQUFBQUFBQUFBQUFBSUMvQUFBQUFBQUFnRDhBQUFDQUFBQUFBQUFBZ0w4QUFBQ0FBQUFBQUFBQUFBQUFBSUEvQUFDQVB3QUFBQUFBQUFDQUFBQUFBQUFBQUFBQUFJQS9BQUFBQUFBQWdEOEFBQUNBQUFDQVB3QUFBQUFBQUFDQUFBQUFBQUFBZ0w4QUFBQ0FBQUFBQUFBQUFBQUFBSUMvQUFDQVB3QUFBQUFBQUFDQUFBQUFBQUFBQUFBQUFJQy9BQUFBQUFBQWdEOEFBQUNBQUFDQVB3QUFBQUFBQUFDQUFBREFQZ0FBZ0Q4QUFBQStBQUNBUGdBQXdENEFBQUFBQUFBZ1B3QUFnRDhBQUNBL0FBQUFBQUFBWUQ4QUFJQStBQURBUGdBQVFEOEFBQUErQUFBQVB3QUF3RDRBQUVBL0FBQWdQd0FBUUQ4QUFDQS9BQUJBUHdBQVlEOEFBQUEvQUFEQVBnQUFnRDRBQU1BK0FBQ0FQZ0FBd0Q0QUFJQStBQUFnUHdBQWdENEFBQ0EvQUFDQVBnQUFJRDhBQUlBK0FBREFQZ0FBQUQ4QUFNQStBQUFBUHdBQXdENEFBQUEvQUFBZ1B3QUFBRDhBQUNBL0FBQUFQd0FBSUQ4QUFBQS9BQUFEQUFrQUFBQUpBQVlBQ0FBS0FCVUFDQUFWQUJNQUZBQVhBQkVBRkFBUkFBNEFEUUFQQUFRQURRQUVBQUlBQndBU0FBd0FCd0FNQUFFQUZnQUxBQVVBRmdBRkFCQUEiCiAgICAgICAgfQogICAgXQp9Cg==: importMesh of undefined from undefined version: undefined, exporter version: undefinedimportMesh has failed JSON parse
base64 seems to be correctly converted. I am not sure whatâs going on haha
Let me share a more complete code block that works for me. It is running on node.js. Hopefully you find something useful.
import * as BABYLON from '@babylonjs/core';
import "@babylonjs/loaders/glTF";
import fs from 'fs';
import path from 'path';
const engine = new BABYLON.NullEngine();
const scene = new BABYLON.Scene(engine);
const glbRawContent = fs.readFileSync(<YOUR_FILE_PATH>);
const base64Content = Buffer.from(glbRawContent).toString('base64');
const base64ModelString = `data:base64,${base64Content}`;
const { meshes, skeletons, animationGroups } = await BABYLON.SceneLoader.ImportMeshAsync('', '', base64ModelString, scene);
Otherwise, do you want to create a small Github project that can reproduce the issue?
Let me try reproducing
By the way, I thought NullEngine is not capable of producing/rendering an image??
Hereâs the link to mini project.
Itâs so weird that it didnât work without fakeIndexedDB
on my original project, but it works fine without it in the mini one o_O??
running on node version 16.16.0
npm install
npm run dev
// for loading Dude.babylon
go to http://localhost:3000/api/Dude
The dude model loads fine for me too.
Yes, .babylon model can be loaded, but the texture mapping is quite off. I have no idea
and .gltf cannot be loadedâŚ
You got to open the project and reproduce the problem, right? I am worried that I might have not setup th e project right.
I managed to get dummy2 model from https://playground.babylonjs.com/scenes/dummy2.babylon
The problem with dude is it has references to the textures. I guess the babylon.js server mode is not handling the reference to textures correctly. The red strips you saw for the dude model is the default texture applied when the original textures are missing.
@RaananW There is another issue I noticed with gltf loading by using BABYLON.SceneLoader.ImportMeshAsync
. Could you check if anything changed in recent versions?
For example, the code below works for me with babylon.js 5.0.0-alpha.45.
const base64Content = Buffer.from(glbRawContent).toString('base64');
const base64ModelString = `data:base64,${base64Content}`;
const { meshes, skeletons, animationGroups } = await BABYLON.SceneLoader.ImportMeshAsync('', '', base64ModelString, scene);
But in @DOEHOONLEE 's example project, babylon.js loader is not able to recognize the base64 string is gltf. Error showed it still tried to load with babylonFileLoader and thus failed.
Wait. You succeeded in loading .gltf with Babylon.js 5.0.0-alpha version?? Thatâs amazing! I wonder what changed after that hmm
alpha.45 is very old, a lot of things have canged since then. One thing I can say for sure - you need to make sure you define the right extensionif you donât provide a file. Itâs one of the later variables in the ImportMesh function - SceneLoader | Babylon.js Documentation (babylonjs.com) (pluginExtension
should be .gltf)
Oh! I saw your comment on other discussion where you instructed the OP to provide the extension
and I did put it as the last parameter like in the documentation, but still didnât work
@bghgary - was anything changed in the way we load base64-based models in the gtlf loader?
(please be patient, he is away until the beginning of next week).
I will anyhow try finding time to debug this, but not sure when itâll happen. sorryâŚ
I did not mean to rush anything. Please let me apologize if I sounded so.
I guess the babylon.js server mode is not handling the reference to textures correctly
So I will have to modify my codes so that the texture is mapped according to the references somehow. Is that what you are saying?
FYI, I tested a PG I use for baking animations. My model is glb format. Passing base64 blob into BABYLON.SceneLoader.ImportMeshAsync without specifying the plugin extension type still works fine in the latest babylon.js version 5.20.0 in PG.
I tried to load the same glb with BABYLON.SceneLoader.ImportMeshAsync again in @DOEHOONLEE 's project. This time it seems to use the gltf loader. But throwing a different error. The error trace shows the problem is with node.js URL.createObjectURL implementation. It is internally used in the GLTF loader for instantiating the textures.
innerError: TypeError [ERR_INVALID_ARG_TYPE]: The "obj" argument must be an instance of Blob. Received an instance of Blob
at new NodeError (node:internal/errors:372:5)
at Function.createObjectURL (node:internal/url:963:13)
at Function.LoadImage [as _FileToolsLoadImage] (file:///Users/i830561/Development/tmp/babylonTester-main/node_modules/@babylonjs/core/Misc/fileTools.js:153:23)
at Engine.ThinEngine._createTextureBase (file:///Users/i830561/Development/tmp/babylonTester-main/node_modules/@babylonjs/core/Engines/thinEngine.js:3344:28)
There is no much information of this error on line. I only found this post: node.js - createObjectURL error: `argument must be an instance of Blob. Received an instance of Blob` - Stack Overflow
The problem with dude is it has references to the textures. I guess the babylon.js server mode is not handling the reference to textures correctly.
For this part, did you mean that there is something needs to be fixed in my project?
The âobjâ argument must be an instance of Blob. Received an instance of Blob
at new NodeError (node:internal/errors:372:5)
Oh, yeah⌠this is the error I have been seeing for the last week or so
For this part, did you mean that there is something needs to be fixed in my project?
No. I would suggest you to create a minimum babylon.js project that you can reproduce the errors, excluding the next.js, http server, etc. Maybe start with a single .ts file that can be used to reproduce the error from URL.createObjectURL(). And ask if babylon team can help investigating.
The âobjâ argument must be an instance of Blob. Received an instance of Blob
at new NodeError (node:internal/errors:372:5)
Ohh, alright. Let me try to reproduce in just node.hs based project.