Added syncing of physics materials & clear forces methods

This commit is contained in:
Diren D Bharwani 2022-11-14 18:38:32 +08:00
parent 9515fcca4f
commit 10335f3033
11 changed files with 99 additions and 99 deletions

View File

@ -177,9 +177,21 @@ namespace SHADE
{ {
dirty = true; dirty = true;
const auto* colliderComponent = SHComponentManager::GetComponent<SHColliderComponent>(entityID); const auto* COLLIDER = SHComponentManager::GetComponent<SHColliderComponent>(entityID);
auto* box = reinterpret_cast<SHBox*>(shape);
SHVec3 correctedHalfExtents = halfExtents;
// Get current relative halfExtents for error checking. 0 is ignored
const SHVec3& CURRENT_RELATIVE_EXTENTS = box->GetRelativeExtents();
for (size_t i = 0; i < SHVec3::SIZE; ++i)
{
if (SHMath::CompareFloat(halfExtents[i], 0.0f))
correctedHalfExtents[i] = CURRENT_RELATIVE_EXTENTS[i];
}
// Set the half extents relative to world scale // Set the half extents relative to world scale
const SHVec3 WORLD_EXTENTS = halfExtents * colliderComponent->GetScale() * 0.5f; const SHVec3 WORLD_EXTENTS = correctedHalfExtents * COLLIDER->GetScale() * 0.5f;
if (type != Type::BOX) if (type != Type::BOX)
{ {
@ -189,18 +201,24 @@ namespace SHADE
shape = new SHBox{ positionOffset, WORLD_EXTENTS }; shape = new SHBox{ positionOffset, WORLD_EXTENTS };
} }
auto* box = reinterpret_cast<SHBox*>(shape);
box->SetWorldExtents(WORLD_EXTENTS); box->SetWorldExtents(WORLD_EXTENTS);
box->SetRelativeExtents(halfExtents); box->SetRelativeExtents(correctedHalfExtents);
} }
void SHCollisionShape::SetBoundingSphere(float radius) void SHCollisionShape::SetBoundingSphere(float radius)
{ {
dirty = true; dirty = true;
const auto* colliderComponent = SHComponentManager::GetComponent<SHColliderComponent>(entityID); auto* sphere = reinterpret_cast<SHSphere*>(shape);
const auto* COLLIDER = SHComponentManager::GetComponent<SHColliderComponent>(entityID);
// Get current relative halfExtents for error checking. 0 is ignored
const float CURRENT_RELATIVE_RADIUS = sphere->GetRelativeRadius();
if (SHMath::CompareFloat(radius, 0.0f))
radius = CURRENT_RELATIVE_RADIUS;
// Set the radius relative to world scale // Set the radius relative to world scale
const SHVec3 WORLD_SCALE = colliderComponent->GetScale(); const SHVec3 WORLD_SCALE = COLLIDER->GetScale();
const float MAX_SCALE = SHMath::Max({ WORLD_SCALE.x, WORLD_SCALE.y, WORLD_SCALE.z }); const float MAX_SCALE = SHMath::Max({ WORLD_SCALE.x, WORLD_SCALE.y, WORLD_SCALE.z });
const float WORLD_RADIUS = radius * MAX_SCALE * 0.5f; const float WORLD_RADIUS = radius * MAX_SCALE * 0.5f;
@ -212,8 +230,8 @@ namespace SHADE
shape = new SHSphere{ positionOffset, WORLD_RADIUS }; shape = new SHSphere{ positionOffset, WORLD_RADIUS };
} }
auto* sphere = reinterpret_cast<SHSphere*>(shape);
sphere->SetWorldRadius(WORLD_RADIUS); sphere->SetWorldRadius(WORLD_RADIUS);
sphere->SetRelativeRadius(radius);
} }
void SHCollisionShape::SetIsTrigger(bool trigger) noexcept void SHCollisionShape::SetIsTrigger(bool trigger) noexcept

View File

@ -44,7 +44,7 @@ namespace SHADE
&& SHMath::CompareFloat(density, rhs.density); && SHMath::CompareFloat(density, rhs.density);
} }
bool SHPhysicsMaterial::operator!=(const SHPhysicsMaterial& rhs) const noexcept bool SHPhysicsMaterial::operator!=(const SHPhysicsMaterial& rhs) const noexcept
{ {
return !SHMath::CompareFloat(friction, rhs.friction) return !SHMath::CompareFloat(friction, rhs.friction)
|| !SHMath::CompareFloat(bounciness, rhs.bounciness) || !SHMath::CompareFloat(bounciness, rhs.bounciness)

View File

@ -302,6 +302,9 @@ namespace SHADE
{ {
static constexpr int FLAG_POS = 9; static constexpr int FLAG_POS = 9;
if (newMass < 0.0f)
return;
if (type != Type::DYNAMIC) if (type != Type::DYNAMIC)
{ {
SHLOG_WARNING("Cannot set mass of a non-dynamic object {}", GetEID()) SHLOG_WARNING("Cannot set mass of a non-dynamic object {}", GetEID())
@ -385,42 +388,62 @@ namespace SHADE
void SHRigidBodyComponent::AddForce(const SHVec3& force) const noexcept void SHRigidBodyComponent::AddForce(const SHVec3& force) const noexcept
{ {
system->AddForce(GetEID(), force); if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject)
physicsObject->GetRigidBody()->applyWorldForceAtCenterOfMass(force);
} }
void SHRigidBodyComponent::AddForceAtLocalPos(const SHVec3& force, const SHVec3& localPos) const noexcept void SHRigidBodyComponent::AddForceAtLocalPos(const SHVec3& force, const SHVec3& localPos) const noexcept
{ {
system->AddForceAtLocalPos(GetEID(), force, localPos); if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject)
physicsObject->GetRigidBody()->applyWorldForceAtLocalPosition(force, localPos);
} }
void SHRigidBodyComponent::AddForceAtWorldPos(const SHVec3& force, const SHVec3& worldPos) const noexcept void SHRigidBodyComponent::AddForceAtWorldPos(const SHVec3& force, const SHVec3& worldPos) const noexcept
{ {
system->AddForceAtWorldPos(GetEID(), force, worldPos); if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject)
physicsObject->GetRigidBody()->applyWorldForceAtWorldPosition(force, worldPos);
} }
void SHRigidBodyComponent::AddRelativeForce(const SHVec3& relativeForce) const noexcept void SHRigidBodyComponent::AddRelativeForce(const SHVec3& relativeForce) const noexcept
{ {
system->AddRelativeForce(GetEID(), relativeForce); if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject)
physicsObject->GetRigidBody()->applyLocalForceAtCenterOfMass(relativeForce);
} }
void SHRigidBodyComponent::AddRelativeForceAtLocalPos(const SHVec3& relativeForce, const SHVec3& localPos) const noexcept void SHRigidBodyComponent::AddRelativeForceAtLocalPos(const SHVec3& relativeForce, const SHVec3& localPos) const noexcept
{ {
system->AddRelativeForceAtLocalPos(GetEID(), relativeForce, localPos); if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject)
physicsObject->GetRigidBody()->applyLocalForceAtLocalPosition(relativeForce, localPos);
} }
void SHRigidBodyComponent::AddRelativeForceAtWorldPos(const SHVec3& relativeForce, const SHVec3& worldPos) const noexcept void SHRigidBodyComponent::AddRelativeForceAtWorldPos(const SHVec3& relativeForce, const SHVec3& worldPos) const noexcept
{ {
system->AddRelativeForceAtWorldPos(GetEID(), relativeForce, worldPos); if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject)
physicsObject->GetRigidBody()->applyLocalForceAtWorldPosition(relativeForce, worldPos);
} }
void SHRigidBodyComponent::AddTorque(const SHVec3& torque) const noexcept void SHRigidBodyComponent::AddTorque(const SHVec3& torque) const noexcept
{ {
system->AddTorque(GetEID(), torque); if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject)
physicsObject->GetRigidBody()->applyWorldTorque(torque);
} }
void SHRigidBodyComponent::AddRelativeTorque(const SHVec3& relativeTorque) const noexcept void SHRigidBodyComponent::AddRelativeTorque(const SHVec3& relativeTorque) const noexcept
{ {
system->AddRelativeTorque(GetEID(), relativeTorque); if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject)
physicsObject->GetRigidBody()->applyLocalTorque(relativeTorque);
}
void SHRigidBodyComponent::ClearForces() const noexcept
{
if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject)
physicsObject->GetRigidBody()->resetForce();
}
void SHRigidBodyComponent::ClearTorque() const noexcept
{
if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject)
physicsObject->GetRigidBody()->resetTorque();
} }
} // namespace SHADE } // namespace SHADE

View File

@ -125,14 +125,15 @@ namespace SHADE
void AddForce (const SHVec3& force) const noexcept; void AddForce (const SHVec3& force) const noexcept;
void AddForceAtLocalPos (const SHVec3& force, const SHVec3& localPos) const noexcept; void AddForceAtLocalPos (const SHVec3& force, const SHVec3& localPos) const noexcept;
void AddForceAtWorldPos (const SHVec3& force, const SHVec3& worldPos) const noexcept; void AddForceAtWorldPos (const SHVec3& force, const SHVec3& worldPos) const noexcept;
void AddRelativeForce (const SHVec3& relativeForce) const noexcept; void AddRelativeForce (const SHVec3& relativeForce) const noexcept;
void AddRelativeForceAtLocalPos (const SHVec3& relativeForce, const SHVec3& localPos) const noexcept; void AddRelativeForceAtLocalPos (const SHVec3& relativeForce, const SHVec3& localPos) const noexcept;
void AddRelativeForceAtWorldPos (const SHVec3& relativeForce, const SHVec3& worldPos) const noexcept; void AddRelativeForceAtWorldPos (const SHVec3& relativeForce, const SHVec3& worldPos) const noexcept;
void AddTorque (const SHVec3& torque) const noexcept; void AddTorque (const SHVec3& torque) const noexcept;
void AddRelativeTorque (const SHVec3& relativeTorque) const noexcept; void AddRelativeTorque (const SHVec3& relativeTorque) const noexcept;
void ClearForces () const noexcept;
void ClearTorque () const noexcept;
private: private:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */

View File

@ -277,23 +277,24 @@ namespace SHADE
if (!rp3dBody->isActive()) if (!rp3dBody->isActive())
return; return;
int index = 0; const int NUM_SHAPES = static_cast<int>(component.collisionShapes.size());
for (auto& collisionShape : component.collisionShapes) for (int i = 0; i < NUM_SHAPES; ++i)
{ {
auto& collisionShape = component.collisionShapes[i];
if (!collisionShape.dirty) if (!collisionShape.dirty)
continue; continue;
switch (collisionShape.GetType()) switch (collisionShape.GetType())
{ {
case SHCollisionShape::Type::BOX: syncBoxShape(index, collisionShape); break; case SHCollisionShape::Type::BOX: syncBoxShape(i, collisionShape); break;
case SHCollisionShape::Type::SPHERE: syncSphereShape(index, collisionShape); break; case SHCollisionShape::Type::SPHERE: syncSphereShape(i, collisionShape); break;
default: break; default: break;
} }
// TODO(Diren): Update Material syncMaterial(i, collisionShape);
collisionShape.dirty = false; collisionShape.dirty = false;
++index;
} }
} }
@ -301,6 +302,14 @@ namespace SHADE
/* Private Function Member Definitions */ /* Private Function Member Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHPhysicsObject::syncMaterial(int colliderIndex, SHCollisionShape& collisionShape) const noexcept
{
auto& rp3dMaterial = rp3dBody->getCollider(colliderIndex)->getMaterial();
rp3dMaterial.setFrictionCoefficient(collisionShape.GetFriction());
rp3dMaterial.setBounciness(collisionShape.GetBounciness());
rp3dMaterial.setMassDensity(collisionShape.GetDensity());
}
void SHPhysicsObject::addBoxShape(SHCollisionShape& boxShape) const noexcept void SHPhysicsObject::addBoxShape(SHCollisionShape& boxShape) const noexcept
{ {
const rp3d::Transform OFFSETS const rp3d::Transform OFFSETS

View File

@ -96,6 +96,8 @@ namespace SHADE
/* Function Members */ /* Function Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void syncMaterial (int colliderIndex, SHCollisionShape& collisionShape) const noexcept;
// Box Shapes // Box Shapes
void addBoxShape (SHCollisionShape& boxShape) const noexcept; void addBoxShape (SHCollisionShape& boxShape) const noexcept;

View File

@ -62,7 +62,7 @@ namespace SHADE
return collisionListener.GetTriggerInfoContainer(); return collisionListener.GetTriggerInfoContainer();
} }
const SHPhysicsObject* const SHPhysicsSystem::GetPhysicsObject(EntityID eid) noexcept const SHPhysicsObject* SHPhysicsSystem::GetPhysicsObject(EntityID eid) noexcept
{ {
return objectManager.GetPhysicsObject(eid); return objectManager.GetPhysicsObject(eid);
} }
@ -223,55 +223,6 @@ namespace SHADE
#endif #endif
} }
void SHPhysicsSystem::AddForce(EntityID eid, const SHVec3& force) noexcept
{
const auto* PHYSICS_OBJECT = objectManager.GetPhysicsObject(eid);
PHYSICS_OBJECT->GetRigidBody()->applyWorldForceAtCenterOfMass(force);
}
void SHPhysicsSystem::AddForceAtLocalPos(EntityID eid, const SHVec3& force, const SHVec3& localPos) noexcept
{
const auto* PHYSICS_OBJECT = objectManager.GetPhysicsObject(eid);
PHYSICS_OBJECT->GetRigidBody()->applyWorldForceAtLocalPosition(force, localPos);
}
void SHPhysicsSystem::AddForceAtWorldPos(EntityID eid, const SHVec3& force, const SHVec3& worldPos) noexcept
{
const auto* PHYSICS_OBJECT = objectManager.GetPhysicsObject(eid);
PHYSICS_OBJECT->GetRigidBody()->applyWorldForceAtWorldPosition(force, worldPos);
}
void SHPhysicsSystem::AddRelativeForce(EntityID eid, const SHVec3& relativeForce) noexcept
{
const auto* PHYSICS_OBJECT = objectManager.GetPhysicsObject(eid);
PHYSICS_OBJECT->GetRigidBody()->applyLocalForceAtCenterOfMass(relativeForce);
}
void SHPhysicsSystem::AddRelativeForceAtLocalPos(EntityID eid, const SHVec3& relativeForce, const SHVec3& localPos) noexcept
{
const auto* PHYSICS_OBJECT = objectManager.GetPhysicsObject(eid);
PHYSICS_OBJECT->GetRigidBody()->applyLocalForceAtLocalPosition(relativeForce, localPos);
}
void SHPhysicsSystem::AddRelativeForceAtWorldPos(EntityID eid, const SHVec3& relativeForce, const SHVec3& worldPos) noexcept
{
const auto* PHYSICS_OBJECT = objectManager.GetPhysicsObject(eid);
PHYSICS_OBJECT->GetRigidBody()->applyLocalForceAtWorldPosition(relativeForce, worldPos);
}
void SHPhysicsSystem::AddTorque(EntityID eid, const SHVec3& torque) noexcept
{
const auto* PHYSICS_OBJECT = objectManager.GetPhysicsObject(eid);
PHYSICS_OBJECT->GetRigidBody()->applyWorldTorque(torque);
}
void SHPhysicsSystem::AddRelativeTorque(EntityID eid, const SHVec3& relativeTorque) noexcept
{
const auto* PHYSICS_OBJECT = objectManager.GetPhysicsObject(eid);
PHYSICS_OBJECT->GetRigidBody()->applyLocalTorque(relativeTorque);
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Private Function Member Definitions */ /* Private Function Member Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/

View File

@ -61,7 +61,7 @@ namespace SHADE
[[nodiscard]] const std::vector<SHCollisionInfo>& GetAllCollisionInfo () const noexcept; [[nodiscard]] const std::vector<SHCollisionInfo>& GetAllCollisionInfo () const noexcept;
[[nodiscard]] const std::vector<SHCollisionInfo>& GetAllTriggerInfo () const noexcept; [[nodiscard]] const std::vector<SHCollisionInfo>& GetAllTriggerInfo () const noexcept;
[[nodiscard]] const SHPhysicsObject* const GetPhysicsObject (EntityID eid) noexcept; [[nodiscard]] const SHPhysicsObject* GetPhysicsObject (EntityID eid) noexcept;
[[nodiscard]] const SHPhysicsObjectManager::PhysicsObjectEntityMap& GetPhysicsObjects () const noexcept; [[nodiscard]] const SHPhysicsObjectManager::PhysicsObjectEntityMap& GetPhysicsObjects () const noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Setter Functions */ /* Setter Functions */
@ -79,25 +79,13 @@ namespace SHADE
void ForceUpdate (); void ForceUpdate ();
// Specific Handling for Collision Shapes as they are not under the Component System // Specific Handling for Collision Shapes as they are not under the Component System.
// This is done as events need to be sent out.
// TODO(Diren): Consider using a static method through the ColliderComponent.
void AddCollisionShape (EntityID eid, int shapeIndex); void AddCollisionShape (EntityID eid, int shapeIndex);
void RemoveCollisionShape (EntityID eid, int shapeIndex); void RemoveCollisionShape (EntityID eid, int shapeIndex);
// Forces are applied from components here. These functions should only be invoked during play (through scripts)
// Thus there is no need to check for an editor.
void AddForce (EntityID eid, const SHVec3& force) noexcept;
void AddForceAtLocalPos (EntityID eid, const SHVec3& force, const SHVec3& localPos) noexcept;
void AddForceAtWorldPos (EntityID eid, const SHVec3& force, const SHVec3& worldPos) noexcept;
void AddRelativeForce (EntityID eid, const SHVec3& relativeForce) noexcept;
void AddRelativeForceAtLocalPos (EntityID eid, const SHVec3& relativeForce, const SHVec3& localPos) noexcept;
void AddRelativeForceAtWorldPos (EntityID eid, const SHVec3& relativeForce, const SHVec3& worldPos) noexcept;
void AddTorque (EntityID eid, const SHVec3& torque) noexcept;
void AddRelativeTorque (EntityID eid, const SHVec3& relativeTorque) noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* System Routines */ /* System Routines */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -13,11 +13,14 @@
// Primary Header // Primary Header
#include "SHPhysicsSystem.h" #include "SHPhysicsSystem.h"
// Project Headers // Project Headers
#include "ECS_Base/Managers/SHEntityManager.h"
#include "ECS_Base/Managers/SHSystemManager.h" #include "ECS_Base/Managers/SHSystemManager.h"
#include "Editor/SHEditor.h" #include "Editor/SHEditor.h"
#include "Scene/SHSceneManager.h" #include "Scene/SHSceneManager.h"
#include "Scripting/SHScriptEngine.h" #include "Scripting/SHScriptEngine.h"
#include "Input/SHInputManager.h"
namespace SHADE namespace SHADE
{ {
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -139,14 +142,6 @@ namespace SHADE
physicsSystem->worldState.world->update(static_cast<rp3d::decimal>(FIXED_DT)); physicsSystem->worldState.world->update(static_cast<rp3d::decimal>(FIXED_DT));
// Clear all forces of every body in the scene after each update
for (auto& physicsObject : physicsSystem->objectManager.physicsObjects | std::views::values)
{
auto* rp3dRigidBody = physicsObject.GetRigidBody();
rp3dRigidBody->resetForce();
rp3dRigidBody->resetTorque();
}
accumulatedTime -= FIXED_DT; accumulatedTime -= FIXED_DT;
++count; ++count;
} }

View File

@ -194,6 +194,12 @@ namespace SHADE
{ {
return Convert::ToCLI(GetNativeComponent()->GetForce()); return Convert::ToCLI(GetNativeComponent()->GetForce());
} }
void RigidBody::ClearForces()
{
GetNativeComponent()->ClearForces();
}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Torque Functions */ /* Torque Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -212,4 +218,9 @@ namespace SHADE
return Convert::ToCLI(GetNativeComponent()->GetTorque()); return Convert::ToCLI(GetNativeComponent()->GetTorque());
} }
void RigidBody::ClearTorque()
{
GetNativeComponent()->ClearTorque();
}
} }

View File

@ -146,6 +146,7 @@ namespace SHADE
void AddRelativeForceAtWorldPos(Vector3 relativeForce, Vector3 worldPos); void AddRelativeForceAtWorldPos(Vector3 relativeForce, Vector3 worldPos);
Vector3 GetForce(); Vector3 GetForce();
void ClearForces();
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Torque Functions */ /* Torque Functions */
@ -154,6 +155,7 @@ namespace SHADE
void AddRelativeTorque(Vector3 relativeForce); void AddRelativeTorque(Vector3 relativeForce);
Vector3 GetTorque(); Vector3 GetTorque();
void ClearTorque();
}; };
} }