Re-render scene when models array is updated in scene

I am creating a web configurator using react.js and babylon.js. And all my models are stored in an array. Then, I render all the models from this array in onSceneMount().

Now, when I update a particular index of the array (replace an existing model in the array with a new model), the scene does not re-render. I have to manually refresh the browser.

I guess this due to the fact that onSceneMount() runs only once on page load.

Is there any way I can render all the models of the array in a continuously render loop such that whenever the array is updated, the scene automatically refreshes with the new model in the scene? (Just like there is return in react.js function component which re-renders itself when the data is updated)

@brianzinn
@Deltakosh

Why not calling scene.render() in this case ?

I have used below code at the end of onSceneMount().
scene.getEngine().runRenderLoop(() => {
if (scene) {
scene.render()
}
})

Do I need call this code from somewhere else also? As the scene does not renders again when my array is updated.

This is my logic where I add models to scene in onSceneMount()
modelsArray.map((modelData) => {
SceneLoader.ImportMesh(
β€˜β€™,
β€˜β€™,
url,
scene,
function (newMeshes) {},
null,
null,
β€˜.glb’
)
})
}

I am updating this array from somewhere else in my react application

Maybe you could always import in the scene and enable/disable the models instead ?

Try to think of the array as having nothing to do with what is rendered, especially how you have done when you are not saving the results. What is rendered to the scene is only what you have loaded with SceneLoader - as long as your renderLoop is running. Your scene should be rendering multiple times/second, so as soon as a model is loaded it should appear in your application. It looks like you are doing things imperatively, so you will need to rely on hiding/disposing models when you replace them in the array (possibly in on success callback of SceneLoader, which you have empty). You can get the best help for that by creating a playground - that solution is not React specific.

If you want to write it as you have above and then you can use a useEffect hook with the array as a dependency and in your effect you can re-run all of the imports (or remember what is loaded because otherwise the models would be imported multiple times). You would probably wrap those in promises and use the onSuccess callback to populate your array to track what is loaded/loading.

If you want to go fully a declarative then you may be interested in this directed graph demo, which loads models dynamically using a map function on an array of model urls and key property for β€˜hiding’. It will dispose of unused models, which may be inefficient for your use-case. This is the demo, but all source is on github.
https://brianzinn.github.io/babylonjs-directed-graph/

1 Like