Browse Source

Added fraction hint to PathConstraintPath::GetClosestPoint (#914)

This can be used to speed up the search along the curve and to disambiguate fractions in case a path reaches the same point multiple times (i.e. a figure-8)

See: jrouwe/JoltPhysics.js#102
Jorrit Rouwe 1 year ago
parent
commit
b91e729e6e

+ 1 - 1
Jolt/Physics/Constraints/PathConstraint.cpp

@@ -119,7 +119,7 @@ void PathConstraint::CalculateConstraintProperties(float inDeltaTime)
 	// Calculate new closest point on path
 	RVec3 position2 = path_to_world_2.GetTranslation();
 	Vec3 position2_local_to_path = Vec3(path_to_world_1.InversedRotationTranslation() * position2);
-	mPathFraction = mPath->GetClosestPoint(position2_local_to_path);
+	mPathFraction = mPath->GetClosestPoint(position2_local_to_path, mPathFraction);
 
 	// Get the point on the path for this fraction
 	Vec3 path_point, path_tangent, path_normal, path_binormal;

+ 2 - 1
Jolt/Physics/Constraints/PathConstraintPath.h

@@ -32,8 +32,9 @@ public:
 
 	/// Get the globally closest point on the curve (Could be slow!)
 	/// @param inPosition Position to find closest point for
+	/// @param inFractionHint Last known fraction along the path (can be used to speed up the search)
 	/// @return Fraction of closest point along the path
-	virtual float		GetClosestPoint(Vec3Arg inPosition) const = 0;
+	virtual float		GetClosestPoint(Vec3Arg inPosition, float inFractionHint) const = 0;
 
 	/// Given the fraction along the path, get the point, tangent and normal.
 	/// @param inFraction Fraction along the path [0, GetPathMaxFraction()].

+ 1 - 1
Jolt/Physics/Constraints/PathConstraintPathHermite.cpp

@@ -203,7 +203,7 @@ void PathConstraintPathHermite::GetIndexAndT(float inFraction, int &outIndex, fl
 	outT = t;
 }
 
-float PathConstraintPathHermite::GetClosestPoint(Vec3Arg inPosition) const
+float PathConstraintPathHermite::GetClosestPoint(Vec3Arg inPosition, float inFractionHint) const
 {
 	JPH_PROFILE_FUNCTION();
 

+ 1 - 1
Jolt/Physics/Constraints/PathConstraintPathHermite.h

@@ -18,7 +18,7 @@ public:
 	virtual float		GetPathMaxFraction() const override									{ return float(IsLooping()? mPoints.size() : mPoints.size() - 1); }
 
 	// See PathConstraintPath::GetClosestPoint
-	virtual float		GetClosestPoint(Vec3Arg inPosition) const override;
+	virtual float		GetClosestPoint(Vec3Arg inPosition, float inFractionHint) const override;
 
 	// See PathConstraintPath::GetPointOnPath
 	virtual void		GetPointOnPath(float inFraction, Vec3 &outPathPosition, Vec3 &outPathTangent, Vec3 &outPathNormal, Vec3 &outPathBinormal) const override;

+ 3 - 3
UnitTests/Physics/PathConstraintTests.cpp

@@ -28,9 +28,9 @@ TEST_SUITE("PathConstraintTests")
 		path->AddPoint(p2, t2, n2);
 
 		// Test that positions before and after the line return 0 and 1
-		float before_start = path->GetClosestPoint(p1 - 0.01f * t1);
+		float before_start = path->GetClosestPoint(p1 - 0.01f * t1, 0.0f);
 		CHECK(before_start == 0.0f);
-		float after_end = path->GetClosestPoint(p2 + 0.01f * t2);
+		float after_end = path->GetClosestPoint(p2 + 0.01f * t2, 0.0f);
 		CHECK(after_end == 1.0f);
 
 		for (int i = 0; i <= 10; ++i)
@@ -41,7 +41,7 @@ TEST_SUITE("PathConstraintTests")
 			path->GetPointOnPath(fraction, pos, tgt, nrm, bin);
 
 			// Let the path determine the fraction of the closest point
-			float closest_fraction = path->GetClosestPoint(pos);
+			float closest_fraction = path->GetClosestPoint(pos, 0.0f);
 
 			// Validate that it is equal to what we put in
 			CHECK_APPROX_EQUAL(fraction, closest_fraction, 1.0e-4f);