How to use ImportMesh with Null Engine on Server Side Nodejs?

Trying to use this snippet as per the documentation at https://doc.babylonjs.com/features/nullengine

var BABYLON = require("../../dist/preview release/babylon.max");
var LOADERS = require("../../dist/preview release/loaders/babylonjs.loaders");
global.XMLHttpRequest = require('xhr2').XMLHttpRequest;

var engine = new BABYLON.NullEngine();
var scene = new BABYLON.Scene(engine);

var light = new BABYLON.PointLight("Omni", new BABYLON.Vector3(20, 20, 100), scene);

var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0.8, 100, BABYLON.Vector3.Zero(), scene);

BABYLON.SceneLoader.ImportMesh("", "https://playground.babylonjs.com/scenes/", "skull.babylon", scene, function (newMeshes) {
    camera.target = newMeshes[0];

    console.log("Meshes loaded from babylon file: " + newMeshes.length);
    for (var index = 0; index < newMeshes.length; index++) {
        console.log(newMeshes[index].toString());
    }

    BABYLON.SceneLoader.ImportMesh("", "https://www.babylonjs.com/Assets/DamagedHelmet/glTF/", "DamagedHelmet.gltf", scene, function (meshes) {
        console.log("Meshes loaded from gltf file: " + meshes.length);
        for (var index = 0; index < meshes.length; index++) {
            console.log(meshes[index].toString());
        }
    });

    console.log("render started")
    engine.runRenderLoop(function() {
        scene.render();
    })
});

does not work as xhr2 does not support file:// as a protocol (as per their documentation). So how do you load a mesh on server side in nodejs? Here is the error log:

Error
    at XMLHttpRequest.send (D:\_PROJECTS\node-babylon2 - PROD\node_modules\xhr2\lib\xhr2.js:281:19)
    at e.send (D:\_PROJECTS\node-babylon2 - PROD\node_modules\babylonjs\babylon.js:16:607299)
    at s (D:\_PROJECTS\node-babylon2 - PROD\node_modules\babylonjs\babylon.js:16:575355)
    at _ (D:\_PROJECTS\node-babylon2 - PROD\node_modules\babylonjs\babylon.js:16:575363)
    at Function.e.RequestFile (D:\_PROJECTS\node-babylon2 - PROD\node_modules\babylonjs\babylon.js:16:575595)
    at t._requestFile (D:\_PROJECTS\node-babylon2 - PROD\node_modules\babylonjs\babylon.js:16:261801)
    at e.requestFile (D:\_PROJECTS\node-babylon2 - PROD\node_modules\babylonjs-loaders\babylonjs.loaders.min.js:1:51455)
    at g (D:\_PROJECTS\node-babylon2 - PROD\node_modules\babylonjs\babylon.js:16:1253939)
    at Function.e._loadData (D:\_PROJECTS\node-babylon2 - PROD\node_modules\babylonjs\babylon.js:16:1254396)
    at Function.e.ImportMesh (D:\_PROJECTS\node-babylon2 - PROD\node_modules\babylonjs\babylon.js:16:1255979)

On client side I was loading it using this, for reference:

let MeshObject = await SceneLoader.ImportMeshAsync(null, MeshPath + ObjFileName);
let mesh: Nullable<Mesh> = mergeMeshes(BlockRef.LayerName, MeshObject.meshes);

So what would be the equivalent for server side?

1 Like

Ping @bghgary who was looking into taking blob as inputs for scene loaders which would solve your issue here.

Use the full server path to the files hosted by your server on NodeJS.
http://localhost:8080/files/obj.babylon

2 Likes

I get an error:


Error in onSuccess callback: ReferenceError: document is not defined
Looks like it is able to get the file correctly(?) since the http server also outputs a log message on the line above it, though iā€™m not sure why it is unable to load it properly. Do you have an idea on what i could be doing wrong?

Code:

global.XMLHttpRequest = require('xhr2').XMLHttpRequest;
 
var BABYLON = require("babylonjs");
require("babylonjs-loaders");

var engine = new BABYLON.NullEngine();
var scene = new BABYLON.Scene(engine);

var light = new BABYLON.PointLight("Omni", new BABYLON.Vector3(20, 20, 100), scene);

var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0.8, 100, BABYLON.Vector3.Zero(), scene);

BABYLON.SceneLoader.ImportMesh("", "http://localhost:8080/lib/commands/Models/", "Egg.obj", scene, function (newMeshes) {
    camera.target = newMeshes[0];

    //console.log("Meshes loaded from babylon file: " + newMeshes.length);
	console.log("Creating Screenshot");
	BABYLON.Tools.CreateScreenshot(engine, camera, 400, function (data) {
		coonsole.log("IMAGE: "+data);
		fs.writeFileSync(file, data);
	});
    console.log("render started");
	engine.runRenderLoop(function() {
		scene.render();
	});
});