Skip to content

Commit 985ac2c

Browse files
authored
Merge pull request #2390 from jMonkeyEngine/sgold/issue/2370
solve issue #2370 (deeply clone MotionEvent path)
2 parents 09b862d + 13d8ebe commit 985ac2c

File tree

5 files changed

+289
-45
lines changed

5 files changed

+289
-45
lines changed

jme3-core/src/main/java/com/jme3/cinematic/MotionPath.java

+38-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2009-2021 jMonkeyEngine
2+
* Copyright (c) 2009-2025 jMonkeyEngine
33
* All rights reserved.
44
*
55
* Redistribution and use in source and binary forms, with or without
@@ -45,6 +45,8 @@
4545
import com.jme3.scene.shape.Box;
4646
import com.jme3.scene.shape.Curve;
4747
import com.jme3.util.TempVars;
48+
import com.jme3.util.clone.Cloner;
49+
import com.jme3.util.clone.JmeCloneable;
4850
import java.io.IOException;
4951
import java.util.ArrayList;
5052
import java.util.Iterator;
@@ -54,7 +56,7 @@
5456
* Motion path is used to create a path between way points.
5557
* @author Nehon
5658
*/
57-
public class MotionPath implements Savable {
59+
public class MotionPath implements JmeCloneable, Savable {
5860

5961
private Node debugNode;
6062
private AssetManager assetManager;
@@ -177,6 +179,40 @@ public void read(JmeImporter im) throws IOException {
177179
spline = (Spline) in.readSavable("spline", null);
178180
}
179181

182+
/**
183+
* Callback from {@link com.jme3.util.clone.Cloner} to convert this
184+
* shallow-cloned MotionPath into a deep-cloned one, using the specified
185+
* cloner and original to resolve copied fields.
186+
*
187+
* @param cloner the cloner that's cloning this MotionPath (not null)
188+
* @param original the object from which this MotionPath was shallow-cloned
189+
* (not null, unaffected)
190+
*/
191+
@Override
192+
public void cloneFields(Cloner cloner, Object original) {
193+
this.debugNode = cloner.clone(debugNode);
194+
this.spline = cloner.clone(spline);
195+
/*
196+
* The clone will share both the asset manager and the list of listeners
197+
* of the original MotionPath.
198+
*/
199+
}
200+
201+
/**
202+
* Creates a shallow clone for the JME cloner.
203+
*
204+
* @return a new object
205+
*/
206+
@Override
207+
public MotionPath jmeClone() {
208+
try {
209+
MotionPath clone = (MotionPath) clone();
210+
return clone;
211+
} catch (CloneNotSupportedException exception) {
212+
throw new RuntimeException(exception);
213+
}
214+
}
215+
180216
/**
181217
* compute the index of the waypoint and the interpolation value according to a distance
182218
* returns a vector 2 containing the index in the x field and the interpolation value in the y field

jme3-core/src/main/java/com/jme3/cinematic/events/MotionEvent.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2009-2021 jMonkeyEngine
2+
* Copyright (c) 2009-2025 jMonkeyEngine
33
* All rights reserved.
44
*
55
* Redistribution and use in source and binary forms, with or without
@@ -312,6 +312,9 @@ public Object jmeClone() {
312312

313313
@Override
314314
public void cloneFields(Cloner cloner, Object original) {
315+
this.lookAt = cloner.clone(lookAt);
316+
this.path = cloner.clone(path);
317+
this.rotation = cloner.clone(rotation);
315318
this.spatial = cloner.clone(spatial);
316319
}
317320

jme3-core/src/main/java/com/jme3/math/Spline.java

+40-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
package com.jme3.math;
3333

3434
import com.jme3.export.*;
35+
import com.jme3.util.clone.Cloner;
36+
import com.jme3.util.clone.JmeCloneable;
3537
import java.io.IOException;
3638
import java.util.ArrayList;
3739
import java.util.Iterator;
@@ -41,7 +43,7 @@
4143
*
4244
* @author Nehon
4345
*/
44-
public class Spline implements Savable {
46+
public class Spline implements JmeCloneable, Savable {
4547

4648
public enum SplineType {
4749
Linear,
@@ -536,4 +538,41 @@ public void read(JmeImporter im) throws IOException {
536538
weights = in.readFloatArray("weights", null);
537539
basisFunctionDegree = in.readInt("basisFunctionDegree", 0);
538540
}
541+
542+
/**
543+
* Callback from {@link com.jme3.util.clone.Cloner} to convert this
544+
* shallow-cloned spline into a deep-cloned one, using the specified cloner
545+
* and original to resolve copied fields.
546+
*
547+
* @param cloner the cloner that's cloning this spline (not null)
548+
* @param original the object from which this spline was shallow-cloned (not
549+
* null, unaffected)
550+
*/
551+
@Override
552+
public void cloneFields(Cloner cloner, Object original) {
553+
this.controlPoints = cloner.clone(controlPoints);
554+
if (segmentsLength != null) {
555+
this.segmentsLength = new ArrayList<>(segmentsLength);
556+
}
557+
this.CRcontrolPoints = cloner.clone(CRcontrolPoints);
558+
if (knots != null) {
559+
this.knots = new ArrayList<>(knots);
560+
}
561+
this.weights = cloner.clone(weights);
562+
}
563+
564+
/**
565+
* Creates a shallow clone for the JME cloner.
566+
*
567+
* @return a new object
568+
*/
569+
@Override
570+
public Spline jmeClone() {
571+
try {
572+
Spline clone = (Spline) clone();
573+
return clone;
574+
} catch (CloneNotSupportedException exception) {
575+
throw new RuntimeException(exception);
576+
}
577+
}
539578
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright (c) 2025 jMonkeyEngine
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are
7+
* met:
8+
*
9+
* * Redistributions of source code must retain the above copyright
10+
* notice, this list of conditions and the following disclaimer.
11+
*
12+
* * Redistributions in binary form must reproduce the above copyright
13+
* notice, this list of conditions and the following disclaimer in the
14+
* documentation and/or other materials provided with the distribution.
15+
*
16+
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17+
* may be used to endorse or promote products derived from this software
18+
* without specific prior written permission.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22+
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28+
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
*/
32+
package com.jme3.cinematic;
33+
34+
import com.jme3.math.Vector3f;
35+
import com.jme3.util.clone.Cloner;
36+
import org.junit.Assert;
37+
import org.junit.Test;
38+
39+
/**
40+
* Verifies that the {@link MotionPath} class works.
41+
*
42+
* @author Stephen Gold
43+
*/
44+
public class MotionPathTest {
45+
46+
/**
47+
* Verifies that MotionPath cloning works.
48+
*/
49+
@Test
50+
public void cloneMotionPath() {
51+
MotionPath original = new MotionPath();
52+
original.setCycle(true);
53+
original.addWayPoint(new Vector3f(20, 3, 0));
54+
original.addWayPoint(new Vector3f(0, 3, 20));
55+
original.addWayPoint(new Vector3f(-20, 3, 0));
56+
original.addWayPoint(new Vector3f(0, 3, -20));
57+
original.setCurveTension(0.83f);
58+
59+
MotionPath clone = Cloner.deepClone(original);
60+
61+
// Verify that the clone is non-null and distinct from the original:
62+
Assert.assertNotNull(clone);
63+
Assert.assertTrue(clone != original);
64+
65+
// Compare the return values of various getters:
66+
Assert.assertEquals(
67+
clone.getCurveTension(), original.getCurveTension(), 0f);
68+
Assert.assertEquals(clone.getLength(), original.getLength(), 0f);
69+
Assert.assertEquals(clone.getNbWayPoints(), original.getNbWayPoints());
70+
Assert.assertEquals(
71+
clone.getPathSplineType(), original.getPathSplineType());
72+
Assert.assertEquals(clone.getWayPoint(0), original.getWayPoint(0));
73+
Assert.assertEquals(clone.isCycle(), original.isCycle());
74+
}
75+
}

0 commit comments

Comments
 (0)