|
@@ -75,7 +75,7 @@ void CharacterVirtual::ContactCollector::AddHit(const CollideShapeResult &inResu
|
|
}
|
|
}
|
|
|
|
|
|
void CharacterVirtual::ContactCastCollector::AddHit(const ShapeCastResult &inResult)
|
|
void CharacterVirtual::ContactCastCollector::AddHit(const ShapeCastResult &inResult)
|
|
-{
|
|
|
|
|
|
+{
|
|
if (inResult.mFraction > 0.0f // Ignore collisions at fraction = 0
|
|
if (inResult.mFraction > 0.0f // Ignore collisions at fraction = 0
|
|
&& inResult.mPenetrationAxis.Dot(mDisplacement) > 0.0f) // Ignore penetrations that we're moving away from
|
|
&& inResult.mPenetrationAxis.Dot(mDisplacement) > 0.0f) // Ignore penetrations that we're moving away from
|
|
{
|
|
{
|
|
@@ -101,7 +101,7 @@ void CharacterVirtual::ContactCastCollector::AddHit(const ShapeCastResult &inRes
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-void CharacterVirtual::CheckCollision(RVec3Arg inPosition, QuatArg inRotation, Vec3Arg inMovementDirection, float inMaxSeparationDistance, const Shape *inShape, RVec3Arg inBaseOffset, CollideShapeCollector &ioCollector, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter) const
|
|
|
|
|
|
+void CharacterVirtual::CheckCollision(RVec3Arg inPosition, QuatArg inRotation, Vec3Arg inMovementDirection, float inMaxSeparationDistance, const Shape *inShape, RVec3Arg inBaseOffset, CollideShapeCollector &ioCollector, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter) const
|
|
{
|
|
{
|
|
// Query shape transform
|
|
// Query shape transform
|
|
RMat44 transform = GetCenterOfMassTransform(inPosition, inRotation, inShape);
|
|
RMat44 transform = GetCenterOfMassTransform(inPosition, inRotation, inShape);
|
|
@@ -114,17 +114,17 @@ void CharacterVirtual::CheckCollision(RVec3Arg inPosition, QuatArg inRotation, V
|
|
settings.mMaxSeparationDistance = mCharacterPadding + inMaxSeparationDistance;
|
|
settings.mMaxSeparationDistance = mCharacterPadding + inMaxSeparationDistance;
|
|
|
|
|
|
// Collide shape
|
|
// Collide shape
|
|
- mSystem->GetNarrowPhaseQuery().CollideShape(inShape, Vec3::sReplicate(1.0f), transform, settings, inBaseOffset, ioCollector, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter);
|
|
|
|
|
|
+ mSystem->GetNarrowPhaseQuery().CollideShape(inShape, Vec3::sReplicate(1.0f), transform, settings, inBaseOffset, ioCollector, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inShapeFilter);
|
|
}
|
|
}
|
|
|
|
|
|
-void CharacterVirtual::GetContactsAtPosition(RVec3Arg inPosition, Vec3Arg inMovementDirection, const Shape *inShape, TempContactList &outContacts, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter) const
|
|
|
|
|
|
+void CharacterVirtual::GetContactsAtPosition(RVec3Arg inPosition, Vec3Arg inMovementDirection, const Shape *inShape, TempContactList &outContacts, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter) const
|
|
{
|
|
{
|
|
// Remove previous results
|
|
// Remove previous results
|
|
outContacts.clear();
|
|
outContacts.clear();
|
|
|
|
|
|
// Collide shape
|
|
// Collide shape
|
|
ContactCollector collector(mSystem, mMaxNumHits, mUp, mPosition, outContacts);
|
|
ContactCollector collector(mSystem, mMaxNumHits, mUp, mPosition, outContacts);
|
|
- CheckCollision(inPosition, mRotation, inMovementDirection, mPredictiveContactDistance, inShape, mPosition, collector, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter);
|
|
|
|
|
|
+ CheckCollision(inPosition, mRotation, inMovementDirection, mPredictiveContactDistance, inShape, mPosition, collector, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inShapeFilter);
|
|
|
|
|
|
// Reduce distance to contact by padding to ensure we stay away from the object by a little margin
|
|
// Reduce distance to contact by padding to ensure we stay away from the object by a little margin
|
|
// (this will make collision detection cheaper - especially for sweep tests as they won't hit the surface if we're properly sliding)
|
|
// (this will make collision detection cheaper - especially for sweep tests as they won't hit the surface if we're properly sliding)
|
|
@@ -205,7 +205,7 @@ inline static bool sCorrectFractionForCharacterPadding(const Shape *inShape, Mat
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-bool CharacterVirtual::GetFirstContactForSweep(RVec3Arg inPosition, Vec3Arg inDisplacement, Contact &outContact, const IgnoredContactList &inIgnoredContacts, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, TempAllocator &inAllocator) const
|
|
|
|
|
|
+bool CharacterVirtual::GetFirstContactForSweep(RVec3Arg inPosition, Vec3Arg inDisplacement, Contact &outContact, const IgnoredContactList &inIgnoredContacts, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator) const
|
|
{
|
|
{
|
|
// Too small distance -> skip checking
|
|
// Too small distance -> skip checking
|
|
float displacement_len_sq = inDisplacement.LengthSq();
|
|
float displacement_len_sq = inDisplacement.LengthSq();
|
|
@@ -228,7 +228,7 @@ bool CharacterVirtual::GetFirstContactForSweep(RVec3Arg inPosition, Vec3Arg inDi
|
|
contacts.reserve(mMaxNumHits);
|
|
contacts.reserve(mMaxNumHits);
|
|
ContactCastCollector collector(mSystem, inDisplacement, mMaxNumHits, mUp, inIgnoredContacts, start.GetTranslation(), contacts);
|
|
ContactCastCollector collector(mSystem, inDisplacement, mMaxNumHits, mUp, inIgnoredContacts, start.GetTranslation(), contacts);
|
|
RShapeCast shape_cast(mShape, Vec3::sReplicate(1.0f), start, inDisplacement);
|
|
RShapeCast shape_cast(mShape, Vec3::sReplicate(1.0f), start, inDisplacement);
|
|
- mSystem->GetNarrowPhaseQuery().CastShape(shape_cast, settings, start.GetTranslation(), collector, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter);
|
|
|
|
|
|
+ mSystem->GetNarrowPhaseQuery().CastShape(shape_cast, settings, start.GetTranslation(), collector, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inShapeFilter);
|
|
if (contacts.empty())
|
|
if (contacts.empty())
|
|
return false;
|
|
return false;
|
|
|
|
|
|
@@ -440,7 +440,7 @@ void CharacterVirtual::SolveConstraints(Vec3Arg inVelocity, float inDeltaTime, f
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
// Sort constraints on proximity
|
|
// Sort constraints on proximity
|
|
QuickSort(sorted_constraints.begin(), sorted_constraints.end(), [](const Constraint *inLHS, const Constraint *inRHS) {
|
|
QuickSort(sorted_constraints.begin(), sorted_constraints.end(), [](const Constraint *inLHS, const Constraint *inRHS) {
|
|
// If both constraints hit at t = 0 then order the one that will push the character furthest first
|
|
// If both constraints hit at t = 0 then order the one that will push the character furthest first
|
|
@@ -542,7 +542,7 @@ void CharacterVirtual::SolveConstraints(Vec3Arg inVelocity, float inDeltaTime, f
|
|
{
|
|
{
|
|
// We don't want parallel or anti-parallel normals as that will cause our cross product below to become zero. Slack is approx 10 degrees.
|
|
// We don't want parallel or anti-parallel normals as that will cause our cross product below to become zero. Slack is approx 10 degrees.
|
|
float dot = other_normal.Dot(plane_normal);
|
|
float dot = other_normal.Dot(plane_normal);
|
|
- if (dot < 0.984f && dot > -0.984f)
|
|
|
|
|
|
+ if (dot < 0.984f && dot > -0.984f)
|
|
{
|
|
{
|
|
highest_penetration = penetration;
|
|
highest_penetration = penetration;
|
|
other_constraint = *c;
|
|
other_constraint = *c;
|
|
@@ -691,7 +691,7 @@ void CharacterVirtual::UpdateSupportingContact(bool inSkipContactVelocityCheck,
|
|
else
|
|
else
|
|
{
|
|
{
|
|
// For keyframed objects that support us calculate the velocity at our position rather than at the contact position so that we properly follow the object
|
|
// For keyframed objects that support us calculate the velocity at our position rather than at the contact position so that we properly follow the object
|
|
- // Note that we don't just take the point velocity because a point on an object with angular velocity traces an arc,
|
|
|
|
|
|
+ // Note that we don't just take the point velocity because a point on an object with angular velocity traces an arc,
|
|
// so if you just take point velocity * delta time you get an error that accumulates over time
|
|
// so if you just take point velocity * delta time you get an error that accumulates over time
|
|
|
|
|
|
// Determine center of mass and angular velocity
|
|
// Determine center of mass and angular velocity
|
|
@@ -817,7 +817,7 @@ void CharacterVirtual::StoreActiveContacts(const TempContactList &inContacts, Te
|
|
UpdateSupportingContact(true, inAllocator);
|
|
UpdateSupportingContact(true, inAllocator);
|
|
}
|
|
}
|
|
|
|
|
|
-void CharacterVirtual::MoveShape(RVec3 &ioPosition, Vec3Arg inVelocity, float inDeltaTime, ContactList *outActiveContacts, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, TempAllocator &inAllocator
|
|
|
|
|
|
+void CharacterVirtual::MoveShape(RVec3 &ioPosition, Vec3Arg inVelocity, float inDeltaTime, ContactList *outActiveContacts, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator
|
|
#ifdef JPH_DEBUG_RENDERER
|
|
#ifdef JPH_DEBUG_RENDERER
|
|
, bool inDrawConstraints
|
|
, bool inDrawConstraints
|
|
#endif // JPH_DEBUG_RENDERER
|
|
#endif // JPH_DEBUG_RENDERER
|
|
@@ -831,7 +831,7 @@ void CharacterVirtual::MoveShape(RVec3 &ioPosition, Vec3Arg inVelocity, float in
|
|
// Determine contacts in the neighborhood
|
|
// Determine contacts in the neighborhood
|
|
TempContactList contacts(inAllocator);
|
|
TempContactList contacts(inAllocator);
|
|
contacts.reserve(mMaxNumHits);
|
|
contacts.reserve(mMaxNumHits);
|
|
- GetContactsAtPosition(ioPosition, movement_direction, mShape, contacts, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter);
|
|
|
|
|
|
+ GetContactsAtPosition(ioPosition, movement_direction, mShape, contacts, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inShapeFilter);
|
|
|
|
|
|
// Remove contacts with the same body that have conflicting normals
|
|
// Remove contacts with the same body that have conflicting normals
|
|
IgnoredContactList ignored_contacts(inAllocator);
|
|
IgnoredContactList ignored_contacts(inAllocator);
|
|
@@ -878,7 +878,7 @@ void CharacterVirtual::MoveShape(RVec3 &ioPosition, Vec3Arg inVelocity, float in
|
|
|
|
|
|
// Do a sweep to test if the path is really unobstructed
|
|
// Do a sweep to test if the path is really unobstructed
|
|
Contact cast_contact;
|
|
Contact cast_contact;
|
|
- if (GetFirstContactForSweep(ioPosition, displacement, cast_contact, ignored_contacts, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inAllocator))
|
|
|
|
|
|
+ if (GetFirstContactForSweep(ioPosition, displacement, cast_contact, ignored_contacts, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inShapeFilter, inAllocator))
|
|
{
|
|
{
|
|
displacement *= cast_contact.mFraction;
|
|
displacement *= cast_contact.mFraction;
|
|
time_simulated *= cast_contact.mFraction;
|
|
time_simulated *= cast_contact.mFraction;
|
|
@@ -901,7 +901,7 @@ Vec3 CharacterVirtual::CancelVelocityTowardsSteepSlopes(Vec3Arg inDesiredVelocit
|
|
if (mGroundState == CharacterVirtual::EGroundState::OnGround
|
|
if (mGroundState == CharacterVirtual::EGroundState::OnGround
|
|
|| mGroundState == CharacterVirtual::EGroundState::InAir)
|
|
|| mGroundState == CharacterVirtual::EGroundState::InAir)
|
|
return inDesiredVelocity;
|
|
return inDesiredVelocity;
|
|
-
|
|
|
|
|
|
+
|
|
Vec3 desired_velocity = inDesiredVelocity;
|
|
Vec3 desired_velocity = inDesiredVelocity;
|
|
for (const Contact &c : mActiveContacts)
|
|
for (const Contact &c : mActiveContacts)
|
|
if (c.mHadCollision
|
|
if (c.mHadCollision
|
|
@@ -920,7 +920,7 @@ Vec3 CharacterVirtual::CancelVelocityTowardsSteepSlopes(Vec3Arg inDesiredVelocit
|
|
return desired_velocity;
|
|
return desired_velocity;
|
|
}
|
|
}
|
|
|
|
|
|
-void CharacterVirtual::Update(float inDeltaTime, Vec3Arg inGravity, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, TempAllocator &inAllocator)
|
|
|
|
|
|
+void CharacterVirtual::Update(float inDeltaTime, Vec3Arg inGravity, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator)
|
|
{
|
|
{
|
|
// If there's no delta time, we don't need to do anything
|
|
// If there's no delta time, we don't need to do anything
|
|
if (inDeltaTime <= 0.0f)
|
|
if (inDeltaTime <= 0.0f)
|
|
@@ -930,7 +930,7 @@ void CharacterVirtual::Update(float inDeltaTime, Vec3Arg inGravity, const BroadP
|
|
mLastDeltaTime = inDeltaTime;
|
|
mLastDeltaTime = inDeltaTime;
|
|
|
|
|
|
// Slide the shape through the world
|
|
// Slide the shape through the world
|
|
- MoveShape(mPosition, mLinearVelocity, inDeltaTime, &mActiveContacts, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inAllocator
|
|
|
|
|
|
+ MoveShape(mPosition, mLinearVelocity, inDeltaTime, &mActiveContacts, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inShapeFilter, inAllocator
|
|
#ifdef JPH_DEBUG_RENDERER
|
|
#ifdef JPH_DEBUG_RENDERER
|
|
, sDrawConstraints
|
|
, sDrawConstraints
|
|
#endif // JPH_DEBUG_RENDERER
|
|
#endif // JPH_DEBUG_RENDERER
|
|
@@ -952,17 +952,17 @@ void CharacterVirtual::Update(float inDeltaTime, Vec3Arg inGravity, const BroadP
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-void CharacterVirtual::RefreshContacts(const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, TempAllocator &inAllocator)
|
|
|
|
|
|
+void CharacterVirtual::RefreshContacts(const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator)
|
|
{
|
|
{
|
|
// Determine the contacts
|
|
// Determine the contacts
|
|
TempContactList contacts(inAllocator);
|
|
TempContactList contacts(inAllocator);
|
|
contacts.reserve(mMaxNumHits);
|
|
contacts.reserve(mMaxNumHits);
|
|
- GetContactsAtPosition(mPosition, mLinearVelocity.NormalizedOr(Vec3::sZero()), mShape, contacts, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter);
|
|
|
|
|
|
+ GetContactsAtPosition(mPosition, mLinearVelocity.NormalizedOr(Vec3::sZero()), mShape, contacts, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inShapeFilter);
|
|
|
|
|
|
StoreActiveContacts(contacts, inAllocator);
|
|
StoreActiveContacts(contacts, inAllocator);
|
|
}
|
|
}
|
|
|
|
|
|
-void CharacterVirtual::MoveToContact(RVec3Arg inPosition, const Contact &inContact, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, TempAllocator &inAllocator)
|
|
|
|
|
|
+void CharacterVirtual::MoveToContact(RVec3Arg inPosition, const Contact &inContact, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator)
|
|
{
|
|
{
|
|
// Set the new position
|
|
// Set the new position
|
|
SetPosition(inPosition);
|
|
SetPosition(inPosition);
|
|
@@ -970,7 +970,7 @@ void CharacterVirtual::MoveToContact(RVec3Arg inPosition, const Contact &inConta
|
|
// Determine the contacts
|
|
// Determine the contacts
|
|
TempContactList contacts(inAllocator);
|
|
TempContactList contacts(inAllocator);
|
|
contacts.reserve(mMaxNumHits + 1); // +1 because we can add one extra below
|
|
contacts.reserve(mMaxNumHits + 1); // +1 because we can add one extra below
|
|
- GetContactsAtPosition(mPosition, mLinearVelocity.NormalizedOr(Vec3::sZero()), mShape, contacts, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter);
|
|
|
|
|
|
+ GetContactsAtPosition(mPosition, mLinearVelocity.NormalizedOr(Vec3::sZero()), mShape, contacts, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inShapeFilter);
|
|
|
|
|
|
// Ensure that we mark inContact as colliding
|
|
// Ensure that we mark inContact as colliding
|
|
bool found_contact = false;
|
|
bool found_contact = false;
|
|
@@ -993,7 +993,7 @@ void CharacterVirtual::MoveToContact(RVec3Arg inPosition, const Contact &inConta
|
|
JPH_ASSERT(mGroundState != EGroundState::InAir);
|
|
JPH_ASSERT(mGroundState != EGroundState::InAir);
|
|
}
|
|
}
|
|
|
|
|
|
-bool CharacterVirtual::SetShape(const Shape *inShape, float inMaxPenetrationDepth, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, TempAllocator &inAllocator)
|
|
|
|
|
|
+bool CharacterVirtual::SetShape(const Shape *inShape, float inMaxPenetrationDepth, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator)
|
|
{
|
|
{
|
|
if (mShape == nullptr || mSystem == nullptr)
|
|
if (mShape == nullptr || mSystem == nullptr)
|
|
{
|
|
{
|
|
@@ -1009,7 +1009,7 @@ bool CharacterVirtual::SetShape(const Shape *inShape, float inMaxPenetrationDept
|
|
// Check collision around the new shape
|
|
// Check collision around the new shape
|
|
TempContactList contacts(inAllocator);
|
|
TempContactList contacts(inAllocator);
|
|
contacts.reserve(mMaxNumHits);
|
|
contacts.reserve(mMaxNumHits);
|
|
- GetContactsAtPosition(mPosition, mLinearVelocity.NormalizedOr(Vec3::sZero()), inShape, contacts, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter);
|
|
|
|
|
|
+ GetContactsAtPosition(mPosition, mLinearVelocity.NormalizedOr(Vec3::sZero()), inShape, contacts, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inShapeFilter);
|
|
|
|
|
|
// Test if this results in penetration, if so cancel the transition
|
|
// Test if this results in penetration, if so cancel the transition
|
|
for (const Contact &c : contacts)
|
|
for (const Contact &c : contacts)
|
|
@@ -1047,13 +1047,13 @@ bool CharacterVirtual::CanWalkStairs(Vec3Arg inLinearVelocity) const
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
-bool CharacterVirtual::WalkStairs(float inDeltaTime, Vec3Arg inStepUp, Vec3Arg inStepForward, Vec3Arg inStepForwardTest, Vec3Arg inStepDownExtra, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, TempAllocator &inAllocator)
|
|
|
|
|
|
+bool CharacterVirtual::WalkStairs(float inDeltaTime, Vec3Arg inStepUp, Vec3Arg inStepForward, Vec3Arg inStepForwardTest, Vec3Arg inStepDownExtra, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator)
|
|
{
|
|
{
|
|
// Move up
|
|
// Move up
|
|
Vec3 up = inStepUp;
|
|
Vec3 up = inStepUp;
|
|
Contact contact;
|
|
Contact contact;
|
|
IgnoredContactList dummy_ignored_contacts(inAllocator);
|
|
IgnoredContactList dummy_ignored_contacts(inAllocator);
|
|
- if (GetFirstContactForSweep(mPosition, up, contact, dummy_ignored_contacts, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inAllocator))
|
|
|
|
|
|
+ if (GetFirstContactForSweep(mPosition, up, contact, dummy_ignored_contacts, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inShapeFilter, inAllocator))
|
|
{
|
|
{
|
|
if (contact.mFraction < 1.0e-6f)
|
|
if (contact.mFraction < 1.0e-6f)
|
|
return false; // No movement, cancel
|
|
return false; // No movement, cancel
|
|
@@ -1071,7 +1071,7 @@ bool CharacterVirtual::WalkStairs(float inDeltaTime, Vec3Arg inStepUp, Vec3Arg i
|
|
|
|
|
|
// Horizontal movement
|
|
// Horizontal movement
|
|
RVec3 new_position = up_position;
|
|
RVec3 new_position = up_position;
|
|
- MoveShape(new_position, inStepForward / inDeltaTime, inDeltaTime, nullptr, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inAllocator);
|
|
|
|
|
|
+ MoveShape(new_position, inStepForward / inDeltaTime, inDeltaTime, nullptr, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inShapeFilter, inAllocator);
|
|
float horizontal_movement_sq = Vec3(new_position - up_position).LengthSq();
|
|
float horizontal_movement_sq = Vec3(new_position - up_position).LengthSq();
|
|
if (horizontal_movement_sq < 1.0e-8f)
|
|
if (horizontal_movement_sq < 1.0e-8f)
|
|
return false; // No movement, cancel
|
|
return false; // No movement, cancel
|
|
@@ -1086,14 +1086,14 @@ bool CharacterVirtual::WalkStairs(float inDeltaTime, Vec3Arg inStepUp, Vec3Arg i
|
|
// Note that we travel the same amount down as we travelled up with the character padding and the specified extra
|
|
// Note that we travel the same amount down as we travelled up with the character padding and the specified extra
|
|
// If we don't add the character padding, we may miss the floor (note that GetFirstContactForSweep will subtract the padding when it finds a hit)
|
|
// If we don't add the character padding, we may miss the floor (note that GetFirstContactForSweep will subtract the padding when it finds a hit)
|
|
Vec3 down = -up - mCharacterPadding * mUp + inStepDownExtra;
|
|
Vec3 down = -up - mCharacterPadding * mUp + inStepDownExtra;
|
|
- if (!GetFirstContactForSweep(new_position, down, contact, dummy_ignored_contacts, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inAllocator))
|
|
|
|
|
|
+ if (!GetFirstContactForSweep(new_position, down, contact, dummy_ignored_contacts, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inShapeFilter, inAllocator))
|
|
return false; // No floor found, we're in mid air, cancel stair walk
|
|
return false; // No floor found, we're in mid air, cancel stair walk
|
|
|
|
|
|
#ifdef JPH_DEBUG_RENDERER
|
|
#ifdef JPH_DEBUG_RENDERER
|
|
// Draw sweep down
|
|
// Draw sweep down
|
|
if (sDrawWalkStairs)
|
|
if (sDrawWalkStairs)
|
|
{
|
|
{
|
|
- RVec3 debug_pos = new_position + contact.mFraction * down;
|
|
|
|
|
|
+ RVec3 debug_pos = new_position + contact.mFraction * down;
|
|
DebugRenderer::sInstance->DrawArrow(new_position, debug_pos, Color::sWhite, 0.01f);
|
|
DebugRenderer::sInstance->DrawArrow(new_position, debug_pos, Color::sWhite, 0.01f);
|
|
DebugRenderer::sInstance->DrawArrow(contact.mPosition, contact.mPosition + contact.mSurfaceNormal, Color::sWhite, 0.01f);
|
|
DebugRenderer::sInstance->DrawArrow(contact.mPosition, contact.mPosition + contact.mSurfaceNormal, Color::sWhite, 0.01f);
|
|
mShape->Draw(DebugRenderer::sInstance, GetCenterOfMassTransform(debug_pos, mRotation, mShape), Vec3::sReplicate(1.0f), Color::sWhite, false, true);
|
|
mShape->Draw(DebugRenderer::sInstance, GetCenterOfMassTransform(debug_pos, mRotation, mShape), Vec3::sReplicate(1.0f), Color::sWhite, false, true);
|
|
@@ -1111,7 +1111,7 @@ bool CharacterVirtual::WalkStairs(float inDeltaTime, Vec3Arg inStepUp, Vec3Arg i
|
|
// In order to judge if the floor is flat further along the sweep, we test again for a floor at inStepForwardTest
|
|
// In order to judge if the floor is flat further along the sweep, we test again for a floor at inStepForwardTest
|
|
// and check if the normal is valid there.
|
|
// and check if the normal is valid there.
|
|
RVec3 test_position = up_position;
|
|
RVec3 test_position = up_position;
|
|
- MoveShape(test_position, inStepForwardTest / inDeltaTime, inDeltaTime, nullptr, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inAllocator);
|
|
|
|
|
|
+ MoveShape(test_position, inStepForwardTest / inDeltaTime, inDeltaTime, nullptr, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inShapeFilter, inAllocator);
|
|
float test_horizontal_movement_sq = Vec3(test_position - up_position).LengthSq();
|
|
float test_horizontal_movement_sq = Vec3(test_position - up_position).LengthSq();
|
|
if (test_horizontal_movement_sq <= horizontal_movement_sq + 1.0e-8f)
|
|
if (test_horizontal_movement_sq <= horizontal_movement_sq + 1.0e-8f)
|
|
return false; // We didn't move any further than in the previous test
|
|
return false; // We didn't move any further than in the previous test
|
|
@@ -1124,14 +1124,14 @@ bool CharacterVirtual::WalkStairs(float inDeltaTime, Vec3Arg inStepUp, Vec3Arg i
|
|
|
|
|
|
// Then sweep down
|
|
// Then sweep down
|
|
Contact test_contact;
|
|
Contact test_contact;
|
|
- if (!GetFirstContactForSweep(test_position, down, test_contact, dummy_ignored_contacts, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inAllocator))
|
|
|
|
|
|
+ if (!GetFirstContactForSweep(test_position, down, test_contact, dummy_ignored_contacts, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inShapeFilter, inAllocator))
|
|
return false;
|
|
return false;
|
|
|
|
|
|
#ifdef JPH_DEBUG_RENDERER
|
|
#ifdef JPH_DEBUG_RENDERER
|
|
// Draw 2nd sweep down
|
|
// Draw 2nd sweep down
|
|
if (sDrawWalkStairs)
|
|
if (sDrawWalkStairs)
|
|
{
|
|
{
|
|
- RVec3 debug_pos = test_position + test_contact.mFraction * down;
|
|
|
|
|
|
+ RVec3 debug_pos = test_position + test_contact.mFraction * down;
|
|
DebugRenderer::sInstance->DrawArrow(test_position, debug_pos, Color::sCyan, 0.01f);
|
|
DebugRenderer::sInstance->DrawArrow(test_position, debug_pos, Color::sCyan, 0.01f);
|
|
DebugRenderer::sInstance->DrawArrow(test_contact.mPosition, test_contact.mPosition + test_contact.mSurfaceNormal, Color::sCyan, 0.01f);
|
|
DebugRenderer::sInstance->DrawArrow(test_contact.mPosition, test_contact.mPosition + test_contact.mSurfaceNormal, Color::sCyan, 0.01f);
|
|
mShape->Draw(DebugRenderer::sInstance, GetCenterOfMassTransform(debug_pos, mRotation, mShape), Vec3::sReplicate(1.0f), Color::sCyan, false, true);
|
|
mShape->Draw(DebugRenderer::sInstance, GetCenterOfMassTransform(debug_pos, mRotation, mShape), Vec3::sReplicate(1.0f), Color::sCyan, false, true);
|
|
@@ -1147,7 +1147,7 @@ bool CharacterVirtual::WalkStairs(float inDeltaTime, Vec3Arg inStepUp, Vec3Arg i
|
|
new_position += down;
|
|
new_position += down;
|
|
|
|
|
|
// Move the character to the new location
|
|
// Move the character to the new location
|
|
- MoveToContact(new_position, contact, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inAllocator);
|
|
|
|
|
|
+ MoveToContact(new_position, contact, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inShapeFilter, inAllocator);
|
|
|
|
|
|
// Override ground state to 'on ground', it is possible that the contact normal is too steep, but in this case the inStepForwardTest has found a contact normal that is not too steep
|
|
// Override ground state to 'on ground', it is possible that the contact normal is too steep, but in this case the inStepForwardTest has found a contact normal that is not too steep
|
|
mGroundState = EGroundState::OnGround;
|
|
mGroundState = EGroundState::OnGround;
|
|
@@ -1155,12 +1155,12 @@ bool CharacterVirtual::WalkStairs(float inDeltaTime, Vec3Arg inStepUp, Vec3Arg i
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
-bool CharacterVirtual::StickToFloor(Vec3Arg inStepDown, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, TempAllocator &inAllocator)
|
|
|
|
|
|
+bool CharacterVirtual::StickToFloor(Vec3Arg inStepDown, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator)
|
|
{
|
|
{
|
|
// Try to find the floor
|
|
// Try to find the floor
|
|
Contact contact;
|
|
Contact contact;
|
|
IgnoredContactList dummy_ignored_contacts(inAllocator);
|
|
IgnoredContactList dummy_ignored_contacts(inAllocator);
|
|
- if (!GetFirstContactForSweep(mPosition, inStepDown, contact, dummy_ignored_contacts, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inAllocator))
|
|
|
|
|
|
+ if (!GetFirstContactForSweep(mPosition, inStepDown, contact, dummy_ignored_contacts, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inShapeFilter, inAllocator))
|
|
return false; // If no floor found, don't update our position
|
|
return false; // If no floor found, don't update our position
|
|
|
|
|
|
// Calculate new position
|
|
// Calculate new position
|
|
@@ -1176,16 +1176,16 @@ bool CharacterVirtual::StickToFloor(Vec3Arg inStepDown, const BroadPhaseLayerFil
|
|
#endif // JPH_DEBUG_RENDERER
|
|
#endif // JPH_DEBUG_RENDERER
|
|
|
|
|
|
// Move the character to the new location
|
|
// Move the character to the new location
|
|
- MoveToContact(new_position, contact, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inAllocator);
|
|
|
|
|
|
+ MoveToContact(new_position, contact, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inShapeFilter, inAllocator);
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
-void CharacterVirtual::ExtendedUpdate(float inDeltaTime, Vec3Arg inGravity, const ExtendedUpdateSettings &inSettings, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, TempAllocator &inAllocator)
|
|
|
|
|
|
+void CharacterVirtual::ExtendedUpdate(float inDeltaTime, Vec3Arg inGravity, const ExtendedUpdateSettings &inSettings, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator)
|
|
{
|
|
{
|
|
// Update the velocity
|
|
// Update the velocity
|
|
Vec3 desired_velocity = mLinearVelocity;
|
|
Vec3 desired_velocity = mLinearVelocity;
|
|
mLinearVelocity = CancelVelocityTowardsSteepSlopes(desired_velocity);
|
|
mLinearVelocity = CancelVelocityTowardsSteepSlopes(desired_velocity);
|
|
-
|
|
|
|
|
|
+
|
|
// Remember old position
|
|
// Remember old position
|
|
RVec3 old_position = mPosition;
|
|
RVec3 old_position = mPosition;
|
|
|
|
|
|
@@ -1193,7 +1193,7 @@ void CharacterVirtual::ExtendedUpdate(float inDeltaTime, Vec3Arg inGravity, cons
|
|
bool ground_to_air = IsSupported();
|
|
bool ground_to_air = IsSupported();
|
|
|
|
|
|
// Update the character position (instant, do not have to wait for physics update)
|
|
// Update the character position (instant, do not have to wait for physics update)
|
|
- Update(inDeltaTime, inGravity, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inAllocator);
|
|
|
|
|
|
+ Update(inDeltaTime, inGravity, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inShapeFilter, inAllocator);
|
|
|
|
|
|
// ... and that we got into air after
|
|
// ... and that we got into air after
|
|
if (IsSupported())
|
|
if (IsSupported())
|
|
@@ -1205,7 +1205,7 @@ void CharacterVirtual::ExtendedUpdate(float inDeltaTime, Vec3Arg inGravity, cons
|
|
// If we're not moving up, stick to the floor
|
|
// If we're not moving up, stick to the floor
|
|
float velocity = Vec3(mPosition - old_position).Dot(mUp) / inDeltaTime;
|
|
float velocity = Vec3(mPosition - old_position).Dot(mUp) / inDeltaTime;
|
|
if (velocity <= 1.0e-6f)
|
|
if (velocity <= 1.0e-6f)
|
|
- StickToFloor(inSettings.mStickToFloorStepDown, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inAllocator);
|
|
|
|
|
|
+ StickToFloor(inSettings.mStickToFloorStepDown, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inShapeFilter, inAllocator);
|
|
}
|
|
}
|
|
|
|
|
|
// If walk stairs enabled
|
|
// If walk stairs enabled
|
|
@@ -1252,7 +1252,7 @@ void CharacterVirtual::ExtendedUpdate(float inDeltaTime, Vec3Arg inGravity, cons
|
|
// Calculate the correct magnitude for the test vector
|
|
// Calculate the correct magnitude for the test vector
|
|
step_forward_test *= inSettings.mWalkStairsStepForwardTest;
|
|
step_forward_test *= inSettings.mWalkStairsStepForwardTest;
|
|
|
|
|
|
- WalkStairs(inDeltaTime, inSettings.mWalkStairsStepUp, step_forward, step_forward_test, inSettings.mWalkStairsStepDownExtra, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inAllocator);
|
|
|
|
|
|
+ WalkStairs(inDeltaTime, inSettings.mWalkStairsStepUp, step_forward, step_forward_test, inSettings.mWalkStairsStepDownExtra, inBroadPhaseLayerFilter, inObjectLayerFilter, inBodyFilter, inShapeFilter, inAllocator);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|