From 1b2ff7f4a28526646e990c248e50c02689258971 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Tue, 15 Nov 2022 23:57:38 +0800 Subject: [PATCH 1/9] Expanded Collision Shape C# Interface --- SHADE_Managed/src/Components/Collider.cxx | 135 +++++++++++++++++----- SHADE_Managed/src/Components/Collider.h++ | 6 +- SHADE_Managed/src/Components/Collider.hxx | 76 ++++++++++-- 3 files changed, 179 insertions(+), 38 deletions(-) diff --git a/SHADE_Managed/src/Components/Collider.cxx b/SHADE_Managed/src/Components/Collider.cxx index 1a53f9e1..41910d66 100644 --- a/SHADE_Managed/src/Components/Collider.cxx +++ b/SHADE_Managed/src/Components/Collider.cxx @@ -20,7 +20,7 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { /*---------------------------------------------------------------------------------*/ - /* ColliderBound - Constructors */ + /* CollisionShape - Constructors */ /*---------------------------------------------------------------------------------*/ CollisionShape::CollisionShape(int arrayIdx, Entity attachedEntity) : arrayIndex { arrayIdx } @@ -28,102 +28,183 @@ namespace SHADE {} /*---------------------------------------------------------------------------------*/ - /* ColliderBound - Setter Functions */ + /* CollisionShape - Properties */ + /*---------------------------------------------------------------------------------*/ + + bool CollisionShape::IsTrigger::get() + { + return getNativeCollisionShape().IsTrigger(); + } + + void CollisionShape::IsTrigger::set(bool value) + { + getNativeCollisionShape().SetIsTrigger(value); + } + + Vector3 CollisionShape::PositionOffset::get() + { + return Convert::ToCLI(getNativeCollisionShape().GetPositionOffset()); + } + + void CollisionShape::PositionOffset::set(Vector3 value) + { + getNativeCollisionShape().SetPositionOffset(Convert::ToNative(value)); + } + + Vector3 CollisionShape::RotationOffset::get() + { + return Convert::ToCLI(getNativeCollisionShape().GetRotationOffset()); + } + + void CollisionShape::RotationOffset::set(Vector3 value) + { + getNativeCollisionShape().SetRotationOffset(Convert::ToNative(value)); + } + + float CollisionShape::Friction::get() + { + return getNativeCollisionShape().GetFriction(); + } + + void CollisionShape::Friction::set(float value) + { + getNativeCollisionShape().SetFriction(value); + } + + float CollisionShape::Bounciness::get() + { + return getNativeCollisionShape().GetBounciness(); + } + + void CollisionShape::Bounciness::set(float value) + { + getNativeCollisionShape().SetBounciness(value); + } + + float CollisionShape::Density::get() + { + return getNativeCollisionShape().GetDensity(); + } + + void CollisionShape::Density::set(float value) + { + getNativeCollisionShape().SetDensity(value); + } + + /*---------------------------------------------------------------------------------*/ + /* CollisionShape - helper Functions */ /*---------------------------------------------------------------------------------*/ void CollisionShape::updateArrayIndex(int index) { arrayIndex = index; } + SHCollisionShape& SHADE::CollisionShape::getNativeCollisionShape() + { + SHColliderComponent* collider = SHComponentManager::GetComponent_s(entity); + if (!collider) + throw gcnew System::InvalidOperationException("Unable to retrieve Collider component!"); + + try + { + auto& shape = collider->GetCollisionShape(arrayIndex); + return shape; + } + catch (std::invalid_argument&) + { + throw gcnew System::IndexOutOfRangeException("Attempted to retrieve out of range CollisionShape!"); + } + } + /*---------------------------------------------------------------------------------*/ - /* BoxColliderBound - Constructors */ + /* BoxCollider - Constructors */ /*---------------------------------------------------------------------------------*/ BoxCollider::BoxCollider(int arrayIdx, Entity attachedEntity) : CollisionShape { arrayIndex, attachedEntity } {} /*---------------------------------------------------------------------------------*/ - /* BoxColliderBound - Properties */ + /* BoxCollider - Properties */ /*---------------------------------------------------------------------------------*/ Vector3 BoxCollider::Center::get() { - return Convert::ToCLI(getNativeBoundObject().GetCenter()); + return Convert::ToCLI(getNativeCollisionShape().GetCenter()); } void BoxCollider::Center::set(Vector3 value) { - getNativeBoundObject().SetCenter(Convert::ToNative(value)); + getNativeCollisionShape().SetCenter(Convert::ToNative(value)); } Vector3 BoxCollider::HalfExtents::get() { - return Convert::ToCLI(getNativeBoundObject().GetWorldExtents()); + return Convert::ToCLI(getNativeCollisionShape().GetWorldExtents()); } void BoxCollider::HalfExtents::set(Vector3 value) { - getNativeBoundObject().SetWorldExtents(Convert::ToNative(value)); + getNativeCollisionShape().SetWorldExtents(Convert::ToNative(value)); } Vector3 BoxCollider::Min::get() { - return Convert::ToCLI(getNativeBoundObject().GetMin()); + return Convert::ToCLI(getNativeCollisionShape().GetMin()); } void BoxCollider::Min::set(Vector3 value) { - getNativeBoundObject().SetMin(Convert::ToNative(value)); + getNativeCollisionShape().SetMin(Convert::ToNative(value)); } Vector3 BoxCollider::Max::get() { - return Convert::ToCLI(getNativeBoundObject().GetMax()); + return Convert::ToCLI(getNativeCollisionShape().GetMax()); } void BoxCollider::Max::set(Vector3 value) { - getNativeBoundObject().SetMax(Convert::ToNative(value)); + getNativeCollisionShape().SetMax(Convert::ToNative(value)); } /*---------------------------------------------------------------------------------*/ - /* BoxColliderBound - Usage Functions */ + /* BoxCollider - Usage Functions */ /*---------------------------------------------------------------------------------*/ bool BoxCollider::TestPoint(Vector3 point) { - return getNativeBoundObject().TestPoint(Convert::ToNative(point)); + return getNativeCollisionShape().TestPoint(Convert::ToNative(point)); } bool BoxCollider::Raycast(Ray ray, float maxDistance) { - return getNativeBoundObject().Raycast(Convert::ToNative(ray), maxDistance); + return getNativeCollisionShape().Raycast(Convert::ToNative(ray), maxDistance); } /*---------------------------------------------------------------------------------*/ - /* BoxColliderBound - Properties */ + /* SphereCollider - Properties */ /*---------------------------------------------------------------------------------*/ Vector3 SphereCollider::Center::get() { - return Convert::ToCLI(getNativeBoundObject().GetCenter()); + return Convert::ToCLI(getNativeCollisionShape().GetCenter()); } void SphereCollider::Center::set(Vector3 value) { - getNativeBoundObject().SetCenter(Convert::ToNative(value)); + getNativeCollisionShape().SetCenter(Convert::ToNative(value)); } float SphereCollider::Radius::get() { - return getNativeBoundObject().GetWorldRadius(); + return getNativeCollisionShape().GetWorldRadius(); } void SphereCollider::Radius::set(float value) { - getNativeBoundObject().SetWorldRadius(value); + getNativeCollisionShape().SetWorldRadius(value); } /*---------------------------------------------------------------------------------*/ - /* SphereColliderBound - Usage Functions */ + /* SphereCollider - Usage Functions */ /*---------------------------------------------------------------------------------*/ bool SphereCollider::TestPoint(Vector3 point) { - return getNativeBoundObject().TestPoint(Convert::ToNative(point)); + return getNativeCollisionShape().TestPoint(Convert::ToNative(point)); } bool SphereCollider::Raycast(Ray ray, float maxDistance) { - return getNativeBoundObject().Raycast(Convert::ToNative(ray), maxDistance); + return getNativeCollisionShape().Raycast(Convert::ToNative(ray), maxDistance); } /*---------------------------------------------------------------------------------*/ - /* SphereColliderBound - Constructors */ + /* SphereCollider - Constructors */ /*---------------------------------------------------------------------------------*/ SphereCollider::SphereCollider(int arrayIndex, Entity attachedEntity) : CollisionShape{ arrayIndex, attachedEntity } @@ -154,7 +235,7 @@ namespace SHADE } /*---------------------------------------------------------------------------------*/ - /* Collider - ColliderBound Functions */ + /* Collider - Collider Functions */ /*---------------------------------------------------------------------------------*/ CollisionShape^ Collider::GetCollisionShape(int index) { @@ -166,7 +247,7 @@ namespace SHADE // Check if valid if (index < 0 || index >= subColliderList->Count) - throw gcnew System::ArgumentException("[Collider] Invalid index for Collider Bound retrieval."); + throw gcnew System::ArgumentException("[Collider] Invalid index for Collision Shape retrieval."); // Return the bound return subColliderList[index]; @@ -217,7 +298,7 @@ namespace SHADE { collidersList->Remove(wr); } - SAFE_NATIVE_CALL_END("Collider.OnColliderBoundChanged") + SAFE_NATIVE_CALL_END("Collider.OnCollisionShapeChanged") } void Collider::updateSubColliderList() diff --git a/SHADE_Managed/src/Components/Collider.h++ b/SHADE_Managed/src/Components/Collider.h++ index 6e165619..8ea648aa 100644 --- a/SHADE_Managed/src/Components/Collider.h++ +++ b/SHADE_Managed/src/Components/Collider.h++ @@ -19,7 +19,7 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { template - CollisionShapeType& SHADE::CollisionShape::getNativeBoundObject() + CollisionShapeType& SHADE::CollisionShape::getNativeCollisionShape() { SHColliderComponent* collider = SHComponentManager::GetComponent_s(entity); if (!collider) @@ -29,13 +29,13 @@ namespace SHADE { auto& shape = collider->GetCollisionShape(arrayIndex); if (shape.GetType() != SHCollisionShape::Type::BOX) - throw gcnew System::InvalidOperationException("Attempted to retrieve invalid ColliderBound."); + throw gcnew System::InvalidOperationException("Attempted to retrieve invalid CollisionShape."); return reinterpret_cast(shape); } catch (std::invalid_argument&) { - throw gcnew System::IndexOutOfRangeException("Attempted to retrieve out of range ColliderBound!"); + throw gcnew System::IndexOutOfRangeException("Attempted to retrieve out of range CollisionShape!"); } } } diff --git a/SHADE_Managed/src/Components/Collider.hxx b/SHADE_Managed/src/Components/Collider.hxx index 1711e8b9..a649483f 100644 --- a/SHADE_Managed/src/Components/Collider.hxx +++ b/SHADE_Managed/src/Components/Collider.hxx @@ -30,6 +30,61 @@ namespace SHADE public ref class CollisionShape abstract { public: + /*-----------------------------------------------------------------------------*/ + /* Properties */ + /*-----------------------------------------------------------------------------*/ + + /// + /// Whether or not this CollisionShape is a trigger. + /// + property bool IsTrigger + { + bool get(); + void set(bool value); + } + /// + /// The positional offset of this collision shape from the transform's position. + /// + property Vector3 PositionOffset + { + Vector3 get(); + void set(Vector3 value); + } + /// + /// The rotational offset of this collision shape from the transform's rotation. + /// + property Vector3 RotationOffset + { + Vector3 get(); + void set(Vector3 value); + } + + // TODO(Diren): Swap this to Physics Materials once asset implementation for that is done + /// + /// The frictional coefficient of the shape. Clamped between 0 and 1. + /// + property float Friction + { + float get(); + void set(float value); + } + /// + /// The bounciness factor of the shape. Clamped between 0 and 1. + /// + property float Bounciness + { + float get(); + void set(float value); + } + /// + /// The mass density of this shape. Cannot be negative. + /// + property float Density + { + float get(); + void set(float value); + } + /*-----------------------------------------------------------------------------*/ /* Usage Functions */ /*-----------------------------------------------------------------------------*/ @@ -56,20 +111,25 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Data Members */ /*-----------------------------------------------------------------------------*/ - int arrayIndex; // Index into the colliders vector on the native object - Entity entity; // Entity holding the collider component that this collider bounds is on + int arrayIndex; // Index into the colliders vector on the native object + Entity entity; // Entity holding the collider component that this collider bounds is on /*-----------------------------------------------------------------------------*/ /* Helper Functions */ /*-----------------------------------------------------------------------------*/ template - CollisionShapeType& getNativeBoundObject(); + CollisionShapeType& getNativeCollisionShape(); internal: /*-----------------------------------------------------------------------------*/ /* Setter Functions */ /*-----------------------------------------------------------------------------*/ void updateArrayIndex(int index); + + /*-----------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------*/ + SHCollisionShape& getNativeCollisionShape(); }; /// @@ -205,18 +265,18 @@ namespace SHADE /* Usage Functions */ /*-----------------------------------------------------------------------------*/ /// - /// Retrieves a ColliderBound at the specified index in the ColliderBound list. + /// Retrieves a CollisionShape at the specified index in the CollisionShapes list. /// /// Index to retrieve a ColliderBound from. /// ColliderBound for the specified index. CollisionShape^ GetCollisionShape(int index); /// - /// Retrieves a ColliderBound at the specified index in the ColliderBound list + /// Retrieves a CollisionShape at the specified index in the CollisionShapes list /// and casts it to the appropriate type. /// - /// Type of the ColliderBound to cast to. - /// Index to retrieve a ColliderBound from. - /// ColliderBound for the specified index. + /// Type of the CollisionShape to cast to. + /// Index to retrieve a CollisionShape from. + /// CollisionShape for the specified index. generic where T:CollisionShape T GetCollisionShape(int index); From f172ccb74430cd26f24d1246bdd9d2d932f6aa79 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Tue, 15 Nov 2022 23:58:08 +0800 Subject: [PATCH 2/9] Added Automass and Sleep check for Rigidbodies --- .../Interface/SHRigidBodyComponent.cpp | 66 +++++++--- .../Physics/Interface/SHRigidBodyComponent.h | 18 ++- .../Physics/PhysicsObject/SHPhysicsObject.cpp | 14 +- .../src/Physics/System/SHPhysicsSystem.cpp | 123 ++++-------------- .../src/Physics/System/SHPhysicsSystem.h | 36 +++-- .../System/SHPhysicsSystemRoutines.cpp | 90 +++++++++++++ 6 files changed, 203 insertions(+), 144 deletions(-) diff --git a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp index 765decd8..e892a5aa 100644 --- a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp +++ b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp @@ -29,7 +29,6 @@ namespace SHADE SHRigidBodyComponent::SHRigidBodyComponent() noexcept : type { Type::DYNAMIC } - , interpolate { true } , flags { 0 } , dirtyFlags { std::numeric_limits::max() } , mass { 1.0f } @@ -40,6 +39,7 @@ namespace SHADE // Initialise default flags flags |= 1U << 0; // Gravity set to true flags |= 1U << 1; // Sleeping allowed + flags |= 1U << 8; // Interpolate by default } /*-----------------------------------------------------------------------------------*/ @@ -60,7 +60,16 @@ namespace SHADE bool SHRigidBodyComponent::IsInterpolating() const noexcept { - return interpolate; + static constexpr int FLAG_POS = 8; + return flags & (1U << FLAG_POS); + } + + bool SHRigidBodyComponent::GetIsSleeping() const noexcept + { + if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject) + return physicsObject->GetRigidBody()->isSleeping(); + + return false; } SHRigidBodyComponent::Type SHRigidBodyComponent::GetType() const noexcept @@ -68,21 +77,6 @@ namespace SHADE return type; } - float SHRigidBodyComponent::GetMass() const noexcept - { - return mass; - } - - float SHRigidBodyComponent::GetDrag() const noexcept - { - return drag; - } - - float SHRigidBodyComponent::GetAngularDrag() const noexcept - { - return angularDrag; - } - bool SHRigidBodyComponent::GetFreezePositionX() const noexcept { static constexpr int FLAG_POS = 2; @@ -119,6 +113,27 @@ namespace SHADE return flags & (1U << FLAG_POS); } + bool SHRigidBodyComponent::GetAutoMass() const noexcept + { + static constexpr int FLAG_POS = 9; + return flags & (1U << FLAG_POS); + } + + float SHRigidBodyComponent::GetMass() const noexcept + { + return mass; + } + + float SHRigidBodyComponent::GetDrag() const noexcept + { + return drag; + } + + float SHRigidBodyComponent::GetAngularDrag() const noexcept + { + return angularDrag; + } + SHVec3 SHRigidBodyComponent::GetForce() const noexcept { if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject) @@ -295,9 +310,19 @@ namespace SHADE void SHRigidBodyComponent::SetInterpolate(bool allowInterpolation) noexcept { - interpolate = allowInterpolation; + static constexpr int FLAG_POS = 8; + allowInterpolation ? flags |= 1U << FLAG_POS : flags &= ~(1U << FLAG_POS); } + void SHRigidBodyComponent::SetAutoMass(bool autoMass) noexcept + { + static constexpr int FLAG_POS = 9; + autoMass ? flags |= 1U << FLAG_POS : flags &= ~(1U << FLAG_POS); + + dirtyFlags |= 1U << FLAG_POS; + } + + void SHRigidBodyComponent::SetMass(float newMass) noexcept { static constexpr int FLAG_POS = 9; @@ -313,6 +338,9 @@ namespace SHADE dirtyFlags |= 1U << FLAG_POS; mass = newMass; + + // Turn off automass + flags &= ~(1U << FLAG_POS); } void SHRigidBodyComponent::SetDrag(float newDrag) noexcept @@ -467,6 +495,8 @@ RTTR_REGISTRATION .property("Angular Drag" , &SHRigidBodyComponent::GetAngularDrag , &SHRigidBodyComponent::SetAngularDrag ) .property("Use Gravity" , &SHRigidBodyComponent::IsGravityEnabled , &SHRigidBodyComponent::SetGravityEnabled ) .property("Interpolate" , &SHRigidBodyComponent::IsInterpolating , &SHRigidBodyComponent::SetInterpolate ) + .property("Sleeping Enabled" , &SHRigidBodyComponent::IsAllowedToSleep , &SHRigidBodyComponent::SetIsAllowedToSleep) + .property("Auto Mass" , &SHRigidBodyComponent::GetAutoMass , &SHRigidBodyComponent::SetAutoMass ) .property("Freeze Position X" , &SHRigidBodyComponent::GetFreezePositionX , &SHRigidBodyComponent::SetFreezePositionX ) .property("Freeze Position Y" , &SHRigidBodyComponent::GetFreezePositionY , &SHRigidBodyComponent::SetFreezePositionY ) .property("Freeze Position Z" , &SHRigidBodyComponent::GetFreezePositionZ , &SHRigidBodyComponent::SetFreezePositionZ ) diff --git a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h index f7062f96..658c60e1 100644 --- a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h +++ b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h @@ -71,19 +71,23 @@ namespace SHADE [[nodiscard]] bool IsAllowedToSleep () const noexcept; [[nodiscard]] bool IsInterpolating () const noexcept; + [[nodiscard]] bool GetIsSleeping () const noexcept; + [[nodiscard]] Type GetType () const noexcept; - [[nodiscard]] float GetMass () const noexcept; - [[nodiscard]] float GetDrag () const noexcept; - [[nodiscard]] float GetAngularDrag () const noexcept; - + [[nodiscard]] bool GetFreezePositionX () const noexcept; [[nodiscard]] bool GetFreezePositionY () const noexcept; [[nodiscard]] bool GetFreezePositionZ () const noexcept; - [[nodiscard]] bool GetFreezeRotationX () const noexcept; [[nodiscard]] bool GetFreezeRotationY () const noexcept; [[nodiscard]] bool GetFreezeRotationZ () const noexcept; + [[nodiscard]] bool GetAutoMass () const noexcept; + + [[nodiscard]] float GetMass () const noexcept; + [[nodiscard]] float GetDrag () const noexcept; + [[nodiscard]] float GetAngularDrag () const noexcept; + [[nodiscard]] SHVec3 GetForce () const noexcept; [[nodiscard]] SHVec3 GetTorque () const noexcept; [[nodiscard]] SHVec3 GetLinearVelocity () const noexcept; @@ -108,6 +112,7 @@ namespace SHADE void SetFreezeRotationY (bool freezeRotationY) noexcept; void SetFreezeRotationZ (bool freezeRotationZ) noexcept; void SetInterpolate (bool allowInterpolation) noexcept; + void SetAutoMass (bool autoMass) noexcept; void SetMass (float newMass) noexcept; void SetDrag (float newDrag) noexcept; @@ -144,8 +149,7 @@ namespace SHADE Type type; - bool interpolate; - uint8_t flags; // aZ aY aX lZ lY lX slp g + uint16_t flags; // 0 0 0 0 0 0 am ip aZ aY aX lZ lY lX slp g uint16_t dirtyFlags; // 0 0 0 0 aD d m t aZ aY aX lZ lY lX slp g float mass; diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp index a52d3899..eb94aecb 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp @@ -245,9 +245,17 @@ namespace SHADE } case 9: // Mass { - rp3dBody->setMass(component.mass); - rp3dBody->updateLocalCenterOfMassFromColliders(); - rp3dBody->updateLocalInertiaTensorFromColliders(); + if (component.GetAutoMass()) + { + rp3dBody->updateMassPropertiesFromColliders(); + component.mass = rp3dBody->getMass(); + } + else + { + rp3dBody->setMass(component.mass); + rp3dBody->updateLocalCenterOfMassFromColliders(); + rp3dBody->updateLocalInertiaTensorFromColliders(); + } break; } diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp index 33ba88e7..50590e04 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp @@ -154,14 +154,32 @@ namespace SHADE auto* rigidBodyComponent = SHComponentManager::GetComponent_s(entityID); auto* colliderComponent = SHComponentManager::GetComponent_s(entityID); - postUpdateSyncTransforms - ( - physicsObject - , transformComponent - , rigidBodyComponent - , colliderComponent - , 1.0 // We use 1.0 here to avoid any interpolation - ); + const auto& CURRENT_TF = physicsObject.GetRigidBody()->getTransform(); + const auto& RENDER_POS = CURRENT_TF.getPosition(); + const auto& RENDER_ROT = CURRENT_TF.getOrientation(); + + // Cache transform + physicsObject.prevTransform = CURRENT_TF; + + // Sync with physics components + if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive(entityID)) + { + rigidBodyComponent->position = RENDER_POS; + rigidBodyComponent->orientation = RENDER_ROT; + } + + if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive(entityID)) + { + colliderComponent->position = RENDER_POS; + colliderComponent->orientation = RENDER_ROT; + } + + // Set transform for rendering + if (transformComponent) + { + transformComponent->SetWorldPosition(RENDER_POS); + transformComponent->SetWorldOrientation(RENDER_ROT); + } } } @@ -337,93 +355,4 @@ namespace SHADE return onStopEvent->handle; } - void SHPhysicsSystem::preUpdateSyncTransform - ( - SHPhysicsObject& physicsObject - , SHTransformComponent* transformComponent - , SHRigidBodyComponent* rigidBodyComponent - , SHColliderComponent* colliderComponent - ) noexcept - { - if (!transformComponent) - return; - - const SHVec3& WORLD_POS = transformComponent->GetWorldPosition(); - const SHQuaternion& WORLD_ROT = transformComponent->GetWorldOrientation(); - const SHVec3& WORLD_SCL = transformComponent->GetWorldScale(); - - const rp3d::Transform RP3D_TRANSFORM { WORLD_POS, WORLD_ROT }; - physicsObject.GetRigidBody()->setTransform(RP3D_TRANSFORM); - - if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive(physicsObject.entityID)) - { - rigidBodyComponent->position = WORLD_POS; - rigidBodyComponent->orientation = WORLD_ROT; - } - - if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive(physicsObject.entityID)) - { - colliderComponent->position = WORLD_POS; - colliderComponent->orientation = WORLD_ROT; - colliderComponent->scale = WORLD_SCL; - - colliderComponent->RecomputeCollisionShapes(); - } - } - - void SHPhysicsSystem::postUpdateSyncTransforms - ( - SHPhysicsObject& physicsObject - , SHTransformComponent* transformComponent - , SHRigidBodyComponent* rigidBodyComponent - , SHColliderComponent* colliderComponent - , double interpolationFactor - ) noexcept - { - const rp3d::Transform& CURRENT_TF = physicsObject.GetRigidBody()->getTransform(); - auto renderPos = CURRENT_TF.getPosition(); - auto renderRot = CURRENT_TF.getOrientation(); - - // Cache transforms - if (physicsObject.GetRigidBody()->isActive()) - physicsObject.prevTransform = CURRENT_TF; - - // Sync with rigid bodies - if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive(physicsObject.entityID)) - { - // Skip static bodies - if (rigidBodyComponent->GetType() == SHRigidBodyComponent::Type::STATIC) - return; - - // Check if transform should be interpolated - if (rigidBodyComponent->IsInterpolating()) - { - // Interpolate transforms between current and predicted next transform - - const rp3d::Transform PREV_TF = physicsObject.prevTransform; - const rp3d::Transform INTERPOLATED_TF = rp3d::Transform::interpolateTransforms(PREV_TF, CURRENT_TF, static_cast(interpolationFactor)); - - renderPos = INTERPOLATED_TF.getPosition(); - renderRot = INTERPOLATED_TF.getOrientation(); - } - - rigidBodyComponent->position = CURRENT_TF.getPosition(); - rigidBodyComponent->orientation = CURRENT_TF.getOrientation(); - } - - // Sync with colliders - if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive(physicsObject.entityID)) - { - colliderComponent->position = CURRENT_TF.getPosition(); - colliderComponent->orientation = CURRENT_TF.getOrientation(); - } - - // Set transform for rendering - if (transformComponent) - { - transformComponent->SetWorldPosition(renderPos); - transformComponent->SetWorldOrientation(renderRot); - } - } - } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h index 3da7094b..3e6cd622 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h @@ -113,6 +113,23 @@ namespace SHADE void syncRigidBodyActive (EntityID eid, SHPhysicsObject& physicsObject) const noexcept; void syncColliderActive (EntityID eid, SHPhysicsObject& physicsObject) const noexcept; static void syncOnPlay (EntityID eid, SHPhysicsObject& physicsObject) noexcept; + + static void preUpdateSyncTransform + ( + SHPhysicsObject& physicsObject + , SHTransformComponent* transformComponent + , SHRigidBodyComponent* rigidBodyComponent + , SHColliderComponent* colliderComponent + ) noexcept; + + static void postUpdateSyncTransforms + ( + SHPhysicsObject& physicsObject + , SHTransformComponent* transformComponent + , SHRigidBodyComponent* rigidBodyComponent + , SHColliderComponent* colliderComponent + , double interpolationFactor + ) noexcept; }; class SH_API PhysicsFixedUpdate final : public SHFixedSystemRoutine @@ -178,24 +195,5 @@ namespace SHADE SHEventHandle onPlay (SHEventPtr onPlayEvent); SHEventHandle onStop (SHEventPtr onStopEvent); - - - static void preUpdateSyncTransform - ( - SHPhysicsObject& physicsObject - , SHTransformComponent* transformComponent - , SHRigidBodyComponent* rigidBodyComponent - , SHColliderComponent* colliderComponent - ) noexcept; - - static void postUpdateSyncTransforms - ( - SHPhysicsObject& physicsObject - , SHTransformComponent* transformComponent - , SHRigidBodyComponent* rigidBodyComponent - , SHColliderComponent* colliderComponent - , double interpolationFactor - ) noexcept; - }; } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp index 3e56ca14..f4719056 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp @@ -262,4 +262,94 @@ namespace SHADE if (colliderComponent) physicsObject.SyncColliders(*colliderComponent); } + + void SHPhysicsSystem::PhysicsPreUpdate::preUpdateSyncTransform + ( + SHPhysicsObject& physicsObject + , SHTransformComponent* transformComponent + , SHRigidBodyComponent* rigidBodyComponent + , SHColliderComponent* colliderComponent + ) noexcept + { + if (!transformComponent) + return; + + const SHVec3& WORLD_POS = transformComponent->GetWorldPosition(); + const SHQuaternion& WORLD_ROT = transformComponent->GetWorldOrientation(); + const SHVec3& WORLD_SCL = transformComponent->GetWorldScale(); + + const rp3d::Transform RP3D_TRANSFORM { WORLD_POS, WORLD_ROT }; + physicsObject.GetRigidBody()->setTransform(RP3D_TRANSFORM); + physicsObject.prevTransform = RP3D_TRANSFORM; + + if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive(physicsObject.entityID)) + { + rigidBodyComponent->position = WORLD_POS; + rigidBodyComponent->orientation = WORLD_ROT; + } + + if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive(physicsObject.entityID)) + { + colliderComponent->position = WORLD_POS; + colliderComponent->orientation = WORLD_ROT; + colliderComponent->scale = WORLD_SCL; + + colliderComponent->RecomputeCollisionShapes(); + } + } + + void SHPhysicsSystem::PhysicsPreUpdate::postUpdateSyncTransforms + ( + SHPhysicsObject& physicsObject + , SHTransformComponent* transformComponent + , SHRigidBodyComponent* rigidBodyComponent + , SHColliderComponent* colliderComponent + , double interpolationFactor + ) noexcept + { + const rp3d::Transform& CURRENT_TF = physicsObject.GetRigidBody()->getTransform(); + auto renderPos = CURRENT_TF.getPosition(); + auto renderRot = CURRENT_TF.getOrientation(); + + // Cache transforms + if (physicsObject.GetRigidBody()->isActive()) + physicsObject.prevTransform = CURRENT_TF; + + // Sync with rigid bodies + if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive(physicsObject.entityID)) + { + // Skip static bodies + if (rigidBodyComponent->GetType() == SHRigidBodyComponent::Type::STATIC) + return; + + // Check if transform should be interpolated + if (rigidBodyComponent->IsInterpolating()) + { + // Interpolate transforms between current and predicted next transform + + const rp3d::Transform PREV_TF = physicsObject.prevTransform; + const rp3d::Transform INTERPOLATED_TF = rp3d::Transform::interpolateTransforms(PREV_TF, CURRENT_TF, static_cast(interpolationFactor)); + + renderPos = INTERPOLATED_TF.getPosition(); + renderRot = INTERPOLATED_TF.getOrientation(); + } + + rigidBodyComponent->position = CURRENT_TF.getPosition(); + rigidBodyComponent->orientation = CURRENT_TF.getOrientation(); + } + + // Sync with colliders + if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive(physicsObject.entityID)) + { + colliderComponent->position = CURRENT_TF.getPosition(); + colliderComponent->orientation = CURRENT_TF.getOrientation(); + } + + // Set transform for rendering + if (transformComponent) + { + transformComponent->SetWorldPosition(renderPos); + transformComponent->SetWorldOrientation(renderRot); + } + } } // namespace SHADE \ No newline at end of file From a9f77d666c2dc88512bbd02d4313e460f2e6bcf7 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Wed, 16 Nov 2022 00:04:56 +0800 Subject: [PATCH 3/9] Fixed compile error --- .../src/Physics/System/SHPhysicsSystem.h | 24 ++++++++++++------- .../System/SHPhysicsSystemRoutines.cpp | 2 +- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h index 3e6cd622..9638e05c 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h @@ -121,15 +121,6 @@ namespace SHADE , SHRigidBodyComponent* rigidBodyComponent , SHColliderComponent* colliderComponent ) noexcept; - - static void postUpdateSyncTransforms - ( - SHPhysicsObject& physicsObject - , SHTransformComponent* transformComponent - , SHRigidBodyComponent* rigidBodyComponent - , SHColliderComponent* colliderComponent - , double interpolationFactor - ) noexcept; }; class SH_API PhysicsFixedUpdate final : public SHFixedSystemRoutine @@ -162,6 +153,21 @@ namespace SHADE /*-------------------------------------------------------------------------------*/ void Execute(double dt) noexcept override; + + private: + + /*-------------------------------------------------------------------------------*/ + /* Function Members */ + /*-------------------------------------------------------------------------------*/ + + static void postUpdateSyncTransforms + ( + SHPhysicsObject& physicsObject + , SHTransformComponent* transformComponent + , SHRigidBodyComponent* rigidBodyComponent + , SHColliderComponent* colliderComponent + , double interpolationFactor + ) noexcept; }; private: diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp index f4719056..9d860bf9 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp @@ -298,7 +298,7 @@ namespace SHADE } } - void SHPhysicsSystem::PhysicsPreUpdate::postUpdateSyncTransforms + void SHPhysicsSystem::PhysicsPostUpdate::postUpdateSyncTransforms ( SHPhysicsObject& physicsObject , SHTransformComponent* transformComponent From 39a8ca131f783a0634a7e9ac7cbced2aa59f8864 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 17 Nov 2022 00:11:55 +0800 Subject: [PATCH 4/9] Fixed Collision & Trigger Messages not being cleared on deactivating objects --- .../src/Physics/Collision/SHCollisionListener.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/SHADE_Engine/src/Physics/Collision/SHCollisionListener.cpp b/SHADE_Engine/src/Physics/Collision/SHCollisionListener.cpp index e8379b09..f16303f4 100644 --- a/SHADE_Engine/src/Physics/Collision/SHCollisionListener.cpp +++ b/SHADE_Engine/src/Physics/Collision/SHCollisionListener.cpp @@ -16,6 +16,7 @@ // Project Headers #include "Physics/PhysicsObject/SHPhysicsObject.h" #include "Physics/System/SHPhysicsSystem.h" +#include "Scene/SHSceneManager.h" /*-------------------------------------------------------------------------------------*/ /* Local Helper Functions */ @@ -80,10 +81,15 @@ namespace SHADE { for (auto eventIter = container.begin(); eventIter != container.end();) { - const bool CLEAR_EVENT = eventIter->GetCollisionState() == SHCollisionInfo::State::EXIT - || eventIter->GetCollisionState() == SHCollisionInfo::State::INVALID; + const SHCollisionInfo& C_INFO = *eventIter; - if (CLEAR_EVENT) + const bool CLEAR_EVENT = C_INFO.GetCollisionState() == SHCollisionInfo::State::EXIT + || C_INFO.GetCollisionState() == SHCollisionInfo::State::INVALID; + + const bool INACTIVE_OBJECT = !SHSceneManager::CheckNodeAndComponentsActive(C_INFO.GetEntityA()) + || !SHSceneManager::CheckNodeAndComponentsActive(C_INFO.GetEntityB()); + + if (CLEAR_EVENT || INACTIVE_OBJECT) eventIter = container.erase(eventIter); else ++eventIter; From 8f9fedff4151e16f5540886e890e82559dc0c1ac Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 17 Nov 2022 01:39:05 +0800 Subject: [PATCH 5/9] Added sleeping debug info to Rigidbody Inspector --- .../src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 79891b82..895237ad 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -290,6 +290,7 @@ namespace SHADE { SHEditorWidgets::DragVec3("Force", { "X", "Y", "Z" }, [component] {return component->GetForce(); }, [](SHVec3 const& value) {}, false, "Force", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly); SHEditorWidgets::DragVec3("Torque", { "X", "Y", "Z" }, [component] {return component->GetTorque(); }, [](SHVec3 const& value) {}, false, "Torque", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly); + SHEditorWidgets::CheckBox("Is Asleep", [component] {return component->GetIsSleeping(); }, [](bool value) {}, "If the Rigid Body is asleep"); } } From 72888945079268a1b4992b6fbb4647c8a43f0a8a Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 17 Nov 2022 10:42:45 +0800 Subject: [PATCH 6/9] Fixed bug where adding colliders would fail to maintain previous collider sizes --- .../src/Physics/Interface/SHCollisionShape.cpp | 6 ++++++ .../src/Physics/PhysicsObject/SHPhysicsObject.cpp | 15 +++++++++++++-- SHADE_Engine/src/Physics/SHPhysicsWorld.h | 4 ++-- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp b/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp index e63895d5..14743845 100644 --- a/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp +++ b/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp @@ -304,6 +304,9 @@ namespace SHADE const auto* RHS_BOX = reinterpret_cast(rhs); shape = new SHBox{ positionOffset, RHS_BOX->GetWorldExtents() }; + auto* lhsBox = reinterpret_cast(shape); + lhsBox->SetRelativeExtents(RHS_BOX->GetRelativeExtents()); + break; } case Type::SPHERE: @@ -311,6 +314,9 @@ namespace SHADE const auto* RHS_SPHERE = reinterpret_cast(rhs); shape = new SHSphere{ positionOffset, RHS_SPHERE->GetWorldRadius() }; + auto* lhsSphere = reinterpret_cast(shape); + lhsSphere->SetRelativeRadius(RHS_SPHERE->GetRelativeRadius()); + break; } default: break; diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp index eb94aecb..67ace078 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp @@ -109,14 +109,25 @@ namespace SHADE { // TODO(Diren): Add more collider shapes - case SHCollisionShape::Type::BOX: addBoxShape(collisionShape); break; - case SHCollisionShape::Type::SPHERE: addSphereShape(collisionShape); break; + case SHCollisionShape::Type::BOX: + { + addBoxShape(collisionShape); + break; + } + + case SHCollisionShape::Type::SPHERE: + { + addSphereShape(collisionShape); + break; + } default: break; } rp3dBody->updateLocalCenterOfMassFromColliders(); rp3dBody->updateLocalInertiaTensorFromColliders(); + SyncColliders(*colliderComponent); + return index; } diff --git a/SHADE_Engine/src/Physics/SHPhysicsWorld.h b/SHADE_Engine/src/Physics/SHPhysicsWorld.h index 091ae062..c5152c44 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsWorld.h +++ b/SHADE_Engine/src/Physics/SHPhysicsWorld.h @@ -38,8 +38,8 @@ namespace SHADE /*-------------------------------------------------------------------------------*/ SHVec3 gravity = SHVec3{ 0.0f, -9.81f, 0.0f }; - uint16_t numVelocitySolverIterations = 15; - uint16_t numPositionSolverIterations = 8; + uint16_t numVelocitySolverIterations = 10; + uint16_t numPositionSolverIterations = 5; bool sleepingEnabled = true; }; From 18218443ec857cd8f275802021466c459f13c98b Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 17 Nov 2022 12:20:28 +0800 Subject: [PATCH 7/9] Fixed a bug --- SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp index 67ace078..67172d8e 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp @@ -126,8 +126,6 @@ namespace SHADE rp3dBody->updateLocalCenterOfMassFromColliders(); rp3dBody->updateLocalInertiaTensorFromColliders(); - SyncColliders(*colliderComponent); - return index; } From 360c55fa2bb80e43b002e43f40353f72b7aba413 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 17 Nov 2022 12:27:00 +0800 Subject: [PATCH 8/9] Disabled automass on rigid bodies --- .../Interface/SHRigidBodyComponent.cpp | 25 +++++++++---------- .../Physics/Interface/SHRigidBodyComponent.h | 4 +-- .../Physics/PhysicsObject/SHPhysicsObject.cpp | 16 ++++++------ 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp index e892a5aa..28b6f842 100644 --- a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp +++ b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp @@ -113,11 +113,11 @@ namespace SHADE return flags & (1U << FLAG_POS); } - bool SHRigidBodyComponent::GetAutoMass() const noexcept - { - static constexpr int FLAG_POS = 9; - return flags & (1U << FLAG_POS); - } + //bool SHRigidBodyComponent::GetAutoMass() const noexcept + //{ + // static constexpr int FLAG_POS = 9; + // return flags & (1U << FLAG_POS); + //} float SHRigidBodyComponent::GetMass() const noexcept { @@ -314,14 +314,13 @@ namespace SHADE allowInterpolation ? flags |= 1U << FLAG_POS : flags &= ~(1U << FLAG_POS); } - void SHRigidBodyComponent::SetAutoMass(bool autoMass) noexcept - { - static constexpr int FLAG_POS = 9; - autoMass ? flags |= 1U << FLAG_POS : flags &= ~(1U << FLAG_POS); - - dirtyFlags |= 1U << FLAG_POS; - } + //void SHRigidBodyComponent::SetAutoMass(bool autoMass) noexcept + //{ + // static constexpr int FLAG_POS = 9; + // autoMass ? flags |= 1U << FLAG_POS : flags &= ~(1U << FLAG_POS); + // dirtyFlags |= 1U << FLAG_POS; + //} void SHRigidBodyComponent::SetMass(float newMass) noexcept { @@ -496,7 +495,7 @@ RTTR_REGISTRATION .property("Use Gravity" , &SHRigidBodyComponent::IsGravityEnabled , &SHRigidBodyComponent::SetGravityEnabled ) .property("Interpolate" , &SHRigidBodyComponent::IsInterpolating , &SHRigidBodyComponent::SetInterpolate ) .property("Sleeping Enabled" , &SHRigidBodyComponent::IsAllowedToSleep , &SHRigidBodyComponent::SetIsAllowedToSleep) - .property("Auto Mass" , &SHRigidBodyComponent::GetAutoMass , &SHRigidBodyComponent::SetAutoMass ) + //.property("Auto Mass" , &SHRigidBodyComponent::GetAutoMass , &SHRigidBodyComponent::SetAutoMass ) .property("Freeze Position X" , &SHRigidBodyComponent::GetFreezePositionX , &SHRigidBodyComponent::SetFreezePositionX ) .property("Freeze Position Y" , &SHRigidBodyComponent::GetFreezePositionY , &SHRigidBodyComponent::SetFreezePositionY ) .property("Freeze Position Z" , &SHRigidBodyComponent::GetFreezePositionZ , &SHRigidBodyComponent::SetFreezePositionZ ) diff --git a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h index 658c60e1..d5204d94 100644 --- a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h +++ b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h @@ -82,7 +82,7 @@ namespace SHADE [[nodiscard]] bool GetFreezeRotationY () const noexcept; [[nodiscard]] bool GetFreezeRotationZ () const noexcept; - [[nodiscard]] bool GetAutoMass () const noexcept; + //[[nodiscard]] bool GetAutoMass () const noexcept; [[nodiscard]] float GetMass () const noexcept; [[nodiscard]] float GetDrag () const noexcept; @@ -112,7 +112,7 @@ namespace SHADE void SetFreezeRotationY (bool freezeRotationY) noexcept; void SetFreezeRotationZ (bool freezeRotationZ) noexcept; void SetInterpolate (bool allowInterpolation) noexcept; - void SetAutoMass (bool autoMass) noexcept; + //void SetAutoMass (bool autoMass) noexcept; void SetMass (float newMass) noexcept; void SetDrag (float newDrag) noexcept; diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp index 67172d8e..0a0ff201 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp @@ -254,17 +254,17 @@ namespace SHADE } case 9: // Mass { - if (component.GetAutoMass()) - { - rp3dBody->updateMassPropertiesFromColliders(); - component.mass = rp3dBody->getMass(); - } - else - { + //if (component.GetAutoMass()) + //{ + // rp3dBody->updateMassPropertiesFromColliders(); + // component.mass = rp3dBody->getMass(); + //} + //else + //{ rp3dBody->setMass(component.mass); rp3dBody->updateLocalCenterOfMassFromColliders(); rp3dBody->updateLocalInertiaTensorFromColliders(); - } + //} break; } From b3fbfce56f2407a136ef77ec582eb947a70ef1fd Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 17 Nov 2022 12:58:01 +0800 Subject: [PATCH 9/9] FIxed debug draw for offset colliders --- SHADE_Engine/src/Math/Geometry/SHBox.cpp | 2 +- SHADE_Engine/src/Math/Geometry/SHBox.h | 14 ++--- .../System/SHPhysicsDebugDrawSystem.cpp | 57 ++++++++++++------- .../Physics/System/SHPhysicsDebugDrawSystem.h | 25 ++++++-- 4 files changed, 62 insertions(+), 36 deletions(-) diff --git a/SHADE_Engine/src/Math/Geometry/SHBox.cpp b/SHADE_Engine/src/Math/Geometry/SHBox.cpp index cf094a9d..a52cf0d2 100644 --- a/SHADE_Engine/src/Math/Geometry/SHBox.cpp +++ b/SHADE_Engine/src/Math/Geometry/SHBox.cpp @@ -1,5 +1,5 @@ /**************************************************************************************** - * \file SHBoundingBox.cpp + * \file SHBox.cpp * \author Diren D Bharwani, diren.dbharwani, 390002520 * \brief Implementation for a 3-Dimensional Axis Aligned Bounding Box * diff --git a/SHADE_Engine/src/Math/Geometry/SHBox.h b/SHADE_Engine/src/Math/Geometry/SHBox.h index 0ea950ab..19c80bd2 100644 --- a/SHADE_Engine/src/Math/Geometry/SHBox.h +++ b/SHADE_Engine/src/Math/Geometry/SHBox.h @@ -1,5 +1,5 @@ /**************************************************************************************** - * \file SHBoundingBox.h + * \file SHBox.h * \author Diren D Bharwani, diren.dbharwani, 390002520 * \brief Interface for a 3-Dimensional Axis Aligned Bounding Box * @@ -79,17 +79,17 @@ namespace SHADE [[nodiscard]] bool TestPoint (const SHVec3& point) noexcept override; [[nodiscard]] bool Raycast (const SHRay& ray, float& distance) noexcept override; - [[nodiscard]] bool Contains (const SHBox& rhs) const noexcept; - [[nodiscard]] float Volume () const noexcept; - [[nodiscard]] float SurfaceArea () const noexcept; + [[nodiscard]] bool Contains (const SHBox& rhs) const noexcept; + [[nodiscard]] float Volume () const noexcept; + [[nodiscard]] float SurfaceArea () const noexcept; /*---------------------------------------------------------------------------------*/ /* Static Function Members */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] static SHBox Combine (const SHBox& lhs, const SHBox& rhs) noexcept; - [[nodiscard]] static bool Intersect (const SHBox& lhs, const SHBox& rhs) noexcept; - [[nodiscard]] static SHBox BuildFromBoxes (const SHBox* boxes, size_t numBoxes) noexcept; + [[nodiscard]] static SHBox Combine (const SHBox& lhs, const SHBox& rhs) noexcept; + [[nodiscard]] static bool Intersect (const SHBox& lhs, const SHBox& rhs) noexcept; + [[nodiscard]] static SHBox BuildFromBoxes (const SHBox* boxes, size_t numBoxes) noexcept; [[nodiscard]] static SHBox BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept; private: diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp index 44875289..7ccfb225 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp @@ -24,7 +24,7 @@ namespace SHADE /* Static Data Member Definitions */ /*-----------------------------------------------------------------------------------*/ - const SHPhysicsDebugDrawSystem::DebugDrawFunction SHPhysicsDebugDrawSystem::drawFunctions[SHPhysicsDebugDrawSystem::NUM_FLAGS] = + const SHPhysicsDebugDrawSystem::DebugDrawFunction SHPhysicsDebugDrawSystem::drawFunctions[NUM_FLAGS] = { SHPhysicsDebugDrawSystem::drawColliders , SHPhysicsDebugDrawSystem::drawColliderAABBs @@ -33,6 +33,8 @@ namespace SHADE , SHPhysicsDebugDrawSystem::drawContactNormals }; + SHVec3 SHPhysicsDebugDrawSystem::boxVertices[NUM_BOX_VERTICES]; + /*-----------------------------------------------------------------------------------*/ /* Constructors & Destructor Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -42,7 +44,7 @@ namespace SHADE , physicsSystem { nullptr } , rp3dDebugRenderer { nullptr } { - debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::COLLIDER)] = + debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::COLLIDER)] = SHColour::GREEN; debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::COLLIDER_AABB)] = SHColour::YELLOW; debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::BROAD_PHASE_AABB)] = SHColour::CYAN; debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::CONTACT_POINTS)] = SHColour::RED; @@ -95,6 +97,9 @@ namespace SHADE SHASSERT(physicsSystem == nullptr, "Non-existent physics system attached to the physics debug draw system!") physicsSystem = SHSystemManager::GetSystem(); + + // Generate shapes + generateBox(); } void SHPhysicsDebugDrawSystem::Exit() @@ -159,21 +164,20 @@ namespace SHADE } + void SHPhysicsDebugDrawSystem::generateBox() noexcept + { + boxVertices[0] = { 0.5f, 0.5f, -0.5f }; // TOP_RIGHT_BACK + boxVertices[1] = { -0.5f, 0.5f, -0.5f }; // TOP_LEFT_BACK + boxVertices[2] = { 0.5f, -0.5f, -0.5f }; // BTM_RIGHT_BACK + boxVertices[3] = { -0.5f, -0.5f, -0.5f }; // BTM_LEFT_BACK + boxVertices[4] = { 0.5f, 0.5f, 0.5f }; // TOP_RIGHT_FRONT + boxVertices[5] = { -0.5f, 0.5f, 0.5f }; // TOP_LEFT_FRONT + boxVertices[6] = { 0.5f, -0.5f, 0.5f }; // BTM_RIGHT_FRONT + boxVertices[7] = { -0.5f, -0.5f, 0.5f }; // BTM_LEFT_FRONT + } + void SHPhysicsDebugDrawSystem::debugDrawBox(const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept { - static constexpr uint32_t NUM_BOX_VERTICES = 8; - static const SHVec3 boxVertices[NUM_BOX_VERTICES] - { - { 0.5f, 0.5f, -0.5f } // TOP_RIGHT_BACK - , { -0.5f, 0.5f, -0.5f } // TOP_LEFT_BACK - , { 0.5f, -0.5f, -0.5f } // BTM_RIGHT_BACK - , { -0.5f, -0.5f, -0.5f } // BTM_LEFT_BACK - , { 0.5f, 0.5f, 0.5f } // TOP_RIGHT_FRONT - , { -0.5f, 0.5f, 0.5f } // TOP_LEFT_FRONT - , { 0.5f, -0.5f, 0.5f } // BTM_RIGHT_FRONT - , { -0.5f, -0.5f, 0.5f } // BTM_LEFT_FRONT - }; - auto* debugDrawSystem = SHSystemManager::GetSystem(); if (debugDrawSystem == nullptr) { @@ -184,10 +188,16 @@ namespace SHADE auto* BOX = reinterpret_cast(collisionShape.GetShape()); // Calculate final position & orientation - const SHVec3 FINAL_POS = colliderComponent.GetPosition() + collisionShape.GetPositionOffset(); - const SHQuaternion FINAL_ROT = colliderComponent.GetOrientation() * SHQuaternion::FromEuler(collisionShape.GetRotationOffset()); + const SHVec3 COLLIDER_POS = colliderComponent.GetPosition(); + const SHVec3 BOX_POS = collisionShape.GetPositionOffset(); + const SHQuaternion COLLIDER_ROT = colliderComponent.GetOrientation(); + const SHQuaternion BOX_ROT = SHQuaternion::FromEuler(collisionShape.GetRotationOffset()); - const SHMatrix BOX_TRS = SHMatrix::Scale(BOX->GetWorldExtents() * 2.0f) * SHMatrix::Rotate(FINAL_ROT) * SHMatrix::Translate(FINAL_POS); + + const SHMatrix COLLIDER_TR = SHMatrix::Rotate(COLLIDER_ROT) * SHMatrix::Translate(COLLIDER_POS); + const SHMatrix BOX_TRS = SHMatrix::Scale(BOX->GetWorldExtents() * 2.0f) * SHMatrix::Rotate(BOX_ROT) * SHMatrix::Translate(BOX_POS); + + const SHMatrix FINAL_TRS = BOX_TRS * COLLIDER_TR; const SHColour COLLIDER_COLOUR = collisionShape.IsTrigger() ? SHColour::PURPLE : SHColour::GREEN; @@ -197,8 +207,8 @@ namespace SHADE const uint32_t IDX1 = i; const uint32_t IDX2 = i + NUM_BOX_VERTICES / 2; - transformedVertices[IDX1] = SHVec3::Transform(boxVertices[IDX1], BOX_TRS); - transformedVertices[IDX2] = SHVec3::Transform(boxVertices[IDX2], BOX_TRS); + transformedVertices[IDX1] = SHVec3::Transform(boxVertices[IDX1], FINAL_TRS); + transformedVertices[IDX2] = SHVec3::Transform(boxVertices[IDX2], FINAL_TRS); // Draw 4 line to connect the quads debugDrawSystem->DrawLine(COLLIDER_COLOUR, transformedVertices[IDX1], transformedVertices[IDX2]); @@ -207,6 +217,7 @@ namespace SHADE // A, B, C, D std::array backQuad { transformedVertices[0], transformedVertices[1], transformedVertices[3], transformedVertices[2] }; debugDrawSystem->DrawPoly(COLLIDER_COLOUR, backQuad.begin(), backQuad.end()); + // E, F, G, H std::array frontQuad { transformedVertices[4], transformedVertices[5], transformedVertices[7], transformedVertices[6] }; debugDrawSystem->DrawPoly(COLLIDER_COLOUR, frontQuad.begin(), frontQuad.end()); @@ -226,8 +237,10 @@ namespace SHADE const SHColour COLLIDER_COLOUR = collisionShape.IsTrigger() ? SHColour::PURPLE : SHColour::GREEN; // Calculate final position & orientation - const SHVec3 FINAL_POS = colliderComponent.GetPosition() + collisionShape.GetPositionOffset(); - debugDrawSystem->DrawSphere(COLLIDER_COLOUR, FINAL_POS, SPHERE->GetWorldRadius()); + const SHQuaternion FINAL_ROT = colliderComponent.GetOrientation() * SHQuaternion::FromEuler(collisionShape.GetRotationOffset()); + const SHMatrix TR = SHMatrix::Rotate(FINAL_ROT) * SHMatrix::Translate(colliderComponent.GetPosition()); + + debugDrawSystem->DrawSphere(COLLIDER_COLOUR, SHVec3::Transform(collisionShape.GetPositionOffset(), TR), SPHERE->GetWorldRadius()); } } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.h b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.h index 390e3d69..149ed6c1 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.h +++ b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.h @@ -97,25 +97,38 @@ namespace SHADE /* Data Members */ /*---------------------------------------------------------------------------------*/ - static constexpr int NUM_FLAGS = SHUtilities::ConvertEnum(DebugDrawFlags::NUM_FLAGS); - + static constexpr int NUM_FLAGS = SHUtilities::ConvertEnum(DebugDrawFlags::NUM_FLAGS); static const DebugDrawFunction drawFunctions[NUM_FLAGS]; - uint8_t debugDrawFlags; - SHPhysicsSystem* physicsSystem; - rp3d::DebugRenderer* rp3dDebugRenderer; - SHColour debugColours[NUM_FLAGS]; + // SHAPES INFO + + static constexpr size_t NUM_BOX_VERTICES = 8; + static SHVec3 boxVertices[NUM_BOX_VERTICES]; + + + uint8_t debugDrawFlags; + SHPhysicsSystem* physicsSystem; + rp3d::DebugRenderer* rp3dDebugRenderer; + SHColour debugColours[NUM_FLAGS]; /*---------------------------------------------------------------------------------*/ /* Function Members */ /*---------------------------------------------------------------------------------*/ + // Generic Draw Functions + static void drawColliders (rp3d::DebugRenderer* debugRenderer) noexcept; static void drawColliderAABBs (rp3d::DebugRenderer* debugRenderer) noexcept; static void drawBroadPhaseAABBs (rp3d::DebugRenderer* debugRenderer) noexcept; static void drawContactPoints (rp3d::DebugRenderer* debugRenderer) noexcept; static void drawContactNormals (rp3d::DebugRenderer* debugRenderer) noexcept; + // Shape Generation Functions + + static void generateBox () noexcept; + + // Shape Draw Functions + static void debugDrawBox (const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept; static void debugDrawSphere (const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept; };