First round of getting JmeCloneable implemented... added

support for Cloner to the controls that implemented cloneForSpatial().
Unused until spatial cloning is implemented.
cleanup_build_scripts
Paul Speed 9 years ago
parent 197b9c28e8
commit 8b1ddbe60f
  1. 10
      jme3-bullet/src/common/java/com/jme3/bullet/control/AbstractPhysicsControl.java
  2. 12
      jme3-bullet/src/common/java/com/jme3/bullet/control/BetterCharacterControl.java
  3. 27
      jme3-bullet/src/common/java/com/jme3/bullet/control/CharacterControl.java
  4. 23
      jme3-bullet/src/common/java/com/jme3/bullet/control/GhostControl.java
  5. 15
      jme3-bullet/src/common/java/com/jme3/bullet/control/KinematicRagdollControl.java
  6. 37
      jme3-bullet/src/common/java/com/jme3/bullet/control/RigidBodyControl.java
  7. 61
      jme3-bullet/src/common/java/com/jme3/bullet/control/VehicleControl.java
  8. 31
      jme3-core/src/main/java/com/jme3/animation/AnimControl.java
  9. 31
      jme3-core/src/main/java/com/jme3/animation/Animation.java
  10. 22
      jme3-core/src/main/java/com/jme3/animation/AudioTrack.java
  11. 3
      jme3-core/src/main/java/com/jme3/animation/ClonableTrack.java
  12. 33
      jme3-core/src/main/java/com/jme3/animation/EffectTrack.java
  13. 13
      jme3-core/src/main/java/com/jme3/animation/Skeleton.java
  14. 27
      jme3-core/src/main/java/com/jme3/animation/SkeletonControl.java
  15. 18
      jme3-core/src/main/java/com/jme3/animation/TrackInfo.java
  16. 14
      jme3-core/src/main/java/com/jme3/app/StatsView.java
  17. 29
      jme3-core/src/main/java/com/jme3/cinematic/events/MotionEvent.java
  18. 18
      jme3-core/src/main/java/com/jme3/effect/ParticleEmitter.java
  19. 21
      jme3-core/src/main/java/com/jme3/input/ChaseCamera.java
  20. 18
      jme3-core/src/main/java/com/jme3/scene/control/AbstractControl.java
  21. 13
      jme3-core/src/main/java/com/jme3/scene/control/LodControl.java
  22. 13
      jme3-core/src/main/java/com/jme3/scene/control/UpdateControl.java
  23. 18
      jme3-core/src/main/java/com/jme3/scene/instancing/InstancedNode.java
  24. 14
      jme3-examples/src/main/java/jme3test/bullet/PhysicsHoverControl.java
  25. 11
      jme3-examples/src/main/java/jme3test/light/TestPssmShadow.java
  26. 9
      jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/NormalRecalcControl.java
  27. 24
      jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainLodControl.java

@ -41,6 +41,8 @@ import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Spatial;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
/**
@ -49,7 +51,7 @@ import java.io.IOException;
*
* @author normenhansen
*/
public abstract class AbstractPhysicsControl implements PhysicsControl {
public abstract class AbstractPhysicsControl implements PhysicsControl, JmeCloneable {
private final Quaternion tmp_inverseWorldRotation = new Quaternion();
protected Spatial spatial;
@ -161,6 +163,12 @@ public abstract class AbstractPhysicsControl implements PhysicsControl {
}
@Override
public void cloneFields( Cloner cloner, Object original ) {
this.spatial = cloner.clone(spatial);
createSpatialData(this.spatial);
}
public void setSpatial(Spatial spatial) {
if (this.spatial != null && this.spatial != spatial) {
removeSpatialData(this.spatial);

@ -50,6 +50,8 @@ import com.jme3.renderer.ViewPort;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.Control;
import com.jme3.util.TempVars;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
@ -68,7 +70,7 @@ import java.util.logging.Logger;
*
* @author normenhansen
*/
public class BetterCharacterControl extends AbstractPhysicsControl implements PhysicsTickListener {
public class BetterCharacterControl extends AbstractPhysicsControl implements PhysicsTickListener, JmeCloneable {
protected static final Logger logger = Logger.getLogger(BetterCharacterControl.class.getName());
protected PhysicsRigidBody rigidBody;
@ -670,6 +672,14 @@ public class BetterCharacterControl extends AbstractPhysicsControl implements Ph
return control;
}
@Override
public Object jmeClone() {
BetterCharacterControl control = new BetterCharacterControl(radius, height, mass);
control.setJumpForce(jumpForce);
control.spatial = this.spatial;
return control;
}
@Override
public void write(JmeExporter ex) throws IOException {
super.write(ex);

@ -44,13 +44,15 @@ import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.Control;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
/**
* You might want to try <code>BetterCharacterControl</code> as well.
* @author normenhansen
*/
public class CharacterControl extends PhysicsCharacter implements PhysicsControl {
public class CharacterControl extends PhysicsCharacter implements PhysicsControl, JmeCloneable {
protected Spatial spatial;
protected boolean enabled = true;
@ -104,6 +106,29 @@ public class CharacterControl extends PhysicsCharacter implements PhysicsControl
return control;
}
@Override
public Object jmeClone() {
CharacterControl control = new CharacterControl(collisionShape, stepHeight);
control.setCcdMotionThreshold(getCcdMotionThreshold());
control.setCcdSweptSphereRadius(getCcdSweptSphereRadius());
control.setCollideWithGroups(getCollideWithGroups());
control.setCollisionGroup(getCollisionGroup());
control.setFallSpeed(getFallSpeed());
control.setGravity(getGravity());
control.setJumpSpeed(getJumpSpeed());
control.setMaxSlope(getMaxSlope());
control.setPhysicsLocation(getPhysicsLocation());
control.setUpAxis(getUpAxis());
control.setApplyPhysicsLocal(isApplyPhysicsLocal());
control.spatial = this.spatial;
return control;
}
@Override
public void cloneFields( Cloner cloner, Object original ) {
this.spatial = cloner.clone(spatial);
}
public void setSpatial(Spatial spatial) {
this.spatial = spatial;
setUserObject(spatial);

@ -44,6 +44,8 @@ import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.Control;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
/**
@ -51,7 +53,7 @@ import java.io.IOException;
* overlaps with other physics objects (e.g. aggro radius).
* @author normenhansen
*/
public class GhostControl extends PhysicsGhostObject implements PhysicsControl {
public class GhostControl extends PhysicsGhostObject implements PhysicsControl, JmeCloneable {
protected Spatial spatial;
protected boolean enabled = true;
@ -106,6 +108,25 @@ public class GhostControl extends PhysicsGhostObject implements PhysicsControl {
return control;
}
@Override
public Object jmeClone() {
GhostControl control = new GhostControl(collisionShape);
control.setCcdMotionThreshold(getCcdMotionThreshold());
control.setCcdSweptSphereRadius(getCcdSweptSphereRadius());
control.setCollideWithGroups(getCollideWithGroups());
control.setCollisionGroup(getCollisionGroup());
control.setPhysicsLocation(getPhysicsLocation());
control.setPhysicsRotation(getPhysicsRotationMatrix());
control.setApplyPhysicsLocal(isApplyPhysicsLocal());
control.spatial = this.spatial;
return control;
}
@Override
public void cloneFields( Cloner cloner, Object original ) {
this.spatial = cloner.clone(spatial);
}
public void setSpatial(Spatial spatial) {
this.spatial = spatial;
setUserObject(spatial);

@ -61,6 +61,8 @@ import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.Control;
import com.jme3.util.TempVars;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
import java.util.*;
import java.util.logging.Level;
@ -92,7 +94,7 @@ import java.util.logging.Logger;
*
* @author Normen Hansen and Rémy Bouquet (Nehon)
*/
public class KinematicRagdollControl extends AbstractPhysicsControl implements PhysicsCollisionListener {
public class KinematicRagdollControl extends AbstractPhysicsControl implements PhysicsCollisionListener, JmeCloneable {
protected static final Logger logger = Logger.getLogger(KinematicRagdollControl.class.getName());
protected List<RagdollCollisionListener> listeners;
@ -920,6 +922,17 @@ public class KinematicRagdollControl extends AbstractPhysicsControl implements P
return control;
}
@Override
public Object jmeClone() {
KinematicRagdollControl control = new KinematicRagdollControl(preset, weightThreshold);
control.setMode(mode);
control.setRootMass(rootMass);
control.setWeightThreshold(weightThreshold);
control.setApplyPhysicsLocal(applyLocal);
control.spatial = this.spatial;
return control;
}
public Vector3f setIKTarget(Bone bone, Vector3f worldPos, int chainLength) {
Vector3f target = worldPos.subtract(targetModel.getWorldTranslation());
ikTargets.put(bone.getName(), target);

@ -51,13 +51,15 @@ import com.jme3.scene.Spatial;
import com.jme3.scene.control.Control;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
/**
*
* @author normenhansen
*/
public class RigidBodyControl extends PhysicsRigidBody implements PhysicsControl {
public class RigidBodyControl extends PhysicsRigidBody implements PhysicsControl, JmeCloneable {
protected Spatial spatial;
protected boolean enabled = true;
@ -116,6 +118,39 @@ public class RigidBodyControl extends PhysicsRigidBody implements PhysicsControl
return control;
}
@Override
public Object jmeClone() {
RigidBodyControl control = new RigidBodyControl(collisionShape, mass);
control.setAngularFactor(getAngularFactor());
control.setAngularSleepingThreshold(getAngularSleepingThreshold());
control.setCcdMotionThreshold(getCcdMotionThreshold());
control.setCcdSweptSphereRadius(getCcdSweptSphereRadius());
control.setCollideWithGroups(getCollideWithGroups());
control.setCollisionGroup(getCollisionGroup());
control.setDamping(getLinearDamping(), getAngularDamping());
control.setFriction(getFriction());
control.setGravity(getGravity());
control.setKinematic(isKinematic());
control.setKinematicSpatial(isKinematicSpatial());
control.setLinearSleepingThreshold(getLinearSleepingThreshold());
control.setPhysicsLocation(getPhysicsLocation(null));
control.setPhysicsRotation(getPhysicsRotationMatrix(null));
control.setRestitution(getRestitution());
if (mass > 0) {
control.setAngularVelocity(getAngularVelocity());
control.setLinearVelocity(getLinearVelocity());
}
control.setApplyPhysicsLocal(isApplyPhysicsLocal());
control.spatial = this.spatial;
return control;
}
@Override
public void cloneFields( Cloner cloner, Object original ) {
this.spatial = cloner.clone(spatial);
}
public void setSpatial(Spatial spatial) {
this.spatial = spatial;
setUserObject(spatial);

@ -46,6 +46,8 @@ import com.jme3.renderer.ViewPort;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.Control;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
import java.util.Iterator;
@ -53,7 +55,7 @@ import java.util.Iterator;
*
* @author normenhansen
*/
public class VehicleControl extends PhysicsVehicle implements PhysicsControl {
public class VehicleControl extends PhysicsVehicle implements PhysicsControl, JmeCloneable {
protected Spatial spatial;
protected boolean enabled = true;
@ -156,6 +158,63 @@ public class VehicleControl extends PhysicsVehicle implements PhysicsControl {
return control;
}
@Override
public Object jmeClone() {
VehicleControl control = new VehicleControl(collisionShape, mass);
control.setAngularFactor(getAngularFactor());
control.setAngularSleepingThreshold(getAngularSleepingThreshold());
control.setAngularVelocity(getAngularVelocity());
control.setCcdMotionThreshold(getCcdMotionThreshold());
control.setCcdSweptSphereRadius(getCcdSweptSphereRadius());
control.setCollideWithGroups(getCollideWithGroups());
control.setCollisionGroup(getCollisionGroup());
control.setDamping(getLinearDamping(), getAngularDamping());
control.setFriction(getFriction());
control.setGravity(getGravity());
control.setKinematic(isKinematic());
control.setLinearSleepingThreshold(getLinearSleepingThreshold());
control.setLinearVelocity(getLinearVelocity());
control.setPhysicsLocation(getPhysicsLocation());
control.setPhysicsRotation(getPhysicsRotationMatrix());
control.setRestitution(getRestitution());
control.setFrictionSlip(getFrictionSlip());
control.setMaxSuspensionTravelCm(getMaxSuspensionTravelCm());
control.setSuspensionStiffness(getSuspensionStiffness());
control.setSuspensionCompression(tuning.suspensionCompression);
control.setSuspensionDamping(tuning.suspensionDamping);
control.setMaxSuspensionForce(getMaxSuspensionForce());
for (Iterator<VehicleWheel> it = wheels.iterator(); it.hasNext();) {
VehicleWheel wheel = it.next();
VehicleWheel newWheel = control.addWheel(wheel.getLocation(), wheel.getDirection(), wheel.getAxle(), wheel.getRestLength(), wheel.getRadius(), wheel.isFrontWheel());
newWheel.setFrictionSlip(wheel.getFrictionSlip());
newWheel.setMaxSuspensionTravelCm(wheel.getMaxSuspensionTravelCm());
newWheel.setSuspensionStiffness(wheel.getSuspensionStiffness());
newWheel.setWheelsDampingCompression(wheel.getWheelsDampingCompression());
newWheel.setWheelsDampingRelaxation(wheel.getWheelsDampingRelaxation());
newWheel.setMaxSuspensionForce(wheel.getMaxSuspensionForce());
// Copy the wheel spatial reference directly for now. They'll
// get fixed up in the cloneFields() method
newWheel.setWheelSpatial(wheel.getWheelSpatial());
}
control.setApplyPhysicsLocal(isApplyPhysicsLocal());
control.spatial = spatial;
return control;
}
@Override
public void cloneFields( Cloner cloner, Object original ) {
this.spatial = cloner.clone(spatial);
for( VehicleWheel wheel : wheels ) {
Spatial spatial = cloner.clone(wheel.getWheelSpatial());
wheel.setWheelSpatial(spatial);
}
}
public void setSpatial(Spatial spatial) {
this.spatial = spatial;
setUserObject(spatial);

@ -38,11 +38,14 @@ import com.jme3.scene.Mesh;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
import com.jme3.scene.control.Control;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import com.jme3.util.TempVars;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
/**
@ -65,7 +68,7 @@ import java.util.Map.Entry;
*
* @author Kirill Vainer
*/
public final class AnimControl extends AbstractControl implements Cloneable {
public final class AnimControl extends AbstractControl implements Cloneable, JmeCloneable {
/**
* Skeleton object must contain corresponding data for the targets' weight buffers.
@ -131,6 +134,32 @@ public final class AnimControl extends AbstractControl implements Cloneable {
}
}
@Override
public Object jmeClone() {
AnimControl clone = (AnimControl) super.jmeClone();
clone.channels = new ArrayList<AnimChannel>();
clone.listeners = new ArrayList<AnimEventListener>();
return clone;
}
@Override
public void cloneFields( Cloner cloner, Object original ) {
super.cloneFields(cloner, original);
this.skeleton = cloner.clone(skeleton);
// Note cloneForSpatial() never actually cloned the animation map... just its reference
HashMap<String, Animation> newMap = new HashMap<>();
// animationMap is cloned, but only ClonableTracks will be cloned as they need a reference to a cloned spatial
for( Map.Entry<String, Animation> e : animationMap.entrySet() ) {
newMap.put(e.getKey(), cloner.clone(e.getValue()));
}
this.animationMap = newMap;
}
/**
* @param animations Set the animations that this <code>AnimControl</code>
* will be capable of playing. The animations should be compatible

@ -35,6 +35,8 @@ import com.jme3.export.*;
import com.jme3.scene.Spatial;
import com.jme3.util.SafeArrayList;
import com.jme3.util.TempVars;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
/**
@ -42,7 +44,7 @@ import java.io.IOException;
*
* @author Kirill Vainer, Marcin Roguski (Kaelthas)
*/
public class Animation implements Savable, Cloneable {
public class Animation implements Savable, Cloneable, JmeCloneable {
/**
* The name of the animation.
@ -190,6 +192,33 @@ public class Animation implements Savable, Cloneable {
}
}
@Override
public Object jmeClone() {
try {
return super.clone();
} catch( CloneNotSupportedException e ) {
throw new RuntimeException("Error cloning", e);
}
}
@Override
public void cloneFields( Cloner cloner, Object original ) {
// There is some logic here that I'm copying but I'm not sure if
// it's a mistake or not. If a track is not a CloneableTrack then it
// isn't cloned at all... even though they all implement clone() methods. -pspeed
SafeArrayList<Track> newTracks = new SafeArrayList<>(Track.class);
for( Track track : tracks ) {
if( track instanceof ClonableTrack ) {
newTracks.add(cloner.clone(track));
} else {
// this is the part that seems fishy
newTracks.add(track);
}
}
this.tracks = newTracks;
}
@Override
public String toString() {
return getClass().getSimpleName() + "[name=" + name + ", length=" + length + ']';

@ -39,6 +39,8 @@ import com.jme3.export.OutputCapsule;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.util.TempVars;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -193,6 +195,26 @@ public class AudioTrack implements ClonableTrack {
return audioTrack;
}
@Override
public Object jmeClone() {
try {
return super.clone();
} catch( CloneNotSupportedException e ) {
throw new RuntimeException("Error cloning", e);
}
}
@Override
public void cloneFields( Cloner cloner, Object original ) {
// Duplicating the old cloned state from cloneForSpatial()
this.initialized = false;
this.started = false;
this.played = false;
this.audio = cloner.clone(audio);
}
/**
* recursive function responsible for finding the newly cloned AudioNode
*

@ -32,6 +32,7 @@
package com.jme3.animation;
import com.jme3.scene.Spatial;
import com.jme3.util.clone.JmeCloneable;
/**
* An interface that allow to clone a Track for a given Spatial.
@ -43,7 +44,7 @@ import com.jme3.scene.Spatial;
*
* @author Nehon
*/
public interface ClonableTrack extends Track {
public interface ClonableTrack extends Track, JmeCloneable {
/**
* Allows to clone the track for a given Spatial.

@ -44,6 +44,8 @@ import com.jme3.scene.Spatial.CullHint;
import com.jme3.scene.control.AbstractControl;
import com.jme3.scene.control.Control;
import com.jme3.util.TempVars;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -116,6 +118,22 @@ public class EffectTrack implements ClonableTrack {
}
}
@Override
public Object jmeClone() {
KillParticleControl c = new KillParticleControl();
//this control should be removed as it shouldn't have been persisted in the first place
//In the quest to find the less hackish solution to achieve this,
//making it remove itself from the spatial in the first update loop when loaded was the less bad.
c.remove = true;
c.spatial = spatial;
return c;
}
@Override
public void cloneFields( Cloner cloner, Object original ) {
this.spatial = cloner.clone(spatial);
}
@Override
protected void controlRender(RenderManager rm, ViewPort vp) {
}
@ -284,6 +302,21 @@ public class EffectTrack implements ClonableTrack {
return effectTrack;
}
@Override
public Object jmeClone() {
try {
return super.clone();
} catch( CloneNotSupportedException e ) {
throw new RuntimeException("Error cloning", e);
}
}
@Override
public void cloneFields( Cloner cloner, Object original ) {
this.emitter = cloner.clone(emitter);
}
/**
* recursive function responsible for finding the newly cloned Emitter
*

@ -34,6 +34,8 @@ package com.jme3.animation;
import com.jme3.export.*;
import com.jme3.math.Matrix4f;
import com.jme3.util.TempVars;
import com.jme3.util.clone.JmeCloneable;
import com.jme3.util.clone.Cloner;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@ -45,7 +47,7 @@ import java.util.List;
*
* @author Kirill Vainer
*/
public final class Skeleton implements Savable {
public final class Skeleton implements Savable, JmeCloneable {
private Bone[] rootBones;
private Bone[] boneList;
@ -118,6 +120,15 @@ public final class Skeleton implements Savable {
public Skeleton() {
}
@Override
public Object jmeClone() {
return new Skeleton(this);
}
@Override
public void cloneFields( Cloner cloner, Object original ) {
}
private void createSkinningMatrices() {
skinningMatrixes = new Matrix4f[boneList.length];
for (int i = 0; i < skinningMatrixes.length; i++) {

@ -46,6 +46,8 @@ import com.jme3.scene.control.Control;
import com.jme3.shader.VarType;
import com.jme3.util.SafeArrayList;
import com.jme3.util.TempVars;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
import java.nio.Buffer;
import java.nio.ByteBuffer;
@ -63,7 +65,7 @@ import java.util.logging.Logger;
*
* @author Rémy Bouquet Based on AnimControl by Kirill Vainer
*/
public class SkeletonControl extends AbstractControl implements Cloneable {
public class SkeletonControl extends AbstractControl implements Cloneable, JmeCloneable {
/**
* The skeleton of the model.
@ -386,6 +388,29 @@ public class SkeletonControl extends AbstractControl implements Cloneable {
return clone;
}
@Override
public Object jmeClone() {
return super.jmeClone();
}
@Override
public void cloneFields( Cloner cloner, Object original ) {
super.cloneFields(cloner, original);
this.skeleton = cloner.clone(skeleton);
// If the targets were cloned then this will clone them. If the targets
// were shared then this will share them.
this.targets = cloner.clone(targets);
// Not automatic set cloning yet
Set<Material> newMaterials = new HashSet<Material>();
for( Material m : this.materials ) {
newMaterials.add(cloner.clone(m));
}
this.materials = newMaterials;
}
/**
*
* @param boneName the name of the bone

@ -36,6 +36,8 @@ import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import com.jme3.export.Savable;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
import java.util.ArrayList;
@ -48,7 +50,7 @@ import java.util.ArrayList;
*
* @author Nehon
*/
public class TrackInfo implements Savable {
public class TrackInfo implements Savable, JmeCloneable {
ArrayList<Track> tracks = new ArrayList<Track>();
@ -72,4 +74,18 @@ public class TrackInfo implements Savable {
public void addTrack(Track track) {
tracks.add(track);
}
@Override
public Object jmeClone() {
try {
return super.clone();
} catch( CloneNotSupportedException e ) {
throw new RuntimeException("Error cloning", e);
}
}
@Override
public void cloneFields( Cloner cloner, Object original ) {
this.tracks = cloner.clone(tracks);
}
}

@ -41,6 +41,8 @@ import com.jme3.renderer.queue.RenderQueue.Bucket;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.Control;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
/**
* The <code>StatsView</code> provides a heads-up display (HUD) of various
@ -58,7 +60,7 @@ import com.jme3.scene.control.Control;
* rootNode.attachChild(statsView);<br/>
* </code>
*/
public class StatsView extends Node implements Control {
public class StatsView extends Node implements Control, JmeCloneable {
private BitmapText statText;
private Statistics statistics;
@ -120,6 +122,16 @@ public class StatsView extends Node implements Control {
return (Control) spatial;
}
@Override
public Object jmeClone() {
throw new UnsupportedOperationException("Not yet implemented.");
}
@Override
public void cloneFields( Cloner cloner, Object original ) {
throw new UnsupportedOperationException("Not yet implemented.");
}
public void setSpatial(Spatial spatial) {
}

@ -47,6 +47,8 @@ import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.Control;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
/**
@ -56,7 +58,7 @@ import java.io.IOException;
*
* @author Nehon
*/
public class MotionEvent extends AbstractCinematicEvent implements Control {
public class MotionEvent extends AbstractCinematicEvent implements Control, JmeCloneable {
protected Spatial spatial;
protected int currentWayPoint;
@ -292,6 +294,31 @@ public class MotionEvent extends AbstractCinematicEvent implements Control {
return control;
}
@Override
public Object jmeClone() {
MotionEvent control = new MotionEvent();
control.path = path;
control.playState = playState;
control.currentWayPoint = currentWayPoint;
control.currentValue = currentValue;
control.direction = direction.clone();
control.lookAt = lookAt.clone();
control.upVector = upVector.clone();
control.rotation = rotation.clone();
control.initialDuration = initialDuration;
control.speed = speed;
control.loopMode = loopMode;
control.directionType = directionType;
control.spatial = spatial;
return control;
}
@Override
public void cloneFields( Cloner cloner, Object original ) {
this.spatial = cloner.clone(spatial);
}
@Override
public void onPlay() {
traveledDistance = 0;

@ -54,6 +54,8 @@ import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.Control;
import com.jme3.util.TempVars;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
/**
@ -108,7 +110,7 @@ public class ParticleEmitter extends Geometry {
private transient Vector3f temp = new Vector3f();
private transient Vector3f lastPos;
public static class ParticleEmitterControl implements Control {
public static class ParticleEmitterControl implements Control, JmeCloneable {
ParticleEmitter parentEmitter;
@ -125,6 +127,20 @@ public class ParticleEmitter extends Geometry {
// fixed automatically by ParticleEmitter.clone() method.
}
@Override
public Object jmeClone() {
try {
return super.clone();
} catch( CloneNotSupportedException e ) {
throw new RuntimeException("Error cloning", e);
}
}
@Override
public void cloneFields( Cloner cloner, Object original ) {
this.parentEmitter = cloner.clone(parentEmitter);
}
public void setSpatial(Spatial spatial) {
}

@ -43,13 +43,15 @@ import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.Control;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
/**
* A camera that follows a spatial and can turn around it by dragging the mouse
* @author nehon
*/
public class ChaseCamera implements ActionListener, AnalogListener, Control {
public class ChaseCamera implements ActionListener, AnalogListener, Control, JmeCloneable {
protected Spatial target = null;
protected float minVerticalRotation = 0.00f;
@ -575,6 +577,23 @@ public class ChaseCamera implements ActionListener, AnalogListener, Control {
return cc;
}
@Override
public Object jmeClone() {
ChaseCamera cc = new ChaseCamera(cam, inputManager);
cc.target = target;
cc.setMaxDistance(getMaxDistance());
cc.setMinDistance(getMinDistance());
return cc;
}
@Override
public void cloneFields( Cloner cloner, Object original ) {
this.target = cloner.clone(target);
computePosition();
prevPos = new Vector3f(target.getWorldTranslation());
cam.setLocation(pos);
}
/**
* Sets the spacial for the camera control, should only be used internally
* @param spatial

@ -38,6 +38,8 @@ import com.jme3.export.OutputCapsule;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Spatial;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
/**
@ -45,7 +47,7 @@ import java.io.IOException;
*
* @author Kirill Vainer
*/
public abstract class AbstractControl implements Control, Cloneable {
public abstract class AbstractControl implements Control, JmeCloneable {
protected boolean enabled = true;
protected Spatial spatial;
@ -105,6 +107,20 @@ public abstract class AbstractControl implements Control, Cloneable {
}
}
@Override
public Object jmeClone() {
try {
return super.clone();
} catch( CloneNotSupportedException e ) {
throw new RuntimeException( "Can't clone control for spatial", e );
}
}
@Override
public void cloneFields( Cloner cloner, Object original ) {
this.spatial = cloner.clone(spatial);
}
public void update(float tpf) {
if (!enabled)
return;

@ -43,6 +43,8 @@ import com.jme3.renderer.ViewPort;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Spatial;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
/**
@ -56,7 +58,7 @@ import java.io.IOException;
* and will update the spatial's LOD if the camera has moved by a specified
* amount.
*/
public class LodControl extends AbstractControl implements Cloneable {
public class LodControl extends AbstractControl implements Cloneable, JmeCloneable {
private float trisPerPixel = 1f;
private float distTolerance = 1f;
@ -142,6 +144,15 @@ public class LodControl extends AbstractControl implements Cloneable {
return clone;
}
@Override
public Object jmeClone() {
LodControl clone = (LodControl)super.jmeClone();
clone.lastDistance = 0;
clone.lastLevel = 0;
clone.numTris = numTris != null ? numTris.clone() : null;
return clone;
}
@Override
protected void controlUpdate(float tpf) {
}

@ -35,6 +35,8 @@ import com.jme3.app.AppTask;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Spatial;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Future;
@ -94,4 +96,15 @@ public class UpdateControl extends AbstractControl {
return control;
}
@Override
public Object jmeClone() {
UpdateControl clone = (UpdateControl)super.jmeClone();
// This is kind of questionable since the tasks aren't cloned and have
// no reference to the new spatial or anything. They'll get run again
// but it's not clear to me why that would be desired. I'm doing it
// because the old cloneForSpatial() code does. FIXME? -pspeed
clone.taskQueue.addAll(taskQueue);
return clone;
}
}

@ -44,6 +44,8 @@ import com.jme3.scene.control.Control;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.material.MatParam;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
import java.util.HashMap;
@ -106,7 +108,7 @@ public class InstancedNode extends GeometryGroupNode {
}
}
private static class InstancedNodeControl implements Control {
private static class InstancedNodeControl implements Control, JmeCloneable {
private InstancedNode node;
@ -124,6 +126,20 @@ public class InstancedNode extends GeometryGroupNode {
// fixed automatically by InstancedNode.clone() method.
}
@Override
public Object jmeClone() {
try {
return super.clone();
} catch( CloneNotSupportedException e ) {
throw new RuntimeException("Error cloning control", e);
}
}
@Override
public void cloneFields( Cloner cloner, Object original ) {
this.node = cloner.clone(node);
}
public void setSpatial(Spatial spatial){
}

@ -46,13 +46,15 @@ import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.Control;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
/**
* PhysicsHoverControl uses a RayCast Vehicle with "slippery wheels" to simulate a hovering tank
* @author normenhansen
*/
public class PhysicsHoverControl extends PhysicsVehicle implements PhysicsControl, PhysicsTickListener {
public class PhysicsHoverControl extends PhysicsVehicle implements PhysicsControl, PhysicsTickListener, JmeCloneable {
protected Spatial spatial;
protected boolean enabled = true;
@ -99,6 +101,16 @@ public class PhysicsHoverControl extends PhysicsVehicle implements PhysicsContro
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Object jmeClone() {
throw new UnsupportedOperationException("Not yet implemented.");
}
@Override
public void cloneFields( Cloner cloner, Object original ) {
throw new UnsupportedOperationException("Not yet implemented.");
}
public void setSpatial(Spatial spatial) {
this.spatial = spatial;
setUserObject(spatial);

@ -67,6 +67,8 @@ import com.jme3.texture.Texture;
import com.jme3.texture.Texture.WrapMode;
import com.jme3.util.SkyFactory;
import com.jme3.util.TangentBinormalGenerator;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
public class TestPssmShadow extends SimpleApplication implements ActionListener {
@ -249,6 +251,15 @@ public class TestPssmShadow extends SimpleApplication implements ActionListener
time = 0;
}
@Override
public Object jmeClone() {
return null;
}
@Override
public void cloneFields( Cloner cloner, Object original ) {
}
@Override
protected void controlRender(RenderManager rm, ViewPort vp) {
}

@ -40,6 +40,8 @@ import com.jme3.renderer.ViewPort;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
import com.jme3.scene.control.Control;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
@ -67,6 +69,13 @@ public class NormalRecalcControl extends AbstractControl {
}
@Override
public Object jmeClone() {
NormalRecalcControl control = (NormalRecalcControl)super.jmeClone();
control.setEnabled(true);
return control;
}
@Override
public Control cloneForSpatial(Spatial spatial) {
NormalRecalcControl control = new NormalRecalcControl(terrain);

@ -46,6 +46,8 @@ import com.jme3.scene.control.Control;
import com.jme3.terrain.Terrain;
import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator;
import com.jme3.terrain.geomipmap.lodcalc.LodCalculator;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
@ -299,6 +301,28 @@ public class TerrainLodControl extends AbstractControl {
@Override
public Object jmeClone() {
if (spatial instanceof Terrain) {
TerrainLodControl cloned = new TerrainLodControl((Terrain) spatial, cameras);
cloned.setLodCalculator(lodCalculator.clone());
cloned.spatial = spatial;
return cloned;
}
return null;
}
@Override
public void cloneFields( Cloner cloner, Object original ) {
this.lodCalculator = cloner.clone(lodCalculator);
try {
// Not deep clone of the cameras themselves
this.cameras = cloner.javaClone(cameras);
} catch( CloneNotSupportedException e ) {
throw new RuntimeException("Error cloning", e);
}
}
@Override

Loading…
Cancel
Save