Implemented a custom physics engine #316

Merged
direnbharwani merged 95 commits from SHPhysics into main 2023-01-23 15:55:45 +08:00
2 changed files with 52 additions and 10 deletions
Showing only changes of commit 33ef5e0d3d - Show all commits

View File

@ -15,6 +15,7 @@
#include "SHContactManager.h" #include "SHContactManager.h"
// Project Headers // Project Headers
#include "Math/SHMathHelpers.h"
#include "Physics/Collision/Narrowphase/SHCollisionDispatch.h" #include "Physics/Collision/Narrowphase/SHCollisionDispatch.h"
namespace SHADE namespace SHADE
@ -69,12 +70,12 @@ namespace SHADE
for (auto manifoldPair = manifolds.begin(); manifoldPair != manifolds.end();) for (auto manifoldPair = manifolds.begin(); manifoldPair != manifolds.end();)
{ {
// Test collision of every manifold. // Test collision of every manifold.
SHManifold& oldManifold = manifoldPair->second; SHManifold& manifold = manifoldPair->second;
SHManifold newManifold = oldManifold; SHManifold oldManifold = manifold;
const bool IS_COLLIDING = SHCollisionDispatcher::Collide(newManifold, *newManifold.A, *newManifold.B); const bool IS_COLLIDING = SHCollisionDispatcher::Collide(manifold, *manifold.A, *manifold.B);
auto& collisionState = newManifold.state; auto& collisionState = oldManifold.state;
updateCollisionState(IS_COLLIDING, collisionState); updateCollisionState(IS_COLLIDING, collisionState);
const bool IS_INVALID = collisionState == SHCollisionState::INVALID; const bool IS_INVALID = collisionState == SHCollisionState::INVALID;
@ -84,7 +85,7 @@ namespace SHADE
continue; continue;
} }
updateManifold(oldManifold, newManifold); updateManifold(manifold, oldManifold);
++manifoldPair; ++manifoldPair;
} }
@ -169,15 +170,56 @@ namespace SHADE
} }
} }
void SHContactManager::updateManifold(SHManifold& oldManifold, SHManifold& newManifold) noexcept void SHContactManager::updateManifold(SHManifold& manifold, const SHManifold& oldManifold) noexcept
{ {
oldManifold.state = newManifold.state; manifold.state = oldManifold.state;
// Early out since exiting a collision does not require an update beyond updating the state // Early out since exiting a collision does not require an update beyond updating the state
if (newManifold.state == SHCollisionState::EXIT) if (manifold.state == SHCollisionState::EXIT)
return; return;
const SHVec3& NORMAL = manifold.normal;
SHVec3& tangent0 = manifold.tangents[0];
SHVec3& tangent1 = manifold.tangents[1];
const SHVec3& OLD_TANGENT_0 = oldManifold.tangents[0];
const SHVec3& OLD_TANGENT_1 = oldManifold.tangents[1];
// Compute tangents
if (std::fabs(NORMAL.x) >= SHMath::EULER_CONSTANT)
tangent0 = SHVec3{ NORMAL.y, -NORMAL.x, 0.0f };
else
tangent0 = SHVec3{ 0.0f, NORMAL.z, -NORMAL.y };
tangent0 = SHVec3::Normalise(tangent0);
tangent1 = SHVec3::Cross(NORMAL, tangent0);
// Accumulate impulses
for (uint32_t i = 0; i < manifold.numContacts; ++i)
{
SHContact& contact = manifold.contacts[i];
// Reset impulses
contact.normalImpulse = 0.0f;
contact.tangentImpulse[0] = contact.tangentImpulse[1] = 0.0f;
for (uint32_t j = 0; j < oldManifold.numContacts; ++j)
{
const SHContact& OLD_CONTACT = oldManifold.contacts[j];
if (OLD_CONTACT.featurePair.key != contact.featurePair.key)
continue;
// If contact features persists, re-project old solution
contact.normalImpulse = OLD_CONTACT.normalImpulse;
const SHVec3 FRICTION_FORCE = OLD_TANGENT_0 * OLD_CONTACT.tangentImpulse[0] + OLD_TANGENT_1 * OLD_CONTACT.tangentImpulse[1];
contact.tangentImpulse[0] = SHVec3::Dot(FRICTION_FORCE, tangent0);
contact.tangentImpulse[1] = SHVec3::Dot(FRICTION_FORCE, tangent1);
break;
}
}
} }
} // namespace SHADE } // namespace SHADE

View File

@ -95,8 +95,8 @@ namespace SHADE
/* Member Functions */ /* Member Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
static void updateCollisionState (bool isColliding, SHCollisionState& state) noexcept; static void updateCollisionState (bool isColliding, SHCollisionState& state) noexcept;
static void updateManifold (SHManifold& oldManifold, SHManifold& newManifold) noexcept; static void updateManifold (SHManifold& manifold, const SHManifold& newManifold) noexcept;
// Removal Helpers // Removal Helpers