diff --git a/Assets/Scenes/PhysicsSandbox.shade b/Assets/Scenes/PhysicsSandbox.shade index f600c4ae..0005b35e 100644 --- a/Assets/Scenes/PhysicsSandbox.shade +++ b/Assets/Scenes/PhysicsSandbox.shade @@ -26,6 +26,7 @@ Freeze Rotation Z: false IsActive: true Collider Component: + DrawColliders: true Colliders: - Is Trigger: false Type: Sphere diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 3cb504c0..aa5a4f0e 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -31,6 +31,7 @@ #include "Input/SHInputManager.h" #include "Math/Transform/SHTransformSystem.h" #include "Physics/System/SHPhysicsSystem.h" +#include "Physics/System/SHPhysicsDebugDrawSystem.h" #include "Scripting/SHScriptEngine.h" #include "UI/SHUISystem.h" @@ -83,7 +84,6 @@ namespace Sandbox SHSystemManager::CreateSystem(); SHGraphicsSystem* graphicsSystem = static_cast(SHSystemManager::GetSystem()); - SHPhysicsSystem* physicsSystem = SHSystemManager::GetSystem(); // Link up SHDebugDraw SHSystemManager::CreateSystem(); @@ -98,6 +98,8 @@ namespace Sandbox editor->SetSDLWindow(sdlWindow); editor->SetSHWindow(&window); } + + SHSystemManager::CreateSystem(); #endif // Create Routines @@ -111,8 +113,9 @@ namespace Sandbox SHSystemManager::RegisterRoutine(); SHSystemManager::RegisterRoutine(); SHSystemManager::RegisterRoutine(); + #ifdef SHEDITOR - SHSystemManager::RegisterRoutine(); + SHSystemManager::RegisterRoutine(); #endif SHSystemManager::RegisterRoutine(); diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index dfc89df1..dd531708 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -322,8 +322,7 @@ namespace SHADE { DrawContextMenu(component); - auto* collider = component->GetCollider(); - SHEditorWidgets::CheckBox("Draw Colliders", [collider] { return collider->GetDebugDrawState(); }, [collider](bool value) { collider->SetDebugDrawState(value); }); + SHEditorWidgets::CheckBox("Draw Colliders", [component] { return component->GetDebugDrawState(); }, [component](bool value) { component->SetDebugDrawState(value); }); auto* collisionShapes = component->GetCollisionShapes(); int const size = collisionShapes ? static_cast(collisionShapes->size()) : 0; diff --git a/SHADE_Engine/src/Events/SHEventDefines.h b/SHADE_Engine/src/Events/SHEventDefines.h index bdc4c505..2a45da1b 100644 --- a/SHADE_Engine/src/Events/SHEventDefines.h +++ b/SHADE_Engine/src/Events/SHEventDefines.h @@ -10,16 +10,18 @@ constexpr SHEventIdentifier SH_ENTITY_DESTROYED_EVENT { 1 }; constexpr SHEventIdentifier SH_ENTITY_CREATION_EVENT { 2 }; constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT { 3 }; constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 }; -constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 }; -constexpr SHEventIdentifier SH_SCENEGRAPH_ADD_CHILD_EVENT { 6 }; -constexpr SHEventIdentifier SH_SCENEGRAPH_REMOVE_CHILD_EVENT { 7 }; -constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 8 }; -constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 9 }; -constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 10 }; -constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 11 }; -constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 12 }; -constexpr SHEventIdentifier SH_SCENE_INIT_PRE { 13 }; -constexpr SHEventIdentifier SH_SCENE_INIT_POST { 14 }; -constexpr SHEventIdentifier SH_SCENE_EXIT_PRE { 15 }; -constexpr SHEventIdentifier SH_SCENE_EXIT_POST { 16 }; +constexpr SHEventIdentifier SH_SCENE_INIT_PRE { 5 }; +constexpr SHEventIdentifier SH_SCENE_INIT_POST { 6 }; +constexpr SHEventIdentifier SH_SCENE_EXIT_PRE { 7 }; +constexpr SHEventIdentifier SH_SCENE_EXIT_POST { 8 }; +constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 9 }; +constexpr SHEventIdentifier SH_SCENEGRAPH_ADD_CHILD_EVENT { 10 }; +constexpr SHEventIdentifier SH_SCENEGRAPH_REMOVE_CHILD_EVENT { 11 }; +constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 12 }; +constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 13 }; +constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_DRAW_EVENT { 14 }; +constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 15 }; +constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 16 }; +constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 17 }; + diff --git a/SHADE_Engine/src/Physics/Collision/SHCollider.cpp b/SHADE_Engine/src/Physics/Collision/SHCollider.cpp index 1d29a585..b64bab53 100644 --- a/SHADE_Engine/src/Physics/Collision/SHCollider.cpp +++ b/SHADE_Engine/src/Physics/Collision/SHCollider.cpp @@ -14,7 +14,10 @@ #include "SHCollider.h" // Project Headers +#include "Events/SHEvent.h" #include "Math/SHMathHelpers.h" +#include "Physics/SHPhysicsEvents.h" + namespace SHADE { @@ -25,9 +28,7 @@ namespace SHADE SHCollider::SHCollider(EntityID eid, const SHTransform& worldTransform) noexcept : entityID { eid } , shapeIDCounter { 0 } -#ifdef SHEDITOR , debugDraw { false } -#endif , rigidBody { nullptr } , shapeFactory { nullptr } , transform { worldTransform } @@ -38,9 +39,7 @@ namespace SHADE SHCollider::SHCollider(const SHCollider& rhs) noexcept : entityID { rhs.entityID } , shapeIDCounter { rhs.shapeIDCounter } -#ifdef SHEDITOR , debugDraw { rhs.debugDraw } -#endif , rigidBody { rhs.rigidBody } , shapeFactory { rhs.shapeFactory } , transform { rhs.transform } @@ -57,9 +56,7 @@ namespace SHADE SHCollider::SHCollider(SHCollider&& rhs) noexcept : entityID { rhs.entityID } , shapeIDCounter { rhs.shapeIDCounter } -#ifdef SHEDITOR , debugDraw { rhs.debugDraw } -#endif , rigidBody { rhs.rigidBody } , shapeFactory { rhs.shapeFactory } , transform { rhs.transform } @@ -101,14 +98,11 @@ namespace SHADE } entityID = rhs.entityID; + debugDraw = rhs.debugDraw; rigidBody = rhs.rigidBody; shapeFactory = rhs.shapeFactory; transform = rhs.transform; - #ifdef SHEDITOR - debugDraw = rhs.debugDraw; - #endif - copyShapes(rhs); return *this; @@ -123,14 +117,11 @@ namespace SHADE } entityID = rhs.entityID; + debugDraw = rhs.debugDraw; rigidBody = rhs.rigidBody; shapeFactory = rhs.shapeFactory; transform = rhs.transform; - #ifdef SHEDITOR - debugDraw = rhs.debugDraw; - #endif - copyShapes(rhs); return *this; @@ -140,12 +131,10 @@ namespace SHADE /* Getter Function Definitions */ /*-----------------------------------------------------------------------------------*/ -#ifdef SHEDITOR bool SHCollider::GetDebugDrawState() const noexcept { return debugDraw; } -#endif const SHTransform& SHCollider::GetTransform() const noexcept { @@ -186,12 +175,23 @@ namespace SHADE /* Setter Function Definitions */ /*-----------------------------------------------------------------------------------*/ -#ifdef SHEDITOR void SHCollider::SetDebugDrawState(bool state) noexcept { debugDraw = state; + + #ifdef SHEDITOR + + // Broadcast event for the Debug Draw system to catch + const SHColliderOnDebugDrawEvent EVENT_DATA + { + .entityID = entityID + , .debugDrawState = debugDraw + }; + + SHEventManager::BroadcastEvent(EVENT_DATA, SH_PHYSICS_COLLIDER_DRAW_EVENT); + + #endif } -#endif void SHCollider::SetRigidBody(SHRigidBody* rb) noexcept { @@ -236,7 +236,7 @@ namespace SHADE { if (!shapeFactory) { - SHLOGV_ERROR("Shape factory is unlinked with Composite Collider {}. Unable to add new shape!", entityID) + SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add new shape!", entityID) return -1; } @@ -266,6 +266,17 @@ namespace SHADE sphere->rotationOffset = rotOffset; shapes.emplace_back(sphere); + + // Broadcast Event for adding a shape + const SHPhysicsColliderAddedEvent EVENT_DATA + { + .entityID = entityID + , .colliderType = SHCollisionShape::Type::SPHERE + , .colliderIndex = static_cast(shapes.size()) + }; + + SHEventManager::BroadcastEvent(EVENT_DATA, SH_PHYSICS_COLLIDER_ADDED_EVENT); + return static_cast(shapes.size()); } @@ -273,7 +284,7 @@ namespace SHADE { if (!shapeFactory) { - SHLOGV_ERROR("Shape factory is unlinked with Composite Collider {}. Unable to add remove shape!", entityID) + SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add remove shape!", entityID) return; } @@ -289,12 +300,22 @@ namespace SHADE break; } + const SHPhysicsColliderRemovedEvent EVENT_DATA + { + .entityID = entityID + , .colliderType = (*shapeIter)->GetType() + , .colliderIndex = index + }; + shapeFactory->DestroyShape(*shapeIter); *shapeIter = nullptr; // Remove the shape from the container to prevent accessing a nullptr shapeIter = shapes.erase(shapeIter); + // Broadcast Event for removing a shape + SHEventManager::BroadcastEvent(EVENT_DATA, SH_PHYSICS_COLLIDER_REMOVED_EVENT); + SHLOG_INFO_D("Removing Collision Shape {} from Entity {}", index, entityID) } @@ -386,6 +407,7 @@ namespace SHADE const SHMatrix TRS = SHMatrix::Rotate(FINAL_ROT) * SHMatrix::Translate(transform.position); const SHVec3 NEW_CENTER = SHVec3::Transform(sphere->positionOffset, TRS); + sphere->SetCenter(NEW_CENTER); } diff --git a/SHADE_Engine/src/Physics/Collision/SHCollider.h b/SHADE_Engine/src/Physics/Collision/SHCollider.h index cab433a5..927c6155 100644 --- a/SHADE_Engine/src/Physics/Collision/SHCollider.h +++ b/SHADE_Engine/src/Physics/Collision/SHCollider.h @@ -78,9 +78,7 @@ namespace SHADE /* Getter Functions */ /*---------------------------------------------------------------------------------*/ - #ifdef SHEDITOR [[nodiscard]] bool GetDebugDrawState () const noexcept; - #endif [[nodiscard]] const SHTransform& GetTransform () const noexcept; [[nodiscard]] const SHVec3& GetPosition () const noexcept; @@ -94,9 +92,7 @@ namespace SHADE /* Setter Functions */ /*---------------------------------------------------------------------------------*/ - #ifdef SHEDITOR void SetDebugDrawState (bool state) noexcept; - #endif void SetRigidBody (SHRigidBody* rb) noexcept; @@ -161,9 +157,7 @@ namespace SHADE EntityID entityID; uint32_t shapeIDCounter; // This increments everytime a shape is added to differentiate shapes. - #ifdef SHEDITOR bool debugDraw; - #endif SHRigidBody* rigidBody; SHCollisionShapeFactory* shapeFactory; diff --git a/SHADE_Engine/src/Physics/Dynamics/SHPhysicsWorld.cpp b/SHADE_Engine/src/Physics/Dynamics/SHPhysicsWorld.cpp index e6c02168..7422d6ff 100644 --- a/SHADE_Engine/src/Physics/Dynamics/SHPhysicsWorld.cpp +++ b/SHADE_Engine/src/Physics/Dynamics/SHPhysicsWorld.cpp @@ -136,6 +136,8 @@ namespace SHADE { rigidBody.collider->SetPosition(rigidBody.motionState.position); // TODO: Sync orientations + + rigidBody.collider->RecomputeShapes(); } } diff --git a/SHADE_Engine/src/Physics/Interface/SHColliderComponent.cpp b/SHADE_Engine/src/Physics/Interface/SHColliderComponent.cpp index d345290c..7425f418 100644 --- a/SHADE_Engine/src/Physics/Interface/SHColliderComponent.cpp +++ b/SHADE_Engine/src/Physics/Interface/SHColliderComponent.cpp @@ -54,7 +54,14 @@ namespace SHADE return collider->GetCollisionShape(index); } + bool SHColliderComponent::GetDebugDrawState() const noexcept + { + if (!collider) + return false; + return collider->GetDebugDrawState(); + } + /*-----------------------------------------------------------------------------------*/ /* Setter Function Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -64,6 +71,13 @@ namespace SHADE collider = c; } + void SHColliderComponent::SetDebugDrawState(bool state) noexcept + { + if (collider) + collider->SetDebugDrawState(state); + } + + } // namespace SHADE RTTR_REGISTRATION @@ -71,5 +85,6 @@ RTTR_REGISTRATION using namespace rttr; using namespace SHADE; - registration::class_("Collider Component"); -} \ No newline at end of file + registration::class_("Collider Component") + .property("Is Debug Drawing", &SHColliderComponent::GetDebugDrawState, &SHColliderComponent::SetDebugDrawState); +} \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/Interface/SHColliderComponent.h b/SHADE_Engine/src/Physics/Interface/SHColliderComponent.h index 83fb235c..d62b9b90 100644 --- a/SHADE_Engine/src/Physics/Interface/SHColliderComponent.h +++ b/SHADE_Engine/src/Physics/Interface/SHColliderComponent.h @@ -58,11 +58,19 @@ namespace SHADE [[nodiscard]] const SHCollider::CollisionShapes* const GetCollisionShapes() const noexcept; [[nodiscard]] SHCollisionShape* const GetCollisionShape (int index) const; + // Required for serialisation + + [[nodiscard]] bool GetDebugDrawState () const noexcept; + /*---------------------------------------------------------------------------------*/ /* Setter Functions */ /*---------------------------------------------------------------------------------*/ - void SetCollider(SHCollider* c) noexcept; + void SetCollider (SHCollider* c) noexcept; + + // Required for serialisation + + void SetDebugDrawState (bool state) noexcept; private: /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Physics/SHPhysicsEvents.h b/SHADE_Engine/src/Physics/SHPhysicsEvents.h index 35217347..2f78b6ee 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsEvents.h +++ b/SHADE_Engine/src/Physics/SHPhysicsEvents.h @@ -13,7 +13,6 @@ // Project Headers #include "Collision/CollisionShapes/SHCollisionShape.h" - namespace SHADE { /*-----------------------------------------------------------------------------------*/ @@ -28,9 +27,16 @@ namespace SHADE }; struct SHPhysicsColliderRemovedEvent + { + EntityID entityID; + SHCollisionShape::Type colliderType; + int colliderIndex; + }; + + struct SHColliderOnDebugDrawEvent { EntityID entityID; - int colliderIndex; + bool debugDrawState; }; diff --git a/SHADE_Engine/src/Physics/System/Routines/SHPhysicsDebugDrawRoutine.cpp b/SHADE_Engine/src/Physics/System/Routines/SHPhysicsDebugDrawRoutine.cpp index c73e8ab7..72b2aad5 100644 --- a/SHADE_Engine/src/Physics/System/Routines/SHPhysicsDebugDrawRoutine.cpp +++ b/SHADE_Engine/src/Physics/System/Routines/SHPhysicsDebugDrawRoutine.cpp @@ -1,7 +1,7 @@ /**************************************************************************************** - * \file SHPhysicsDebugDrawRoutine.cpp + * \file SHPhysicsDebugDrawRutine.cpp * \author Diren D Bharwani, diren.dbharwani, 390002520 - * \brief Implementation for the Physics Debug-Draw Routine + * \brief Implementation for the Physics Debut Draw Routine * * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or * disclosure of this file or its contents without the prior written consent @@ -11,14 +11,13 @@ #include // Primary Header -#include "Physics/System/SHPhysicsSystem.h" +#include "Physics/System/SHPhysicsDebugDrawSystem.h" // Project Headers #include "ECS_Base/Managers/SHSystemManager.h" #include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h" - -#include "Scripting/SHScriptEngine.h" - +#include "Math/Transform/SHTransformComponent.h" +#include "Physics/System/SHPhysicsSystem.h" namespace SHADE { @@ -26,35 +25,64 @@ namespace SHADE /* Constructors & Destructor Definitions */ /*-----------------------------------------------------------------------------------*/ - SHPhysicsSystem::PhysicsDebugDraw::PhysicsDebugDraw() - : SHSystemRoutine { "Physics Debug Draw", false } + SHPhysicsDebugDrawSystem::PhysicsDebugDraw::PhysicsDebugDraw() + : SHSystemRoutine { "Physics Debug-Draw", true } {} /*-----------------------------------------------------------------------------------*/ /* Public Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHPhysicsSystem::PhysicsDebugDraw::Execute(double) noexcept + void SHPhysicsDebugDrawSystem::PhysicsDebugDraw::Execute(double) noexcept { - auto* physicsSystem = reinterpret_cast(GetSystem()); - - // Get debug drawing system - auto* debugDrawSystem = SHSystemManager::GetSystem(); - if (!debugDrawSystem) - { - SHLOG_ERROR("Debug draw system unavailable! Colliders cannot be drawn!") + auto* physicsDebugDrawSystem = reinterpret_cast(GetSystem()); + + if (!physicsDebugDrawSystem->GetFlagState(DebugDrawFlags::ACTIVE)) return; + + auto* physicsSystem = SHSystemManager::GetSystem(); + auto* debugDrawSystem = SHSystemManager::GetSystem(); + + const bool DRAW_COLLIDERS = physicsDebugDrawSystem->GetFlagState(DebugDrawFlags::COLLIDERS); + const bool DRAW_CONTACTS = physicsDebugDrawSystem->GetFlagState(DebugDrawFlags::CONTACTS); + const bool DRAW_RAYCASTS = physicsDebugDrawSystem->GetFlagState(DebugDrawFlags::RAYCASTS); + const bool DRAW_BROADPHASE = physicsDebugDrawSystem->GetFlagState(DebugDrawFlags::BROADPHASE); + + // If draw all colliders is active, get all colliders from the dense set and draw. + // Else we check if any colliders have been flagged for drawing. + if (DRAW_COLLIDERS) + { + const auto& COLLIDER_COMPONENT_DENSE = SHComponentManager::GetDense(); + for (const auto& COLLIDER_COMPONENT : COLLIDER_COMPONENT_DENSE) + { + const auto* COLLIDER = COLLIDER_COMPONENT.GetCollider(); + drawCollider(debugDrawSystem, *COLLIDER); + } + } + else if (!physicsDebugDrawSystem->collidersToDraw.empty()) + { + for (const auto EID : physicsDebugDrawSystem->collidersToDraw) + { + const auto* COLLIDER = SHComponentManager::GetComponent(EID)->GetCollider(); + drawCollider(debugDrawSystem, *COLLIDER); + } } - //SHPhysicsDebugDraw& physicsDebugRenderer = physicsSystem->debugRenderer; + if (DRAW_CONTACTS) + { + // TODO + } - //if (!physicsDebugRenderer.GetDebugDrawState()) - // return; + if (DRAW_RAYCASTS) + { + // TODO + physicsDebugDrawSystem->raysToDraw.clear(); + } - //// Draw colliders - //if (physicsDebugRenderer.GetDrawSpecificCollidersState()) - // physicsDebugRenderer.DrawSpecificColliders(debugDrawSystem); - //else if (physicsDebugRenderer.GetDrawAllCollidersState()) - // physicsDebugRenderer.DrawAllColliders(debugDrawSystem); + if (DRAW_BROADPHASE) + { + // TODO + } } -} + +} // namespace SHADE diff --git a/SHADE_Engine/src/Physics/System/Routines/SHPhysicsPostUpdateRoutine.cpp b/SHADE_Engine/src/Physics/System/Routines/SHPhysicsPostUpdateRoutine.cpp index d5492cdf..8e7450ce 100644 --- a/SHADE_Engine/src/Physics/System/Routines/SHPhysicsPostUpdateRoutine.cpp +++ b/SHADE_Engine/src/Physics/System/Routines/SHPhysicsPostUpdateRoutine.cpp @@ -15,7 +15,6 @@ // Project Headers #include "ECS_Base/Managers/SHSystemManager.h" -#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h" #include "Math/Transform/SHTransformComponent.h" #include "Scripting/SHScriptEngine.h" diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp new file mode 100644 index 00000000..77241ae9 --- /dev/null +++ b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp @@ -0,0 +1,158 @@ +/**************************************************************************************** + * \file SHPhysicsDebugDrawSystem.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for the Physics Debug Draw System + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#include + +// Primary Header +#include "SHPhysicsDebugDrawSystem.h" + +// Project Header +#include "ECS_Base/Managers/SHSystemManager.h" +#include "Math/Transform/SHTransformComponent.h" +#include "Physics/SHPhysicsEvents.h" +#include "Tools/Utilities/SHUtilities.h" + +namespace SHADE +{ + const SHColour SHPhysicsDebugDrawSystem::DEBUG_DRAW_COLOURS[SHUtilities::ConvertEnum(Colours::COUNT)] + { + SHColour::GREEN // Colliders + , SHColour::PURPLE // Triggers + , SHColour::RED // Contacts + , SHColour::ORANGE // Raycasts + , SHColour::CYAN // Broadphase + }; + + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHPhysicsDebugDrawSystem::SHPhysicsDebugDrawSystem() noexcept + : flags { 0 } + { + collidersToDraw.clear(); + } + + /*-----------------------------------------------------------------------------------*/ + /* Getter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + bool SHPhysicsDebugDrawSystem::GetFlagState(DebugDrawFlags flag) const noexcept + { + const uint8_t ENUM_VALUE = SHUtilities::ConvertEnum(flag); + return flags & ENUM_VALUE; + } + + /*-----------------------------------------------------------------------------------*/ + /* Setter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHPhysicsDebugDrawSystem::SetFlagState(DebugDrawFlags flag, bool state) noexcept + { + const uint8_t ENUM_VALUE = SHUtilities::ConvertEnum(flag); + state ? flags |= ENUM_VALUE : flags &= ~ENUM_VALUE; + } + + /*-----------------------------------------------------------------------------------*/ + /* Public Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHPhysicsDebugDrawSystem::Init() + { + SystemFamily::GetID(); + + // Register collider draw event + const std::shared_ptr EVENT_RECEIVER = std::make_shared>(this, &SHPhysicsDebugDrawSystem::onColliderDraw); + const ReceiverPtr EVENT_RECEIVER_PTR = std::dynamic_pointer_cast(EVENT_RECEIVER); + + SHEventManager::SubscribeTo(SH_PHYSICS_COLLIDER_DRAW_EVENT, EVENT_RECEIVER_PTR); + } + + void SHPhysicsDebugDrawSystem::Exit() + { + + } + + void SHPhysicsDebugDrawSystem::AddRaycast(const SHRay& ray, const SHPhysicsRaycastResult& result) noexcept + { + + } + + /*-----------------------------------------------------------------------------------*/ + /* Private Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHEventHandle SHPhysicsDebugDrawSystem::onColliderDraw(SHEventPtr onColliderDrawEvent) + { + const auto& EVENT_DATA = reinterpret_cast*>(onColliderDrawEvent.get())->data; + + if (EVENT_DATA->debugDrawState) + { + if (collidersToDraw.empty()) + SetFlagState(DebugDrawFlags::ACTIVE, true); + + collidersToDraw.emplace(EVENT_DATA->entityID); + } + else + { + collidersToDraw.erase(EVENT_DATA->entityID); + + if (collidersToDraw.empty()) + SetFlagState(DebugDrawFlags::ACTIVE, false); + } + + return onColliderDrawEvent.get()->handle; + } + + void SHPhysicsDebugDrawSystem::drawCollider(SHDebugDrawSystem* debugDrawSystem, const SHCollider& collider) noexcept + { + for (const auto* SHAPE : collider.GetCollisionShapes()) + { + switch (SHAPE->GetType()) + { + case SHCollisionShape::Type::SPHERE: + { + const SHSphereCollisionShape* SPHERE = dynamic_cast(SHAPE); + drawSphere(debugDrawSystem, *SPHERE); + + break; + } + case SHCollisionShape::Type::BOX: + { + break; + } + case SHCollisionShape::Type::CAPSULE: + { + break; + } + default: break; + } + } + } + + void SHPhysicsDebugDrawSystem::drawSphere(SHDebugDrawSystem* debugDrawSystem, const SHSphereCollisionShape& sphere) noexcept + { + const SHColour& DRAW_COLOUR = DEBUG_DRAW_COLOURS[SHUtilities::ConvertEnum(sphere.IsTrigger() ? Colours::TRIGGER : Colours::COLLIDER)]; + debugDrawSystem->DrawSphere(DRAW_COLOUR, sphere.GetCenter(), sphere.GetWorldRadius()); + } + + void SHPhysicsDebugDrawSystem::drawContact(SHDebugDrawSystem* debugDrawSystem, const DebugDrawInfo::Contact& contactInfo) noexcept + { + static const SHColour& DRAW_COLOUR = DEBUG_DRAW_COLOURS[SHUtilities::ConvertEnum(Colours::CONTACT)]; + } + + void SHPhysicsDebugDrawSystem::drawRaycast(SHDebugDrawSystem* debugDrawSystem, const DebugDrawInfo::Raycast& raycastInfo) noexcept + { + static const SHColour& DRAW_COLOUR = DEBUG_DRAW_COLOURS[SHUtilities::ConvertEnum(Colours::RAYCAST)]; + } + + + +} // 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 new file mode 100644 index 00000000..423ab62a --- /dev/null +++ b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.h @@ -0,0 +1,150 @@ +/**************************************************************************************** + * \file SHPhysicsDebugDrawSystem.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for the Physics Debug Draw System + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +#include + +// Project Headers +#include "ECS_Base/Entity/SHEntity.h" +#include "ECS_Base/System/SHSystem.h" +#include "ECS_Base/System/SHSystemRoutine.h" +#include "Events/SHEvent.h" +#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h" +#include "Physics/Collision/SHCollider.h" +#include "Physics/Collision/SHPhysicsRaycastResult.h" +#include "Physics/Collision/CollisionShapes/SHSphereCollisionShape.h" + + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + class SH_API SHPhysicsDebugDrawSystem final : public SHSystem + { + public: + + enum class DebugDrawFlags : uint8_t + { + ACTIVE = 0x0001 + , COLLIDERS = 0x0002 + , CONTACTS = 0x0004 + , RAYCASTS = 0x0008 + , BROADPHASE = 0x0010 + }; + + /*---------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*---------------------------------------------------------------------------------*/ + + SHPhysicsDebugDrawSystem () noexcept; + ~SHPhysicsDebugDrawSystem() noexcept = default; + + /*---------------------------------------------------------------------------------*/ + /* Getter Functions */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] bool GetFlagState (DebugDrawFlags flag) const noexcept; + /*---------------------------------------------------------------------------------*/ + /* Setter Functions */ + /*---------------------------------------------------------------------------------*/ + + void SetFlagState (DebugDrawFlags flag, bool state) noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Member Functions */ + /*---------------------------------------------------------------------------------*/ + + void Init () override; + void Exit () override; + + void AddRaycast (const SHRay& ray, const SHPhysicsRaycastResult& result) noexcept; + + /*---------------------------------------------------------------------------------*/ + /* System Routines */ + /*---------------------------------------------------------------------------------*/ + + /** + * @brief + * If the editor is enabled, this routine invokes debug drawing for colliders and collision information. + */ + class SH_API PhysicsDebugDraw final : public SHSystemRoutine + { + public: + PhysicsDebugDraw(); + void Execute(double dt) noexcept override; + }; + + private: + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + + union DebugDrawInfo + { + struct Contact + { + SHVec3 worldPos; + SHVec3 normal; + } contact; + + struct Raycast + { + SHVec3 start; + SHVec3 end; + } raycast; + }; + + using Colliders = std::unordered_set; + using Raycasts = std::vector; + using Contacts = std::vector; + + enum class Colours + { + COLLIDER + , TRIGGER + , CONTACT + , RAYCAST + , BROADPHASE + + , COUNT + }; + + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + + static const SHColour DEBUG_DRAW_COLOURS[static_cast(Colours::COUNT)]; + + // 0 0 0 drawBroadphase drawRaycasts drawContacts drawAllColliders debugDrawActive + uint8_t flags; + + Colliders collidersToDraw; + Raycasts raysToDraw; + Contacts contactToDraw; + + /*---------------------------------------------------------------------------------*/ + /* Member Functions */ + /*---------------------------------------------------------------------------------*/ + + SHEventHandle onColliderDraw(SHEventPtr onColliderDrawEvent); + + static void drawCollider (SHDebugDrawSystem* debugDrawSystem, const SHCollider& collider) noexcept; + static void drawSphere (SHDebugDrawSystem* debugDrawSystem, const SHSphereCollisionShape& sphere) noexcept; + + static void drawContact (SHDebugDrawSystem* debugDrawSystem, const DebugDrawInfo::Contact& contactInfo) noexcept; + static void drawRaycast (SHDebugDrawSystem* debugDrawSystem, const DebugDrawInfo::Raycast& raycastInfo) noexcept; + + }; + + +} // namespace SHADE diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp index 388adadc..20084ebe 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp @@ -110,13 +110,12 @@ namespace SHADE void SHPhysicsSystem::Init() { + // TODO(Diren): Consider using a non-static collision tag matrix. // Initialise collision tags std::filesystem::path defaultCollisionTagNameFilePath { ASSET_ROOT }; defaultCollisionTagNameFilePath.append("CollisionTags.SHConfig"); SHCollisionTagMatrix::Init(defaultCollisionTagNameFilePath); - // Link Managers to system - // Register Events for (int i = 0; i < NUM_EVENT_FUNCTIONS; ++i) { diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h index ca73df81..ce1f1396 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h @@ -27,6 +27,10 @@ namespace SHADE /* Type Definitions */ /*-----------------------------------------------------------------------------------*/ + /** + * @brief + * Encapsulates a system for running and managing the physics simulation of the engine. + */ class SH_API SHPhysicsSystem final : public SHSystem { public: @@ -41,23 +45,27 @@ namespace SHADE /* Getter Functions */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] double GetFixedUpdateRate() const noexcept; - [[nodiscard]] double GetFixedDT() const noexcept; + [[nodiscard]] double GetFixedUpdateRate() const noexcept; + [[nodiscard]] double GetFixedDT() const noexcept; /*---------------------------------------------------------------------------------*/ /* Setter Functions */ /*---------------------------------------------------------------------------------*/ void SetFixedUpdateRate(double fixedUpdateRate) noexcept; - void SetFixedDT(double fixedDt) noexcept; + void SetFixedDT(double fixedDt) noexcept; /*---------------------------------------------------------------------------------*/ - /* Function Members */ + /* Member Functions */ /*---------------------------------------------------------------------------------*/ + /** + * @brief + * - Initialises the static collision tag matrix. + * - Registers the system to catch specific events. + */ void Init() override; void Exit() override; - void ForceUpdate(); /*---------------------------------------------------------------------------------*/ @@ -104,21 +112,6 @@ namespace SHADE void Execute(double dt) noexcept override; }; - #ifdef SHEDITOR - /** - * @brief - * If the editor is enabled, this routine invokes debug drawing for colliders. - * and collision information. - */ - class SH_API PhysicsDebugDraw final : public SHSystemRoutine - { - public: - PhysicsDebugDraw(); - void Execute(double dt) noexcept override; - }; - - #endif - private: /*---------------------------------------------------------------------------------*/ /* Type Definitions */ diff --git a/SHADE_Engine/src/Serialization/SHYAMLConverters.h b/SHADE_Engine/src/Serialization/SHYAMLConverters.h index 73b22fd6..b225a9a4 100644 --- a/SHADE_Engine/src/Serialization/SHYAMLConverters.h +++ b/SHADE_Engine/src/Serialization/SHYAMLConverters.h @@ -204,10 +204,15 @@ namespace YAML template<> struct convert { + static constexpr const char* DrawColliders = "DrawColliders"; static constexpr const char* Colliders = "Colliders"; + static Node encode(SHColliderComponent& rhs) { Node node, collidersNode; + + node[DrawColliders] = rhs.GetDebugDrawState(); + int const numColliders = static_cast(rhs.GetCollisionShapes()->size()); for (int i = 0; i < numColliders; ++i) { @@ -221,6 +226,9 @@ namespace YAML } static bool decode(Node const& node, SHColliderComponent& rhs) { + if (node[DrawColliders].IsDefined()) + rhs.SetDebugDrawState(node[DrawColliders].as()); + if (node[Colliders].IsDefined()) { int numColliders{};