diff --git a/jme3-core/src/main/java/com/jme3/effect/ParticleEmitter.java b/jme3-core/src/main/java/com/jme3/effect/ParticleEmitter.java index d53273c4e..3baf8feb6 100644 --- a/jme3-core/src/main/java/com/jme3/effect/ParticleEmitter.java +++ b/jme3-core/src/main/java/com/jme3/effect/ParticleEmitter.java @@ -65,12 +65,12 @@ import java.io.IOException; * Particle emitters can be used to simulate various kinds of phenomena, * such as fire, smoke, explosions and much more. *
- * Particle emitters have many properties which are used to control the - * simulation. The interpretation of these properties depends on the + * Particle emitters have many properties which are used to control the + * simulation. The interpretation of these properties depends on the * {@link ParticleInfluencer} that has been assigned to the emitter via * {@link ParticleEmitter#setParticleInfluencer(com.jme3.effect.influencers.ParticleInfluencer) }. * By default the implementation {@link DefaultParticleInfluencer} is used. - * + * * @author Kirill Vainer */ public class ParticleEmitter extends Geometry { @@ -100,7 +100,7 @@ public class ParticleEmitter extends Geometry { private Vector3f faceNormal = new Vector3f(Vector3f.NAN); private int imagesX = 1; private int imagesY = 1; - + private ColorRGBA startColor = new ColorRGBA(0.4f, 0.4f, 0.4f, 0.5f); private ColorRGBA endColor = new ColorRGBA(0.1f, 0.1f, 0.1f, 0.0f); private float startSize = 0.2f; @@ -127,20 +127,20 @@ public class ParticleEmitter extends Geometry { // fixed automatically by ParticleEmitter.clone() method. } - @Override + @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 ) { + @Override + public void cloneFields( Cloner cloner, Object original ) { this.parentEmitter = cloner.clone(parentEmitter); } - + public void setSpatial(Spatial spatial) { } @@ -211,6 +211,42 @@ public class ParticleEmitter extends Geometry { return clone; } + /** + * Called internally by com.jme3.util.clone.Cloner. Do not call directly. + */ + @Override + public void cloneFields( Cloner cloner, Object original ) { + this.shape = cloner.clone(shape); + this.control = cloner.clone(control); + this.faceNormal = cloner.clone(faceNormal); + this.startColor = cloner.clone(startColor); + this.endColor = cloner.clone(endColor); + this.particleInfluencer = cloner.clone(particleInfluencer); + + // change in behavior: gravity was not cloned before -pspeed + this.gravity = cloner.clone(gravity); + + // So, simply setting the mesh type will cause all kinds of things + // to happen: + // 1) the new mesh gets created. + // 2) it is set to the Geometry + // 3) the particles array is recreated because setNumParticles() + // + // ...so this should be equivalent but simpler than half of the old clone() + // method. Note: we do not ever want to share particleMesh so we do not + // clone it at all. + setMeshType(meshType); + + // change in behavior: temp and lastPos were not cloned before... + // perhaps because it was believed that 'transient' fields were exluded + // from cloning? (they aren't) + // If it was ok for these to be shared because of how they are used + // then they could just as well be made static... else I think it's clearer + // to clone them. + this.temp = cloner.clone(temp); + this.lastPos = cloner.clone(lastPos); + } + public ParticleEmitter(String name, Type type, int numParticles) { super(name); setBatchHint(BatchHint.Never); @@ -225,7 +261,7 @@ public class ParticleEmitter extends Geometry { meshType = type; - // Must create clone of shape/influencer so that a reference to a static is + // Must create clone of shape/influencer so that a reference to a static is // not maintained shape = shape.deepClone(); particleInfluencer = particleInfluencer.clone(); @@ -267,10 +303,10 @@ public class ParticleEmitter extends Geometry { /** * Set the {@link ParticleInfluencer} to influence this particle emitter. - * - * @param particleInfluencer the {@link ParticleInfluencer} to influence + * + * @param particleInfluencer the {@link ParticleInfluencer} to influence * this particle emitter. - * + * * @see ParticleInfluencer */ public void setParticleInfluencer(ParticleInfluencer particleInfluencer) { @@ -278,12 +314,12 @@ public class ParticleEmitter extends Geometry { } /** - * Returns the {@link ParticleInfluencer} that influences this + * Returns the {@link ParticleInfluencer} that influences this * particle emitter. - * - * @return the {@link ParticleInfluencer} that influences this + * + * @return the {@link ParticleInfluencer} that influences this * particle emitter. - * + * * @see ParticleInfluencer */ public ParticleInfluencer getParticleInfluencer() { @@ -292,12 +328,12 @@ public class ParticleEmitter extends Geometry { /** * Returns the mesh type used by the particle emitter. - * - * + * + * * @return the mesh type used by the particle emitter. - * + * * @see #setMeshType(com.jme3.effect.ParticleMesh.Type) - * @see ParticleEmitter#ParticleEmitter(java.lang.String, com.jme3.effect.ParticleMesh.Type, int) + * @see ParticleEmitter#ParticleEmitter(java.lang.String, com.jme3.effect.ParticleMesh.Type, int) */ public ParticleMesh.Type getMeshType() { return meshType; @@ -325,26 +361,26 @@ public class ParticleEmitter extends Geometry { } /** - * Returns true if particles should spawn in world space. - * - * @return true if particles should spawn in world space. - * - * @see ParticleEmitter#setInWorldSpace(boolean) + * Returns true if particles should spawn in world space. + * + * @return true if particles should spawn in world space. + * + * @see ParticleEmitter#setInWorldSpace(boolean) */ public boolean isInWorldSpace() { return worldSpace; } /** - * Set to true if particles should spawn in world space. - * + * Set to true if particles should spawn in world space. + * *
If set to true and the particle emitter is moved in the scene, * then particles that have already spawned won't be effected by this * motion. If set to false, the particles will emit in local space * and when the emitter is moved, so are all the particles that * were emitted previously. - * - * @param worldSpace true if particles should spawn in world space. + * + * @param worldSpace true if particles should spawn in world space. */ public void setInWorldSpace(boolean worldSpace) { this.setIgnoreTransform(worldSpace); @@ -353,7 +389,7 @@ public class ParticleEmitter extends Geometry { /** * Returns the number of visible particles (spawned but not dead). - * + * * @return the number of visible particles */ public int getNumVisibleParticles() { @@ -365,7 +401,7 @@ public class ParticleEmitter extends Geometry { * Set the maximum amount of particles that * can exist at the same time with this emitter. * Calling this method many times is not recommended. - * + * * @param numParticles the maximum amount of particles that * can exist at the same time with this emitter. */ @@ -387,13 +423,13 @@ public class ParticleEmitter extends Geometry { /** * Returns a list of all particles (shouldn't be used in most cases). - * + * *
* This includes both existing and non-existing particles.
* The size of the array is set to the numParticles
value
* specified in the constructor or {@link ParticleEmitter#setNumParticles(int) }
- * method.
- *
+ * method.
+ *
* @return a list of all particles.
*/
public Particle[] getParticles() {
@@ -401,11 +437,11 @@ public class ParticleEmitter extends Geometry {
}
/**
- * Get the normal which particles are facing.
- *
- * @return the normal which particles are facing.
- *
- * @see ParticleEmitter#setFaceNormal(com.jme3.math.Vector3f)
+ * Get the normal which particles are facing.
+ *
+ * @return the normal which particles are facing.
+ *
+ * @see ParticleEmitter#setFaceNormal(com.jme3.math.Vector3f)
*/
public Vector3f getFaceNormal() {
if (Vector3f.isValidVector(faceNormal)) {
@@ -416,8 +452,8 @@ public class ParticleEmitter extends Geometry {
}
/**
- * Sets the normal which particles are facing.
- *
+ * Sets the normal which particles are facing.
+ *
*
By default, particles * will face the camera, but for some effects (e.g shockwave) it may * be necessary to face a specific direction instead. To restore @@ -437,10 +473,10 @@ public class ParticleEmitter extends Geometry { /** * Returns the rotation speed in radians/sec for particles. - * + * * @return the rotation speed in radians/sec for particles. - * - * @see ParticleEmitter#setRotateSpeed(float) + * + * @see ParticleEmitter#setRotateSpeed(float) */ public float getRotateSpeed() { return rotateSpeed; @@ -449,7 +485,7 @@ public class ParticleEmitter extends Geometry { /** * Set the rotation speed in radians/sec for particles * spawned after the invocation of this method. - * + * * @param rotateSpeed the rotation speed in radians/sec for particles * spawned after the invocation of this method. */ @@ -459,12 +495,12 @@ public class ParticleEmitter extends Geometry { /** * Returns true if every particle spawned - * should have a random facing angle. - * + * should have a random facing angle. + * * @return true if every particle spawned - * should have a random facing angle. - * - * @see ParticleEmitter#setRandomAngle(boolean) + * should have a random facing angle. + * + * @see ParticleEmitter#setRandomAngle(boolean) */ public boolean isRandomAngle() { return randomAngle; @@ -472,8 +508,8 @@ public class ParticleEmitter extends Geometry { /** * Set to true if every particle spawned - * should have a random facing angle. - * + * should have a random facing angle. + * * @param randomAngle if every particle spawned * should have a random facing angle. */ @@ -484,11 +520,11 @@ public class ParticleEmitter extends Geometry { /** * Returns true if every particle spawned should get a random * image. - * + * * @return True if every particle spawned should get a random * image. - * - * @see ParticleEmitter#setSelectRandomImage(boolean) + * + * @see ParticleEmitter#setSelectRandomImage(boolean) */ public boolean isSelectRandomImage() { return selectRandomImage; @@ -498,7 +534,7 @@ public class ParticleEmitter extends Geometry { * Set to true if every particle spawned * should get a random image from a pool of images constructed from * the texture, with X by Y possible images. - * + * *
By default, X and Y are equal * to 1, thus allowing only 1 possible image to be selected, but if the * particle is configured with multiple images by using {@link ParticleEmitter#setImagesX(int) } @@ -506,7 +542,7 @@ public class ParticleEmitter extends Geometry { * can be selected. Setting to false will cause each particle to have an animation * of images displayed, starting at image 1, and going until image X*Y when * the particle reaches its end of life. - * + * * @param selectRandomImage True if every particle spawned should get a random * image. */ @@ -516,10 +552,10 @@ public class ParticleEmitter extends Geometry { /** * Check if particles spawned should face their velocity. - * + * * @return True if particles spawned should face their velocity. - * - * @see ParticleEmitter#setFacingVelocity(boolean) + * + * @see ParticleEmitter#setFacingVelocity(boolean) */ public boolean isFacingVelocity() { return facingVelocity; @@ -528,11 +564,11 @@ public class ParticleEmitter extends Geometry { /** * Set to true if particles spawned should face * their velocity (or direction to which they are moving towards). - * + * *
This is typically used for e.g spark effects. - * + * * @param followVelocity True if particles spawned should face their velocity. - * + * */ public void setFacingVelocity(boolean followVelocity) { this.facingVelocity = followVelocity; @@ -540,10 +576,10 @@ public class ParticleEmitter extends Geometry { /** * Get the end color of the particles spawned. - * + * * @return the end color of the particles spawned. - * - * @see ParticleEmitter#setEndColor(com.jme3.math.ColorRGBA) + * + * @see ParticleEmitter#setEndColor(com.jme3.math.ColorRGBA) */ public ColorRGBA getEndColor() { return endColor; @@ -551,12 +587,12 @@ public class ParticleEmitter extends Geometry { /** * Set the end color of the particles spawned. - * + * *
The * particle color at any time is determined by blending the start color * and end color based on the particle's current time of life relative * to its end of life. - * + * * @param endColor the end color of the particles spawned. */ public void setEndColor(ColorRGBA endColor) { @@ -565,10 +601,10 @@ public class ParticleEmitter extends Geometry { /** * Get the end size of the particles spawned. - * + * * @return the end size of the particles spawned. - * - * @see ParticleEmitter#setEndSize(float) + * + * @see ParticleEmitter#setEndSize(float) */ public float getEndSize() { return endSize; @@ -576,12 +612,12 @@ public class ParticleEmitter extends Geometry { /** * Set the end size of the particles spawned. - * + * *
The * particle size at any time is determined by blending the start size * and end size based on the particle's current time of life relative * to its end of life. - * + * * @param endSize the end size of the particles spawned. */ public void setEndSize(float endSize) { @@ -590,10 +626,10 @@ public class ParticleEmitter extends Geometry { /** * Get the gravity vector. - * + * * @return the gravity vector. - * - * @see ParticleEmitter#setGravity(com.jme3.math.Vector3f) + * + * @see ParticleEmitter#setGravity(com.jme3.math.Vector3f) */ public Vector3f getGravity() { return gravity; @@ -601,7 +637,7 @@ public class ParticleEmitter extends Geometry { /** * This method sets the gravity vector. - * + * * @param gravity the gravity vector */ public void setGravity(Vector3f gravity) { @@ -610,7 +646,7 @@ public class ParticleEmitter extends Geometry { /** * Sets the gravity vector. - * + * * @param x the x component of the gravity vector * @param y the y component of the gravity vector * @param z the z component of the gravity vector @@ -623,10 +659,10 @@ public class ParticleEmitter extends Geometry { /** * Get the high value of life. - * + * * @return the high value of life. - * - * @see ParticleEmitter#setHighLife(float) + * + * @see ParticleEmitter#setHighLife(float) */ public float getHighLife() { return highLife; @@ -634,10 +670,10 @@ public class ParticleEmitter extends Geometry { /** * Set the high value of life. - * + * *
The particle's lifetime/expiration * is determined by randomly selecting a time between low life and high life. - * + * * @param highLife the high value of life. */ public void setHighLife(float highLife) { @@ -646,10 +682,10 @@ public class ParticleEmitter extends Geometry { /** * Get the number of images along the X axis (width). - * + * * @return the number of images along the X axis (width). - * - * @see ParticleEmitter#setImagesX(int) + * + * @see ParticleEmitter#setImagesX(int) */ public int getImagesX() { return imagesX; @@ -657,11 +693,11 @@ public class ParticleEmitter extends Geometry { /** * Set the number of images along the X axis (width). - * + * *
To determine * how multiple particle images are selected and used, see the * {@link ParticleEmitter#setSelectRandomImage(boolean) } method. - * + * * @param imagesX the number of images along the X axis (width). */ public void setImagesX(int imagesX) { @@ -671,10 +707,10 @@ public class ParticleEmitter extends Geometry { /** * Get the number of images along the Y axis (height). - * + * * @return the number of images along the Y axis (height). - * - * @see ParticleEmitter#setImagesY(int) + * + * @see ParticleEmitter#setImagesY(int) */ public int getImagesY() { return imagesY; @@ -682,10 +718,10 @@ public class ParticleEmitter extends Geometry { /** * Set the number of images along the Y axis (height). - * + * *
To determine how multiple particle images are selected and used, see the * {@link ParticleEmitter#setSelectRandomImage(boolean) } method. - * + * * @param imagesY the number of images along the Y axis (height). */ public void setImagesY(int imagesY) { @@ -695,10 +731,10 @@ public class ParticleEmitter extends Geometry { /** * Get the low value of life. - * + * * @return the low value of life. - * - * @see ParticleEmitter#setLowLife(float) + * + * @see ParticleEmitter#setLowLife(float) */ public float getLowLife() { return lowLife; @@ -706,10 +742,10 @@ public class ParticleEmitter extends Geometry { /** * Set the low value of life. - * + * *
The particle's lifetime/expiration * is determined by randomly selecting a time between low life and high life. - * + * * @param lowLife the low value of life. */ public void setLowLife(float lowLife) { @@ -719,11 +755,11 @@ public class ParticleEmitter extends Geometry { /** * Get the number of particles to spawn per * second. - * + * * @return the number of particles to spawn per * second. - * - * @see ParticleEmitter#setParticlesPerSec(float) + * + * @see ParticleEmitter#setParticlesPerSec(float) */ public float getParticlesPerSec() { return particlesPerSec; @@ -732,7 +768,7 @@ public class ParticleEmitter extends Geometry { /** * Set the number of particles to spawn per * second. - * + * * @param particlesPerSec the number of particles to spawn per * second. */ @@ -740,13 +776,13 @@ public class ParticleEmitter extends Geometry { this.particlesPerSec = particlesPerSec; timeDifference = 0; } - + /** * Get the start color of the particles spawned. - * + * * @return the start color of the particles spawned. - * - * @see ParticleEmitter#setStartColor(com.jme3.math.ColorRGBA) + * + * @see ParticleEmitter#setStartColor(com.jme3.math.ColorRGBA) */ public ColorRGBA getStartColor() { return startColor; @@ -754,11 +790,11 @@ public class ParticleEmitter extends Geometry { /** * Set the start color of the particles spawned. - * + * *
The particle color at any time is determined by blending the start color * and end color based on the particle's current time of life relative * to its end of life. - * + * * @param startColor the start color of the particles spawned */ public void setStartColor(ColorRGBA startColor) { @@ -767,10 +803,10 @@ public class ParticleEmitter extends Geometry { /** * Get the start color of the particles spawned. - * + * * @return the start color of the particles spawned. - * - * @see ParticleEmitter#setStartSize(float) + * + * @see ParticleEmitter#setStartSize(float) */ public float getStartSize() { return startSize; @@ -778,11 +814,11 @@ public class ParticleEmitter extends Geometry { /** * Set the start size of the particles spawned. - * + * *
The particle size at any time is determined by blending the start size * and end size based on the particle's current time of life relative * to its end of life. - * + * * @param startSize the start size of the particles spawned. */ public void setStartSize(float startSize) { @@ -805,10 +841,10 @@ public class ParticleEmitter extends Geometry { * gravity. * * @deprecated - * This method is deprecated. + * This method is deprecated. * Use ParticleEmitter.getParticleInfluencer().setInitialVelocity(initialVelocity); instead. * - * @see ParticleEmitter#setVelocityVariation(float) + * @see ParticleEmitter#setVelocityVariation(float) * @see ParticleEmitter#setGravity(float) */ @Deprecated @@ -818,7 +854,7 @@ public class ParticleEmitter extends Geometry { /** * @deprecated - * This method is deprecated. + * This method is deprecated. * Use ParticleEmitter.getParticleInfluencer().getVelocityVariation(); instead. * @return the initial velocity variation factor */ @@ -833,9 +869,9 @@ public class ParticleEmitter extends Geometry { * from 0 to 1, where 0 means particles are to spawn with exactly * the velocity given in {@link ParticleEmitter#setStartVel(com.jme3.math.Vector3f) }, * and 1 means particles are to spawn with a completely random velocity. - * + * * @deprecated - * This method is deprecated. + * This method is deprecated. * Use ParticleEmitter.getParticleInfluencer().setVelocityVariation(variation); instead. */ @Deprecated @@ -923,7 +959,7 @@ public class ParticleEmitter extends Geometry { vars.release(); } - + /** * Instantly kills all active particles, after this method is called, all * particles will be dead and no longer visible. @@ -935,12 +971,12 @@ public class ParticleEmitter extends Geometry { } } } - + /** * Kills the particle at the given index. - * + * * @param index The index of the particle to kill - * @see #getParticles() + * @see #getParticles() */ public void killParticle(int index){ freeParticle(index); @@ -995,7 +1031,7 @@ public class ParticleEmitter extends Geometry { p.imageIndex = (int) (b * imagesX * imagesY); } } - + private void updateParticleState(float tpf) { // Force world transform to update this.getWorldTransform(); @@ -1028,7 +1064,7 @@ public class ParticleEmitter extends Geometry { firstUnUsed++; } } - + // Spawns particles within the tpf timeslot with proper age float interval = 1f / particlesPerSec; float originalTpf = tpf; @@ -1065,10 +1101,10 @@ public class ParticleEmitter extends Geometry { /** * Set to enable or disable the particle emitter - * + * *
When a particle is
* disabled, it will be "frozen in time" and not update.
- *
+ *
* @param enabled True to enable the particle emitter
*/
public void setEnabled(boolean enabled) {
@@ -1077,10 +1113,10 @@ public class ParticleEmitter extends Geometry {
/**
* Check if a particle emitter is enabled for update.
- *
+ *
* @return True if a particle emitter is enabled for update.
- *
- * @see ParticleEmitter#setEnabled(boolean)
+ *
+ * @see ParticleEmitter#setEnabled(boolean)
*/
public boolean isEnabled() {
return enabled;
@@ -1088,7 +1124,7 @@ public class ParticleEmitter extends Geometry {
/**
* Callback from Control.update(), do not use.
- * @param tpf
+ * @param tpf
*/
public void updateFromControl(float tpf) {
if (enabled) {
@@ -1098,9 +1134,9 @@ public class ParticleEmitter extends Geometry {
/**
* Callback from Control.render(), do not use.
- *
+ *
* @param rm
- * @param vp
+ * @param vp
*/
private void renderFromControl(RenderManager rm, ViewPort vp) {
Camera cam = vp.getCamera();
@@ -1236,7 +1272,7 @@ public class ParticleEmitter extends Geometry {
gravity.y = ic.readFloat("gravity", 0);
}
} else {
- // since the parentEmitter is not loaded, it must be
+ // since the parentEmitter is not loaded, it must be
// loaded separately
control = getControl(ParticleEmitterControl.class);
control.parentEmitter = this;
diff --git a/jme3-core/src/main/java/com/jme3/effect/influencers/DefaultParticleInfluencer.java b/jme3-core/src/main/java/com/jme3/effect/influencers/DefaultParticleInfluencer.java
index b52d8df80..9cd06f0e3 100644
--- a/jme3-core/src/main/java/com/jme3/effect/influencers/DefaultParticleInfluencer.java
+++ b/jme3-core/src/main/java/com/jme3/effect/influencers/DefaultParticleInfluencer.java
@@ -39,6 +39,8 @@ import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
+import com.jme3.util.clone.Cloner;
+import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
/**
@@ -49,7 +51,7 @@ import java.io.IOException;
*/
public class DefaultParticleInfluencer implements ParticleInfluencer {
- //Version #1 : changed startVelocity to initialvelocity for consistency with accessors
+ //Version #1 : changed startVelocity to initialvelocity for consistency with accessors
//and also changed it in serialization
public static final int SAVABLE_VERSION = 1;
/** Temporary variable used to help with calculations. */
@@ -94,7 +96,7 @@ public class DefaultParticleInfluencer implements ParticleInfluencer {
initialVelocity = (Vector3f) ic.readSavable("startVelocity", Vector3f.ZERO.clone());
}else{
initialVelocity = (Vector3f) ic.readSavable("initialVelocity", Vector3f.ZERO.clone());
- }
+ }
velocityVariation = ic.readFloat("variation", 0.2f);
}
@@ -109,6 +111,35 @@ public class DefaultParticleInfluencer implements ParticleInfluencer {
}
}
+ /**
+ * 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.initialVelocity = cloner.clone(initialVelocity);
+
+ // Change in behavior: I'm cloning 'for real' the 'temp' field because
+ // otherwise it will be shared across all clones. Note: if this is
+ // ok because of how its used then it might as well be static and let
+ // everything share it.
+ // Note 2: transient fields _are_ cloned just like anything else so
+ // thinking it wouldn't get cloned is also not right.
+ // -pspeed
+ this.temp = cloner.clone(temp);
+ }
+
@Override
public void setInitialVelocity(Vector3f initialVelocity) {
this.initialVelocity.set(initialVelocity);
diff --git a/jme3-core/src/main/java/com/jme3/effect/influencers/EmptyParticleInfluencer.java b/jme3-core/src/main/java/com/jme3/effect/influencers/EmptyParticleInfluencer.java
index ccbc7e5e6..88e938430 100644
--- a/jme3-core/src/main/java/com/jme3/effect/influencers/EmptyParticleInfluencer.java
+++ b/jme3-core/src/main/java/com/jme3/effect/influencers/EmptyParticleInfluencer.java
@@ -36,6 +36,8 @@ import com.jme3.effect.shapes.EmitterShape;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.math.Vector3f;
+import com.jme3.util.clone.Cloner;
+import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
/**
@@ -83,4 +85,23 @@ public class EmptyParticleInfluencer implements ParticleInfluencer {
throw new AssertionError();
}
}
+
+ /**
+ * 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 ) {
+ }
}
diff --git a/jme3-core/src/main/java/com/jme3/effect/influencers/NewtonianParticleInfluencer.java b/jme3-core/src/main/java/com/jme3/effect/influencers/NewtonianParticleInfluencer.java
index b2f81f9a8..b0bc1be25 100644
--- a/jme3-core/src/main/java/com/jme3/effect/influencers/NewtonianParticleInfluencer.java
+++ b/jme3-core/src/main/java/com/jme3/effect/influencers/NewtonianParticleInfluencer.java
@@ -39,6 +39,8 @@ import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import com.jme3.math.FastMath;
import com.jme3.math.Matrix3f;
+import com.jme3.util.clone.Cloner;
+import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
/**
diff --git a/jme3-core/src/main/java/com/jme3/effect/influencers/ParticleInfluencer.java b/jme3-core/src/main/java/com/jme3/effect/influencers/ParticleInfluencer.java
index 5e3532bb0..4f322df74 100644
--- a/jme3-core/src/main/java/com/jme3/effect/influencers/ParticleInfluencer.java
+++ b/jme3-core/src/main/java/com/jme3/effect/influencers/ParticleInfluencer.java
@@ -36,12 +36,13 @@ import com.jme3.effect.ParticleEmitter;
import com.jme3.effect.shapes.EmitterShape;
import com.jme3.export.Savable;
import com.jme3.math.Vector3f;
+import com.jme3.util.clone.JmeCloneable;
/**
* An interface that defines the methods to affect initial velocity of the particles.
* @author Marcin Roguski (Kaelthas)
*/
-public interface ParticleInfluencer extends Savable, Cloneable {
+public interface ParticleInfluencer extends Savable, Cloneable, JmeCloneable {
/**
* This method influences the particle.
diff --git a/jme3-core/src/main/java/com/jme3/effect/influencers/RadialParticleInfluencer.java b/jme3-core/src/main/java/com/jme3/effect/influencers/RadialParticleInfluencer.java
index 87c5ce507..0cacfe5b0 100644
--- a/jme3-core/src/main/java/com/jme3/effect/influencers/RadialParticleInfluencer.java
+++ b/jme3-core/src/main/java/com/jme3/effect/influencers/RadialParticleInfluencer.java
@@ -38,6 +38,7 @@ import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
+import com.jme3.util.clone.Cloner;
import java.io.IOException;
/**
@@ -81,7 +82,7 @@ public class RadialParticleInfluencer extends DefaultParticleInfluencer {
/**
* the origin used for computing the radial velocity direction
- * @param origin
+ * @param origin
*/
public void setOrigin(Vector3f origin) {
this.origin = origin;
@@ -97,7 +98,7 @@ public class RadialParticleInfluencer extends DefaultParticleInfluencer {
/**
* the radial velocity
- * @param radialVelocity
+ * @param radialVelocity
*/
public void setRadialVelocity(float radialVelocity) {
this.radialVelocity = radialVelocity;
@@ -105,7 +106,7 @@ public class RadialParticleInfluencer extends DefaultParticleInfluencer {
/**
* nullify y component of particle velocity to make the effect expand only on x and z axis
- * @return
+ * @return
*/
public boolean isHorizontal() {
return horizontal;
@@ -113,12 +114,22 @@ public class RadialParticleInfluencer extends DefaultParticleInfluencer {
/**
* nullify y component of particle velocity to make the effect expand only on x and z axis
- * @param horizontal
+ * @param horizontal
*/
public void setHorizontal(boolean horizontal) {
this.horizontal = horizontal;
}
+ /**
+ * Called internally by com.jme3.util.clone.Cloner. Do not call directly.
+ */
+ @Override
+ public void cloneFields( Cloner cloner, Object original ) {
+ // Change in behavior: the old origin was not cloned -pspeed
+ this.origin = cloner.clone(origin);
+ }
+
+
@Override
public void write(JmeExporter ex) throws IOException {
super.write(ex);
diff --git a/jme3-core/src/main/java/com/jme3/effect/shapes/EmitterBoxShape.java b/jme3-core/src/main/java/com/jme3/effect/shapes/EmitterBoxShape.java
index 63323db7b..6b29843c9 100644
--- a/jme3-core/src/main/java/com/jme3/effect/shapes/EmitterBoxShape.java
+++ b/jme3-core/src/main/java/com/jme3/effect/shapes/EmitterBoxShape.java
@@ -37,6 +37,8 @@ import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
+import com.jme3.util.clone.Cloner;
+import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
public class EmitterBoxShape implements EmitterShape {
@@ -86,6 +88,27 @@ public class EmitterBoxShape implements EmitterShape {
}
}
+ /**
+ * 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.min = cloner.clone(min);
+ this.len = cloner.clone(len);
+ }
+
public Vector3f getMin() {
return min;
}
diff --git a/jme3-core/src/main/java/com/jme3/effect/shapes/EmitterMeshVertexShape.java b/jme3-core/src/main/java/com/jme3/effect/shapes/EmitterMeshVertexShape.java
index 0a5ba128a..b996e63cb 100644
--- a/jme3-core/src/main/java/com/jme3/effect/shapes/EmitterMeshVertexShape.java
+++ b/jme3-core/src/main/java/com/jme3/effect/shapes/EmitterMeshVertexShape.java
@@ -40,6 +40,8 @@ import com.jme3.math.Vector3f;
import com.jme3.scene.Mesh;
import com.jme3.scene.VertexBuffer.Type;
import com.jme3.util.BufferUtils;
+import com.jme3.util.clone.Cloner;
+import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -168,6 +170,27 @@ public class EmitterMeshVertexShape implements EmitterShape {
}
}
+ /**
+ * 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.vertices = cloner.clone(vertices);
+ this.normals = cloner.clone(normals);
+ }
+
@Override
public void write(JmeExporter ex) throws IOException {
OutputCapsule oc = ex.getCapsule(this);
@@ -180,7 +203,7 @@ public class EmitterMeshVertexShape implements EmitterShape {
public void read(JmeImporter im) throws IOException {
InputCapsule ic = im.getCapsule(this);
this.vertices = ic.readSavableArrayList("vertices", null);
-
+
List> tmpNormals = ic.readSavableArrayList("normals", null);
if (tmpNormals != null){
this.normals = tmpNormals;
diff --git a/jme3-core/src/main/java/com/jme3/effect/shapes/EmitterPointShape.java b/jme3-core/src/main/java/com/jme3/effect/shapes/EmitterPointShape.java
index 9f7e71107..e33691101 100644
--- a/jme3-core/src/main/java/com/jme3/effect/shapes/EmitterPointShape.java
+++ b/jme3-core/src/main/java/com/jme3/effect/shapes/EmitterPointShape.java
@@ -35,6 +35,8 @@ import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import com.jme3.math.Vector3f;
+import com.jme3.util.clone.Cloner;
+import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
public class EmitterPointShape implements EmitterShape {
@@ -59,6 +61,26 @@ public class EmitterPointShape implements EmitterShape {
}
}
+ /**
+ * 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.point = cloner.clone(point);
+ }
+
@Override
public void getRandomPoint(Vector3f store) {
store.set(point);
diff --git a/jme3-core/src/main/java/com/jme3/effect/shapes/EmitterShape.java b/jme3-core/src/main/java/com/jme3/effect/shapes/EmitterShape.java
index bdecd5b5f..f247412d0 100644
--- a/jme3-core/src/main/java/com/jme3/effect/shapes/EmitterShape.java
+++ b/jme3-core/src/main/java/com/jme3/effect/shapes/EmitterShape.java
@@ -33,12 +33,13 @@ package com.jme3.effect.shapes;
import com.jme3.export.Savable;
import com.jme3.math.Vector3f;
+import com.jme3.util.clone.JmeCloneable;
/**
* This interface declares methods used by all shapes that represent particle emitters.
* @author Kirill
*/
-public interface EmitterShape extends Savable, Cloneable {
+public interface EmitterShape extends Savable, Cloneable, JmeCloneable {
/**
* This method fills in the initial position of the particle.
diff --git a/jme3-core/src/main/java/com/jme3/effect/shapes/EmitterSphereShape.java b/jme3-core/src/main/java/com/jme3/effect/shapes/EmitterSphereShape.java
index 770ba6c9d..99d76205d 100644
--- a/jme3-core/src/main/java/com/jme3/effect/shapes/EmitterSphereShape.java
+++ b/jme3-core/src/main/java/com/jme3/effect/shapes/EmitterSphereShape.java
@@ -37,6 +37,8 @@ import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
+import com.jme3.util.clone.Cloner;
+import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
public class EmitterSphereShape implements EmitterShape {
@@ -71,6 +73,26 @@ public class EmitterSphereShape implements EmitterShape {
}
}
+ /**
+ * 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.center = cloner.clone(center);
+ }
+
@Override
public void getRandomPoint(Vector3f store) {
do {