Skip to content

Commit 16a97ce

Browse files
Copilotriccardobl
andcommitted
Make barycentric coordinate computation opt-in via CollisionResults flag
Agent-Logs-Url: https://github.com/jMonkeyEngine/jmonkeyengine/sessions/86d05467-fc58-41ed-a878-1c31d48e6575 Co-authored-by: riccardobl <4943530+riccardobl@users.noreply.github.com>
1 parent d351e60 commit 16a97ce

4 files changed

Lines changed: 69 additions & 6 deletions

File tree

jme3-core/src/main/java/com/jme3/collision/CollisionResults.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,38 @@ public class CollisionResults implements Iterable<CollisionResult> {
4646

4747
private ArrayList<CollisionResult> results = null;
4848
private boolean sorted = true;
49+
private boolean requiresBaryCoords = false;
50+
51+
/**
52+
* Returns whether collision queries against this instance will compute and
53+
* store barycentric coordinates in each {@link CollisionResult}.
54+
*
55+
* <p>Barycentric coordinate computation is disabled by default.
56+
* Enable it when you need the (u, v) weights for texture-coordinate
57+
* interpolation or other per-hit surface lookups.
58+
*
59+
* @return true if barycentric coordinates will be computed
60+
* @see #setRequiresBaryCoords(boolean)
61+
*/
62+
public boolean isRequiresBaryCoords() {
63+
return requiresBaryCoords;
64+
}
65+
66+
/**
67+
* Controls whether collision queries against this instance should compute
68+
* and store barycentric coordinates in each {@link CollisionResult}.
69+
*
70+
* <p>Barycentric coordinate computation is disabled by default.
71+
* Enable it when you need the (u, v) weights for texture-coordinate
72+
* interpolation or other per-hit surface lookups.
73+
*
74+
* @param requiresBaryCoords true to enable barycentric coordinate
75+
* computation, false (the default) to skip it
76+
* @see #isRequiresBaryCoords()
77+
*/
78+
public void setRequiresBaryCoords(boolean requiresBaryCoords) {
79+
this.requiresBaryCoords = requiresBaryCoords;
80+
}
4981

5082
/**
5183
* Clears all collision results added to this list

jme3-core/src/main/java/com/jme3/collision/bih/BIHNode.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ public final int intersectWhere(Ray r,
402402
for (int i = node.leftIndex; i <= node.rightIndex; i++) {
403403
tree.getTriangle(i, v1, v2, v3);
404404

405-
Vector2f baryCoords = new Vector2f();
405+
Vector2f baryCoords = results.isRequiresBaryCoords() ? new Vector2f() : null;
406406
float t = r.intersects(v1, v2, v3, baryCoords);
407407
if (!Float.isInfinite(t)) {
408408
if (worldMatrix != null) {
@@ -424,7 +424,9 @@ public final int intersectWhere(Ray r,
424424
CollisionResult cr = new CollisionResult(contactPoint, worldSpaceDist);
425425
cr.setContactNormal(contactNormal);
426426
cr.setTriangleIndex(tree.getTriangleIndex(i));
427-
cr.setContactBaryCoords(baryCoords);
427+
if (baryCoords != null) {
428+
cr.setContactBaryCoords(baryCoords);
429+
}
428430
results.addCollision(cr);
429431
cols++;
430432
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,15 +477,17 @@ public int collideWith(Collidable other, CollisionResults results) {
477477
return bv.collideWith(this, results);
478478
} else if (other instanceof AbstractTriangle) {
479479
AbstractTriangle tri = (AbstractTriangle) other;
480-
Vector2f baryCoords = new Vector2f();
480+
Vector2f baryCoords = results.isRequiresBaryCoords() ? new Vector2f() : null;
481481
float d = intersects(tri.get1(), tri.get2(), tri.get3(), baryCoords);
482482
if (Float.isInfinite(d) || Float.isNaN(d)) {
483483
return 0;
484484
}
485485

486486
Vector3f point = new Vector3f(direction).multLocal(d).addLocal(origin);
487487
CollisionResult cr = new CollisionResult(point, d);
488-
cr.setContactBaryCoords(baryCoords);
488+
if (baryCoords != null) {
489+
cr.setContactBaryCoords(baryCoords);
490+
}
489491
results.addCollision(cr);
490492
return 1;
491493
} else {

jme3-core/src/test/java/com/jme3/collision/RayCollisionTest.java

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ public void testBarycentricReconstructsContactPoint() {
166166

167167
/**
168168
* Verifies that CollisionResult contains barycentric coords when a ray
169-
* collides with an AbstractTriangle.
169+
* collides with an AbstractTriangle and the flag is enabled.
170170
*/
171171
@Test
172172
public void testCollisionResultContainsBaryCoords() {
@@ -181,6 +181,7 @@ public void testCollisionResultContainsBaryCoords() {
181181

182182
Triangle tri = new Triangle(v0, v1, v2);
183183
CollisionResults results = new CollisionResults();
184+
results.setRequiresBaryCoords(true);
184185
int count = ray.collideWith(tri, results);
185186

186187
Assert.assertEquals("Expected exactly 1 collision", 1, count);
@@ -189,11 +190,37 @@ public void testCollisionResultContainsBaryCoords() {
189190
Assert.assertNotNull("CollisionResult should not be null", cr);
190191

191192
Vector2f bary = cr.getContactBaryCoords();
192-
Assert.assertNotNull("Barycentric coords should be set", bary);
193+
Assert.assertNotNull("Barycentric coords should be set when flag is enabled", bary);
193194
Assert.assertEquals("u should be 1/3", 1f / 3f, bary.x, DELTA);
194195
Assert.assertEquals("v should be 1/3", 1f / 3f, bary.y, DELTA);
195196
}
196197

198+
/**
199+
* Verifies that barycentric coords are NOT computed when the flag is
200+
* disabled (the default).
201+
*/
202+
@Test
203+
public void testCollisionResultNoBaryCoordsByDefault() {
204+
Vector3f v0 = new Vector3f(0f, 0f, 0f);
205+
Vector3f v1 = new Vector3f(1f, 0f, 0f);
206+
Vector3f v2 = new Vector3f(0f, 1f, 0f);
207+
208+
float cx = (v0.x + v1.x + v2.x) / 3f;
209+
float cy = (v0.y + v1.y + v2.y) / 3f;
210+
Ray ray = new Ray(new Vector3f(cx, cy, 5f), new Vector3f(0f, 0f, -1f));
211+
212+
Triangle tri = new Triangle(v0, v1, v2);
213+
CollisionResults results = new CollisionResults(); // flag defaults to false
214+
int count = ray.collideWith(tri, results);
215+
216+
Assert.assertEquals("Expected exactly 1 collision", 1, count);
217+
218+
CollisionResult cr = results.getClosestCollision();
219+
Assert.assertNotNull("CollisionResult should not be null", cr);
220+
Assert.assertNull("Barycentric coords should be null when flag is disabled",
221+
cr.getContactBaryCoords());
222+
}
223+
197224
/**
198225
* Verifies that no intersection returns POSITIVE_INFINITY and bary is not
199226
* modified.

0 commit comments

Comments
 (0)