What does cloneForSpatial do?

The documentation on cloneForSpatial, such as it is, has an example that says you may or my not need to copy user data into the clone.

There appears to be clones made of all of the Controls in the scene. Why is this? What are they used for?

Are each of the Spatials cloned as well?

In the end, how do you know what data these clones actually need?

They are used when the spatial is cloned and contains controls. Which is basically every time a model with controls is loaded.

And in 99% of the cases, you can just defer to what AbstractControl is doing, ie: don’t even bother to override this method.

So what use is made of these cloned objects? Why does it go to the trouble of creating them?

@Zachary-Hilbun said: So what use is made of these cloned objects? Why does it go to the trouble of creating them?

A new Spatial with a new control. Like if you load a model twice the Control simply can’t be the same.

Ok, but why is it creating a clone of all the scene in the first place? What does it do with these clones of spatials and controls it has gone to the trouble to create? There must be some purpose for them .

@Zachary-Hilbun said: Ok, but why is it creating a clone of all the scene in the first place? What does it do with these clones of spatials and controls it has gone to the trouble to create? There must be some purpose for them .

You load a model, for example for a car, you place it in the scene. Now you load the same model again and place it in the scene. Its taken from the cache of the AssetManager, cloned including its Controls and placed in the scene.

I only load 1 scene 1 time using loadModel.

I see the Constructors for each Control called followed by the read method being called for that Control object.
That happens for all the Controls in the scene.
I then see the Constructors called again for the same Controls followed by cloneForSpatial for that Control object.
It appears that loadModel loads the scene once, and then cloans the entire scene or at least the Controls in it.

It seems to me that once loadModel created the Spatials the first time I had everything it needs to display the scene and does need to cloan them again.

The questions I have is why loadModel is doing all of this cloaning, what the cloans are untimately used for, and under what conditions are you supposed to do something with the cloans.

@Zachary-Hilbun said: I only load 1 scene 1 time using loadModel.

I see the Constructors for each Control called followed by the read method being called for that Control object.
That happens for all the Controls in the scene.
I then see the Constructors called again for the same Controls followed by cloneForSpatial for that Control object.
It appears that loadModel loads the scene once, and then cloans the entire scene or at least the Controls in it.

It seems to me that once loadModel created the Spatials the first time I had everything it needs to display the scene and does need to cloan them again.

The questions I have is why loadModel is doing all of this cloaning, what the cloans are untimately used for, and under what conditions are you supposed to do something with the cloans.

Repeating…

If you load a model of a car and then place it in your scene… and then later load the same car model and place it elsewhere in your scene then they are BOTH (both of them, as in both of the models, as in every model that was loaded, all of them) are CLONED. Otherwise, how would it work? You load one car and then move that around in the scene and later load another car and try to clone that original one but now it’s had a 100 changes made to it and the original is no longer there to clone.

JME has no way to predict which models you will only load once. So it caches them and clones it. In truth this is essentially free anyway. The biggest parts of the models are shared (the meshes, textures, etc.)

Ok, I think I understand what is being said now. Correct me if I’m wrong. In my case, these cloans are not used. However, if a person does load a model more than once, it’s easier to read it from a cache than to read it off of the drive again. cloneForSpatial is provided to allow you to initialize the cloan for those cases where it makes a difference that a Control is a cloaned copy rather than the original that was read off of the disk.

Is cloneForSpatial only called 1 time when the 1st cloan of a Control is created, or is it called each time a cloan copy is needed because the model has been reloaded?

@Zachary-Hilbun said: Ok, I think I understand what is being said now. Correct me if I'm wrong. In my case, these cloans are not used. However, if a person does load a model more than once, it's easier to read it from a cache than to read it off of the drive again. cloneForSpatial is provided to allow you to initialize the cloan for those cases where it makes a difference that a Control is a cloaned copy rather than the original that was read off of the disk.

Is cloneForSpatial only called 1 time when the 1st cloan of a Control is created, or is it called each time a cloan copy is needed because the model has been reloaded?

Each time.

I will try to spell it out painfully clear since so far we’ve done a poor job I guess.

  1. App asks object “foo” to be loaded.
  2. Asset manager reads that object from disk and sticks it in the cache.
  3. Asset manager CLONES that object and returns the CLONE to the caller.
  4. app now uses that clone and not the originally loaded object.

If the app asks for that asset again:

  1. App asks object “foo” to be loaded.
  2. Asset manager gets the object from cache that it already loaded before.
  3. Asset manager CLONES that object and returns the CLONE to the caller.
  4. app now uses that clone and not the originally loaded object.

Clearer?

1 Like

And note again, if you extend AbstractControl then you likely do not even have to worry about cloneForSpatial() because there is a default implementation that works for 99% of use-cases.

If you are not extending AbstractControl then you are doing things the hard way and will have to be an expert on lots of stuff to get it right, I guess.

Thanks for the comment pspeed. You have made it very clear now. I think I’m in the 1% of use-cases in that I actually want to initialize the cloaned copy using data that I have in the cached copy.

@Zachary-Hilbun said: Thanks for the comment pspeed. You have made it very clear now. I think I'm in the 1% of use-cases in that I actually want to initialize the cloaned copy using data that I have in the cached copy.

That’s not really what cloneForSpatial is for unless you need to look at the Spatial hierarchy for some reason.

The regular clone() method is probably what you want and in Java those semantics are well understood.

cloneForSpatial() is mostly to make up for a deficiency in regular cloning regarding cloning fix-ups… like, you can use it for cases like AnimControl that must find the new clone’s SkeletonControl or whatever… and even in most of those kinds of cases, setSpatial() would be enough. The use-cases where cloneForSpatial() is required is vanishingly small and it seems extremely unlikely that you would need it unless you are doing something else wrong.

Ok, I switched it to use clone () and it works fine. Thanks for the help on this issue.