Started implementing the JmeCloneable stuff for Spatial
and Mesh. Still need to catch some of the outer subclasses of Node and Geometry. Nothing is hooked up or tested yet.
This commit is contained in:
parent
911b4be868
commit
2bdb3de2f5
@ -123,7 +123,7 @@ public class StatsView extends Node implements Control, JmeCloneable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jmeClone() {
|
||||
public StatsView jmeClone() {
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,8 @@ package com.jme3.light;
|
||||
|
||||
import com.jme3.export.*;
|
||||
import com.jme3.scene.Spatial;
|
||||
import com.jme3.util.clone.Cloner;
|
||||
import com.jme3.util.clone.JmeCloneable;
|
||||
import com.jme3.util.SortUtil;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
@ -43,7 +45,7 @@ import java.util.*;
|
||||
*
|
||||
* @author Kirill Vainer
|
||||
*/
|
||||
public final class LightList implements Iterable<Light>, Savable, Cloneable {
|
||||
public final class LightList implements Iterable<Light>, Savable, Cloneable, JmeCloneable {
|
||||
|
||||
private Light[] list, tlist;
|
||||
private float[] distToOwner;
|
||||
@ -302,6 +304,24 @@ public final class LightList implements Iterable<Light>, Savable, Cloneable {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LightList jmeClone() {
|
||||
try{
|
||||
LightList clone = (LightList)super.clone();
|
||||
clone.tlist = null; // list used for sorting only
|
||||
return clone;
|
||||
}catch (CloneNotSupportedException ex){
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cloneFields( Cloner cloner, Object original ) {
|
||||
this.owner = cloner.clone(owner);
|
||||
this.list = cloner.clone(list);
|
||||
this.distToOwner = cloner.clone(distToOwner);
|
||||
}
|
||||
|
||||
public void write(JmeExporter ex) throws IOException {
|
||||
OutputCapsule oc = ex.getCapsule(this);
|
||||
// oc.write(owner, "owner", null);
|
||||
|
@ -39,6 +39,7 @@ import com.jme3.export.JmeExporter;
|
||||
import com.jme3.export.JmeImporter;
|
||||
import com.jme3.export.OutputCapsule;
|
||||
import com.jme3.export.binary.BinaryImporter;
|
||||
import com.jme3.util.clone.Cloner;
|
||||
import com.jme3.util.SafeArrayList;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
@ -70,6 +71,18 @@ public class AssetLinkNode extends Node {
|
||||
assetLoaderKeys.add(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called internally by com.jme3.util.clone.Cloner. Do not call directly.
|
||||
*/
|
||||
@Override
|
||||
public void cloneFields( Cloner cloner, Object original ) {
|
||||
// This is a change in behavior because the old version did not clone
|
||||
// this list... changes to one clone would be reflected in all.
|
||||
// I think that's probably undesirable. -pspeed
|
||||
this.assetLoaderKeys = cloner.clone(assetLoaderKeys);
|
||||
this.assetChildren = new HashMap<ModelKey, Spatial>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a "linked" child. These are loaded from the assetManager when the
|
||||
* AssetLinkNode is loaded from a binary file.
|
||||
|
@ -48,6 +48,8 @@ import com.jme3.math.Vector3f;
|
||||
import com.jme3.scene.mesh.IndexBuffer;
|
||||
import com.jme3.util.SafeArrayList;
|
||||
import com.jme3.util.TempVars;
|
||||
import com.jme3.util.clone.Cloner;
|
||||
import com.jme3.util.clone.JmeCloneable;
|
||||
|
||||
/**
|
||||
* BatchNode holds geometries that are a batched version of all the geometries that are in its sub scenegraph.
|
||||
@ -662,7 +664,7 @@ public class BatchNode extends GeometryGroupNode {
|
||||
vars.release();
|
||||
}
|
||||
|
||||
protected class Batch {
|
||||
protected class Batch implements JmeCloneable {
|
||||
/**
|
||||
* update the batchesByGeom map for this batch with the given List of geometries
|
||||
* @param list
|
||||
@ -679,6 +681,21 @@ public class BatchNode extends GeometryGroupNode {
|
||||
public final Geometry getGeometry() {
|
||||
return geometry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Batch jmeClone() {
|
||||
try {
|
||||
return (Batch)super.clone();
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cloneFields( Cloner cloner, Object original ) {
|
||||
this.geometry = cloner.clone(geometry);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void setNeedsFullRebatch(boolean needsFullRebatch) {
|
||||
@ -705,6 +722,24 @@ public class BatchNode extends GeometryGroupNode {
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called internally by com.jme3.util.clone.Cloner. Do not call directly.
|
||||
*/
|
||||
@Override
|
||||
public void cloneFields( Cloner cloner, Object original ) {
|
||||
this.batches = cloner.clone(batches);
|
||||
this.tmpFloat = cloner.clone(tmpFloat);
|
||||
this.tmpFloatN = cloner.clone(tmpFloatN);
|
||||
this.tmpFloatT = cloner.clone(tmpFloatT);
|
||||
|
||||
|
||||
HashMap<Geometry, Batch> newBatchesByGeom = new HashMap<Geometry, Batch>();
|
||||
for( Map.Entry<Geometry, Batch> e : batchesByGeom.entrySet() ) {
|
||||
newBatchesByGeom.put(cloner.clone(e.getKey()), cloner.clone(e.getValue()));
|
||||
}
|
||||
this.batchesByGeom = newBatchesByGeom;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int collideWith(Collidable other, CollisionResults results) {
|
||||
int total = 0;
|
||||
|
@ -36,6 +36,7 @@ import com.jme3.export.JmeImporter;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.scene.control.CameraControl;
|
||||
import com.jme3.scene.control.CameraControl.ControlDirection;
|
||||
import com.jme3.util.clone.Cloner;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
@ -94,6 +95,17 @@ public class CameraNode extends Node {
|
||||
// camControl.getCamera().lookAt(position, upVector);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Called internally by com.jme3.util.clone.Cloner. Do not call directly.
|
||||
*/
|
||||
@Override
|
||||
public void cloneFields( Cloner cloner, Object original ) {
|
||||
// A change in behavior... I think previously CameraNode was probably
|
||||
// not really cloneable... or at least its camControl would be pointing
|
||||
// to the wrong control. -pspeed
|
||||
this.camControl = cloner.clone(camControl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(JmeImporter im) throws IOException {
|
||||
super.read(im);
|
||||
|
@ -43,6 +43,7 @@ import com.jme3.material.Material;
|
||||
import com.jme3.math.Matrix4f;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.scene.VertexBuffer.Type;
|
||||
import com.jme3.util.clone.Cloner;
|
||||
import com.jme3.util.TempVars;
|
||||
import java.io.IOException;
|
||||
import java.util.Queue;
|
||||
@ -539,6 +540,16 @@ public class Geometry extends Spatial {
|
||||
return geomClone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called internally by com.jme3.util.clone.Cloner. Do not call directly.
|
||||
*/
|
||||
@Override
|
||||
public void cloneFields( Cloner cloner, Object original ) {
|
||||
this.mesh = cloner.clone(mesh);
|
||||
this.material = cloner.clone(material);
|
||||
this.groupNode = cloner.clone(groupNode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(JmeExporter ex) throws IOException {
|
||||
super.write(ex);
|
||||
|
@ -36,6 +36,7 @@ import com.jme3.export.JmeImporter;
|
||||
import com.jme3.light.Light;
|
||||
import com.jme3.scene.control.LightControl;
|
||||
import com.jme3.scene.control.LightControl.ControlDirection;
|
||||
import com.jme3.util.clone.Cloner;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
@ -94,6 +95,17 @@ public class LightNode extends Node {
|
||||
return lightControl.getLight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called internally by com.jme3.util.clone.Cloner. Do not call directly.
|
||||
*/
|
||||
@Override
|
||||
public void cloneFields( Cloner cloner, Object original ) {
|
||||
// A change in behavior... I think previously LightNode was probably
|
||||
// not really cloneable... or at least its lightControl would be pointing
|
||||
// to the wrong control. -pspeed
|
||||
this.lightControl = cloner.clone(lightControl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(JmeImporter im) throws IOException {
|
||||
super.read(im);
|
||||
|
@ -51,6 +51,8 @@ import com.jme3.util.BufferUtils;
|
||||
import com.jme3.util.IntMap;
|
||||
import com.jme3.util.IntMap.Entry;
|
||||
import com.jme3.util.SafeArrayList;
|
||||
import com.jme3.util.clone.Cloner;
|
||||
import com.jme3.util.clone.JmeCloneable;
|
||||
import java.io.IOException;
|
||||
import java.nio.*;
|
||||
import java.util.ArrayList;
|
||||
@ -72,7 +74,7 @@ import java.util.ArrayList;
|
||||
*
|
||||
* @author Kirill Vainer
|
||||
*/
|
||||
public class Mesh implements Savable, Cloneable {
|
||||
public class Mesh implements Savable, Cloneable, JmeCloneable {
|
||||
|
||||
/**
|
||||
* The mode of the Mesh specifies both the type of primitive represented
|
||||
@ -299,6 +301,35 @@ public class Mesh implements Savable, Cloneable {
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called internally by com.jme3.util.clone.Cloner. Do not call directly.
|
||||
*/
|
||||
@Override
|
||||
public Mesh jmeClone() {
|
||||
try {
|
||||
return (Mesh)super.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 ) {
|
||||
|
||||
// Probably could clone this now but it will get regenerated anyway.
|
||||
this.collisionTree = null;
|
||||
|
||||
this.meshBound = cloner.clone(meshBound);
|
||||
this.buffersList = cloner.clone(buffersList);
|
||||
this.buffers = cloner.clone(buffers);
|
||||
this.lodLevels = cloner.clone(lodLevels);
|
||||
this.elementLengths = cloner.clone(elementLengths);
|
||||
this.modeStart = cloner.clone(modeStart);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the {@link Type#BindPosePosition}, {@link Type#BindPoseNormal},
|
||||
* and {@link Type#BindPoseTangent}
|
||||
|
@ -40,6 +40,7 @@ import com.jme3.export.Savable;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.util.SafeArrayList;
|
||||
import com.jme3.util.TempVars;
|
||||
import com.jme3.util.clone.Cloner;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -707,6 +708,19 @@ public class Node extends Spatial {
|
||||
return nodeClone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called internally by com.jme3.util.clone.Cloner. Do not call directly.
|
||||
*/
|
||||
@Override
|
||||
public void cloneFields( Cloner cloner, Object original ) {
|
||||
this.children = cloner.clone(children);
|
||||
|
||||
// Only the outer cloning thing knows whether this should be nulled
|
||||
// or not... after all, we might be cloning a root node in which case
|
||||
// cloning this list is fine.
|
||||
this.updateList = cloner.clone(updateList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(JmeExporter e) throws IOException {
|
||||
super.write(e);
|
||||
|
@ -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>();
|
||||
|
@ -47,6 +47,7 @@ import com.jme3.scene.VertexBuffer.Type;
|
||||
import com.jme3.scene.VertexBuffer.Usage;
|
||||
import com.jme3.util.BufferUtils;
|
||||
import com.jme3.util.TempVars;
|
||||
import com.jme3.util.clone.Cloner;
|
||||
import java.io.IOException;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.ArrayList;
|
||||
@ -343,6 +344,16 @@ public class InstancedGeometry extends Geometry {
|
||||
return allData.toArray(new VertexBuffer[allData.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called internally by com.jme3.util.clone.Cloner. Do not call directly.
|
||||
*/
|
||||
@Override
|
||||
public void cloneFields( Cloner cloner, Object original ) {
|
||||
this.globalInstanceData = cloner.clone(globalInstanceData);
|
||||
this.transformInstanceData = cloner.clone(transformInstanceData);
|
||||
this.geometries = cloner.clone(geometries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(JmeExporter exporter) throws IOException {
|
||||
super.write(exporter);
|
||||
|
@ -48,6 +48,7 @@ import com.jme3.util.clone.Cloner;
|
||||
import com.jme3.util.clone.JmeCloneable;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class InstancedNode extends GeometryGroupNode {
|
||||
|
||||
@ -59,7 +60,7 @@ public class InstancedNode extends GeometryGroupNode {
|
||||
setGeometryStartIndex(geom, startIndex);
|
||||
}
|
||||
|
||||
private static final class InstanceTypeKey implements Cloneable {
|
||||
private static final class InstanceTypeKey implements Cloneable, JmeCloneable {
|
||||
|
||||
Mesh mesh;
|
||||
Material material;
|
||||
@ -106,6 +107,21 @@ public class InstancedNode extends GeometryGroupNode {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jmeClone() {
|
||||
try {
|
||||
return super.clone();
|
||||
} catch( CloneNotSupportedException e ) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cloneFields( Cloner cloner, Object original ) {
|
||||
this.mesh = cloner.clone(mesh);
|
||||
this.material = cloner.clone(material);
|
||||
}
|
||||
}
|
||||
|
||||
private static class InstancedNodeControl implements Control, JmeCloneable {
|
||||
@ -329,6 +345,27 @@ public class InstancedNode extends GeometryGroupNode {
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called internally by com.jme3.util.clone.Cloner. Do not call directly.
|
||||
*/
|
||||
@Override
|
||||
public void cloneFields( Cloner cloner, Object original ) {
|
||||
this.control = cloner.clone(control);
|
||||
this.lookUp = cloner.clone(lookUp);
|
||||
|
||||
HashMap<Geometry, InstancedGeometry> newIgByGeom = new HashMap<Geometry, InstancedGeometry>();
|
||||
for( Map.Entry<Geometry, InstancedGeometry> e : igByGeom.entrySet() ) {
|
||||
newIgByGeom.put(cloner.clone(e.getKey()), cloner.clone(e.getValue()));
|
||||
}
|
||||
this.igByGeom = newIgByGeom;
|
||||
|
||||
HashMap<InstanceTypeKey, InstancedGeometry> newInstancesMap = new HashMap<InstanceTypeKey, InstancedGeometry>();
|
||||
for( Map.Entry<InstanceTypeKey, InstancedGeometry> e : instancesMap.entrySet() ) {
|
||||
newInstancesMap.put(cloner.clone(e.getKey()), cloner.clone(e.getValue()));
|
||||
}
|
||||
this.instancesMap = newInstancesMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransformChange(Geometry geom) {
|
||||
// Handled automatically
|
||||
|
@ -32,6 +32,8 @@
|
||||
package com.jme3.util;
|
||||
|
||||
import com.jme3.util.IntMap.Entry;
|
||||
import com.jme3.util.clone.Cloner;
|
||||
import com.jme3.util.clone.JmeCloneable;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
@ -43,7 +45,7 @@ import java.util.NoSuchElementException;
|
||||
*
|
||||
* @author Nate
|
||||
*/
|
||||
public final class IntMap<T> implements Iterable<Entry<T>>, Cloneable {
|
||||
public final class IntMap<T> implements Iterable<Entry<T>>, Cloneable, JmeCloneable {
|
||||
|
||||
private Entry[] table;
|
||||
private final float loadFactor;
|
||||
@ -93,6 +95,26 @@ public final class IntMap<T> implements Iterable<Entry<T>>, Cloneable {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called internally by com.jme3.util.clone.Cloner. Do not call directly.
|
||||
*/
|
||||
@Override
|
||||
public Object jmeClone() {
|
||||
try {
|
||||
return super.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 ) {
|
||||
this.table = cloner.clone(table);
|
||||
}
|
||||
|
||||
public boolean containsValue(Object value) {
|
||||
Entry[] table = this.table;
|
||||
for (int i = table.length; i-- > 0;){
|
||||
@ -268,7 +290,7 @@ public final class IntMap<T> implements Iterable<Entry<T>>, Cloneable {
|
||||
|
||||
}
|
||||
|
||||
public static final class Entry<T> implements Cloneable {
|
||||
public static final class Entry<T> implements Cloneable, JmeCloneable {
|
||||
|
||||
final int key;
|
||||
T value;
|
||||
@ -303,5 +325,20 @@ public final class IntMap<T> implements Iterable<Entry<T>>, Cloneable {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jmeClone() {
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cloneFields( Cloner cloner, Object original ) {
|
||||
this.value = cloner.clone(value);
|
||||
this.next = cloner.clone(next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
# THIS IS AN AUTO-GENERATED FILE..
|
||||
# DO NOT MODIFY!
|
||||
build.date=1900-01-01
|
||||
build.date=2016-03-25
|
||||
git.revision=0
|
||||
git.branch=unknown
|
||||
git.hash=
|
||||
git.hash.short=
|
||||
git.tag=
|
||||
name.full=jMonkeyEngine 3.1.0-UNKNOWN
|
||||
version.full=3.1.0-UNKNOWN
|
||||
version.number=3.1.0
|
||||
version.tag=SNAPSHOT
|
Loading…
x
Reference in New Issue
Block a user