Fixed clipping of contacts against reference planes

This commit is contained in:
Diren D Bharwani 2023-03-01 21:30:00 +08:00
parent 0e3a84a06b
commit 2d2c8a1b20
8 changed files with 473 additions and 464 deletions

View File

@ -23,15 +23,39 @@
Transform Component:
Translate: {x: 0, y: 0, z: 0}
Rotate: {x: 0, y: 0, z: 0}
Scale: {x: 2, y: 1, z: 1}
Scale: {x: 1, y: 1, z: 1}
IsActive: true
Collider Component:
DrawColliders: false
Colliders:
- Is Trigger: false
Collision Tag: 1
Type: Box
Half Extents: {x: 1, y: 1, z: 1}
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0, z: 0}
Rotation Offset: {x: 0, y: 0, z: 0}
IsActive: true
Scripts: ~
- EID: 3
Name: Default
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: 0, y: 2, z: 0}
Rotate: {x: 0, y: 0.785398185, z: 0}
Scale: {x: 1, y: 1, z: 1}
IsActive: true
RigidBody Component:
Type: Static
Type: Dynamic
Auto Mass: false
Mass: .inf
Mass: 1
Drag: 0.00999999978
Angular Drag: 0.00999999978
Use Gravity: false
Use Gravity: true
Gravity Scale: 1
Interpolate: true
Sleeping Enabled: true
@ -56,44 +80,3 @@
Rotation Offset: {x: 0, y: 0, z: 0}
IsActive: true
Scripts: ~
- EID: 2
Name: Default
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: 1.14999998, y: 3, z: 0.550000012}
Rotate: {x: 0, y: 0, z: 0}
Scale: {x: 1, y: 1, z: 1}
IsActive: true
RigidBody Component:
Type: Dynamic
Auto Mass: false
Mass: 1
Drag: 0.00999999978
Angular Drag: 0.00999999978
Use Gravity: true
Gravity Scale: 0.25
Interpolate: true
Sleeping Enabled: true
Freeze Position X: false
Freeze Position Y: false
Freeze Position Z: false
Freeze Rotation X: false
Freeze Rotation Y: false
Freeze Rotation Z: false
IsActive: true
Collider Component:
DrawColliders: false
Colliders:
- Is Trigger: false
Collision Tag: 1
Type: Sphere
Radius: 1
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0, z: 0}
Rotation Offset: {x: 0, y: 0, z: 0}
IsActive: true
Scripts: ~

View File

@ -238,7 +238,7 @@ namespace SHADE
// Build plane equation
// Use first vertex to build the plane
const SHPlane FACE_PLANE { polyhedron.GetVertex(FACE.vertexIndices[0].index), polyhedron.GetNormal(i) };
const SHPlane FACE_PLANE { polyhedron.GetVertex(FACE.vertexIndices[0].index), -polyhedron.GetNormal(i) };
// Find signed distance of center to plane
const float SIGNED_DIST = FACE_PLANE.SignedDistance(CENTER);

View File

@ -68,8 +68,8 @@ namespace SHADE
const SHCollisionUtils::ShapeTransform TF_A = { SPHERE_A.GetWorldCentroid(), SPHERE_A.GetWorldOrientation() };
const SHCollisionUtils::ShapeTransform TF_B = { SPHERE_B.GetWorldCentroid(), SPHERE_B.GetWorldOrientation() };
const SHCollisionUtils::ShapeTransform INV_TF_A = TF_A.GetInverse();
const SHCollisionUtils::ShapeTransform INV_TF_B = TF_B.GetInverse();
// Only populate the manifold if there is a collision
@ -83,16 +83,16 @@ namespace SHADE
if (SHMath::CompareFloat(DISTANCE_BETWEEN_CENTERS_SQUARED, 0.0f))
{
manifold.normal = SHVec3::UnitY;
contact.localPointA = RADIUS_A * SHVec3::Rotate(manifold.normal, TF_A.GetInverse().orientation);
contact.localPointB = RADIUS_B * SHVec3::Rotate(manifold.normal, TF_B.GetInverse().orientation);
contact.localPointA = RADIUS_A * SHVec3::Rotate(manifold.normal, INV_TF_A.orientation);
contact.localPointB = RADIUS_B * SHVec3::Rotate(manifold.normal, INV_TF_B.orientation);
manifold.contacts[numContacts++] = contact;
}
else
{
manifold.normal = SHVec3::Normalise(A_TO_B);
contact.localPointA = RADIUS_A * SHVec3::Normalise(TF_A.GetInverse() * CENTER_B);
contact.localPointB = RADIUS_B * SHVec3::Normalise(TF_B.GetInverse() * CENTER_A);
contact.localPointA = RADIUS_A * SHVec3::Normalise(INV_TF_A * CENTER_B);
contact.localPointB = RADIUS_B * SHVec3::Normalise(INV_TF_B * CENTER_A);
manifold.contacts[numContacts++] = contact;

View File

@ -130,8 +130,8 @@ namespace SHADE
* Right: 1 (1,5,6,2) Normal: X
* Back: 2 (5,4,7,6) Normal: Z
* Left: 3 (4,0,3,7) Normal: -X
* Top: 4 (3,2,6,7) Normal: Y
* Bottom: 5 (4,5,1,0) Normal: -Y
* Bottom: 4 (0,4,5,1) Normal: -Y
* Top: 5 (2,6,7,3) Normal: Y
*
*/
@ -143,18 +143,18 @@ namespace SHADE
, SHVec3::UnitX
, SHVec3::UnitZ
, -SHVec3::UnitX
, SHVec3::UnitY
, -SHVec3::UnitY
, SHVec3::UnitY
};
const int32_t FACE_VERTICES[NUM_FACES][NUM_VERTICES_PER_FACE]
{
{ 0, 1, 2, 3 }
, { 5, 6, 2, 1 }
, { 5, 4, 7, 6 }
, { 0, 3, 7, 4 }
, { 1, 5, 6, 2 }
, { 4, 7, 6, 5 }
, { 4, 0, 3, 7 }
, { 0, 4, 5, 1 }
, { 2, 6, 7, 3 }
, { 5, 1, 0, 4 }
};
for (int i = 0; i < NUM_FACES; ++i)

View File

@ -52,18 +52,15 @@ namespace SHADE
, .normal = manifold.normal
};
const auto* SHAPE_A = manifold.shapeA;
const auto* SHAPE_B = manifold.shapeB;
const SHCollisionUtils::ShapeTransform TF_A = { SHAPE_A->GetWorldCentroid(), SHAPE_A->GetWorldOrientation() };
const SHCollisionUtils::ShapeTransform TF_B = { SHAPE_B->GetWorldCentroid(), SHAPE_B->GetWorldOrientation() };
for (uint32_t i = 0; i < manifold.numContacts; ++i)
{
const SHVec3 WORLD_POINT_A = TF_A * manifold.contacts[i].localPointA;
const SHVec3 WORLD_POINT_A = TF_B * manifold.contacts[i].localPointA;
const SHVec3 WORLD_POINT_B = TF_B * manifold.contacts[i].localPointB;
collisionEvent.contactPoints[i] = SHVec3::ClampedLerp(WORLD_POINT_A, WORLD_POINT_B, 0.5f);
collisionEvent.contactPoints[i] = WORLD_POINT_A;
}
collisionEvents.emplace_back(collisionEvent);
@ -92,12 +89,12 @@ namespace SHADE
for (uint32_t i = 0; i < manifold.numContacts; ++i)
{
// Contact position will be the middle of worldPointA & worldPointB
const SHVec3 WORLD_POINT_A = TF_A * manifold.contacts[i].localPointA;
const SHVec3 WORLD_POINT_A = TF_B * manifold.contacts[i].localPointA;
const SHVec3 WORLD_POINT_B = TF_B * manifold.contacts[i].localPointB;
const ContactInfo INFO
{
.position = SHVec3::ClampedLerp(WORLD_POINT_A, WORLD_POINT_B, 0.5f)
.position = WORLD_POINT_A
, .normal = manifold.normal
};

View File

@ -100,7 +100,6 @@ namespace SHADE
// Collision data
newConstraint.numContacts = manifold.numContacts;
newConstraint.normal = manifold.normal;
static constexpr size_t TANGENTS_SIZE = sizeof(SHVec3) * SHContact::NUM_TANGENTS;
@ -109,14 +108,14 @@ namespace SHADE
memcpy_s(newConstraint.tangents, TANGENTS_SIZE, manifold.tangents, TANGENTS_SIZE);
memcpy_s(newConstraint.contacts, CONTACTS_SIZE, manifold.contacts, CONTACTS_SIZE);
const SHCollisionUtils::ShapeTransform TF_A = { SHAPE_A->GetWorldCentroid(), SHAPE_A->GetWorldOrientation() };
const SHCollisionUtils::ShapeTransform TF_B = { SHAPE_B->GetWorldCentroid(), SHAPE_B->GetWorldOrientation() };
// Compute rA & rB for contacts with the local centroids
const SHVec3 LOCAL_COM_A = BODY_A ? BODY_A->localCentroid : SHVec3::Zero;
const SHVec3 LOCAL_COM_B = BODY_B ? BODY_B->localCentroid : SHVec3::Zero;
// Compute rA & rB for contacts
for (uint32_t i = 0; i < newConstraint.numContacts; ++i)
{
newConstraint.contacts[i].rA = (TF_A * newConstraint.contacts[i].localPointA) - newConstraint.centerOfMassA;
newConstraint.contacts[i].rB = (TF_B * newConstraint.contacts[i].localPointB) - newConstraint.centerOfMassB;
newConstraint.contacts[i].rA = newConstraint.contacts[i].localPointA - LOCAL_COM_A;
newConstraint.contacts[i].rB = newConstraint.contacts[i].localPointB - LOCAL_COM_B;
}
}

View File

@ -80,7 +80,7 @@ namespace SHADE
for (auto& contactPoint : CONTACT_POINTS)
{
const SHMatrix TRS = SHMatrix::Transform(contactPoint.position, SHQuaternion::Identity, SHVec3{ 0.1f });
debugDrawSystem->DrawSphere(TRS, CONTACT_COLOUR);
debugDrawSystem->DrawWireSphere(TRS, CONTACT_COLOUR);
debugDrawSystem->DrawLine(contactPoint.position, contactPoint.position + contactPoint.normal * 0.5f, CONTACT_COLOUR, true);
}
}