My use case is as follows:
- User should be able to create multiple three js scenes in tabs.
- If they are switching tabs the progress of these scenes should stay the same (autosave probably). I don’t need an undo/ redo
- Once they hit a SAVE button these scenes should be saved (to a sever) so that these can be downloaded/ accessed at a later time.
I have been exploring how it’s been done in the
editor https://threejs.org/editor/ and some other related posts. But my question is more on the best practices side.
Alternatives of achieving the #1 and #2 objectives might be
- For each tab I have a separate scene (and its file) as what editor has in a way, which I load and keep updated as user make changes in these different files explicitly made for separate tabs.
- I have only one scene and once a user switches tab, I save that scene into JSON (or other format); then remove everything from the scene, so that it can be used anew. Same sequence of events whenever tabs are switched.
Going deeper, there are two alternatives in each of these:
- I save the scene to a server and reload whenever it is required to be.
- I use either local storage or indexedDB to save the scene.
I might not have the knowledge of other alternatives, pardon me for that. Hence, please feel free to let me know if there is a more performant way to achieve my objective and what should be the preferred approach as per current
threejs dev branch codebase and the alternatives given above and your experiences.
As mentioned at this issue at github, the editor’s autosave feature is not really scalable. It always serializes the whole scene graph which is in some sense a brute force method. It would be nicer if only delta values are saved (the things that have actually changed over time). An other problem is that serialization to JSON and then to a string is slower than other techniques like an approach based on binary data.
You should keep these points in mind when developing your app. If the complexity of your scenes is manageable, the performance of the editor’s JSON based autosave which serializes the entire scene is sufficient. In all other cases, consider to implement a custom solution.
After going through multiple cases of how it is being managed, for my use case, we will go ahead with
JSON serialisation of only translation (loc, rot, scale) data, and we will re-create the scene on run time with objects downloaded from the server and translated as per saved
JSON translation data. Thanks Mike.
Little more descriptively, I can use
userData to store my local data with an object and only update whenever required, let’s say when user hits a save button. Then on export, all of these
userData would be serialised into JSON and stored in the DB. Something like the last three console logs below.
3 or 4 years ago I developed a multi-viewport editor for editing ontologies, where the base data for the nodes of the ontologies was held at the application level in the client, and the viewports each held entirely different views of subsets of the data in the application on the client — ALL in 3js and JS. The reason for this was the need to do cut and paste / drag and drop between viewer viewport windows, and to position each viewport window differently. I was able to navigate rapidly at 60fps in each of 8 viewports with an average of 3000 spheres showing in each viewport, each with a text label. Of course, the navigation was done on one viewport window at a time, and I only had 3300 nodes in my database on that project, so I was basically not stressing 3JS too much. It was much more an issue of getting the data into the viewports and doing the control functions. Also, the scenes were simple because I only used a small number of spheres referenced by positions in the scenegraph and the text labels were all generated when first loaded. I can’t see any reason why I could not show 100,000 spheres in each viewport with today’s tech.
Simple Shapes are just examples, the actual application is supposed to have multiple heavy objects, so to speak. However, the way I am doing my simple serialisation, and download the models from the server (Cache enabled) whenever required suits my purpose for now. Having said that your answer gives me more confidence, hence thanks for that.