Collider now will have it's sub collider list updated based on events

This commit is contained in:
Kah Wei 2022-10-27 12:32:06 +08:00
parent cd04132fd7
commit d45d621701
11 changed files with 202 additions and 46 deletions

View File

@ -10,6 +10,9 @@
#include <SHpch.h> #include <SHpch.h>
// External Dependencies
#include <reactphysics3d/reactphysics3d.h>
// Primary Header // Primary Header
#include "SHRigidBodyComponent.h" #include "SHRigidBodyComponent.h"

View File

@ -10,7 +10,6 @@
#pragma once #pragma once
#include <reactphysics3d/reactphysics3d.h>
#include <rttr/registration> #include <rttr/registration>
// Project Headers // Project Headers
@ -23,6 +22,11 @@
// class SHPhysicsSystem; // class SHPhysicsSystem;
//} //}
namespace reactphysics3d
{
class RigidBody;
}
namespace SHADE namespace SHADE
{ {
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -153,7 +157,7 @@ namespace SHADE
uint16_t dirtyFlags; uint16_t dirtyFlags;
bool interpolate; bool interpolate;
rp3d::RigidBody* rp3dBody; reactphysics3d::RigidBody* rp3dBody;
float mass; float mass;
float drag; float drag;

View File

@ -24,6 +24,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Events/SHEvent.h" #include "Events/SHEvent.h"
#include "Events/SHEventReceiver.h" #include "Events/SHEventReceiver.h"
#include "Events/SHEventManager.hpp" #include "Events/SHEventManager.hpp"
#include "Physics/SHPhysicsSystem.h"
namespace SHADE namespace SHADE
{ {
@ -60,7 +61,7 @@ namespace SHADE
// Initialise the CSharp Engine // Initialise the CSharp Engine
csEngineInit(); csEngineInit();
// Register entity creation events // Register all events
registerEvents(); registerEvents();
} }
void SHScriptEngine::UnloadScriptAssembly() void SHScriptEngine::UnloadScriptAssembly()
@ -284,6 +285,20 @@ namespace SHADE
return eventData->handle; return eventData->handle;
} }
SHEventHandle SHScriptEngine::onColliderAdded(SHEventPtr eventPtr)
{
auto eventData = reinterpret_cast<const SHEventSpec<SHPhysicsColliderAddedEvent>*>(eventPtr.get());
csColliderOnListChanged(eventData->data->entityID);
return eventData->handle;
}
SHEventHandle SHScriptEngine::onColliderRemoved(SHEventPtr eventPtr)
{
auto eventData = reinterpret_cast<const SHEventSpec<SHPhysicsColliderRemovedEvent>*>(eventPtr.get());
csColliderOnListChanged(eventData->data->entityID);
return eventData->handle;
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -384,6 +399,12 @@ namespace SHADE
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore", DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
"DeserialiseScripts" "DeserialiseScripts"
); );
csColliderOnListChanged = dotNet.GetFunctionPtr<CsEventRelayFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".Collider",
"OnColliderBoundChanged"
);
csEditorRenderScripts = dotNet.GetFunctionPtr<CsScriptEditorFuncPtr> csEditorRenderScripts = dotNet.GetFunctionPtr<CsScriptEditorFuncPtr>
( (
DEFAULT_CSHARP_LIB_NAME, DEFAULT_CSHARP_LIB_NAME,
@ -411,8 +432,21 @@ namespace SHADE
{ {
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onEntityDestroyed) std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onEntityDestroyed)
}; };
ReceiverPtr receiver = std::dynamic_pointer_cast<SHEventReceiver>(destroyedEventReceiver); SHEventManager::SubscribeTo(SH_ENTITY_DESTROYED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(destroyedEventReceiver));
SHEventManager::SubscribeTo(SH_ENTITY_DESTROYED_EVENT, receiver);
// Register for collider added event
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> addedColliderEventReceiver
{
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onColliderAdded)
};
SHEventManager::SubscribeTo(SH_PHYSICS_COLLIDER_ADDED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(addedColliderEventReceiver));
// Register for collider removed event
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> removedColliderEventReceiver
{
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onColliderRemoved)
};
SHEventManager::SubscribeTo(SH_PHYSICS_COLLIDER_REMOVED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(removedColliderEventReceiver));
} }
void SHScriptEngine::dumpBuildLog(const std::string_view& buildLogPath) void SHScriptEngine::dumpBuildLog(const std::string_view& buildLogPath)

View File

@ -218,6 +218,7 @@ namespace SHADE
using CsScriptSerialiseYamlFuncPtr = bool(*)(EntityID, void*); using CsScriptSerialiseYamlFuncPtr = bool(*)(EntityID, void*);
using CsScriptDeserialiseYamlFuncPtr = bool(*)(EntityID, const void*); using CsScriptDeserialiseYamlFuncPtr = bool(*)(EntityID, const void*);
using CsScriptEditorFuncPtr = void(*)(EntityID); using CsScriptEditorFuncPtr = void(*)(EntityID);
using CsEventRelayFuncPtr = void(*)(EntityID);
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constants */ /* Constants */
@ -250,6 +251,8 @@ namespace SHADE
CsScriptOptionalFuncPtr csScriptsRemoveAllImmediately = nullptr; CsScriptOptionalFuncPtr csScriptsRemoveAllImmediately = nullptr;
CsScriptSerialiseYamlFuncPtr csScriptsSerialiseYaml = nullptr; CsScriptSerialiseYamlFuncPtr csScriptsSerialiseYaml = nullptr;
CsScriptDeserialiseYamlFuncPtr csScriptsDeserialiseYaml = nullptr; CsScriptDeserialiseYamlFuncPtr csScriptsDeserialiseYaml = nullptr;
// - Events
CsEventRelayFuncPtr csColliderOnListChanged = nullptr;
// - Editor // - Editor
CsScriptEditorFuncPtr csEditorRenderScripts = nullptr; CsScriptEditorFuncPtr csEditorRenderScripts = nullptr;
CsFuncPtr csEditorUndo = nullptr; CsFuncPtr csEditorUndo = nullptr;
@ -259,6 +262,8 @@ namespace SHADE
/* Event Handler Functions */ /* Event Handler Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
SHEventHandle onEntityDestroyed(SHEventPtr eventPtr); SHEventHandle onEntityDestroyed(SHEventPtr eventPtr);
SHEventHandle onColliderAdded(SHEventPtr eventPtr);
SHEventHandle onColliderRemoved(SHEventPtr eventPtr);
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */

View File

@ -134,7 +134,16 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
Collider::Collider(Entity entity) Collider::Collider(Entity entity)
: Component(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 */ /* Collider - Properties */
@ -152,29 +161,7 @@ namespace SHADE
// Populate the list if it hasn't been // Populate the list if it hasn't been
if (subColliderList == nullptr) if (subColliderList == nullptr)
{ {
subColliderList = gcnew System::Collections::Generic::List<ColliderBound^>(); updateSubColliderList();
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);
}
} }
// Check if valid // Check if valid
@ -189,4 +176,68 @@ namespace SHADE
{ {
return safe_cast<T>(GetColliderBound(index)); return safe_cast<T>(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<System::WeakReference^>^ toRemove = gcnew System::Collections::Generic::List<System::WeakReference ^>();
WeakReferenceList^ collidersList = colliders[entity];
for each (System::WeakReference^ wr in collidersList)
{
Collider^ collider = safe_cast<Collider^>(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<ColliderBound^>();
// 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);
}
}
} }

View File

@ -136,7 +136,7 @@ namespace SHADE
/// </summary> /// </summary>
public ref class SphereColliderBound : public ColliderBound public ref class SphereColliderBound : public ColliderBound
{ {
public: public:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Properties */ /* Properties */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -165,7 +165,7 @@ namespace SHADE
/// <inheritdoc/> /// <inheritdoc/>
bool Raycast(Ray ray, float maxDistance) override; bool Raycast(Ray ray, float maxDistance) override;
internal: internal:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constructors */ /* Constructors */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -220,11 +220,33 @@ namespace SHADE
generic<typename T> where T:ColliderBound generic<typename T> where T:ColliderBound
T GetColliderBound(int index); T GetColliderBound(int index);
internal:
/*-----------------------------------------------------------------------------*/
/* Event Handling Functions */
/*-----------------------------------------------------------------------------*/
static void OnColliderBoundChanged(EntityID entity);
private: private:
/*-----------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------*/
using WeakReferenceList = System::Collections::Generic::List<System::WeakReference^>;
using CollidersMap = System::Collections::Generic::Dictionary<EntityID, WeakReferenceList^>;
/*-----------------------------------------------------------------------------*/
/* Static Data Members */
/*-----------------------------------------------------------------------------*/
static CollidersMap^ colliders;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
System::Collections::Generic::List<ColliderBound^>^ subColliderList; // TODO: Update elements in this list if the list on native collider changes System::Collections::Generic::List<ColliderBound^>^ subColliderList;
/*-----------------------------------------------------------------------------*/
/* Helper Functions */
/*-----------------------------------------------------------------------------*/
void updateSubColliderList();
}; };
} }

View File

@ -22,6 +22,8 @@ of DigiPen Institute of Technology is prohibited.
// External Dependencies // External Dependencies
#include "ECS_Base/Managers/SHEntityManager.h" #include "ECS_Base/Managers/SHEntityManager.h"
#include "Math/Transform/SHTransformComponent.h" #include "Math/Transform/SHTransformComponent.h"
#include "Physics\Components\SHColliderComponent.h"
#include "Physics\Components\SHRigidBodyComponent.h"
#include "Scene/SHSceneManager.h" #include "Scene/SHSceneManager.h"
#include "Scene/SHSceneGraph.h" #include "Scene/SHSceneGraph.h"
#include "Tools/SHLog.h" #include "Tools/SHLog.h"
@ -29,6 +31,8 @@ of DigiPen Institute of Technology is prohibited.
#include "Utility/Convert.hxx" #include "Utility/Convert.hxx"
#include "Utility/Debug.hxx" #include "Utility/Debug.hxx"
#include "Components/Transform.hxx" #include "Components/Transform.hxx"
#include "Components\RigidBody.hxx"
#include "Components\Collider.hxx"
namespace SHADE namespace SHADE
{ {
@ -242,6 +246,8 @@ namespace SHADE
static ECS::ECS() static ECS::ECS()
{ {
componentMap.Add(createComponentSet<SHTransformComponent, Transform>()); componentMap.Add(createComponentSet<SHTransformComponent, Transform>());
componentMap.Add(createComponentSet<SHColliderComponent, Collider>());
componentMap.Add(createComponentSet<SHRigidBodyComponent, RigidBody>());
} }
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -132,7 +132,7 @@ namespace SHADE
/// Immutable list of references to scripts of the specified type. /// Immutable list of references to scripts of the specified type.
/// </returns> /// </returns>
generic<typename T> where T : ref class, Script generic<typename T> where T : ref class, Script
static System::Collections::Generic::IEnumerable<T> ^ GetScripts(Entity entity); static System::Collections::Generic::IEnumerable<T>^ GetScripts(Entity entity);
/// <summary> /// <summary>
/// Retrieves an immutable list of all scripts attached to a specified Entity. /// Retrieves an immutable list of all scripts attached to a specified Entity.
/// </summary> /// </summary>
@ -295,4 +295,4 @@ namespace SHADE
static System::Type^ getScriptType(System::String^ scriptName); static System::Type^ getScriptType(System::String^ scriptName);
static bool isEntityActive(Entity entity); static bool isEntityActive(Entity entity);
}; };
} // namespace PlushieAPI }

View File

@ -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<RigidBody>();
if (RigidBody == null)
{
Debug.LogError("RigidBody is NULL!");
}
Collider = GetComponent<Collider>();
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);
}
}
}

View File

@ -12,7 +12,7 @@ public class RaccoonShowcase : Script
//private int test = 5; //private int test = 5;
[SerializeField] [SerializeField]
[Tooltip("Speed of the scaling in radians per second around each axis.")] [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 Transform Transform;
private double rotation = 0.0; private double rotation = 0.0;
private Vector3 scale = Vector3.Zero; private Vector3 scale = Vector3.Zero;
@ -31,9 +31,9 @@ public class RaccoonShowcase : Script
} }
protected override void update() protected override void update()
{ {
rotation += RotateSpeed * 0.16; //rotation += RotateSpeed * 0.16;
scale += ScaleSpeed * 0.16; //scale += ScaleSpeed * 0.16;
Transform.LocalRotation = new Vector3(0.0f, rotation, 0.0f); //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); //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);
} }
} }

View File

@ -5,8 +5,8 @@ public class RaccoonSpin : Script
{ {
[SerializeField] [SerializeField]
[Tooltip("Speed of the rotation in radians per second.")] [Tooltip("Speed of the rotation in radians per second.")]
private double RotateSpeed = 1.0; private float RotateSpeed = 1.0f;
private double rotation = 0.0; private float rotation = 0.0f;
[SerializeField] [SerializeField]
private CallbackEvent<int> testEvent; private CallbackEvent<int> testEvent;
[SerializeField] [SerializeField]
@ -22,9 +22,4 @@ public class RaccoonSpin : Script
Debug.LogError("Transform is NULL!"); Debug.LogError("Transform is NULL!");
} }
} }
protected override void update()
{
rotation += RotateSpeed * 0.16;
Transform.LocalRotation = new Vector3(0.0f, rotation, 0.0f);
}
} }