I’ve been looking a bit at the Cinematics system. Especially serialization saving/loading etc.
The reason is that I noticed that it didn’t work. Saving seemed fine, but it crashed on loading. I reported on that in another thread.
Eventually I managed to stop it from crashing; There was an anonymous inner class after all that I didn’t see when looking the first time. Fixing that and a bunch of default constructors and it loads, but doesn’t show anything.
There were some other issues. In the read method of AnimationEvent I saw this:
//FIXME always the same issue, because of the clonning of assets, this won't work
//we have to somehow store userdata in the spatial and then recurse the
//scene sub scenegraph to find the correct instance of the model
//This brings a reflaxion about the cinematic being an appstate,
//shouldn't it be a control over the scene
// this would allow to use the cloneForSpatial method and automatically
//rebind cloned references of original objects.
**//for now as nobody probably ever saved a cinematic, this is not a critical issue**
I guess someone just did.
In fact, the Cinematics are kind of useless if they can’t be saved (or loaded).
So it brings up a number of questions. It had already struck me that a Cinematic could be a Control, considering it’s coupled to a spatial rather than the app.
Another is whether it’s a good idea that the AnimationEvent saves the spatial. I can see the benefit of not having to load a scene (which might have changed since the Cinematic was created). But I can also see a benefit in having the Cinematic be more dynamic and adapt, if for example a model changes.
Shouldn’t Cinematics rather be a “dumb” data element and then we have some CinematicPlayControl?
On the other hand an appstate would be better for that, so you don’t have to attach controls to every cinematic but rather let that happen all internally?
I’d also be against saving a Spatial but how would you do it then? You could save a ModelKey but then you can’t easily run cinematics for an already existing scene. How would one do this binding then? Like: Everything which wasn’t binded by .bind("Chair01", myChair); would be loaded by it’s ModelKey?
What I wanted to say, let’s try to do this structured by defining potential uses/needs:
Automatically load all the required Models
Use an already existing scene (e.g. the custom player model)
Note: one point is that these sorts of clone-time fixups used to be really nasty before I reimplemented the cloning system. Now it’s safe to simply refer to the spatials and they will get cloned properly, including sharing references, etc…
This may or may not be appropriate here but the point is that if you had Node X with cinematic controls or whatever then nothing special needs to be done to “fix them up” as long as they are using the cloning system. So that comment is sort of wrong now.
Whether any of this makes sense for cinematics, I don’t know. If it’s a control decorating a sub-graph then it could be just saved regularly if the JmeCloner stuff is properly implemented in the control.
I’ve made a PR that solves loading of Cinematic’s. I’m not 100% satisfied with the solution so I’d encourage others to look at it and come with suggestions on how to solve it otherwise.
Currently the solution consists of storing the model’s name in AnimationEvent (the model is still saved as well). When initializing the event, it looks through the Cinematic’s scene and replaces the model with the same name with the saved one (using the scene model is not possible since the model in AnimationEvent has had controls added to it).
It requires the scene to be loaded before hand. (I think this is acceptable, the scene is never saved in Cinematic)
What if there are several models with the same name?
The second change required is related to the camera’s.
Cinematic saves CameraNodes, but when loading, the camera is not coupled to the application’s camera. So, again, in initialize I replace the saved cameras with the application’s cam.
Is this safe? Can it be expected that there are other camera’s