From d45d62170136a23796c139eba8416020426fa5e3 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 27 Oct 2022 12:32:06 +0800 Subject: [PATCH] Collider now will have it's sub collider list updated based on events --- .../Components/SHRigidBodyComponent.cpp | 3 + .../Physics/Components/SHRigidBodyComponent.h | 8 +- SHADE_Engine/src/Scripting/SHScriptEngine.cpp | 40 +++++++- SHADE_Engine/src/Scripting/SHScriptEngine.h | 5 + SHADE_Managed/src/Components/Collider.cxx | 99 ++++++++++++++----- SHADE_Managed/src/Components/Collider.hxx | 28 +++++- SHADE_Managed/src/Engine/ECS.cxx | 6 ++ SHADE_Managed/src/Scripts/ScriptStore.hxx | 4 +- TempScriptsFolder/PhysicsTest.cs | 36 +++++++ TempScriptsFolder/RaccoonShowcase.cs | 10 +- TempScriptsFolder/RaccoonSpin.cs | 9 +- 11 files changed, 202 insertions(+), 46 deletions(-) create mode 100644 TempScriptsFolder/PhysicsTest.cs diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp index b0172f64..c1969557 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp @@ -10,6 +10,9 @@ #include +// External Dependencies +#include + // Primary Header #include "SHRigidBodyComponent.h" diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h index 78de84e7..3c5dd4f9 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h @@ -10,7 +10,6 @@ #pragma once -#include #include // Project Headers @@ -23,6 +22,11 @@ // class SHPhysicsSystem; //} +namespace reactphysics3d +{ + class RigidBody; +} + namespace SHADE { /*-----------------------------------------------------------------------------------*/ @@ -153,7 +157,7 @@ namespace SHADE uint16_t dirtyFlags; bool interpolate; - rp3d::RigidBody* rp3dBody; + reactphysics3d::RigidBody* rp3dBody; float mass; float drag; diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index 195d8ee3..3a2ea29f 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -24,6 +24,7 @@ of DigiPen Institute of Technology is prohibited. #include "Events/SHEvent.h" #include "Events/SHEventReceiver.h" #include "Events/SHEventManager.hpp" +#include "Physics/SHPhysicsSystem.h" namespace SHADE { @@ -60,7 +61,7 @@ namespace SHADE // Initialise the CSharp Engine csEngineInit(); - // Register entity creation events + // Register all events registerEvents(); } void SHScriptEngine::UnloadScriptAssembly() @@ -284,6 +285,20 @@ namespace SHADE return eventData->handle; } + SHEventHandle SHScriptEngine::onColliderAdded(SHEventPtr eventPtr) + { + auto eventData = reinterpret_cast*>(eventPtr.get()); + csColliderOnListChanged(eventData->data->entityID); + return eventData->handle; + } + + SHEventHandle SHScriptEngine::onColliderRemoved(SHEventPtr eventPtr) + { + auto eventData = reinterpret_cast*>(eventPtr.get()); + csColliderOnListChanged(eventData->data->entityID); + return eventData->handle; + } + /*-----------------------------------------------------------------------------------*/ /* Helper Functions */ /*-----------------------------------------------------------------------------------*/ @@ -384,6 +399,12 @@ namespace SHADE DEFAULT_CSHARP_NAMESPACE + ".ScriptStore", "DeserialiseScripts" ); + csColliderOnListChanged = dotNet.GetFunctionPtr + ( + DEFAULT_CSHARP_LIB_NAME, + DEFAULT_CSHARP_NAMESPACE + ".Collider", + "OnColliderBoundChanged" + ); csEditorRenderScripts = dotNet.GetFunctionPtr ( DEFAULT_CSHARP_LIB_NAME, @@ -411,8 +432,21 @@ namespace SHADE { std::make_shared>(this, &SHScriptEngine::onEntityDestroyed) }; - ReceiverPtr receiver = std::dynamic_pointer_cast(destroyedEventReceiver); - SHEventManager::SubscribeTo(SH_ENTITY_DESTROYED_EVENT, receiver); + SHEventManager::SubscribeTo(SH_ENTITY_DESTROYED_EVENT, std::dynamic_pointer_cast(destroyedEventReceiver)); + + // Register for collider added event + std::shared_ptr> addedColliderEventReceiver + { + std::make_shared>(this, &SHScriptEngine::onColliderAdded) + }; + SHEventManager::SubscribeTo(SH_PHYSICS_COLLIDER_ADDED_EVENT, std::dynamic_pointer_cast(addedColliderEventReceiver)); + + // Register for collider removed event + std::shared_ptr> removedColliderEventReceiver + { + std::make_shared>(this, &SHScriptEngine::onColliderRemoved) + }; + SHEventManager::SubscribeTo(SH_PHYSICS_COLLIDER_REMOVED_EVENT, std::dynamic_pointer_cast(removedColliderEventReceiver)); } void SHScriptEngine::dumpBuildLog(const std::string_view& buildLogPath) diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.h b/SHADE_Engine/src/Scripting/SHScriptEngine.h index 137d978f..a909a334 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.h +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.h @@ -218,6 +218,7 @@ namespace SHADE using CsScriptSerialiseYamlFuncPtr = bool(*)(EntityID, void*); using CsScriptDeserialiseYamlFuncPtr = bool(*)(EntityID, const void*); using CsScriptEditorFuncPtr = void(*)(EntityID); + using CsEventRelayFuncPtr = void(*)(EntityID); /*-----------------------------------------------------------------------------*/ /* Constants */ @@ -250,6 +251,8 @@ namespace SHADE CsScriptOptionalFuncPtr csScriptsRemoveAllImmediately = nullptr; CsScriptSerialiseYamlFuncPtr csScriptsSerialiseYaml = nullptr; CsScriptDeserialiseYamlFuncPtr csScriptsDeserialiseYaml = nullptr; + // - Events + CsEventRelayFuncPtr csColliderOnListChanged = nullptr; // - Editor CsScriptEditorFuncPtr csEditorRenderScripts = nullptr; CsFuncPtr csEditorUndo = nullptr; @@ -259,6 +262,8 @@ namespace SHADE /* Event Handler Functions */ /*-----------------------------------------------------------------------------*/ SHEventHandle onEntityDestroyed(SHEventPtr eventPtr); + SHEventHandle onColliderAdded(SHEventPtr eventPtr); + SHEventHandle onColliderRemoved(SHEventPtr eventPtr); /*-----------------------------------------------------------------------------*/ /* Helper Functions */ diff --git a/SHADE_Managed/src/Components/Collider.cxx b/SHADE_Managed/src/Components/Collider.cxx index e09b7ead..7f41ad44 100644 --- a/SHADE_Managed/src/Components/Collider.cxx +++ b/SHADE_Managed/src/Components/Collider.cxx @@ -134,7 +134,16 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ Collider::Collider(Entity entity) : Component(entity) - {} + { + // Create lists if they don't exist + if (colliders == nullptr) + colliders = gcnew CollidersMap; + if (!colliders->ContainsKey(entity)) + colliders->Add(entity, gcnew WeakReferenceList()); + + // Store a weak reference + colliders[entity]->Add(gcnew System::WeakReference(this)); + } /*---------------------------------------------------------------------------------*/ /* Collider - Properties */ @@ -152,29 +161,7 @@ namespace SHADE // Populate the list if it hasn't been if (subColliderList == nullptr) { - subColliderList = gcnew System::Collections::Generic::List(); - for (const auto& collider : GetNativeComponent()->GetColliders()) - { - ColliderBound^ bound = nullptr; - switch (collider.first.GetType()) - { - case SHCollider::Type::BOX: - bound = gcnew BoxColliderBound(index, Owner.GetEntity()); - break; - case SHCollider::Type::SPHERE: - bound = gcnew SphereColliderBound(index, Owner.GetEntity()); - break; - case SHCollider::Type::CAPSULE: - // TODO - break; - default: - Debug::LogWarning("[Collider] An invalid Collider Type was detected. Skipping."); - break; - } - - // Add into list - subColliderList->Add(bound); - } + updateSubColliderList(); } // Check if valid @@ -189,4 +176,68 @@ namespace SHADE { return safe_cast(GetColliderBound(index)); } + + /*---------------------------------------------------------------------------------*/ + /* Event Handling Functions */ + /*---------------------------------------------------------------------------------*/ + void Collider::OnColliderBoundChanged(EntityID entity) + { + // Check if there are any colliders to update + if (colliders == nullptr || !colliders->ContainsKey(entity)) + return; + + // Update any colliders + System::Collections::Generic::List^ toRemove = gcnew System::Collections::Generic::List(); + WeakReferenceList^ collidersList = colliders[entity]; + for each (System::WeakReference^ wr in collidersList) + { + Collider^ collider = safe_cast(wr->Target); + // Update collider bounds + if (collider && collider->subColliderList != nullptr) + collider->updateSubColliderList(); + else + toRemove->Add(wr); + } + + // Sweep through and clear any invalid references while we're at it + for each (System::WeakReference ^ wr in toRemove) + { + collidersList->Remove(wr); + } + } + + void Collider::updateSubColliderList() + { + // Prepare the list + if (subColliderList) + subColliderList->Clear(); + else + subColliderList = gcnew System::Collections::Generic::List(); + + // Populate the list + int i = 0; + for (const auto& collider : GetNativeComponent()->GetColliders()) + { + ColliderBound^ bound = nullptr; + switch (collider.first.GetType()) + { + case SHCollider::Type::BOX: + bound = gcnew BoxColliderBound(i, Owner.GetEntity()); + break; + case SHCollider::Type::SPHERE: + bound = gcnew SphereColliderBound(i, Owner.GetEntity()); + break; + case SHCollider::Type::CAPSULE: + // TODO + break; + default: + Debug::LogWarning("[Collider] An invalid Collider Type was detected. Skipping."); + break; + } + ++i; + + // Add into list + subColliderList->Add(bound); + } + } } diff --git a/SHADE_Managed/src/Components/Collider.hxx b/SHADE_Managed/src/Components/Collider.hxx index c85ee21c..8e63fc83 100644 --- a/SHADE_Managed/src/Components/Collider.hxx +++ b/SHADE_Managed/src/Components/Collider.hxx @@ -136,7 +136,7 @@ namespace SHADE /// public ref class SphereColliderBound : public ColliderBound { - public: + public: /*-----------------------------------------------------------------------------*/ /* Properties */ /*-----------------------------------------------------------------------------*/ @@ -165,7 +165,7 @@ namespace SHADE /// bool Raycast(Ray ray, float maxDistance) override; - internal: + internal: /*-----------------------------------------------------------------------------*/ /* Constructors */ /*-----------------------------------------------------------------------------*/ @@ -220,11 +220,33 @@ namespace SHADE generic where T:ColliderBound T GetColliderBound(int index); + internal: + /*-----------------------------------------------------------------------------*/ + /* Event Handling Functions */ + /*-----------------------------------------------------------------------------*/ + static void OnColliderBoundChanged(EntityID entity); + private: + /*-----------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------*/ + using WeakReferenceList = System::Collections::Generic::List; + using CollidersMap = System::Collections::Generic::Dictionary; + + /*-----------------------------------------------------------------------------*/ + /* Static Data Members */ + /*-----------------------------------------------------------------------------*/ + static CollidersMap^ colliders; + /*-----------------------------------------------------------------------------*/ /* Data Members */ /*-----------------------------------------------------------------------------*/ - System::Collections::Generic::List^ subColliderList; // TODO: Update elements in this list if the list on native collider changes + System::Collections::Generic::List^ subColliderList; + + /*-----------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------*/ + void updateSubColliderList(); }; } diff --git a/SHADE_Managed/src/Engine/ECS.cxx b/SHADE_Managed/src/Engine/ECS.cxx index 4d62f643..df67c788 100644 --- a/SHADE_Managed/src/Engine/ECS.cxx +++ b/SHADE_Managed/src/Engine/ECS.cxx @@ -22,6 +22,8 @@ of DigiPen Institute of Technology is prohibited. // External Dependencies #include "ECS_Base/Managers/SHEntityManager.h" #include "Math/Transform/SHTransformComponent.h" +#include "Physics\Components\SHColliderComponent.h" +#include "Physics\Components\SHRigidBodyComponent.h" #include "Scene/SHSceneManager.h" #include "Scene/SHSceneGraph.h" #include "Tools/SHLog.h" @@ -29,6 +31,8 @@ of DigiPen Institute of Technology is prohibited. #include "Utility/Convert.hxx" #include "Utility/Debug.hxx" #include "Components/Transform.hxx" +#include "Components\RigidBody.hxx" +#include "Components\Collider.hxx" namespace SHADE { @@ -242,6 +246,8 @@ namespace SHADE static ECS::ECS() { componentMap.Add(createComponentSet()); + componentMap.Add(createComponentSet()); + componentMap.Add(createComponentSet()); } /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Scripts/ScriptStore.hxx b/SHADE_Managed/src/Scripts/ScriptStore.hxx index 4a9be721..9aa66fcd 100644 --- a/SHADE_Managed/src/Scripts/ScriptStore.hxx +++ b/SHADE_Managed/src/Scripts/ScriptStore.hxx @@ -132,7 +132,7 @@ namespace SHADE /// Immutable list of references to scripts of the specified type. /// generic where T : ref class, Script - static System::Collections::Generic::IEnumerable ^ GetScripts(Entity entity); + static System::Collections::Generic::IEnumerable^ GetScripts(Entity entity); /// /// Retrieves an immutable list of all scripts attached to a specified Entity. /// @@ -295,4 +295,4 @@ namespace SHADE static System::Type^ getScriptType(System::String^ scriptName); static bool isEntityActive(Entity entity); }; -} // namespace PlushieAPI \ No newline at end of file +} diff --git a/TempScriptsFolder/PhysicsTest.cs b/TempScriptsFolder/PhysicsTest.cs new file mode 100644 index 00000000..72e8a205 --- /dev/null +++ b/TempScriptsFolder/PhysicsTest.cs @@ -0,0 +1,36 @@ +using SHADE; +using System; + +public class PhysicsTest : Script +{ + [SerializeField] + [Tooltip("Force to apply when pressing Space.")] + private Vector3 Force = new Vector3(0.0f, 1.0f, 0.0f); + private RigidBody RigidBody; + private Collider Collider; + public PhysicsTest(GameObject gameObj) : base(gameObj) { } + + protected override void awake() + { + RigidBody = GetComponent(); + if (RigidBody == null) + { + Debug.LogError("RigidBody is NULL!"); + } + Collider = GetComponent(); + if (Collider == null) + { + Debug.LogError("Collider is NULL!"); + } + + var subColider = Collider.ColliderBoundsCount; + Debug.Log($"There are {subColider} colliders."); + } + protected override void update() + { + if (Input.GetKeyUp(Input.KeyCode.Space)) + { + RigidBody.AddForce(Force); + } + } +} \ No newline at end of file diff --git a/TempScriptsFolder/RaccoonShowcase.cs b/TempScriptsFolder/RaccoonShowcase.cs index 4191a6e5..da0b89d2 100644 --- a/TempScriptsFolder/RaccoonShowcase.cs +++ b/TempScriptsFolder/RaccoonShowcase.cs @@ -12,7 +12,7 @@ public class RaccoonShowcase : Script //private int test = 5; [SerializeField] [Tooltip("Speed of the scaling in radians per second around each axis.")] - private Vector3 ScaleSpeed = new Vector3(1.0, 1.0, 0.0); + private Vector3 ScaleSpeed = Vector3.One; private Transform Transform; private double rotation = 0.0; private Vector3 scale = Vector3.Zero; @@ -31,9 +31,9 @@ public class RaccoonShowcase : Script } protected override void update() { - rotation += RotateSpeed * 0.16; - scale += ScaleSpeed * 0.16; - Transform.LocalRotation = new Vector3(0.0f, rotation, 0.0f); - Transform.LocalScale = new Vector3(System.Math.Abs(System.Math.Sin(scale.x)) * originalScale, System.Math.Abs(System.Math.Cos(scale.y)) * originalScale, System.Math.Abs(System.Math.Sin(scale.z)) * originalScale); + //rotation += RotateSpeed * 0.16; + //scale += ScaleSpeed * 0.16; + //Transform.LocalRotation = new Vector3(0.0f, rotation, 0.0f); + //Transform.LocalScale = new Vector3(System.Math.Abs(System.Math.Sin(scale.x)) * originalScale, System.Math.Abs(System.Math.Cos(scale.y)) * originalScale, System.Math.Abs(System.Math.Sin(scale.z)) * originalScale); } } \ No newline at end of file diff --git a/TempScriptsFolder/RaccoonSpin.cs b/TempScriptsFolder/RaccoonSpin.cs index 6bbd1462..c5420ffb 100644 --- a/TempScriptsFolder/RaccoonSpin.cs +++ b/TempScriptsFolder/RaccoonSpin.cs @@ -5,8 +5,8 @@ public class RaccoonSpin : Script { [SerializeField] [Tooltip("Speed of the rotation in radians per second.")] - private double RotateSpeed = 1.0; - private double rotation = 0.0; + private float RotateSpeed = 1.0f; + private float rotation = 0.0f; [SerializeField] private CallbackEvent testEvent; [SerializeField] @@ -22,9 +22,4 @@ public class RaccoonSpin : Script Debug.LogError("Transform is NULL!"); } } - protected override void update() - { - rotation += RotateSpeed * 0.16; - Transform.LocalRotation = new Vector3(0.0f, rotation, 0.0f); - } } \ No newline at end of file