Skip to content

Commit

Permalink
Fixed bug in MustIncludeC logic in GetClosestPointOnTriangle (#749)
Browse files Browse the repository at this point in the history
If A and C are swapped to get a better normal, then skipping skipping edge AB is incorrect as it is actually edge BC
  • Loading branch information
bttner authored Nov 11, 2023
1 parent fda7b11 commit ce6c135
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/determinism_check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Determinism Check

env:
CONVEX_VS_MESH_HASH: '0x10139effe747511'
RAGDOLL_HASH: '0xeb0afdf14f49c318'
RAGDOLL_HASH: '0xcdcbb4da185d1a13'

on:
push:
Expand Down
40 changes: 23 additions & 17 deletions Jolt/Geometry/ClosestPoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ namespace ClosestPoint
float best_dist_sq = inC.LengthSq();

// If the closest point must include C then A or B cannot be closest
// Note that we test vertices first because we want to prefer a closest vertex over a closest edge (this results in an outSet with fewer bits set)
if constexpr (!MustIncludeC)
{
// Try vertex A
Expand All @@ -203,21 +204,6 @@ namespace ClosestPoint
closest_point = inB;
best_dist_sq = b_len_sq;
}

// Edge AB
float ab_len_sq = ab.LengthSq();
if (ab_len_sq > Square(FLT_EPSILON))
{
float v = Clamp(-a.Dot(ab) / ab_len_sq, 0.0f, 1.0f);
Vec3 q = a + v * ab;
float dist_sq = q.LengthSq();
if (dist_sq < best_dist_sq)
{
closest_set = swap_ac.GetX()? 0b0110 : 0b0011;
closest_point = q;
best_dist_sq = dist_sq;
}
}
}

// Edge AC
Expand All @@ -236,7 +222,7 @@ namespace ClosestPoint
}

// Edge BC
Vec3 bc = c - inB;
Vec3 bc = inC - inB;
float bc_len_sq = bc.LengthSq();
if (bc_len_sq > Square(FLT_EPSILON))
{
Expand All @@ -245,12 +231,32 @@ namespace ClosestPoint
float dist_sq = q.LengthSq();
if (dist_sq < best_dist_sq)
{
closest_set = swap_ac.GetX()? 0b0011 : 0b0110;
closest_set = 0b0110;
closest_point = q;
best_dist_sq = dist_sq;
}
}

// If the closest point must include C then AB cannot be closest
if constexpr (!MustIncludeC)
{
// Edge AB
ab = inB - inA;
float ab_len_sq = ab.LengthSq();
if (ab_len_sq > Square(FLT_EPSILON))
{
float v = Clamp(-inA.Dot(ab) / ab_len_sq, 0.0f, 1.0f);
Vec3 q = inA + v * ab;
float dist_sq = q.LengthSq();
if (dist_sq < best_dist_sq)
{
closest_set = 0b0011;
closest_point = q;
best_dist_sq = dist_sq;
}
}
}

outSet = closest_set;
return closest_point;
}
Expand Down

0 comments on commit ce6c135

Please sign in to comment.