Browse Source

Merge pull request #2407 from capdevon/capdevon-ParticleInfluencer

DefaultParticleInfluencer: incorrect cloning of variables
Ryan McDonough 3 months ago
parent
commit
a905e41687

+ 6 - 8
jme3-core/src/main/java/com/jme3/effect/influencers/DefaultParticleInfluencer.java

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2021 jMonkeyEngine
+ * Copyright (c) 2009-2025 jMonkeyEngine
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -40,6 +40,7 @@ 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;
 
 /**
@@ -101,13 +102,10 @@ public class DefaultParticleInfluencer implements ParticleInfluencer {
 
     @Override
     public DefaultParticleInfluencer clone() {
-        try {
-            DefaultParticleInfluencer clone = (DefaultParticleInfluencer) super.clone();
-            clone.initialVelocity = initialVelocity.clone();
-            return clone;
-        } catch (CloneNotSupportedException e) {
-            throw new AssertionError();
-        }
+        // Set up the cloner for the type of cloning we want to do.
+        Cloner cloner = new Cloner();
+        DefaultParticleInfluencer clone = cloner.clone(this);
+        return clone;
     }
 
     /**

+ 1 - 12
jme3-core/src/main/java/com/jme3/effect/influencers/NewtonianParticleInfluencer.java

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2012 jMonkeyEngine
+ * Copyright (c) 2009-2025 jMonkeyEngine
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -142,17 +142,6 @@ public class NewtonianParticleInfluencer extends DefaultParticleInfluencer {
         particle.velocity.addLocal(temp);
     }
 
-    @Override
-    public NewtonianParticleInfluencer clone() {
-        NewtonianParticleInfluencer result = new NewtonianParticleInfluencer();
-        result.normalVelocity = normalVelocity;
-        result.initialVelocity = initialVelocity;
-        result.velocityVariation = velocityVariation;
-        result.surfaceTangentFactor = surfaceTangentFactor;
-        result.surfaceTangentRotation = surfaceTangentRotation;
-        return result;
-    }
-
     @Override
     public void write(JmeExporter ex) throws IOException {
         super.write(ex);

+ 3 - 3
jme3-core/src/main/java/com/jme3/effect/influencers/ParticleInfluencer.java

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2018 jMonkeyEngine
+ * Copyright (c) 2009-2025 jMonkeyEngine
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -42,7 +42,7 @@ 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, JmeCloneable {
+public interface ParticleInfluencer extends Savable, JmeCloneable {
 
     /**
      * This method influences the particle.
@@ -57,7 +57,7 @@ public interface ParticleInfluencer extends Savable, Cloneable, JmeCloneable {
      * This method clones the influencer instance.
      * @return cloned instance
      */
-    public ParticleInfluencer clone();
+    ParticleInfluencer clone();
 
     /**
      * @param initialVelocity

+ 78 - 0
jme3-core/src/test/java/com/jme3/effect/influencers/ParticleInfluencerTest.java

@@ -0,0 +1,78 @@
+package com.jme3.effect.influencers;
+
+import com.jme3.asset.AssetManager;
+import com.jme3.asset.DesktopAssetManager;
+import com.jme3.export.binary.BinaryExporter;
+import com.jme3.math.Vector3f;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Automated tests for the {@code ParticleInfluencer} class.
+ *
+ * @author capdevon
+ */
+public class ParticleInfluencerTest {
+
+    /**
+     * Tests cloning, serialization and de-serialization of a {@code NewtonianParticleInfluencer}.
+     */
+    @Test
+    public void testNewtonianParticleInfluencer() {
+        AssetManager assetManager = new DesktopAssetManager(true);
+
+        NewtonianParticleInfluencer inf = new NewtonianParticleInfluencer();
+        inf.setNormalVelocity(1);
+        inf.setSurfaceTangentFactor(0.5f);
+        inf.setSurfaceTangentRotation(2.5f);
+        inf.setInitialVelocity(new Vector3f(0, 1, 0));
+        inf.setVelocityVariation(2f);
+
+        NewtonianParticleInfluencer clone = (NewtonianParticleInfluencer) inf.clone();
+        assertEquals(inf, clone);
+        Assert.assertNotSame(inf.temp, clone.temp);
+
+        NewtonianParticleInfluencer copy = BinaryExporter.saveAndLoad(assetManager, inf);
+        assertEquals(inf, copy);
+    }
+
+    private void assertEquals(NewtonianParticleInfluencer inf, NewtonianParticleInfluencer clone) {
+        Assert.assertEquals(inf.getNormalVelocity(), clone.getNormalVelocity(), 0.001f);
+        Assert.assertEquals(inf.getSurfaceTangentFactor(), clone.getSurfaceTangentFactor(), 0.001f);
+        Assert.assertEquals(inf.getSurfaceTangentRotation(), clone.getSurfaceTangentRotation(), 0.001f);
+        Assert.assertEquals(inf.getInitialVelocity(), clone.getInitialVelocity());
+        Assert.assertEquals(inf.getVelocityVariation(), clone.getVelocityVariation(), 0.001f);
+    }
+
+    /**
+     * Tests cloning, serialization and de-serialization of a {@code RadialParticleInfluencer}.
+     */
+    @Test
+    public void testRadialParticleInfluencer() {
+        AssetManager assetManager = new DesktopAssetManager(true);
+
+        RadialParticleInfluencer inf = new RadialParticleInfluencer();
+        inf.setHorizontal(true);
+        inf.setOrigin(new Vector3f(0, 1, 0));
+        inf.setRadialVelocity(2f);
+        inf.setInitialVelocity(new Vector3f(0, 1, 0));
+        inf.setVelocityVariation(2f);
+
+        RadialParticleInfluencer clone = (RadialParticleInfluencer) inf.clone();
+        assertEquals(inf, clone);
+        Assert.assertNotSame(inf.temp, clone.temp);
+        Assert.assertNotSame(inf.getOrigin(), clone.getOrigin());
+
+        RadialParticleInfluencer copy = BinaryExporter.saveAndLoad(assetManager, inf);
+        assertEquals(inf, copy);
+    }
+
+    private void assertEquals(RadialParticleInfluencer inf, RadialParticleInfluencer clone) {
+        Assert.assertEquals(inf.isHorizontal(), clone.isHorizontal());
+        Assert.assertEquals(inf.getOrigin(), clone.getOrigin());
+        Assert.assertEquals(inf.getRadialVelocity(), clone.getRadialVelocity(), 0.001f);
+        Assert.assertEquals(inf.getInitialVelocity(), clone.getInitialVelocity());
+        Assert.assertEquals(inf.getVelocityVariation(), clone.getVelocityVariation(), 0.001f);
+    }
+
+}