|
|
|
@ -47,6 +47,8 @@ import com.jme3.renderer.queue.RenderQueue; |
|
|
|
|
import com.jme3.renderer.queue.RenderQueue.Bucket; |
|
|
|
|
import com.jme3.renderer.queue.RenderQueue.ShadowMode; |
|
|
|
|
import com.jme3.scene.control.Control; |
|
|
|
|
import com.jme3.util.clone.Cloner; |
|
|
|
|
import com.jme3.util.clone.JmeCloneable; |
|
|
|
|
import com.jme3.util.SafeArrayList; |
|
|
|
|
import com.jme3.util.TempVars; |
|
|
|
|
import java.io.IOException; |
|
|
|
@ -63,7 +65,7 @@ import java.util.logging.Logger; |
|
|
|
|
* @author Joshua Slack |
|
|
|
|
* @version $Revision: 4075 $, $Data$ |
|
|
|
|
*/ |
|
|
|
|
public abstract class Spatial implements Savable, Cloneable, Collidable, CloneableSmartAsset { |
|
|
|
|
public abstract class Spatial implements Savable, Cloneable, Collidable, CloneableSmartAsset, JmeCloneable { |
|
|
|
|
|
|
|
|
|
private static final Logger logger = Logger.getLogger(Spatial.class.getName()); |
|
|
|
|
|
|
|
|
@ -1344,6 +1346,52 @@ public abstract class Spatial implements Savable, Cloneable, Collidable, Cloneab |
|
|
|
|
*/ |
|
|
|
|
public abstract Spatial deepClone(); |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Called internally by com.jme3.util.clone.Cloner. Do not call directly. |
|
|
|
|
*/ |
|
|
|
|
@Override |
|
|
|
|
public Spatial jmeClone() { |
|
|
|
|
try { |
|
|
|
|
Spatial clone = (Spatial)super.clone(); |
|
|
|
|
return clone; |
|
|
|
|
} catch (CloneNotSupportedException ex) { |
|
|
|
|
throw new AssertionError(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Called internally by com.jme3.util.clone.Cloner. Do not call directly. |
|
|
|
|
*/ |
|
|
|
|
@Override |
|
|
|
|
public void cloneFields( Cloner cloner, Object original ) { |
|
|
|
|
|
|
|
|
|
// Clone all of the fields that need fix-ups and/or potential
|
|
|
|
|
// sharing.
|
|
|
|
|
this.parent = cloner.clone(parent); |
|
|
|
|
this.worldBound = cloner.clone(worldBound); |
|
|
|
|
this.worldLights = cloner.clone(worldLights); |
|
|
|
|
this.localLights = cloner.clone(localLights); |
|
|
|
|
this.worldTransform = cloner.clone(worldTransform); |
|
|
|
|
this.localTransform = cloner.clone(localTransform); |
|
|
|
|
this.controls = cloner.clone(controls); |
|
|
|
|
|
|
|
|
|
// Cloner doesn't handle maps on its own just yet.
|
|
|
|
|
// Note: this is more advanced cloning than the old clone() method
|
|
|
|
|
// did because it just shallow cloned the map. In this case, we want
|
|
|
|
|
// to avoid all of the nasty cloneForSpatial() fixup style code that
|
|
|
|
|
// used to inject stuff into the clone's user data. By using cloner
|
|
|
|
|
// to clone the user data we get this automatically.
|
|
|
|
|
userData = (HashMap<String, Savable>)userData.clone(); |
|
|
|
|
for( Map.Entry<String, Savable> e : userData.entrySet() ) { |
|
|
|
|
Savable value = e.getValue(); |
|
|
|
|
if( value instanceof Cloneable ) { |
|
|
|
|
// Note: all JmeCloneable objects are also Cloneable so this
|
|
|
|
|
// catches both cases.
|
|
|
|
|
e.setValue(cloner.clone(value)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public void setUserData(String key, Object data) { |
|
|
|
|
if (userData == null) { |
|
|
|
|
userData = new HashMap<String, Savable>(); |
|
|
|
|