Add barycentric coordinates to ray vs. triangle collision results - #2663
riccardobl with Copilot wants to merge 3 commits into
Conversation
Agent-Logs-Url: https://github.com/jMonkeyEngine/jmonkeyengine/sessions/75a9c930-942a-438a-b24e-9cc4c7daa5a2 Co-authored-by: riccardobl <4943530+riccardobl@users.noreply.github.com>
|
Can you add a boolean flag to CollisionResults to enable barycentric coordinate computation? So that it is done only when the developer need them? @copilot |
Agent-Logs-Url: https://github.com/jMonkeyEngine/jmonkeyengine/sessions/86d05467-fc58-41ed-a878-1c31d48e6575 Co-authored-by: riccardobl <4943530+riccardobl@users.noreply.github.com>
Done in commit 16a97ce. Added |
| * @return the distance along the ray to the intersection, or | ||
| * {@link Float#POSITIVE_INFINITY} if there is no intersection | ||
| */ | ||
| public float intersects(Vector3f v0, Vector3f v1, Vector3f v2, Vector2f baryCoords) { |
There was a problem hiding this comment.
Nice — the (u, v) values produced here match the convention already used by intersectWherePlanar() (u = weight of v1, v = weight of v2), so the two APIs agree and the javadoc is accurate.
One maintainability note: this new overload is a line-for-line copy of the existing intersects(Vector3f, Vector3f, Vector3f) method (which in turn mirrors the private intersects(...)), so the same ray/triangle math now lives in three places and can silently drift apart when one copy is fixed. Since intersects(v0, v1, v2) is still public API, it could simply delegate:
public float intersects(Vector3f v0, Vector3f v1, Vector3f v2) {
return intersects(v0, v1, v2, null);
}Same behaviour, one implementation to maintain. (Couldn't attach it as a one-click suggestion because those lines aren't part of this diff.)
| CollisionResult cr = new CollisionResult(contactPoint, worldSpaceDist); | ||
| cr.setContactNormal(contactNormal); | ||
| cr.setTriangleIndex(tree.getTriangleIndex(i)); | ||
| if (baryCoords != null) { |
There was a problem hiding this comment.
This BIH leaf is the branch real geometry.collideWith(ray, results) calls go through, but the new tests only exercise the direct Ray/Triangle API. A small test that builds a Mesh/Geometry, enables setRequiresBaryCoords(true), and asserts the coords on the returned CollisionResult would guard this path too — including the world-transform case just above.
jaime-jmebot
left a comment
There was a problem hiding this comment.
Nice work — the feature is tidy and the opt-in flag addresses the earlier request well.
- The
(u, v)convention is consistent acrossRay.intersectWherePlanar, the new overload, andCollisionResult, and the weights line up with what the BIH leaf loop stores, so the documented usage (interpolating per-vertex attributes) is correct. - One maintainability nit inline: the new
Ray.intersectsoverload duplicates the existing three-argument method, so the ray/triangle math now exists in two more copies. - The added unit tests cover the direct triangle path; a mesh/
Geometry-level test would also exercise the BIH branch (inline note).
Nothing blocking from my side.
Ray-triangle collision results (
CollisionResult) had no way to retrieve barycentric coordinates of the contact point, making texture-coord interpolation and surface-parameter lookups impossible without redundant re-computation.Changes
CollisionResult: AddedcontactBaryCoords(Vector2f) field with getter/setter. Convention:(u, v)whereu= weight ofv1,v= weight ofv2,1-u-v= weight ofv0.CollisionResults: AddedrequiresBaryCoordsboolean flag (defaultfalse) withsetRequiresBaryCoords(boolean)/isRequiresBaryCoords(). Barycentric coordinates are only computed and stored when this flag is enabled, avoiding unnecessary allocation and math for callers that don't need them.Ray: Addedintersects(Vector3f v0, Vector3f v1, Vector3f v2, Vector2f baryCoords)overload that computes barycentric coordinates alongside the hit distance in a single pass. UpdatedcollideWith(AbstractTriangle)to populatecontactBaryCoordson the result only when the flag is set.BIHNode: UpdatedintersectWhere()leaf loop (mesh collision path) to use the new overload and store barycentric coords on eachCollisionResultonly when the flag is set.Usage
getContactBaryCoords()returnsnullwhen the flag is disabled (default) or for collision types that don't involve a triangle (e.g. bounding volume hits).✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.