Skip to content

Commit

Permalink
Support for ScaledShape as shape for CharacterVirtual (#1283)
Browse files Browse the repository at this point in the history
  • Loading branch information
jrouwe authored Sep 27, 2024
1 parent a8327c3 commit b6e22f7
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 15 deletions.
16 changes: 11 additions & 5 deletions Jolt/Physics/Character/CharacterVirtual.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -524,23 +525,28 @@ 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;
return gjk.CastShape(inStart, inDisplacement, cDefaultCollisionTolerance, *support, inPolygon, ioFraction);
}
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
{
Expand Down Expand Up @@ -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)
{
Expand Down
20 changes: 10 additions & 10 deletions Jolt/Physics/Collision/Shape/RotatedTranslatedShape.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,16 @@ class JPH_EXPORT RotatedTranslatedShape final : public DecoratedShape
// 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();

Expand All @@ -143,16 +153,6 @@ class JPH_EXPORT RotatedTranslatedShape final : public DecoratedShape
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
Expand Down

0 comments on commit b6e22f7

Please sign in to comment.