diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 24f0a214..a4fef1fa 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -108,13 +108,10 @@ namespace Sandbox SHComponentManager::CreateComponentSparseSet(); SHComponentManager::CreateComponentSparseSet(); SHComponentManager::CreateComponentSparseSet(); - SHComponentManager::CreateComponentSparseSet(); + //SHComponentManager::CreateComponentSparseSet(); SHAssetManager::Load(); - auto id = SHFamilyID::GetID(); - auto id2 = SHFamilyID::GetID(); - auto id3 = SHFamilyID::GetID(); SHSystemManager::RegisterRoutine(); diff --git a/SHADE_Engine/src/Camera/SHCameraArmComponent.cpp b/SHADE_Engine/src/Camera/SHCameraArmComponent.cpp new file mode 100644 index 00000000..9cb221ff --- /dev/null +++ b/SHADE_Engine/src/Camera/SHCameraArmComponent.cpp @@ -0,0 +1,68 @@ +#include "SHpch.h" +#include "SHCameraArmComponent.h" + + + +namespace SHADE +{ + + SHCameraArmComponent::SHCameraArmComponent() + :pitch(0.0f), yaw(0.0f), armLength(1.0f),offset(), dirty(true), lookAtCameraOrigin(true) + { + + } + + + SHVec3 const& SHCameraArmComponent::GetOffset() const noexcept + { + return offset; + } + + float SHCameraArmComponent::GetPitch() const noexcept + { + return pitch; + } + + float SHCameraArmComponent::GetYaw() const noexcept + { + return yaw; + } + + float SHCameraArmComponent::GetArmLength() const noexcept + { + return armLength; + } + + void SHCameraArmComponent::SetPitch(float pitch) noexcept + { + this->pitch = pitch; + dirty = true; + } + + void SHCameraArmComponent::SetYaw(float yaw) noexcept + { + this->yaw = yaw; + dirty = true; + } + + void SHCameraArmComponent::SetArmLength(float length) noexcept + { + this->armLength = length; + dirty = true; + } + +}//namespace SHADE + + +RTTR_REGISTRATION +{ + using namespace SHADE; + using namespace rttr; + + registration::class_("Camera Arm Component") + .property("Arm Pitch", &SHCameraArmComponent::GetPitch, &SHCameraArmComponent::SetPitch) + .property("Arm Yaw", &SHCameraArmComponent::GetYaw, &SHCameraArmComponent::SetYaw) + .property("Arm Length", &SHCameraArmComponent::GetArmLength, &SHCameraArmComponent::SetArmLength) + .property("Look At Camera Origin", &SHCameraArmComponent::lookAtCameraOrigin); + +} \ No newline at end of file diff --git a/SHADE_Engine/src/Camera/SHCameraArmComponent.h b/SHADE_Engine/src/Camera/SHCameraArmComponent.h new file mode 100644 index 00000000..2b81a808 --- /dev/null +++ b/SHADE_Engine/src/Camera/SHCameraArmComponent.h @@ -0,0 +1,44 @@ +#pragma once + + +#include +#include "ECS_Base/Components/SHComponent.h" +#include "Math/SHMatrix.h" +#include "SH_API.h" + +namespace SHADE +{ + class SH_API SHCameraArmComponent final: public SHComponent + { + private: + float pitch; + float yaw; + float armLength; + + bool dirty; + SHVec3 offset; + + public: + friend class SHCameraSystem; + SHCameraArmComponent(); + virtual ~SHCameraArmComponent() = default; + + bool lookAtCameraOrigin; + //Getters + //SHMatrix const& GetMatrix() const noexcept; + SHVec3 const& GetOffset() const noexcept; + float GetPitch() const noexcept; + float GetYaw() const noexcept; + float GetArmLength() const noexcept; + + //Setters + void SetPitch(float pitch) noexcept; + void SetYaw(float yaw) noexcept; + void SetArmLength(float length) noexcept; + + protected: + + + }; + +}//namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Camera/SHCameraComponent.cpp b/SHADE_Engine/src/Camera/SHCameraComponent.cpp index 31afe2ac..ac451df5 100644 --- a/SHADE_Engine/src/Camera/SHCameraComponent.cpp +++ b/SHADE_Engine/src/Camera/SHCameraComponent.cpp @@ -13,7 +13,7 @@ namespace SHADE , width(1920.0f), height(1080.0f), zNear(0.01f), zFar(10000.0f), fov(90.0f), movementSpeed(1.0f), turnSpeed(0.5f) , perspProj(true), dirtyView(true), dirtyProj(true) , viewMatrix(), projMatrix() - , position() + , position(), offset() { ComponentFamily::GetID(); } diff --git a/SHADE_Engine/src/Camera/SHCameraComponent.h b/SHADE_Engine/src/Camera/SHCameraComponent.h index f5e08af4..b778b8fa 100644 --- a/SHADE_Engine/src/Camera/SHCameraComponent.h +++ b/SHADE_Engine/src/Camera/SHCameraComponent.h @@ -33,7 +33,7 @@ namespace SHADE SHVec3 position; bool perspProj; - + SHVec3 offset; @@ -41,7 +41,7 @@ namespace SHADE friend class SHCameraSystem; SHCameraComponent(); - ~SHCameraComponent(); + virtual ~SHCameraComponent(); //Getters and setters. diff --git a/SHADE_Engine/src/Camera/SHCameraDirector.cpp b/SHADE_Engine/src/Camera/SHCameraDirector.cpp index 559897c0..98341098 100644 --- a/SHADE_Engine/src/Camera/SHCameraDirector.cpp +++ b/SHADE_Engine/src/Camera/SHCameraDirector.cpp @@ -1,6 +1,7 @@ #include "SHpch.h" #include "SHCameraDirector.h" #include "SHCameraComponent.h" +#include "SHCameraArmComponent.h" #include "ECS_Base/Managers/SHComponentManager.h" #include "ECS_Base/SHECSMacros.h" #include "ECS_Base/Managers/SHEntityManager.h" @@ -48,6 +49,7 @@ namespace SHADE viewMatrix = camComponent->GetViewMatrix(); projMatrix = camComponent->GetProjMatrix(); } + } void SHCameraDirector::SetMainCamera(SHCameraComponent& camera) noexcept diff --git a/SHADE_Engine/src/Camera/SHCameraDirector.h b/SHADE_Engine/src/Camera/SHCameraDirector.h index 5d09788b..6d5404c5 100644 --- a/SHADE_Engine/src/Camera/SHCameraDirector.h +++ b/SHADE_Engine/src/Camera/SHCameraDirector.h @@ -21,6 +21,7 @@ namespace SHADE EntityID mainCameraEID; EntityID transitionCameraEID; + SHMatrix GetViewMatrix() const noexcept; SHMatrix GetProjMatrix() const noexcept; @@ -35,7 +36,7 @@ namespace SHADE protected: SHMatrix viewMatrix; SHMatrix projMatrix; - + }; typedef Handle DirectorHandle; diff --git a/SHADE_Engine/src/Camera/SHCameraSystem.cpp b/SHADE_Engine/src/Camera/SHCameraSystem.cpp index 609805f8..d5bd414d 100644 --- a/SHADE_Engine/src/Camera/SHCameraSystem.cpp +++ b/SHADE_Engine/src/Camera/SHCameraSystem.cpp @@ -1,10 +1,12 @@ #include "SHpch.h" #include "SHCameraSystem.h" +#include "SHCameraArmComponent.h" #include "Math/SHMathHelpers.h" #include "Input/SHInputManager.h" #include "Math/Vector/SHVec2.h" #include "ECS_Base/Managers/SHComponentManager.h" #include "Math/Transform/SHTransformComponent.h" +#include namespace SHADE @@ -59,6 +61,7 @@ namespace SHADE } UpdateCameraComponent(editorCamera); + } void SHCameraSystem::EditorCameraUpdate::Execute(double dt) noexcept { @@ -112,6 +115,8 @@ namespace SHADE //std::cout << "Camera position: " << camera.position.x << " " << camera.position.y << std::endl; system->UpdateCameraComponent(system->editorCamera); + + system->DecomposeViewMatrix(camera.viewMatrix, camera.pitch, camera.yaw, camera.roll, camera.position); } void SHCameraSystem::Init(void) @@ -121,6 +126,9 @@ namespace SHADE editorCamera.SetYaw(0.0f); editorCamera.SetRoll(0.0f); editorCamera.movementSpeed = 2.0f; + + SHComponentManager::CreateComponentSparseSet(); + SHComponentManager::CreateComponentSparseSet(); } @@ -134,6 +142,26 @@ namespace SHADE return &editorCamera; } + void SHCameraSystem::UpdatePivotArmComponent(SHCameraArmComponent& pivot) noexcept + { + if (pivot.dirty) + { + + SHVec3 offset{ 0.0f,0.0f, pivot.GetArmLength() }; + offset = SHVec3::RotateX(offset, -(SHMath::DegreesToRadians(pivot.GetPitch()))); + offset = SHVec3::RotateY(offset, (SHMath::DegreesToRadians(pivot.GetYaw()))); + + + //pivot.rtMatrix = SHMatrix::RotateX(SHMath::DegreesToRadians(pivot.GetPitch())) + // * SHMatrix::RotateY(SHMath::DegreesToRadians(pivot.GetYaw())) + // * SHMatrix::Translate(SHVec3(0.0f , 0.0f, pivot.GetArmLength())); + + pivot.offset = offset; + // pivot.rtMatrix = SHMatrix::Inverse(pivot.rtMatrix); + } + } + + void SHCameraSystem::UpdateCameraComponent(SHCameraComponent& camera) noexcept { if (SHComponentManager::HasComponent(camera.GetEID()) == true && &camera != &editorCamera) @@ -151,6 +179,15 @@ namespace SHADE if (camera.dirtyView) { + camera.offset = SHVec3{ 0.0f }; + if (SHComponentManager::HasComponent(camera.GetEID())) + { + auto arm = SHComponentManager::GetComponent(camera.GetEID()); + camera.offset = arm->GetOffset(); + if(arm->lookAtCameraOrigin) + CameraLookAt(camera, camera.position); + } + SHVec3 view, right, UP; @@ -171,9 +208,12 @@ namespace SHADE camera.viewMatrix(2, 1) = view[1]; camera.viewMatrix(2, 2) = view[2]; - camera.viewMatrix(0, 3) = -right.Dot(camera.position); - camera.viewMatrix(1, 3) = -UP.Dot(camera.position); - camera.viewMatrix(2, 3) = -view.Dot(camera.position); + camera.viewMatrix(0, 3) = -right.Dot(camera.position + camera.offset); + camera.viewMatrix(1, 3) = -UP.Dot(camera.position + camera.offset); + camera.viewMatrix(2, 3) = -view.Dot(camera.position + camera.offset); + + + camera.dirtyView = false; } @@ -221,6 +261,8 @@ namespace SHADE SHVec3 up = { 0.0f,1.0f,0.0f }; + + target = SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch)); target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw)); target += camera.position; @@ -241,6 +283,13 @@ namespace SHADE { SHCameraSystem* system = static_cast(GetSystem()); auto& dense = SHComponentManager::GetDense(); + auto& pivotDense = SHComponentManager::GetDense(); + + for (auto& pivot : pivotDense) + { + system->UpdatePivotArmComponent(pivot); + } + for (auto& cam : dense) { system->UpdateCameraComponent(cam); @@ -274,18 +323,115 @@ namespace SHADE } void SHCameraSystem::ClampCameraRotation(SHCameraComponent& camera) noexcept { + constexpr float clampVal = 85.0f; + if (camera.pitch > clampVal) + camera.SetPitch(clampVal); + if (camera.pitch < -clampVal) + camera.SetPitch(-clampVal); + if (camera.roll > clampVal) + camera.SetRoll(clampVal); + if (camera.roll < -clampVal) + camera.SetRoll(-clampVal); - if (camera.pitch > 85) - camera.SetPitch(85); - if (camera.pitch < -85) - camera.SetPitch(-85); - if (camera.roll > 85) - camera.SetRoll(85); - if (camera.roll < -85) - camera.SetRoll(-85); + while (camera.yaw > 360) + camera.yaw -= 360; + while (camera.yaw < -360) + camera.yaw += 360; } + void SHCameraSystem::SetMainCamera(EntityID eid, size_t directorIndex) noexcept + { + if (SHComponentManager::HasComponent(eid) && directorIndex < directorHandleList.size()) + directorHandleList[directorIndex]->SetMainCamera(*SHComponentManager::GetComponent(eid)); + else + { + SHLOG_WARNING("Set Main Camera warning: Entity does not have camera component or director does not exist.") + } + } + + void SHCameraSystem::DecomposeViewMatrix(SHMatrix const& viewMatrix, float& pitch, float& yaw, float& roll, SHVec3& pos) noexcept + { + + float initPitch = pitch; + SHVec3 initPos = pos; + SHVec3 translate3, scale; + SHQuaternion quat; + + //SHMatrix viewInverse = viewMatrix; + + viewMatrix.Decompose(translate3, quat, scale); + yaw = 180+ SHMath::RadiansToDegrees(quat.ToEuler().y); + pitch = -SHMath::RadiansToDegrees(quat.ToEuler().x); + + SHVec4 dotPos{ -viewMatrix(0,3),-viewMatrix(1,3), -viewMatrix(2,3), 1.0f }; + SHMatrix mtx = viewMatrix; + mtx(0, 3) = 0.0f; + mtx(1, 3) = 0.0f; + mtx(2, 3) = 0.0f; + mtx.Transpose(); + mtx = SHMatrix::Inverse(mtx); + SHVec4 translate = mtx* dotPos; + + pos.x = translate.x; + pos.y = translate.y; + pos.z = translate.z; + + } + void SHCameraSystem::SetCameraViewMatrix(SHCameraComponent& camera, SHMatrix const& viewMatrix) noexcept + { + DecomposeViewMatrix(viewMatrix, camera.pitch, camera.yaw, camera.roll, camera.position); + camera.dirtyView = true; + } + + void SHCameraSystem::CameraLookAt(SHCameraComponent& camera, SHVec3 target) noexcept + { + + if (camera.position == target) + { + //lets off set it abit so the view is nt fked + target.z -= 0.0001f; + } + SHVec3 forward, right, upVec; + + SHVec3 up = { 0.0f,1.0f,0.0f }; + + + ////SHVec3::RotateZ(target, SHMath::DegreesToRadians(camera.roll)); + + //target = SHVec3::Normalise(target); + + SHVec3::RotateZ(up, camera.roll); + up = SHVec3::Normalise(up); + + + forward = target - (camera.position + camera.offset); forward = SHVec3::Normalise(forward); + right = SHVec3::Cross(forward, up); right = SHVec3::Normalise(right); + upVec = SHVec3::Cross(forward, right); + + + SHMatrix viewMtx; + viewMtx = SHMatrix::Identity; + viewMtx(0, 0) = right[0]; + viewMtx(0, 1) = right[1]; + viewMtx(0, 2) = right[2]; + + viewMtx(1, 0) = upVec[0]; + viewMtx(1, 1) = upVec[1]; + viewMtx(1, 2) = upVec[2]; + + viewMtx(2, 0) = forward[0]; + viewMtx(2, 1) = forward[1]; + viewMtx(2, 2) = forward[2]; + + viewMtx(0, 3) = -right.Dot(camera.position + camera.offset); + viewMtx(1, 3) = -upVec.Dot(camera.position + camera.offset); + viewMtx(2, 3) = -forward.Dot(camera.position + camera.offset); + + + SetCameraViewMatrix(camera, viewMtx); + } + } diff --git a/SHADE_Engine/src/Camera/SHCameraSystem.h b/SHADE_Engine/src/Camera/SHCameraSystem.h index 68071160..98fd442f 100644 --- a/SHADE_Engine/src/Camera/SHCameraSystem.h +++ b/SHADE_Engine/src/Camera/SHCameraSystem.h @@ -9,6 +9,9 @@ namespace SHADE { + + class SHCameraArmComponent; + class SH_API SHCameraSystem final : public SHSystem { private: @@ -19,6 +22,11 @@ namespace SHADE SHResourceLibrary directorLibrary; std::vector directorHandleList; + + void UpdateCameraComponent(SHCameraComponent& camera) noexcept; + void UpdatePivotArmComponent(SHCameraArmComponent& pivot) noexcept; + + public: SHCameraSystem(void) = default; virtual ~SHCameraSystem(void) = default; @@ -39,7 +47,7 @@ namespace SHADE class SH_API CameraSystemUpdate final: public SHSystemRoutine { public: - CameraSystemUpdate() : SHSystemRoutine("Camera System Update", false) {}; + CameraSystemUpdate() : SHSystemRoutine("Camera System Update", true) {}; virtual void Execute(double dt)noexcept override final; }; friend class CameraSystemUpdate; @@ -51,12 +59,10 @@ namespace SHADE DirectorHandle GetDirector(size_t index) noexcept; void ClampCameraRotation(SHCameraComponent& camera) noexcept; void UpdateEditorCamera(double dt) noexcept; - protected: - - void UpdateCameraComponent(SHCameraComponent& camera) noexcept; - - - + void SetMainCamera(EntityID eid, size_t directorIndex) noexcept; + void DecomposeViewMatrix(SHMatrix const& matrix, float& pitch, float& yaw, float& roll, SHVec3& pos) noexcept; + void SetCameraViewMatrix(SHCameraComponent& camera, SHMatrix const& viewMatrix) noexcept; + void CameraLookAt(SHCameraComponent& camera, SHVec3 target) noexcept; }; diff --git a/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.cpp b/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.cpp index be78a146..75a86f37 100644 --- a/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.cpp +++ b/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.cpp @@ -40,6 +40,12 @@ namespace SHADE { comp->OnDestroy(); } + SHComponentRemovedEvent eventData; + eventData.eid = entityID; + eventData.removedComponentType = i; + + SHEventManager::BroadcastEvent(eventData, SH_COMPONENT_REMOVED_EVENT); + } @@ -53,6 +59,7 @@ namespace SHADE //entityHandle.RemoveHandle(entityID); + } diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp index c4a86785..2fecae25 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp @@ -17,6 +17,7 @@ #include "Physics/Components/SHRigidBodyComponent.h" #include "Physics/Components/SHColliderComponent.h" #include "Camera/SHCameraComponent.h" +#include "Camera/SHCameraArmComponent.h" #include "SHEditorComponentView.h" namespace SHADE @@ -126,6 +127,9 @@ namespace SHADE if (auto cameraComponent = SHComponentManager::GetComponent_s(eid)) { DrawComponent(cameraComponent); + }if (auto cameraArmComponent = SHComponentManager::GetComponent_s(eid)) + { + DrawComponent(cameraArmComponent); } ImGui::Separator(); // Render Scripts @@ -136,6 +140,7 @@ namespace SHADE { DrawAddComponentButton(eid); DrawAddComponentButton(eid); + DrawAddComponentButton(eid); DrawAddComponentButton(eid); // Components that require Transforms diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp index 156a47cc..de42121d 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp @@ -47,16 +47,14 @@ namespace SHADE { // Get the current scene graph to traverse and update const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); - - // TODO(Diren): Consider how to clear dirty in pause / stop mode and update physics, but do not clear in play mode. - UpdateEntity(SCENE_GRAPH.GetRoot(), false); + UpdateEntity(SCENE_GRAPH.GetRoot(), !IsRunInEditorPause); } void SHTransformSystem::TransformPostPhysicsUpdate::Execute(double) noexcept { // Get the current scene graph to traverse and update const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); - UpdateEntity(SCENE_GRAPH.GetRoot(), true); + UpdateEntity(SCENE_GRAPH.GetRoot(), IsRunInEditorPause); } void SHTransformSystem::Init() diff --git a/SHADE_Engine/src/Physics/SHCollider.h b/SHADE_Engine/src/Physics/SHCollider.h index f760ffd0..65e35698 100644 --- a/SHADE_Engine/src/Physics/SHCollider.h +++ b/SHADE_Engine/src/Physics/SHCollider.h @@ -96,7 +96,7 @@ namespace SHADE void SetDensity (float density) noexcept; void SetMaterial (const SHPhysicsMaterial& newMaterial) noexcept; - void SetPositionOffset (const SHVec3& positionOffset) noexcept; + void SetPositionOffset (const SHVec3& posOffset) noexcept; private: /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp index 4d4d8cd7..8b556409 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp @@ -172,90 +172,94 @@ namespace SHADE { SHASSERT(rp3dBody != nullptr, "ReactPhysics body does not exist!") - if (rb->dirtyFlags == 0) - return; - auto* rigidBody = reinterpret_cast(rp3dBody); - - const uint16_t RB_FLAGS = rb->dirtyFlags; - for (size_t i = 0; i < SHRigidBodyComponent::NUM_DIRTY_FLAGS; ++i) + if (rb->dirtyFlags != 0) { - // Check if current dirty flag has been set to true - if (RB_FLAGS & 1U << i) + const uint16_t RB_FLAGS = rb->dirtyFlags; + for (size_t i = 0; i < SHRigidBodyComponent::NUM_DIRTY_FLAGS; ++i) { - switch (i) + // Check if current dirty flag has been set to true + if (RB_FLAGS & 1U << i) { - case 0: // Gravity + switch (i) { - rigidBody->enableGravity(rb->IsGravityEnabled()); - break; - } - case 1: // Sleeping - { - rigidBody->setIsAllowedToSleep(rb->IsAllowedToSleep()); - break; - } - case 2: // Linear Constraints - { - const rp3d::Vector3 CONSTRAINTS + case 0: // Gravity { - rb->flags & 1U << 2 ? 0.0f : 1.0f, - rb->flags & 1U << 3 ? 0.0f : 1.0f, - rb->flags & 1U << 4 ? 0.0f : 1.0f - }; + rigidBody->enableGravity(rb->IsGravityEnabled()); + break; + } + case 1: // Sleeping + { + rigidBody->setIsAllowedToSleep(rb->IsAllowedToSleep()); + break; + } + case 2: // Linear Constraints + { + const rp3d::Vector3 CONSTRAINTS + { + rb->flags & 1U << 2 ? 0.0f : 1.0f, + rb->flags & 1U << 3 ? 0.0f : 1.0f, + rb->flags & 1U << 4 ? 0.0f : 1.0f + }; - rigidBody->setLinearLockAxisFactor(CONSTRAINTS); - break; - } - case 3: // Angular Constraints - { - const rp3d::Vector3 CONSTRAINTS + rigidBody->setLinearLockAxisFactor(CONSTRAINTS); + break; + } + case 3: // Angular Constraints { - rb->flags & 1U << 5 ? 0.0f : 1.0f, - rb->flags & 1U << 6 ? 0.0f : 1.0f, - rb->flags & 1U << 7 ? 0.0f : 1.0f - }; + const rp3d::Vector3 CONSTRAINTS + { + rb->flags & 1U << 5 ? 0.0f : 1.0f, + rb->flags & 1U << 6 ? 0.0f : 1.0f, + rb->flags & 1U << 7 ? 0.0f : 1.0f + }; - rigidBody->setAngularLockAxisFactor(CONSTRAINTS); - break; + rigidBody->setAngularLockAxisFactor(CONSTRAINTS); + break; + } + case 4: // Type + { + rigidBody->setType(static_cast(rb->GetType())); + break; + } + case 5: // Mass + { + rigidBody->setMass(rb->GetMass()); + break; + } + case 6: // Drag + { + rigidBody->setLinearDamping(rb->GetDrag()); + break; + } + case 7: // Angular Drag + { + rigidBody->setAngularDamping(rb->GetAngularDrag()); + break; + } + case 8: // Linear Velocity + { + rigidBody->setLinearVelocity(rb->GetLinearVelocity()); + break; + } + case 9: // Angular Velocity + { + rigidBody->setAngularVelocity(rb->GetAngularVelocity()); + break; + } + default: break; } - case 4: // Type - { - rigidBody->setType(static_cast(rb->GetType())); - break; - } - case 5: // Mass - { - rigidBody->setMass(rb->GetMass()); - break; - } - case 6: // Drag - { - rigidBody->setLinearDamping(rb->GetDrag()); - break; - } - case 7: // Angular Drag - { - rigidBody->setAngularDamping(rb->GetAngularDrag()); - break; - } - case 8: // Linear Velocity - { - rigidBody->setLinearVelocity(rb->GetLinearVelocity()); - break; - } - case 9: // Angular Velocity - { - rigidBody->setAngularVelocity(rb->GetAngularVelocity()); - break; - } - default: break; } } - } - rb->dirtyFlags = 0; + rb->dirtyFlags = 0; + } + else + { + rb->linearVelocity = rigidBody->getLinearVelocity(); + rb->angularVelocity = rigidBody->getAngularVelocity(); + } } void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept @@ -266,8 +270,12 @@ namespace SHADE if (!collider.dirty) continue; - // Update offsets auto* rp3dCollider = rp3dBody->getCollider(index); + + // Update trigger flag + rp3dCollider->setIsTrigger(collider.IsTrigger()); + + // Update offsets rp3dCollider->setLocalToBodyTransform(rp3d::Transform(collider.GetPositionOffset(), SHQuaternion::Identity)); switch (collider.GetType()) @@ -293,6 +301,8 @@ namespace SHADE default: break; } + // TODO(Diren): Update Material + collider.dirty = false; ++index; } diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 03241dd4..ac0eb792 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -99,6 +99,16 @@ namespace SHADE return 0; } + const SHPhysicsSystem::CollisionEvents& SHPhysicsSystem::GetCollisionInfo() const noexcept + { + return collisionInfo; + } + + const SHPhysicsSystem::CollisionEvents& SHPhysicsSystem::GetTriggerInfo() const noexcept + { + return triggerInfo; + } + /*-----------------------------------------------------------------------------------*/ /* Setter Function Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -187,6 +197,7 @@ namespace SHADE settings.defaultBounciness = 0.0f; world = factory.createPhysicsWorld(settings); + world->setEventListener(this); // Set up solvers world->setContactsPositionCorrectionTechnique(rp3d::ContactsPositionCorrectionTechnique::SPLIT_IMPULSES); @@ -246,7 +257,10 @@ namespace SHADE if (physicsObject.rp3dBody == nullptr) continue; - const auto* transformComponent = SHComponentManager::GetComponent_s(entityID); + const auto* transformComponent = SHComponentManager::GetComponent_s(entityID); + auto* rigidBodyComponent = SHComponentManager::GetComponent_s(entityID); + auto* colliderComponent = SHComponentManager::GetComponent_s(entityID); + if (transformComponent && transformComponent->HasChanged()) { const auto WORLD_POS = transformComponent->GetWorldPosition(); @@ -255,35 +269,58 @@ namespace SHADE physicsObject.SetPosition(WORLD_POS); physicsObject.SetOrientation(WORLD_ROT); - auto* rigidBodyComponent = SHComponentManager::GetComponent_s(entityID); + // Sync physics component transforms + if (rigidBodyComponent) { rigidBodyComponent->position = WORLD_POS; rigidBodyComponent->orientation = WORLD_ROT; - - // Clear all forces and velocities if editor is stopped - if (SHSystemManager::GetSystem()->editorState == SHEditor::State::STOP) - { - auto* rp3dRigidBody = reinterpret_cast(physicsObject.rp3dBody); - rp3dRigidBody->resetForce(); - rp3dRigidBody->resetTorque(); - rp3dRigidBody->setLinearVelocity(SHVec3::Zero); - rp3dRigidBody->setAngularVelocity(SHVec3::Zero); - } } - auto* colliderComponent = SHComponentManager::GetComponent_s(entityID); if (colliderComponent) { colliderComponent->position = WORLD_POS; colliderComponent->orientation = WORLD_ROT; } } - } - // Update bodies and colliders if component is dirty - system->SyncRigidBodyComponents(SHComponentManager::GetDense()); - system->SyncColliderComponents(SHComponentManager::GetDense()); + // Sync rigid bodies + + if (rigidBodyComponent) + { + // Clear all forces and velocities if editor is stopped + if (SHSystemManager::GetSystem()->editorState == SHEditor::State::STOP) + { + auto* rp3dRigidBody = reinterpret_cast(physicsObject.rp3dBody); + rp3dRigidBody->resetForce(); + rp3dRigidBody->resetTorque(); + rp3dRigidBody->setLinearVelocity(SHVec3::Zero); + rp3dRigidBody->setAngularVelocity(SHVec3::Zero); + } + + // Sync active states + const bool COMPONENT_ACTIVE = rigidBodyComponent->isActive; + SyncActiveStates(physicsObject, COMPONENT_ACTIVE); + + if (!COMPONENT_ACTIVE) + continue; + + physicsObject.SyncRigidBody(rigidBodyComponent); + } + + // Sync colliders + + if (colliderComponent) + { + const bool COMPONENT_ACTIVE = colliderComponent->isActive; + SyncActiveStates(physicsObject, colliderComponent->isActive); + + if (!COMPONENT_ACTIVE) + continue; + + physicsObject.SyncColliders(colliderComponent); + } + } } void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept @@ -316,7 +353,31 @@ namespace SHADE { system->SyncTransforms(); - // TODO(Diren): Handle trigger messages for scripting + // TODO(Kah Wei): Take Collision & Trigger messages here + + system->ClearInvalidCollisions(); + } + } + + void SHPhysicsSystem::onContact(const CallbackData& callbackData) + { + for (uint32_t i = 0; i < callbackData.getNbContactPairs(); ++i) + { + const auto CONTACT_PAIR = callbackData.getContactPair(i); + const SHCollisionEvent NEW_EVENT = GenerateCollisionEvent(CONTACT_PAIR); + + UpdateEventContainers(NEW_EVENT, collisionInfo); + } + } + + void SHPhysicsSystem::onTrigger(const rp3d::OverlapCallback::CallbackData& callbackData) + { + for (uint32_t i = 0; i < callbackData.getNbOverlappingPairs(); ++i) + { + const auto& OVERLAP_PAIR = callbackData.getOverlappingPair(i); + const SHCollisionEvent NEW_EVENT = GenerateCollisionEvent(OVERLAP_PAIR); + + UpdateEventContainers(NEW_EVENT, triggerInfo); } } @@ -353,58 +414,11 @@ namespace SHADE map.erase(entityID); } - void SHPhysicsSystem::SyncActiveStates(SHPhysicsObject* physicsObject, bool componentActive) noexcept + void SHPhysicsSystem::SyncActiveStates(SHPhysicsObject& physicsObject, bool componentActive) noexcept { - const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive(); + const bool RP3D_ACTIVE = physicsObject.rp3dBody->isActive(); if (RP3D_ACTIVE != componentActive) - physicsObject->rp3dBody->setIsActive(componentActive); - } - - - void SHPhysicsSystem::SyncRigidBodyComponents(std::vector& denseArray) noexcept - { - if (denseArray.empty()) - return; - - for (auto& comp : denseArray) - { - const EntityID ENTITY_ID = comp.GetEID(); - - // Get physicsObject - auto* physicsObject = GetPhysicsObject(ENTITY_ID); - - // TODO(Diren): Check if active in hierarchy - const bool COMPONENT_ACTIVE = comp.isActive; - SyncActiveStates(physicsObject, COMPONENT_ACTIVE); - - if (!COMPONENT_ACTIVE) - continue; - - physicsObject->SyncRigidBody(&comp); - } - } - - void SHPhysicsSystem::SyncColliderComponents(std::vector& denseArray) noexcept - { - if (denseArray.empty()) - return; - - for (auto& comp : denseArray) - { - const EntityID ENTITY_ID = comp.GetEID(); - - // Get physicsObject - auto* physicsObject = GetPhysicsObject(ENTITY_ID); - - // TODO(Diren): Check if active in hierarchy - const bool COMPONENT_ACTIVE = comp.isActive; - SyncActiveStates(physicsObject, COMPONENT_ACTIVE); - - if (!COMPONENT_ACTIVE) - continue; - - physicsObject->SyncColliders(&comp); - } + physicsObject.rp3dBody->setIsActive(componentActive); } void SHPhysicsSystem::SyncTransforms() noexcept @@ -459,15 +473,54 @@ namespace SHADE } // Convert RP3D Transform to SHADE - auto* transformComponent = SHComponentManager::GetComponent(entityID); - transformComponent->SetWorldPosition(rp3dPos); - transformComponent->SetWorldOrientation(rp3dRot); + auto* transformComponent = SHComponentManager::GetComponent_s(entityID); + + if (transformComponent != nullptr) + { + transformComponent->SetWorldPosition(rp3dPos); + transformComponent->SetWorldOrientation(rp3dRot); + } // Cache transforms physicsObject.prevTransform = CURRENT_TF; } } + void SHPhysicsSystem::UpdateEventContainers(const SHCollisionEvent& collisionEvent, CollisionEvents& container) noexcept + { + const auto IT = std::ranges::find_if(container.begin(), container.end(), [&](const SHCollisionEvent& e) + { + const bool ENTITY_MATCH = e.value[0] == collisionEvent.value[0]; + const bool COLLIDERS_MATCH = e.value[1] == collisionEvent.value[1]; + return ENTITY_MATCH && COLLIDERS_MATCH; + }); + + if (IT == container.end()) + container.emplace_back(collisionEvent); + else + IT->collisionState = collisionEvent.collisionState; + } + + void SHPhysicsSystem::ClearInvalidCollisions() noexcept + { + static const auto CLEAR = [](CollisionEvents& container) + { + for (auto eventIter = container.begin(); eventIter != container.end();) + { + const bool CLEAR_EVENT = eventIter->GetCollisionState() == SHCollisionEvent::State::EXIT + || eventIter->GetCollisionState() == SHCollisionEvent::State::INVALID; + + if (CLEAR_EVENT) + eventIter = container.erase(eventIter); + else + ++eventIter; + } + }; + + CLEAR(collisionInfo); + CLEAR(triggerInfo); + } + SHEventHandle SHPhysicsSystem::AddPhysicsComponent(SHEventPtr addComponentEvent) { const auto& EVENT_DATA = reinterpret_cast*>(addComponentEvent.get()); @@ -556,6 +609,9 @@ namespace SHADE const EntityID ENTITY_ID = EVENT_DATA->data->eid; auto* physicsObject = GetPhysicsObject(ENTITY_ID); + auto* rigidBodyComponent = SHComponentManager::GetComponent_s(ENTITY_ID); + auto* colliderComponent = SHComponentManager::GetComponent_s(ENTITY_ID); + SHASSERT(physicsObject != nullptr, "Physics object has been lost from the world!") if (REMOVED_ID == RIGID_BODY_ID) @@ -563,7 +619,6 @@ namespace SHADE world->destroyRigidBody(reinterpret_cast(physicsObject->rp3dBody)); physicsObject->rp3dBody = nullptr; - auto* colliderComponent = SHComponentManager::GetComponent_s(ENTITY_ID); if (colliderComponent != nullptr) { // Preserve colliders as a collision body @@ -594,6 +649,10 @@ namespace SHADE auto* collider = physicsObject->rp3dBody->getCollider(i); physicsObject->rp3dBody->removeCollider(collider); } + + // Check for a rigidbody component + if (rigidBodyComponent == nullptr) + physicsObject->rp3dBody = nullptr; } if (physicsObject->rp3dBody == nullptr) diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index a3c3bea1..f564dc2d 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -23,16 +23,23 @@ #include "Math/Transform/SHTransformComponent.h" #include "Scene/SHSceneGraph.h" #include "SHPhysicsObject.h" - +#include "SHPhysicsUtils.h" namespace SHADE { + /*-----------------------------------------------------------------------------------*/ + /* Concepts */ + /*-----------------------------------------------------------------------------------*/ + + + /*-----------------------------------------------------------------------------------*/ /* Type Definitions */ /*-----------------------------------------------------------------------------------*/ - class SH_API SHPhysicsSystem final : public SHSystem + class SH_API SHPhysicsSystem final : public SHSystem + , public rp3d::EventListener { public: /*---------------------------------------------------------------------------------*/ @@ -47,6 +54,8 @@ namespace SHADE bool sleepingEnabled; }; + using CollisionEvents = std::vector; + /*---------------------------------------------------------------------------------*/ /* Constructors & Destructor */ /*---------------------------------------------------------------------------------*/ @@ -57,13 +66,16 @@ namespace SHADE /* Getter Functions */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] double GetFixedDT () const noexcept; + [[nodiscard]] double GetFixedDT () const noexcept; - [[nodiscard]] bool IsSleepingEnabled () const noexcept; + [[nodiscard]] bool IsSleepingEnabled () const noexcept; - [[nodiscard]] SHVec3 GetWorldGravity () const noexcept; - [[nodiscard]] uint16_t GetNumberVelocityIterations () const noexcept; - [[nodiscard]] uint16_t GetNumberPositionIterations () const noexcept; + [[nodiscard]] SHVec3 GetWorldGravity () const noexcept; + [[nodiscard]] uint16_t GetNumberVelocityIterations () const noexcept; + [[nodiscard]] uint16_t GetNumberPositionIterations () const noexcept; + + [[nodiscard]] const CollisionEvents& GetCollisionInfo () const noexcept; + [[nodiscard]] const CollisionEvents& GetTriggerInfo () const noexcept; /*---------------------------------------------------------------------------------*/ @@ -82,16 +94,14 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - void Init () override; - void Exit () override; + void Init () override; + void Exit () override; - //void AddRigidBody (EntityID entityID) noexcept; - //void AddCollider (EntityID entityID) noexcept; - //void RemoveRigidBody (EntityID entityID) noexcept; - //void RemoveCollider (EntityID entityID) noexcept; + void AddCollisionShape (EntityID entityID, SHCollider* collider); + void RemoveCollisionShape (EntityID entityID, int index); - void AddCollisionShape (EntityID entityID, SHCollider* collider); - void RemoveCollisionShape (EntityID entityID, int index); + void onContact (const rp3d::CollisionCallback::CallbackData& callbackData) override; + void onTrigger (const rp3d::OverlapCallback::CallbackData& callbackData) override; /*---------------------------------------------------------------------------------*/ /* System Routines */ @@ -156,49 +166,40 @@ namespace SHADE /* Data Members */ /*---------------------------------------------------------------------------------*/ - bool worldUpdated; + bool worldUpdated; - double interpolationFactor; - double fixedDT; - - rp3d::PhysicsWorld* world; - rp3d::PhysicsCommon factory; - - EntityObjectMap map; + double interpolationFactor; + double fixedDT; + rp3d::PhysicsWorld* world; + rp3d::PhysicsCommon factory; + EntityObjectMap map; + CollisionEvents collisionInfo; + CollisionEvents triggerInfo; /*---------------------------------------------------------------------------------*/ /* Function Members */ /*---------------------------------------------------------------------------------*/ - SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept; - SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept; - void DestroyPhysicsObject (EntityID entityID) noexcept; - void SyncActiveStates (SHPhysicsObject* physicsObject, bool componentActive) noexcept; - void SyncRigidBodyComponents (std::vector& denseArray) noexcept; - void SyncColliderComponents (std::vector& denseArray) noexcept; + SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept; + SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept; + void DestroyPhysicsObject (EntityID entityID) noexcept; + + static void SyncActiveStates (SHPhysicsObject& physicsObject, bool componentActive) noexcept; void SyncTransforms () noexcept; + static void UpdateEventContainers (const SHCollisionEvent& collisionEvent, CollisionEvents& container) noexcept; + void ClearInvalidCollisions () noexcept; + SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent); SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent); + + template + || std::is_same_v>> + SHCollisionEvent GenerateCollisionEvent (const RP3DCollisionPair& cp) noexcept; }; +} // namespace SHADE - /*-----------------------------------------------------------------------------------*/ - /* Event Data Definitions */ - /*-----------------------------------------------------------------------------------*/ - - struct SHPhysicsColliderAddedEvent - { - EntityID entityID; - SHCollider::Type colliderType; - int colliderIndex; - }; - - struct SHPhysicsColliderRemovedEvent - { - EntityID entityID; - int colliderIndex; - }; - -} // namespace SHADE \ No newline at end of file +#include "SHPhysicsSystem.hpp" \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.hpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.hpp new file mode 100644 index 00000000..02569d14 --- /dev/null +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.hpp @@ -0,0 +1,84 @@ +/**************************************************************************************** + * \file SHPhysicsSystem.hpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for templated functions the Physics 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 + +// Primary Header +#include "SHPhysicsSystem.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Private Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + template + SHCollisionEvent SHPhysicsSystem::GenerateCollisionEvent(const RP3DCollisionPair& cp) noexcept + { + static const auto MATCH_COLLIDER = [] + ( + const SHPhysicsObject& physicsObject + , const rp3d::Entity colliderID + )->uint32_t + { + for (uint32_t i = 0; i < physicsObject.rp3dBody->getNbColliders(); ++i) + { + const auto* collider = physicsObject.rp3dBody->getCollider(i); + if (collider->getEntity() == colliderID) + return i; + } + + return std::numeric_limits::max(); + }; + + SHCollisionEvent cInfo; + + // Match body and collider for collision event + const rp3d::Entity body1 = cp.getBody1()->getEntity(); + const rp3d::Entity body2 = cp.getBody2()->getEntity(); + const rp3d::Entity collider1 = cp.getCollider1()->getEntity(); + const rp3d::Entity collider2 = cp.getCollider2()->getEntity(); + + // Find and match both ids + bool matched[2] = { false, false }; + + + for (auto& [entityID, physicsObject] : map) + { + // Match body 1 + if (matched[SHCollisionEvent::ENTITY_A] == false && physicsObject.rp3dBody->getEntity() == body1) + { + cInfo.ids[SHCollisionEvent::ENTITY_A] = entityID; + cInfo.ids[SHCollisionEvent::COLLIDER_A] = MATCH_COLLIDER(physicsObject, collider1); + + matched[SHCollisionEvent::ENTITY_A] = true; + } + + // Match body 2 + if (matched[SHCollisionEvent::ENTITY_B] == false && physicsObject.rp3dBody->getEntity() == body2) + { + cInfo.ids[SHCollisionEvent::ENTITY_B] = entityID; + cInfo.ids[SHCollisionEvent::COLLIDER_B] = MATCH_COLLIDER(physicsObject, collider2); + + matched[SHCollisionEvent::ENTITY_B] = true; + } + + if (matched[SHCollisionEvent::ENTITY_A] == true && matched[SHCollisionEvent::ENTITY_B] == true) + return cInfo; + } + + // Update collision state + cInfo.collisionState = static_cast(cp.getEventType()); + + return cInfo; + } +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsUtils.cpp b/SHADE_Engine/src/Physics/SHPhysicsUtils.cpp new file mode 100644 index 00000000..8d5bc956 --- /dev/null +++ b/SHADE_Engine/src/Physics/SHPhysicsUtils.cpp @@ -0,0 +1,93 @@ +/**************************************************************************************** + * \file SHPhysicsUtils.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for some Physics Utilities + * + * \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 "SHPhysicsUtils.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHCollisionEvent::SHCollisionEvent() noexcept + : collisionState { State::INVALID } + { + ids[ENTITY_A] = MAX_EID; + ids[ENTITY_B] = MAX_EID; + ids[COLLIDER_A] = std::numeric_limits::max(); + ids[COLLIDER_B] = std::numeric_limits::max(); + } + + SHCollisionEvent::SHCollisionEvent(EntityID entityA, EntityID entityB) noexcept + : collisionState { State::INVALID } + { + ids[ENTITY_A] = entityA; + ids[ENTITY_B] = entityB; + ids[COLLIDER_A] = std::numeric_limits::max(); + ids[COLLIDER_B] = std::numeric_limits::max(); + } + + /*-----------------------------------------------------------------------------------*/ + /* Operator Overload Definitions */ + /*-----------------------------------------------------------------------------------*/ + + bool SHCollisionEvent::operator==(const SHCollisionEvent& rhs) const noexcept + { + return value[0] == rhs.value[0] && value[1] == rhs.value[1]; + } + + bool SHCollisionEvent::operator!=(const SHCollisionEvent& rhs) const noexcept + { + return value[0] != rhs.value[0] || value[1] != rhs.value[1]; + } + + /*-----------------------------------------------------------------------------------*/ + /* Getter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + EntityID SHCollisionEvent::GetEntityA() const noexcept + { + return ids[ENTITY_A]; + } + + EntityID SHCollisionEvent::GetEntityB() const noexcept + { + return ids[ENTITY_B]; + } + + const SHRigidBodyComponent* SHCollisionEvent::GetRigidBodyA() const noexcept + { + return SHComponentManager::GetComponent_s(ids[ENTITY_A]); + } + + const SHRigidBodyComponent* SHCollisionEvent::GetRigidBodyB() const noexcept + { + return SHComponentManager::GetComponent_s(ids[ENTITY_B]); + } + + const SHCollider* SHCollisionEvent::GetColliderA() const noexcept + { + return &SHComponentManager::GetComponent(ids[ENTITY_A])->GetCollider(ids[COLLIDER_A]); + } + + const SHCollider* SHCollisionEvent::GetColliderB() const noexcept + { + return &SHComponentManager::GetComponent(ids[ENTITY_B])->GetCollider(ids[COLLIDER_B]); + } + + SHCollisionEvent::State SHCollisionEvent::GetCollisionState() const noexcept + { + return collisionState; + } + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsUtils.h b/SHADE_Engine/src/Physics/SHPhysicsUtils.h new file mode 100644 index 00000000..57f9c6fc --- /dev/null +++ b/SHADE_Engine/src/Physics/SHPhysicsUtils.h @@ -0,0 +1,116 @@ +/**************************************************************************************** + * \file SHPhysicsUtils.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for some Physics Utilities + * + * \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 + +// Project Headers +#include "Components/SHColliderComponent.h" +#include "Components/SHRigidBodyComponent.h" + + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + struct SHPhysicsColliderAddedEvent + { + EntityID entityID; + SHCollider::Type colliderType; + int colliderIndex; + }; + + struct SHPhysicsColliderRemovedEvent + { + EntityID entityID; + int colliderIndex; + }; + + class SH_API SHCollisionEvent + { + private: + /*---------------------------------------------------------------------------------*/ + /* Friends */ + /*---------------------------------------------------------------------------------*/ + + friend class SHPhysicsSystem; + + public: + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + + enum class State + { + ENTER + , STAY + , EXIT + + , TOTAL + , INVALID = -1 + }; + + /*---------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*---------------------------------------------------------------------------------*/ + + SHCollisionEvent () noexcept; + SHCollisionEvent (EntityID entityA, EntityID entityB) noexcept; + + + SHCollisionEvent (const SHCollisionEvent& rhs) = default; + SHCollisionEvent (SHCollisionEvent&& rhs) = default; + ~SHCollisionEvent () = default; + + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + + bool operator== (const SHCollisionEvent& rhs) const noexcept; + bool operator!= (const SHCollisionEvent& rhs) const noexcept; + + SHCollisionEvent& operator= (const SHCollisionEvent& rhs) = default; + SHCollisionEvent& operator= (SHCollisionEvent&& rhs) = default; + + /*---------------------------------------------------------------------------------*/ + /* Getter Functions */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] EntityID GetEntityA () const noexcept; + [[nodiscard]] EntityID GetEntityB () const noexcept; + [[nodiscard]] const SHRigidBodyComponent* GetRigidBodyA () const noexcept; + [[nodiscard]] const SHRigidBodyComponent* GetRigidBodyB () const noexcept; + [[nodiscard]] const SHCollider* GetColliderA () const noexcept; + [[nodiscard]] const SHCollider* GetColliderB () const noexcept; + [[nodiscard]] State GetCollisionState () const noexcept; + + private: + + static constexpr uint32_t ENTITY_A = 0; + static constexpr uint32_t ENTITY_B = 1; + static constexpr uint32_t COLLIDER_A = 2; + static constexpr uint32_t COLLIDER_B = 3; + + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + + union + { + uint64_t value[2]; // EntityValue, ColliderIndexValue + uint32_t ids [4]; // EntityA, EntityB, ColliderIndexA, ColliderIndexB + }; + + State collisionState; + }; + + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Managed/src/Engine/GameObject.cxx b/SHADE_Managed/src/Engine/GameObject.cxx index c9a3cebc..55d53d68 100644 --- a/SHADE_Managed/src/Engine/GameObject.cxx +++ b/SHADE_Managed/src/Engine/GameObject.cxx @@ -21,6 +21,7 @@ of DigiPen Institute of Technology is prohibited. #include "ECS.hxx" #include "Utility/Convert.hxx" #include "Scripts/ScriptStore.hxx" +#include "Utility/Debug.hxx" namespace SHADE { @@ -63,7 +64,13 @@ namespace SHADE } bool GameObject::IsActiveInHierarchy::get() { - return true; // TODO: Update once we have an equivalent on the Entity object + auto node = SHSceneManager::GetCurrentSceneGraph().GetNode(GetEntity()); + if (!node) + { + Debug::LogWarning("Attempting to access a GameObject's ActiveInHierarchy state which does not exist. Assuming inactive."); + return false; + } + return node->IsActive(); } /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Scripts/ScriptStore.cxx b/SHADE_Managed/src/Scripts/ScriptStore.cxx index 1c732358..d7492fdc 100644 --- a/SHADE_Managed/src/Scripts/ScriptStore.cxx +++ b/SHADE_Managed/src/Scripts/ScriptStore.cxx @@ -667,14 +667,10 @@ namespace SHADE bool ScriptStore::isEntityActive(Entity entity) { - // Get native Entity - SHEntity* nativeEntity = SHEntityManager::GetEntityByID(entity); - - // Entity Validity Check - if (nativeEntity == nullptr) + // Invalid entity + if (!EntityUtils::IsValid(entity)) return false; - // Check active state - return nativeEntity->GetActive(); + return GameObject(entity).IsActiveInHierarchy; } } diff --git a/TempScriptsFolder/PrintWhenActive.cs b/TempScriptsFolder/PrintWhenActive.cs new file mode 100644 index 00000000..41afdd58 --- /dev/null +++ b/TempScriptsFolder/PrintWhenActive.cs @@ -0,0 +1,11 @@ +using SHADE; + +public class PrintWhenActive : Script +{ + public PrintWhenActive(GameObject gameObj) : base(gameObj) { } + + protected override void update() + { + Debug.Log("Active!"); + } +} \ No newline at end of file