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.
cleanup_build_scripts
Paul Speed 9 years ago
parent 911b4be868
commit 2bdb3de2f5
  1. 2
      jme3-core/src/main/java/com/jme3/app/StatsView.java
  2. 22
      jme3-core/src/main/java/com/jme3/light/LightList.java
  3. 13
      jme3-core/src/main/java/com/jme3/scene/AssetLinkNode.java
  4. 37
      jme3-core/src/main/java/com/jme3/scene/BatchNode.java
  5. 12
      jme3-core/src/main/java/com/jme3/scene/CameraNode.java
  6. 11
      jme3-core/src/main/java/com/jme3/scene/Geometry.java
  7. 12
      jme3-core/src/main/java/com/jme3/scene/LightNode.java
  8. 33
      jme3-core/src/main/java/com/jme3/scene/Mesh.java
  9. 14
      jme3-core/src/main/java/com/jme3/scene/Node.java
  10. 50
      jme3-core/src/main/java/com/jme3/scene/Spatial.java
  11. 11
      jme3-core/src/main/java/com/jme3/scene/instancing/InstancedGeometry.java
  12. 39
      jme3-core/src/main/java/com/jme3/scene/instancing/InstancedNode.java
  13. 41
      jme3-core/src/main/java/com/jme3/util/IntMap.java
  14. 3
      jme3-core/src/main/resources/com/jme3/system/version.properties

@ -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…
Cancel
Save