|
@@ -202,7 +202,7 @@ void CharacterVirtual::ContactCastCollector::AddHit(const ShapeCastResult &inRes
|
|
|
// Convert the hit result into a contact
|
|
|
sFillContactProperties(mCharacter, contact, body, mUp, mBaseOffset, *this, inResult);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
contact.mFraction = inResult.mFraction;
|
|
|
|
|
|
// Check if the contact that will make us penetrate more than the allowed tolerance
|
|
@@ -397,7 +397,7 @@ void CharacterVirtual::DetermineConstraints(TempContactList &inContacts, float i
|
|
|
// Next check if the angle is too steep and if it is add an additional constraint that holds the character back
|
|
|
if (IsSlopeTooSteep(c.mSurfaceNormal))
|
|
|
{
|
|
|
- // Only take planes that point up.
|
|
|
+ // Only take planes that point up.
|
|
|
// Note that we use the contact normal to allow for better sliding as the surface normal may be in the opposite direction of movement.
|
|
|
float dot = c.mContactNormal.Dot(mUp);
|
|
|
if (dot > 1.0e-3f) // Add a little slack, if the normal is perfectly horizontal we already have our vertical plane.
|
|
@@ -863,27 +863,35 @@ void CharacterVirtual::UpdateSupportingContact(bool inSkipContactVelocityCheck,
|
|
|
}
|
|
|
else if (num_sliding > 0)
|
|
|
{
|
|
|
- // If we're sliding we may actually be standing on multiple sliding contacts in such a way that we can't slide off, in this case we're also supported
|
|
|
-
|
|
|
- // Convert the contacts into constraints
|
|
|
- TempContactList contacts(mActiveContacts.begin(), mActiveContacts.end(), inAllocator);
|
|
|
- ConstraintList constraints(inAllocator);
|
|
|
- constraints.reserve(contacts.size() * 2);
|
|
|
- DetermineConstraints(contacts, mLastDeltaTime, constraints);
|
|
|
-
|
|
|
- // Solve the displacement using these constraints, this is used to check if we didn't move at all because we are supported
|
|
|
- Vec3 displacement;
|
|
|
- float time_simulated;
|
|
|
- IgnoredContactList ignored_contacts(inAllocator);
|
|
|
- ignored_contacts.reserve(contacts.size());
|
|
|
- SolveConstraints(-mUp, 1.0f, 1.0f, constraints, ignored_contacts, time_simulated, displacement, inAllocator);
|
|
|
-
|
|
|
- // If we're blocked then we're supported, otherwise we're sliding
|
|
|
- float min_required_displacement_sq = Square(0.6f * mLastDeltaTime);
|
|
|
- if (time_simulated < 0.001f || displacement.LengthSq() < min_required_displacement_sq)
|
|
|
- mGroundState = EGroundState::OnGround;
|
|
|
- else
|
|
|
+ if ((mLinearVelocity - deepest_contact->mLinearVelocity).Dot(mUp) > 1.0e-4f)
|
|
|
+ {
|
|
|
+ // We cannot be on ground if we're moving upwards relative to the ground
|
|
|
mGroundState = EGroundState::OnSteepGround;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // If we're sliding down, we may actually be standing on multiple sliding contacts in such a way that we can't slide off, in this case we're also supported
|
|
|
+
|
|
|
+ // Convert the contacts into constraints
|
|
|
+ TempContactList contacts(mActiveContacts.begin(), mActiveContacts.end(), inAllocator);
|
|
|
+ ConstraintList constraints(inAllocator);
|
|
|
+ constraints.reserve(contacts.size() * 2);
|
|
|
+ DetermineConstraints(contacts, mLastDeltaTime, constraints);
|
|
|
+
|
|
|
+ // Solve the displacement using these constraints, this is used to check if we didn't move at all because we are supported
|
|
|
+ Vec3 displacement;
|
|
|
+ float time_simulated;
|
|
|
+ IgnoredContactList ignored_contacts(inAllocator);
|
|
|
+ ignored_contacts.reserve(contacts.size());
|
|
|
+ SolveConstraints(-mUp, 1.0f, 1.0f, constraints, ignored_contacts, time_simulated, displacement, inAllocator);
|
|
|
+
|
|
|
+ // If we're blocked then we're supported, otherwise we're sliding
|
|
|
+ float min_required_displacement_sq = Square(0.6f * mLastDeltaTime);
|
|
|
+ if (time_simulated < 0.001f || displacement.LengthSq() < min_required_displacement_sq)
|
|
|
+ mGroundState = EGroundState::OnGround;
|
|
|
+ else
|
|
|
+ mGroundState = EGroundState::OnSteepGround;
|
|
|
+ }
|
|
|
}
|
|
|
else
|
|
|
{
|