Browse Source

Support for ScaledShape as shape for CharacterVirtual (#1283)

See jrouwe/JoltPhysics.js#200
Jorrit Rouwe 10 months ago
parent
commit
b6e22f777b

+ 11 - 5
Jolt/Physics/Character/CharacterVirtual.cpp

@@ -11,6 +11,7 @@
 #include <Jolt/Physics/Collision/ShapeCast.h>
 #include <Jolt/Physics/Collision/CollideShape.h>
 #include <Jolt/Physics/Collision/Shape/RotatedTranslatedShape.h>
+#include <Jolt/Physics/Collision/Shape/ScaledShape.h>
 #include <Jolt/Physics/Collision/InternalEdgeRemovingCollector.h>
 #include <Jolt/Core/QuickSort.h>
 #include <Jolt/Geometry/ConvexSupport.h>
@@ -524,14 +525,14 @@ void CharacterVirtual::ContactAdded(const Contact &inContact, CharacterContactSe
 }
 
 template <class T>
-inline static bool sCorrectFractionForCharacterPadding(const Shape *inShape, Mat44Arg inStart, Vec3Arg inDisplacement, const T &inPolygon, float &ioFraction)
+inline static bool sCorrectFractionForCharacterPadding(const Shape *inShape, Mat44Arg inStart, Vec3Arg inDisplacement, Vec3Arg inScale, const T &inPolygon, float &ioFraction)
 {
 	if (inShape->GetType() == EShapeType::Convex)
 	{
 		// Get the support function for the shape we're casting
 		const ConvexShape *convex_shape = static_cast<const ConvexShape *>(inShape);
 		ConvexShape::SupportBuffer buffer;
-		const ConvexShape::Support *support = convex_shape->GetSupportFunction(ConvexShape::ESupportMode::IncludeConvexRadius, buffer, Vec3::sReplicate(1.0f));
+		const ConvexShape::Support *support = convex_shape->GetSupportFunction(ConvexShape::ESupportMode::IncludeConvexRadius, buffer, inScale);
 
 		// Cast the shape against the polygon
 		GJKClosestPoint gjk;
@@ -539,8 +540,13 @@ inline static bool sCorrectFractionForCharacterPadding(const Shape *inShape, Mat
 	}
 	else if (inShape->GetSubType() == EShapeSubType::RotatedTranslated)
 	{
-		const RotatedTranslatedShape *rt_shape = static_cast<const RotatedTranslatedShape *>(inShape);
-		return sCorrectFractionForCharacterPadding(rt_shape->GetInnerShape(), inStart * Mat44::sRotation(rt_shape->GetRotation()), inDisplacement, inPolygon, ioFraction);
+		const RotatedTranslatedShape *rt_shape = static_cast<const RotatedTranslatedShape *>(inShape);		
+		return sCorrectFractionForCharacterPadding(rt_shape->GetInnerShape(), inStart * Mat44::sRotation(rt_shape->GetRotation()), inDisplacement, rt_shape->TransformScale(inScale), inPolygon, ioFraction);
+	}
+	else if (inShape->GetSubType() == EShapeSubType::Scaled)
+	{
+		const ScaledShape *scaled_shape = static_cast<const ScaledShape *>(inShape);
+		return sCorrectFractionForCharacterPadding(scaled_shape->GetInnerShape(), inStart, inDisplacement, inScale * scaled_shape->GetScale(), inPolygon, ioFraction);
 	}
 	else
 	{
@@ -624,7 +630,7 @@ bool CharacterVirtual::GetFirstContactForSweep(RVec3Arg inPosition, Vec3Arg inDi
 		AddConvexRadius add_cvx(polygon, character_padding);
 
 		// Correct fraction to hit this inflated face instead of the inner shape
-		corrected = sCorrectFractionForCharacterPadding(mShape, start.GetRotation(), inDisplacement, add_cvx, outContact.mFraction);
+		corrected = sCorrectFractionForCharacterPadding(mShape, start.GetRotation(), inDisplacement, Vec3::sReplicate(1.0f), add_cvx, outContact.mFraction);
 	}
 	if (!corrected)
 	{

+ 10 - 10
Jolt/Physics/Collision/Shape/RotatedTranslatedShape.h

@@ -127,6 +127,16 @@ public:
 	// See Shape::MakeScaleValid
 	virtual Vec3					MakeScaleValid(Vec3Arg inScale) const override;
 
+	/// Transform the scale to the local space of the child shape
+	inline Vec3						TransformScale(Vec3Arg inScale) const
+	{
+		// We don't need to transform uniform scale or if the rotation is identity
+		if (mIsRotationIdentity || ScaleHelpers::IsUniformScale(inScale))
+			return inScale;
+
+		return ScaleHelpers::RotateScale(mRotation, inScale);
+	}
+
 	// Register shape functions with the registry
 	static void						sRegister();
 
@@ -143,16 +153,6 @@ private:
 	static void						sCastShapeVsRotatedTranslated(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector);
 	static void						sCastRotatedTranslatedVsRotatedTranslated(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector);
 
-	/// Transform the scale to the local space of the child shape
-	inline Vec3						TransformScale(Vec3Arg inScale) const
-	{
-		// We don't need to transform uniform scale or if the rotation is identity
-		if (mIsRotationIdentity || ScaleHelpers::IsUniformScale(inScale))
-			return inScale;
-
-		return ScaleHelpers::RotateScale(mRotation, inScale);
-	}
-
 	bool							mIsRotationIdentity;									///< If mRotation is close to identity (put here because it falls in padding bytes)
 	Vec3							mCenterOfMass;											///< Position of the center of mass
 	Quat							mRotation;												///< Rotation of the child shape