I want to save and load a scene that contains cannon-es physics.
Myscene contains simple 3D objects that can be moved by mouse drag.
All objects have collision properties with cannon.body.
I can save the scene with scene.toJSON();
and load via const scene = new THREE.ObjectLoader().parse( json ); It is working.
The objects are in the place where they were placed. Light and textures also load properly. However, the physical properties are lost.
I assume that these properties are registered in world (const world = new CANNON.World).
Scenes can be loaded via THREE.ObjectLoader(). I did not find a loader for CANNON.World.
So it won’t be possible to save and load a scene with cannon physics?
The answer is both No and Yes.
It is No, because Three.js and CannonES have a separate representations of the virtual scene, and Three.js does not know (and does not care) about CannonES’s world. That’s why saving a scene to JSON and then loading it ignores all physics properties.
It is Yes, because it is possible to save and load physics world … but someone (you?) has to write code to convert physics properties to JSON and vice versa. A possible workflow is:
- all important physics properties are stored in
userData
property of their Three.js counterparts - then
scene.toJSON()
will save these physics properties in the JSON structure - when such JSON is loaded, the used data properties will also be loaded
- after the scene is loaded, the physics world must be rebuilt by traversing all Three.js objects, reading their
userData
and recreating the corresponding CannonES bodies
Steps 2 and 3 above should work out of the box. However, steps 1 and 4 are not implemented in the default Three.js codebase. So either you have to use some third-party tool (if such exists), or write your own. For simple 3D objects (as said in your post), this should not be that difficult.
I had already suspected that there is no default THREE.js codebase for this.
Also, I haven’t found any third-party tool that can load the physical data to the scene.
In the console I saw that the physical properties are stored in the object world (const world = new CANNON.World).
I save the object world in a JSON file - for example world.json
As you described in #4 of your answer, the physics world needs to be rebuilt from the world.json.
I’ll try that now.
In a small test I was able to successfully change a value in world.
If you process the Three.js scene and the CannonES world separately, how do you plan to rebuild the links between objects and bodies?
I can’t say that yet, I have to find out.