Initializing CSG2 in Node.JS

Im using Babylon in headless mode using NullEngine in Node.Js
BABYLON.InitializeCSG2Async() does not enjoy being outside of the browser.
Is there a workaround?

I’ve tried to load jsdom manually to no extend (initialize seems to enter an infinite loop now).

import { JSDOM } from ‘jsdom’;
const dom = new JSDOM(‘’);
globalThis.window = dom.window;
globalThis.document = dom.window.document;

It seems to me doing boolean operation should not depend on the browser/window/dom.

Well first what is the error? Init does not require access to webgl but csg2 will create and manipulate mesh so that will require a gl context for sure (unless you stick with VertexData then it should work)

Also does Node.js support wasm?

That’s the error I got prior to doing the little hack mentionned in the original question.

Error: Cannot load script module outside of a window or a worker
at […]node_modules@babylonjs\core\Misc\tools.internals.js:31:20
at new Promise ()
at _LoadScriptModuleAsync ([…]node_modules@babylonjs\core\Misc\tools.internals.js:18:12)
at Module.InitializeCSG2Async ([…]node_modules@babylonjs\core\Meshes\csg2.js:344:30)

I’m relatively new to node.js but it seems to support wasm (but it might be accessed / behave differently). I’ve never toyed with webassembly yet.

yeah that may not be the issue. Let me ping the boss @RaananW

Node.js does support WASM. The exception comes from our code and not from node directly. The code is this:

        if (IsWindowObjectExist()) {
            windowAsAny = window;
            windowString = "window";
        } else if (typeof self !== "undefined") {
            windowAsAny = self;
            windowString = "self";
        } else {
            reject(new Error("Cannot load script module outside of a window or a worker"));
            return;
        }

And yes, this will fail in node, as node doesn’t have windows nor self. It does support globalThis, so it should be working correctly with slight adjustments. I can run a few tests tomorrow and see if that solves the issue for js runners (node/deno/bun?)

3 Likes

thanks mate!

The quickest solution is this:

import { InitializeCSG2Async } from "@babylonjs/core";
import Module from "manifold-3d";
const wasm = await Module();
wasm.setup();
const { Manifold, Mesh } = wasm;
InitializeCSG2Async({
  manifoldInstance: Manifold,
  manifoldMeshInstance: Mesh,
}).then(() => {
  console.log("CSG2 initialized");
});

Install manifold-3d and provide the instance yourself after initializing it. No changes needed in Babylon core :slight_smile:

4 Likes

Impressed by how fast you came up with a workaround, good job and thank you very much!

1 Like