Babylon.js Reactjs Object import Problem

Hello everyone,
I would like to ask you a point that makes me crazy. I currently working on a React app that contains Babylon.js framework. I built my app depending on following documentation.
React and Babylonjs Documentation

Yet, my problem is that I couldn’t achieve importing objects into my scene. Without React, I was doing it with ‘Babylon.SceneLoader.Append’ function. Here is the trial that I have done so far. The code is inside a .js file which is run by app.js.

import React, { Component } from 'react';

import * as BABYLON from 'babylonjs';

import 'babylonjs-loaders';

import "@babylonjs/loaders/OBJ";

import "@babylonjs/loaders/OBJ";

import { Engine, Scene } from '@babylonjs/core';

//import * as GUI from "babylonjs-gui";

import BabylonScene from './Babylon.jsx'; // import the component above linking to file we just created.

export default class Viewer extends Component<{}, {}> {

    onSceneMount = (e: SceneEventArgs) => {

        const { canvas, scene, engine } = e;

        const camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 2, Math.PI / 2, 2, new BABYLON.Vector3(0,0,5), scene);

        camera.setTarget(BABYLON.Vector3.Zero());

        camera.attachControl(canvas, true);

        const light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);

        light.intensity = 0.7;

        BABYLON.SceneLoader.Append("/assets/", 'Chair.obj', scene, function (scene) { });

        engine.runRenderLoop(() => {

            if (scene) {

                scene.render();

            }

        });

    }

    render() {

        return (

            // <div>

            <BabylonScene onSceneMount={this.onSceneMount} />

            // </div>

        )

    }

}

my app contains Amplify authentication as well. In addition, the application works perfectly with “BABYLON.MeshBuilder.CreateBox” function. The only problem is the object import. I hope you can help me. Thanks in advance.

1 Like

Hi Nevzat_Anil_Talaym,

Welcome to Babylon! Can you provide some more information about the problem you’re experiencing? A Playground reproducing the issue would be ideal, but a call stack or an error message or something could also help us understand what’s going on. Thanks!

Looks like you mixed the es6 import with the original npm. If you make a public repo I can send you a fix.

Thanks for your interest. I have uploaded my codes into github repository. If you check the Viewer.js file , you will see the code that I have shared earlier. If you run the repository on your local computer, everything works prefect except the import command. The mainBabylon.js page is in the Viewer.js file.

You may want to focus on following line in Viewer.js
BABYLON.SceneLoader.Append("", ‘Chair.obj’, scene, function (scene) { });

Repository Link: React-Trial/Viewer.js at master · NevzatTalay/React-Trial · GitHub

If you need any further information please contact me.

thanks for your interest. Here is the repository of my project.


Thank you very much.

That was super close. The main thing you were missing was the root url for the loader. You can see this from the console log errors (the OBJLoaders couldn’t load your index.html, which is what is served when there is no physical file), but you can also see it from the network tab. Those are in developer tools. Anyway, if you update your Viewer.js to this you should be good:

import React, { Component } from 'react';
import '@babylonjs/loaders'; // import for side-effects (loads OBJ loader automatically)

import { ArcRotateCamera, HemisphericLight, Vector3, SceneLoader } from '@babylonjs/core';
import BabylonScene from './Babylon.jsx'; // import the component above linking to file we just created.
export default class Viewer extends Component {
onSceneMount = (e) => {
    const { canvas, scene, engine } = e;
    const camera = new ArcRotateCamera("Camera", Math.PI / 2, Math.PI / 4, 75, new Vector3(0, 75, 0), scene);
    camera.attachControl(canvas, true);
    const light = new HemisphericLight("light1", new Vector3(0, 1, 0), scene);
    light.intensity = 0.7;


    // You missed the rootUrl only (see /public/assets/) and /public is your ROOT '/'!
    SceneLoader.Append("/assets/", 'Chair.obj', scene, function (scene) { });

    engine.runRenderLoop(() => {

        if (scene) {
            scene.render();
        }
    });
}

render() {
    return (
        <BabylonScene onSceneMount={this.onSceneMount} />
    )
}
}

Then you just need to remove the imports for babylonjs and babylonjs-loaders. And add @babylonjs/loaders. I would recommend an editor like VSCode - it would have shown you also that you had errors in your file (You had TypeScript typings in a javascript file).

I noticed also that you imported react-babylonjs in your project already. If you want to do a declarative version equivalent then you can remove your babylon.jsx and do this instead in Viewer:

import React, { Component } from 'react';
import { Scene, Engine, Model } from 'react-babylonjs'
import { Vector3 } from '@babylonjs/core'

export default class Viewer extends Component {
    render() {
        return (
            <Engine antialias adaptToDeviceRatio width={window.innerWidth} height={window.innerHeight}>
                <Scene>
                    <arcRotateCamera name='camera1' alpha={Math.PI / 2} beta={Math.PI / 4} radius={75.0} target={new Vector3(0, 75, 0)} />
                    <hemisphericLight name='light1' intensity={0.7} direction={Vector3.Up()} />
                    <Model rootUrl={`/assets/`} sceneFilename='chair.obj' />
                </Scene>
            </Engine>
        )
    }
}

So, that’s another way since you have already imported the react-babylonjs NPM, but otherwise you can remove that NPM if you want to do it how you have it before :slight_smile: If you have more questions just @mention me. Cheers.

4 Likes

What is the difference between “babylonjs-loaders” and “@babylonjs/loaders”?

Documentation is confusing because it references “babylonjs-loaders” (.glTF File Loader Plugin | Babylon.js Documentation), and does not mention “@babylonjs/loaders”.

This page will explain a bit better - Babylon.js ES6 support with Tree Shaking | Babylon.js Documentation

But i do agree, we should reference both (or maybe even only the es6 module) in the docs.

1 Like

Is ring-3stone.glb in your /public folder - if you are using CRA. You can check your network tab to see what is being served when that file is downloaded.

Isn’t that partial sphere the model 26m.glb and then it is working as expected? Also, exclude babylonjs from dependencies - it is not needed when you have @babylonjs/core.

1 Like

I would suggest turning on Scene Explorer - as it may be loaded and you cannot see it. Otherwise if you can share a repo.

import "@babylonjs/inspector";
...
const Inspector = () => {
  // this must be inside a <Scene ../> component
  const scene = useScene();
  scene.debugLayer.show();
  return null;
};

Then in your page:

  <Inspector />

Hi, I am just starting to integrate Babylon in my React application. BabylonJS is very new to me. I wanted advise on which path to take. Use react-babylon (which looks easy to integrate and start) or use the babylon library and handle the JS? My application is more into 3D rendering of geographical areas and having object as overlay.

Looking forward.

hi @InduJoseph - welcome to the forum. I don’t have strong advice either way - react-babylonjs will fit more the paradigm that you are accustomed to with building your scene in JSX and allow you to compose you scene. Vanilla-js or babylonjs-hook are also valid options. Maybe a new question would get more community response. I used to work for Ministry of Forests doing mapping - it was more loading overlays and showing/hiding/comparing layers, so if you are integrating DOM or using GUI then I do start to find advantages of react-babylonjs, but your mileage may vary.

1 Like

Thank you for the input. Just integrated react-babylonjs in the app.

2 Likes