Skip to content

Commit ae1715f

Browse files
Copilotriccardobl
andauthored
Fix BoundingBox.merge() inconsistency — deprecate merge() and introduce mergeWith() (#2661)
* Initial plan * Fix BoundingBox.merge() to not modify receiver in place Agent-Logs-Url: https://github.com/jMonkeyEngine/jmonkeyengine/sessions/e27f3192-530d-4525-aa2a-ad3e611ae4ed Co-authored-by: riccardobl <4943530+riccardobl@users.noreply.github.com> * Deprecate merge(), restore original BoundingBox.merge() behavior, add mergeWith() Agent-Logs-Url: https://github.com/jMonkeyEngine/jmonkeyengine/sessions/223ff945-a733-4b7b-8b8b-2e90418270de Co-authored-by: riccardobl <4943530+riccardobl@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: riccardobl <4943530+riccardobl@users.noreply.github.com>
1 parent faab398 commit ae1715f

File tree

4 files changed

+71
-0
lines changed

4 files changed

+71
-0
lines changed

jme3-core/src/main/java/com/jme3/bounding/BoundingBox.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,11 @@ public Plane.Side whichSide(Plane plane) {
412412
* altered)
413413
* @return this box (with its components modified) or null if the second
414414
* volume is of some type other than AABB or Sphere
415+
* @deprecated This method modifies the receiver in place, which is
416+
* inconsistent with {@link BoundingSphere#merge}. Use
417+
* {@link #mergeWith} instead.
415418
*/
419+
@Deprecated
416420
@Override
417421
public BoundingVolume merge(BoundingVolume volume) {
418422
return mergeLocal(volume);

jme3-core/src/main/java/com/jme3/bounding/BoundingSphere.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,9 @@ public Plane.Side whichSide(Plane plane) {
465465
* @param volume
466466
* the sphere to combine with this sphere.
467467
* @return a new sphere
468+
* @deprecated Use {@link #mergeWith} instead.
468469
*/
470+
@Deprecated
469471
@Override
470472
public BoundingVolume merge(BoundingVolume volume) {
471473
if (volume == null) {

jme3-core/src/main/java/com/jme3/bounding/BoundingVolume.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,14 +149,31 @@ public final BoundingVolume transform(Transform trans) {
149149
*/
150150
public abstract void computeFromPoints(FloatBuffer points);
151151

152+
/**
153+
* Combines this bounding volume with a second bounding volume so that the
154+
* result contains both volumes. Returns a new bounding volume without
155+
* modifying either input.
156+
*
157+
* @param volume the volume to combine with this one (may be null)
158+
* @return a new bounding volume containing both volumes
159+
*/
160+
public BoundingVolume mergeWith(BoundingVolume volume) {
161+
return clone(null).mergeLocal(volume);
162+
}
163+
152164
/**
153165
* <code>merge</code> combines two bounding volumes into a single bounding
154166
* volume that contains both this bounding volume and the parameter volume.
155167
*
156168
* @param volume
157169
* the volume to combine.
158170
* @return the new merged bounding volume.
171+
* @deprecated This method has inconsistent behavior across subclasses
172+
* ({@link BoundingBox#merge} modifies the receiver, while
173+
* {@link BoundingSphere#merge} returns a new instance).
174+
* Use {@link #mergeWith} instead.
159175
*/
176+
@Deprecated
160177
public abstract BoundingVolume merge(BoundingVolume volume);
161178

162179
/**

jme3-core/src/test/java/com/jme3/bounding/TestBoundingBox.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,54 @@ public void testEquals() {
7171
Assert.assertEquals(bb5, bb6); // because check planes are ignored
7272
}
7373

74+
/**
75+
* Verify that merge() still modifies the original BoundingBox in place
76+
* (deprecated behavior preserved for backward compatibility).
77+
*/
78+
@Test
79+
@SuppressWarnings("deprecation")
80+
public void testMergeModifiesReceiver() {
81+
BoundingBox bb1 = new BoundingBox(new Vector3f(0f, 0f, 0f), 1f, 1f, 1f);
82+
BoundingBox bb2 = new BoundingBox(new Vector3f(4f, 0f, 0f), 1f, 1f, 1f);
83+
84+
BoundingBox bb1Before = (BoundingBox) bb1.clone();
85+
86+
BoundingVolume result = bb1.merge(bb2);
87+
88+
// merge() delegates to mergeLocal(), so bb1 IS modified.
89+
Assert.assertNotEquals(bb1Before, bb1);
90+
91+
// The result is the same object as bb1.
92+
Assert.assertSame(bb1, result);
93+
}
94+
95+
/**
96+
* Verify that mergeWith() does not modify the original bounding box, and
97+
* that the returned box contains both inputs.
98+
*/
99+
@Test
100+
public void testMergeWithDoesNotModifyReceiver() {
101+
BoundingBox bb1 = new BoundingBox(new Vector3f(0f, 0f, 0f), 1f, 1f, 1f);
102+
BoundingBox bb2 = new BoundingBox(new Vector3f(4f, 0f, 0f), 1f, 1f, 1f);
103+
104+
// Record the original state of bb1 before merging.
105+
BoundingBox bb1Before = (BoundingBox) bb1.clone();
106+
107+
BoundingVolume result = bb1.mergeWith(bb2);
108+
109+
// bb1 must be unmodified.
110+
Assert.assertEquals(bb1Before, bb1);
111+
112+
// The result must be a different object than bb1.
113+
Assert.assertNotSame(bb1, result);
114+
115+
// The result must contain both inputs' centers.
116+
Assert.assertTrue(result instanceof BoundingBox);
117+
BoundingBox merged = (BoundingBox) result;
118+
Assert.assertTrue(merged.contains(bb2.getCenter()));
119+
Assert.assertTrue(merged.contains(bb1.getCenter()));
120+
}
121+
74122
/**
75123
* Verify that isSimilar() behaves as expected.
76124
*/

0 commit comments

Comments
 (0)