diff --git a/Assets/Scenes/M2Scene.shade b/Assets/Scenes/M2Scene.shade index 585582e4..30dea780 100644 --- a/Assets/Scenes/M2Scene.shade +++ b/Assets/Scenes/M2Scene.shade @@ -50,7 +50,7 @@ Colliders: - Is Trigger: false Type: Box - Half Extents: {x: 24.7399445, y: 0.25, z: 8.75} + Half Extents: {x: 1, y: 1, z: 1} Friction: 0.400000006 Bounciness: 0 Density: 1 @@ -90,23 +90,7 @@ Bounciness: 0 Density: 1 Position Offset: {x: 0, y: 0.5, z: 0} - Scripts: - - Type: PlayerController - drag: 2 - currentState: 0 - maxMoveVel: 2 - moveForce: 50 - sprintMultiplier: 2 - rotationFactorPerFrame: 1 - maxJumpHeight: 4 - maxJumpTime: 0.75 - fallMultipler: 2 - lightMultiper: 0.75 - mediumMultiper: 0.5 - heavyMultiper: 0.25 - - Type: PickAndThrow - throwForce: [200, 300, 200] - item: 5 + Scripts: ~ - EID: 3 Name: Default IsActive: true @@ -126,12 +110,7 @@ Translate: {x: 0, y: 0, z: 0} Rotate: {x: 0, y: 0, z: 0} Scale: {x: 1, y: 1, z: 1} - Scripts: - - Type: SHADE_Scripting.ThirdPersonCamera - armLength: 2 - turnSpeedPitch: 0.300000012 - turnSpeedYaw: 0.5 - pitchClamp: 45 + Scripts: ~ - EID: 9 Name: Default IsActive: true @@ -186,9 +165,7 @@ Bounciness: 0 Density: 1 Position Offset: {x: 0, y: 0.5, z: 0} - Scripts: - - Type: Item - currCategory: 0 + Scripts: ~ - EID: 6 Name: AI IsActive: true @@ -223,14 +200,7 @@ Bounciness: 0 Density: 1 Position Offset: {x: 0, y: 0.5, z: 0} - Scripts: - - Type: AIPrototype - movementForceMultiplier: 100 - patrolSpeed: 0.400000006 - chaseSpeed: 0.800000012 - distanceToCapture: 1.20000005 - distanceToStartChase: 2 - distanceToEndChase: 2.5 + Scripts: ~ - EID: 7 Name: Default IsActive: true @@ -256,7 +226,4 @@ Color: {x: 1, y: 1, z: 1, w: 1} Layer: 4294967295 Strength: 0.25 - Scripts: - - Type: PickAndThrow - throwForce: [100, 200, 100] - item: 1 \ No newline at end of file + Scripts: ~ \ No newline at end of file diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index 02977f19..8281f114 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -92,7 +92,7 @@ namespace Sandbox floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC); - auto* floorBox = floorCollider.AddBoundingBox(); + floorCollider.AddBoundingBox(); // Create blank entity with a script //testObj = SHADE::SHEntityManager::CreateEntity(); @@ -114,8 +114,8 @@ namespace Sandbox racoonTransform.SetWorldPosition({ -3.0f, -2.0f, -5.0f }); racoonCollider.AddBoundingBox(); - racoonCollider.GetCollider(0).SetPositionOffset(SHVec3(0.0f,0.5f,0.0f)); - racoonCollider.GetCollider(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f)); + racoonCollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f,0.5f,0.0f)); + racoonCollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f)); auto racoonItemLocation = SHEntityManager::CreateEntity(); auto& racoonItemLocationTransform = *SHComponentManager::GetComponent_s(racoonItemLocation); @@ -140,13 +140,13 @@ namespace Sandbox itemCollider.AddBoundingBox(); itemCollider.AddBoundingBox(SHVec3(2.0f,2.0f,2.0f)); - itemCollider.GetCollider(1).SetIsTrigger(true); + itemCollider.GetCollisionShape(1).SetIsTrigger(true); - itemCollider.GetCollider(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f)); - itemCollider.GetCollider(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f)); + itemCollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f)); + itemCollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f)); - itemCollider.GetCollider(1).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f)); - itemCollider.GetCollider(1).SetBoundingBox(SHVec3(1.0f, 1.0f, 1.0f)); + itemCollider.GetCollisionShape(1).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f)); + itemCollider.GetCollisionShape(1).SetBoundingBox(SHVec3(1.0f, 1.0f, 1.0f)); itemRigidBody.SetInterpolate(false); itemRigidBody.SetFreezeRotationX(true); @@ -168,8 +168,8 @@ namespace Sandbox AITransform.SetWorldPosition({ -8.0f, -2.0f, 2.5f }); AICollider.AddBoundingBox(); - AICollider.GetCollider(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f)); - AICollider.GetCollider(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f)); + AICollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f)); + AICollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f)); AIRigidBody.SetInterpolate(false); AIRigidBody.SetFreezeRotationX(true); diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 72c38d6f..85d10c1a 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -224,9 +224,6 @@ namespace SHADE if (!component) return; - // Get transform component for extrapolating relative sizes - auto* transformComponent = SHComponentManager::GetComponent_s(component->GetEID()); - const auto componentType = rttr::type::get(*component); SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active"); ImGui::SameLine(); @@ -234,46 +231,39 @@ namespace SHADE { DrawContextMenu(component); - auto& colliders = component->GetColliders(); + auto& colliders = component->GetCollisionShapes(); int const size = static_cast(colliders.size()); - ImGui::BeginChild("Colliders", { 0.0f, colliders.empty() ? 1.0f : 250.0f }, true); + ImGui::BeginChild("Collision Shapes", { 0.0f, colliders.empty() ? 1.0f : 250.0f }, true); std::optional colliderToDelete{ std::nullopt }; for (int i{}; i < size; ++i) { ImGui::PushID(i); - SHCollider* collider = &component->GetCollider(i); + SHCollisionShape* collider = &component->GetCollisionShape(i); auto cursorPos = ImGui::GetCursorPos(); //collider->IsTrigger - if (collider->GetType() == SHCollider::Type::BOX) + if (collider->GetType() == SHCollisionShape::Type::BOX) { - SHEditorWidgets::BeginPanel(std::format("{} Box Collider #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); - SHEditorWidgets::CheckBox("Is Trigger", [collider]() {return collider->IsTrigger(); }, [collider](bool const& value) {collider->SetIsTrigger(value); }, "Is Trigger"); + SHEditorWidgets::BeginPanel(std::format("{} Box #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); auto box = reinterpret_cast(collider->GetShape()); SHEditorWidgets::DragVec3 ( "Half Extents", { "X", "Y", "Z" }, - [box, transformComponent] { return (box->GetHalfExtents() * 2.0f) / transformComponent->GetWorldScale(); }, + [box] { return box->GetRelativeExtents(); }, [collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); }); } - else if (collider->GetType() == SHCollider::Type::SPHERE) + else if (collider->GetType() == SHCollisionShape::Type::SPHERE) { - SHEditorWidgets::BeginPanel(std::format("{} Sphere Collider #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); - SHEditorWidgets::CheckBox("Is Trigger", [collider]() {return collider->IsTrigger(); }, [collider](bool const& value) {collider->SetIsTrigger(value); }, "Is Trigger"); + SHEditorWidgets::BeginPanel(std::format("{} Sphere #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); auto sphere = reinterpret_cast(collider->GetShape()); SHEditorWidgets::DragFloat ( "Radius", - [sphere, transformComponent] - { - const SHVec3& TF_WORLD_SCALE = transformComponent->GetWorldScale(); - const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z }); - return (sphere->GetRadius() / MAX_SCALE) * 2.0f; - }, + [sphere] { return sphere->GetRelativeRadius(); }, [collider](float const& value) { collider->SetBoundingSphere(value); }); } - else if (collider->GetType() == SHCollider::Type::CAPSULE) + else if (collider->GetType() == SHCollisionShape::Type::CAPSULE) { } diff --git a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp index d0ba2f14..5bbf5e15 100644 --- a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp +++ b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp @@ -25,11 +25,13 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ SHBoundingBox::SHBoundingBox() noexcept + : RelativeExtents { SHVec3::One } { type = Type::BOX; } SHBoundingBox::SHBoundingBox(const SHVec3& c, const SHVec3& hE) noexcept + : RelativeExtents { SHVec3::One } { type = Type::BOX; @@ -45,16 +47,18 @@ namespace SHADE type = Type::BOX; - Center = rhs.Center; - Extents = rhs.Extents; + Center = rhs.Center; + Extents = rhs.Extents; + RelativeExtents = rhs.RelativeExtents; } SHBoundingBox::SHBoundingBox(SHBoundingBox&& rhs) noexcept { type = Type::BOX; - Center = rhs.Center; - Extents = rhs.Extents; + Center = rhs.Center; + Extents = rhs.Extents; + RelativeExtents = rhs.RelativeExtents; } /*-----------------------------------------------------------------------------------*/ @@ -69,8 +73,9 @@ namespace SHADE } else if (this != &rhs) { - Center = rhs.Center; - Extents = rhs.Extents; + Center = rhs.Center; + Extents = rhs.Extents; + RelativeExtents = rhs.RelativeExtents; } return *this; @@ -84,8 +89,9 @@ namespace SHADE } else { - Center = rhs.Center; - Extents = rhs.Extents; + Center = rhs.Center; + Extents = rhs.Extents; + RelativeExtents = rhs.RelativeExtents; } return *this; @@ -100,11 +106,16 @@ namespace SHADE return Center; } - SHVec3 SHBoundingBox::GetHalfExtents() const noexcept + SHVec3 SHBoundingBox::GetWorldExtents() const noexcept { return Extents; } + const SHVec3& SHBoundingBox::GetRelativeExtents() const noexcept + { + return RelativeExtents; + } + SHVec3 SHBoundingBox::GetMin() const noexcept { return SHVec3{ Center.x - Extents.x, Center.y - Extents.y, Center.z - Extents.z }; @@ -124,9 +135,14 @@ namespace SHADE Center = newCenter; } - void SHBoundingBox::SetHalfExtents(const SHVec3& newHalfExtents) noexcept + void SHBoundingBox::SetWorldExtents(const SHVec3& newWorldExtents) noexcept { - Extents = newHalfExtents; + Extents = newWorldExtents; + } + + void SHBoundingBox::SetRelativeExtents(const SHVec3& newRelativeExtents) noexcept + { + RelativeExtents = newRelativeExtents; } void SHBoundingBox::SetMin(const SHVec3& min) noexcept diff --git a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h index 5b3d26d5..e2757c17 100644 --- a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h +++ b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h @@ -54,21 +54,23 @@ namespace SHADE /* Getter Functions */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] SHVec3 GetCenter () const noexcept; - [[nodiscard]] SHVec3 GetHalfExtents() const noexcept; - [[nodiscard]] SHVec3 GetMin () const noexcept; - [[nodiscard]] SHVec3 GetMax () const noexcept; - [[nodiscard]] std::vector GetVertices () const noexcept; + [[nodiscard]] SHVec3 GetCenter () const noexcept; + [[nodiscard]] SHVec3 GetWorldExtents () const noexcept; + [[nodiscard]] const SHVec3& GetRelativeExtents () const noexcept; + [[nodiscard]] SHVec3 GetMin () const noexcept; + [[nodiscard]] SHVec3 GetMax () const noexcept; + [[nodiscard]] std::vector GetVertices () const noexcept; /*---------------------------------------------------------------------------------*/ /* Setter Functions */ /*---------------------------------------------------------------------------------*/ - void SetCenter (const SHVec3& newCenter) noexcept; - void SetHalfExtents (const SHVec3& newHalfExtents) noexcept; - void SetMin (const SHVec3& min) noexcept; - void SetMax (const SHVec3& max) noexcept; - void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept; + void SetCenter (const SHVec3& newCenter) noexcept; + void SetWorldExtents (const SHVec3& newWorldExtents) noexcept; + void SetRelativeExtents (const SHVec3& newRelativeExtents) noexcept; + void SetMin (const SHVec3& min) noexcept; + void SetMax (const SHVec3& max) noexcept; + void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept; /*---------------------------------------------------------------------------------*/ /* Function Members */ @@ -89,6 +91,13 @@ namespace SHADE [[nodiscard]] static bool Intersect (const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept; [[nodiscard]] static SHBoundingBox BuildFromBoxes (const SHBoundingBox* boxes, size_t numBoxes) noexcept; [[nodiscard]] static SHBoundingBox BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept; + + private: + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + + SHVec3 RelativeExtents; }; diff --git a/SHADE_Engine/src/Math/Geometry/SHBoundingSphere.cpp b/SHADE_Engine/src/Math/Geometry/SHBoundingSphere.cpp index 62bf12b2..f843a6bb 100644 --- a/SHADE_Engine/src/Math/Geometry/SHBoundingSphere.cpp +++ b/SHADE_Engine/src/Math/Geometry/SHBoundingSphere.cpp @@ -25,11 +25,13 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ SHBoundingSphere::SHBoundingSphere() noexcept + : RelativeRadius { 1.0f } { type = Type::SPHERE; } SHBoundingSphere::SHBoundingSphere(const SHVec3& center, float radius) noexcept + : RelativeRadius { 1.0f } { type = Type::SPHERE; @@ -44,16 +46,18 @@ namespace SHADE type = Type::SPHERE; - Center = rhs.Center; - Radius = rhs.Radius; + Center = rhs.Center; + Radius = rhs.Radius; + RelativeRadius = rhs.RelativeRadius; } SHBoundingSphere::SHBoundingSphere(SHBoundingSphere&& rhs) noexcept { type = Type::SPHERE; - Center = rhs.Center; - Radius = rhs.Radius; + Center = rhs.Center; + Radius = rhs.Radius; + RelativeRadius = rhs.RelativeRadius; } /*-----------------------------------------------------------------------------------*/ @@ -68,8 +72,9 @@ namespace SHADE } else if (this != &rhs) { - Center = rhs.Center; - Radius = rhs.Radius; + Center = rhs.Center; + Radius = rhs.Radius; + RelativeRadius = rhs.RelativeRadius; } return *this; @@ -83,8 +88,9 @@ namespace SHADE } else { - Center = rhs.Center; - Radius = rhs.Radius; + Center = rhs.Center; + Radius = rhs.Radius; + RelativeRadius = rhs.RelativeRadius; } return *this; @@ -99,11 +105,16 @@ namespace SHADE return Center; } - float SHBoundingSphere::GetRadius() const noexcept + float SHBoundingSphere::GetWorldRadius() const noexcept { return Radius; } - + + float SHBoundingSphere::GetRelativeRadius() const noexcept + { + return RelativeRadius; + } + /*-----------------------------------------------------------------------------------*/ /* Setter Function Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -113,9 +124,14 @@ namespace SHADE Center = center; } - void SHBoundingSphere::SetRadius(float radius) noexcept + void SHBoundingSphere::SetWorldRadius(float newWorldRadius) noexcept { - Radius = radius; + Radius = newWorldRadius; + } + + void SHBoundingSphere::SetRelativeRadius(float newRelativeRadius) noexcept + { + RelativeRadius = newRelativeRadius; } /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Math/Geometry/SHBoundingSphere.h b/SHADE_Engine/src/Math/Geometry/SHBoundingSphere.h index 001e889b..d94722d6 100644 --- a/SHADE_Engine/src/Math/Geometry/SHBoundingSphere.h +++ b/SHADE_Engine/src/Math/Geometry/SHBoundingSphere.h @@ -48,15 +48,17 @@ namespace SHADE /* Getter Functions */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] SHVec3 GetCenter () const noexcept; - [[nodiscard]] float GetRadius () const noexcept; + [[nodiscard]] SHVec3 GetCenter () const noexcept; + [[nodiscard]] float GetWorldRadius () const noexcept; + [[nodiscard]] float GetRelativeRadius () const noexcept; /*---------------------------------------------------------------------------------*/ /* Setter Functions */ /*---------------------------------------------------------------------------------*/ - void SetCenter (const SHVec3& center) noexcept; - void SetRadius (float radius) noexcept; + void SetCenter (const SHVec3& center) noexcept; + void SetWorldRadius (float newWorldRadius) noexcept; + void SetRelativeRadius (float newRelativeRadius) noexcept; /*---------------------------------------------------------------------------------*/ /* Function Members */ @@ -79,5 +81,12 @@ namespace SHADE [[nodiscard]] static SHBoundingSphere BuildFromSpheres (const SHBoundingSphere* spheres, size_t numSpheres) noexcept; [[nodiscard]] static SHBoundingSphere BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept; + private: + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + + float RelativeRadius; + }; } // namespace SHADE diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp index f000aa5b..94c133dd 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp @@ -231,12 +231,12 @@ namespace SHADE tf.worldRotation = tf.localRotation + (parent ? parent->GetLocalRotation() : SHVec3::Zero); // Set the orientation - // Wrap rotations between -360 and 360 and convert to radians + // Wrap rotations between -720 and 720 and convert to radians SHVec3 worldRotRad, localRotRad; for (size_t i = 0; i < SHVec3::SIZE; ++i) { - worldRotRad[i] = SHMath::Wrap(tf.worldRotation[i], -SHMath::TWO_PI, SHMath::TWO_PI); - localRotRad[i] = SHMath::Wrap(tf.localRotation[i], -SHMath::TWO_PI, SHMath::TWO_PI); + worldRotRad[i] = SHMath::Wrap(tf.worldRotation[i], -2.0f * SHMath::TWO_PI, 2.0f * SHMath::TWO_PI); + localRotRad[i] = SHMath::Wrap(tf.localRotation[i], -2.0f * SHMath::TWO_PI, 2.0f * SHMath::TWO_PI); } tf.world.orientation = SHQuaternion::FromEuler(worldRotRad); diff --git a/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp b/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp index c7e327fa..93126fc5 100644 --- a/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp @@ -48,17 +48,22 @@ namespace SHADE return orientation.ToEuler(); } - const SHColliderComponent::Colliders& SHColliderComponent::GetColliders() const noexcept + const SHVec3& SHColliderComponent::GetScale() const noexcept { - return colliders; + return scale; } - SHCollider& SHColliderComponent::GetCollider(int index) + const SHColliderComponent::CollisionShapes& SHColliderComponent::GetCollisionShapes() const noexcept { - if (index < 0 || static_cast(index) >= colliders.size()) + return collisionShapes; + } + + SHCollisionShape& SHColliderComponent::GetCollisionShape(int index) + { + if (index < 0 || static_cast(index) >= collisionShapes.size()) throw std::invalid_argument("Out-of-range access!"); - return colliders[index]; + return collisionShapes[index]; } /*-----------------------------------------------------------------------------------*/ @@ -75,39 +80,74 @@ namespace SHADE } - SHBoundingBox* SHColliderComponent::AddBoundingBox(const SHVec3& halfExtents, const SHVec3& posOffset) noexcept + void SHColliderComponent::RecomputeCollisionShapes() noexcept + { + for (auto& collisionShape : collisionShapes) + { + switch (collisionShape.GetType()) + { + case SHCollisionShape::Type::BOX: + { + auto* box = reinterpret_cast(collisionShape.GetShape()); + const SHVec3& RELATIVE_EXTENTS = box->GetRelativeExtents(); + + // Recompute world extents based on new scale and fixed relative extents + const SHVec3 WORLD_EXTENTS = RELATIVE_EXTENTS * (scale * 0.5f); + box->SetWorldExtents(WORLD_EXTENTS); + + continue; + } + case SHCollisionShape::Type::SPHERE: + { + auto* sphere = reinterpret_cast(collisionShape.GetShape()); + const float RELATIVE_RADIUS = sphere->GetRelativeRadius(); + + // Recompute world radius based on new scale and fixed radius + const float MAX_SCALE = SHMath::Max({ scale.x, scale.y, scale.z }); + const float WORLD_RADIUS = RELATIVE_RADIUS * MAX_SCALE * 0.5f; + sphere->SetWorldRadius(WORLD_RADIUS); + + continue; + } + default: continue; + } + } + } + + int SHColliderComponent::AddBoundingBox(const SHVec3& halfExtents, const SHVec3& posOffset, const SHVec3& rotOffset) noexcept { if (!system) { SHLOG_ERROR("Physics system does not exist, unable to add Box Collider!") - return nullptr; + return -1; } - static constexpr auto TYPE = SHCollider::Type::BOX; + static constexpr auto TYPE = SHCollisionShape::Type::BOX; - auto& collider = colliders.emplace_back(SHCollider{ GetEID(), TYPE }); + auto& collider = collisionShapes.emplace_back(SHCollisionShape{ GetEID(), TYPE }); collider.entityID = GetEID(); collider.SetPositionOffset(posOffset); + collider.SetRotationOffset(rotOffset); collider.SetBoundingBox(halfExtents); // Notify Physics System system->AddCollisionShape(GetEID(), &collider); - return reinterpret_cast(collider.GetShape()); + return static_cast(collisionShapes.size()) - 1; } - SHBoundingSphere* SHColliderComponent::AddBoundingSphere(float radius, const SHVec3& posOffset) noexcept + int SHColliderComponent::AddBoundingSphere(float radius, const SHVec3& posOffset) noexcept { if (!system) { SHLOG_ERROR("Physics system does not exist, unable to add Sphere Collider!") - return nullptr; + return -1; } - static constexpr auto TYPE = SHCollider::Type::SPHERE; + static constexpr auto TYPE = SHCollisionShape::Type::SPHERE; - auto& collider = colliders.emplace_back(SHCollider{ GetEID(), TYPE }); + auto& collider = collisionShapes.emplace_back(SHCollisionShape{ GetEID(), TYPE }); collider.entityID = GetEID(); collider.SetPositionOffset(posOffset); @@ -116,17 +156,17 @@ namespace SHADE // Notify Physics System system->AddCollisionShape(GetEID(), &collider); - return reinterpret_cast(collider.GetShape()); + return static_cast(collisionShapes.size()) - 1; } void SHColliderComponent::RemoveCollider(int index) { - if (index < 0 || static_cast(index) >= colliders.size()) + if (index < 0 || static_cast(index) >= collisionShapes.size()) throw std::invalid_argument("Out-of-range access!"); int idx = 0; - auto it = colliders.begin(); - for (; it != colliders.end(); ++it) + auto it = collisionShapes.begin(); + for (; it != collisionShapes.end(); ++it) { if (idx == index) break; @@ -134,7 +174,7 @@ namespace SHADE ++idx; } - it = colliders.erase(it); + it = collisionShapes.erase(it); // Notify Physics System if (!system) diff --git a/SHADE_Engine/src/Physics/Components/SHColliderComponent.h b/SHADE_Engine/src/Physics/Components/SHColliderComponent.h index 7ce272a9..5f9b7a1b 100644 --- a/SHADE_Engine/src/Physics/Components/SHColliderComponent.h +++ b/SHADE_Engine/src/Physics/Components/SHColliderComponent.h @@ -14,7 +14,7 @@ // Project Headers #include "ECS_Base/Components/SHComponent.h" -#include "Physics/SHCollider.h" +#include "Physics/SHCollisionShape.h" #include "Math/Geometry/SHBoundingBox.h" #include "Math/Geometry/SHBoundingSphere.h" @@ -43,7 +43,7 @@ namespace SHADE /* Type Definitions */ /*---------------------------------------------------------------------------------*/ - using Colliders = std::vector; + using CollisionShapes = std::vector; public: @@ -67,26 +67,29 @@ namespace SHADE /* Getter Functions */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] bool HasChanged () const noexcept; + [[nodiscard]] bool HasChanged () const noexcept; - [[nodiscard]] const SHVec3& GetPosition () const noexcept; - [[nodiscard]] const SHQuaternion& GetOrientation () const noexcept; - [[nodiscard]] SHVec3 GetRotation () const noexcept; + [[nodiscard]] const SHVec3& GetPosition () const noexcept; + [[nodiscard]] const SHQuaternion& GetOrientation () const noexcept; + [[nodiscard]] SHVec3 GetRotation () const noexcept; + [[nodiscard]] const SHVec3& GetScale () const noexcept; - [[nodiscard]] const Colliders& GetColliders () const noexcept; - [[nodiscard]] SHCollider& GetCollider (int index); + [[nodiscard]] const CollisionShapes& GetCollisionShapes() const noexcept; + [[nodiscard]] SHCollisionShape& GetCollisionShape (int index); /*---------------------------------------------------------------------------------*/ /* Function Members */ /*---------------------------------------------------------------------------------*/ - void OnCreate () override; - void OnDestroy () override; + void OnCreate () override; + void OnDestroy () override; - void RemoveCollider (int index); + void RecomputeCollisionShapes () noexcept; - SHBoundingBox* AddBoundingBox (const SHVec3& halfExtents = SHVec3::One, const SHVec3& posOffset = SHVec3::Zero) noexcept; - SHBoundingSphere* AddBoundingSphere (float radius = 1.0f, const SHVec3& posOffset = SHVec3::Zero) noexcept; + void RemoveCollider (int index); + + int AddBoundingBox (const SHVec3& halfExtents = SHVec3::One, const SHVec3& posOffset = SHVec3::Zero, const SHVec3& rotOffset = SHVec3::Zero) noexcept; + int AddBoundingSphere (float radius = 1.0f, const SHVec3& posOffset = SHVec3::Zero) noexcept; private: @@ -98,7 +101,8 @@ namespace SHADE SHVec3 position; SHQuaternion orientation; - Colliders colliders; + SHVec3 scale; + CollisionShapes collisionShapes; RTTR_ENABLE() }; diff --git a/SHADE_Engine/src/Physics/SHCollider.cpp b/SHADE_Engine/src/Physics/SHCollisionShape.cpp similarity index 62% rename from SHADE_Engine/src/Physics/SHCollider.cpp rename to SHADE_Engine/src/Physics/SHCollisionShape.cpp index 6d455d67..c8f8020c 100644 --- a/SHADE_Engine/src/Physics/SHCollider.cpp +++ b/SHADE_Engine/src/Physics/SHCollisionShape.cpp @@ -11,12 +11,12 @@ #include // Primary Header -#include "SHCollider.h" +#include "SHCollisionShape.h" // Project Headers #include "Math/Geometry/SHBoundingBox.h" #include "Math/Geometry/SHBoundingSphere.h" -#include "Math/Transform/SHTransformComponent.h" #include "Math/SHMathHelpers.h" +#include "Physics/Components/SHColliderComponent.h" #include "Reflection/SHReflectionMetadata.h" namespace SHADE @@ -25,7 +25,7 @@ namespace SHADE /* Constructors & Destructor Definitions */ /*-----------------------------------------------------------------------------------*/ - SHCollider::SHCollider(EntityID eid, Type colliderType, const SHPhysicsMaterial& physicsMaterial) + SHCollisionShape::SHCollisionShape(EntityID eid, Type colliderType, const SHPhysicsMaterial& physicsMaterial) : type { colliderType } , entityID { eid } , isTrigger { false } @@ -49,7 +49,7 @@ namespace SHADE } } - SHCollider::SHCollider(const SHCollider& rhs) noexcept + SHCollisionShape::SHCollisionShape(const SHCollisionShape& rhs) noexcept : type { rhs.type} , entityID { rhs.entityID } , isTrigger { rhs.isTrigger } @@ -61,7 +61,7 @@ namespace SHADE CopyShape(rhs.shape); } - SHCollider::SHCollider(SHCollider&& rhs) noexcept + SHCollisionShape::SHCollisionShape(SHCollisionShape&& rhs) noexcept : type { rhs.type} , entityID { rhs.entityID } , isTrigger { rhs.isTrigger } @@ -73,7 +73,7 @@ namespace SHADE CopyShape(rhs.shape); } - SHCollider::~SHCollider() noexcept + SHCollisionShape::~SHCollisionShape() noexcept { shape = nullptr; } @@ -82,7 +82,7 @@ namespace SHADE /* Operator Overload Definitions */ /*-----------------------------------------------------------------------------------*/ - SHCollider& SHCollider::operator=(const SHCollider& rhs) noexcept + SHCollisionShape& SHCollisionShape::operator=(const SHCollisionShape& rhs) noexcept { if (this == &rhs) return *this; @@ -100,7 +100,7 @@ namespace SHADE return *this; } - SHCollider& SHCollider::operator=(SHCollider&& rhs) noexcept + SHCollisionShape& SHCollisionShape::operator=(SHCollisionShape&& rhs) noexcept { type = rhs.type; entityID = rhs.entityID; @@ -119,52 +119,52 @@ namespace SHADE /* Getter Function Definitions */ /*-----------------------------------------------------------------------------------*/ - bool SHCollider::HasChanged() const noexcept + bool SHCollisionShape::HasChanged() const noexcept { return dirty; } - bool SHCollider::IsTrigger() const noexcept + bool SHCollisionShape::IsTrigger() const noexcept { return isTrigger; } - SHCollider::Type SHCollider::GetType() const noexcept + SHCollisionShape::Type SHCollisionShape::GetType() const noexcept { return type; } - float SHCollider::GetFriction() const noexcept + float SHCollisionShape::GetFriction() const noexcept { return material.GetFriction(); } - float SHCollider::GetBounciness() const noexcept + float SHCollisionShape::GetBounciness() const noexcept { return material.GetBounciness(); } - float SHCollider::GetDensity() const noexcept + float SHCollisionShape::GetDensity() const noexcept { return material.GetDensity(); } - const SHPhysicsMaterial& SHCollider::GetMaterial() const noexcept + const SHPhysicsMaterial& SHCollisionShape::GetMaterial() const noexcept { return material; } - const SHVec3& SHCollider::GetPositionOffset() const noexcept + const SHVec3& SHCollisionShape::GetPositionOffset() const noexcept { return positionOffset; } - const SHVec3& SHCollider::GetRotationOffset() const noexcept + const SHVec3& SHCollisionShape::GetRotationOffset() const noexcept { return rotationOffset; } - SHShape* SHCollider::GetShape() noexcept + SHShape* SHCollisionShape::GetShape() noexcept { dirty = true; return shape; @@ -174,93 +174,80 @@ namespace SHADE /* Setter Function Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHCollider::SetBoundingBox(const SHVec3& halfExtents) + void SHCollisionShape::SetBoundingBox(const SHVec3& halfExtents) { dirty = true; - // Set the half extents relative to transform - SHVec3 worldHalfExtents = halfExtents; + const auto* colliderComponent = SHComponentManager::GetComponent(entityID); + // Set the half extents relative to world scale + const SHVec3 WORLD_EXTENTS = halfExtents * colliderComponent->GetScale() * 0.5f; - const auto* transformComponent = SHComponentManager::GetComponent_s(entityID); - if (transformComponent != nullptr) - worldHalfExtents *= (transformComponent->GetWorldScale() * 0.5f); - - if (type == Type::BOX) - { - auto* box = reinterpret_cast(shape); - box->SetHalfExtents(worldHalfExtents); - } - else + if (type != Type::BOX) { type = Type::BOX; delete shape; - shape = new SHBoundingBox{ positionOffset, worldHalfExtents }; + shape = new SHBoundingBox{ positionOffset, WORLD_EXTENTS }; } + + auto* box = reinterpret_cast(shape); + box->SetWorldExtents(WORLD_EXTENTS); + box->SetRelativeExtents(halfExtents); } - void SHCollider::SetBoundingSphere(float radius) + void SHCollisionShape::SetBoundingSphere(float radius) { dirty = true; - // Set the radius relative to transform - float worldRadius = radius; + const auto* colliderComponent = SHComponentManager::GetComponent(entityID); + // Set the radius relative to world scale + const SHVec3 WORLD_SCALE = colliderComponent->GetScale(); + const float MAX_SCALE = SHMath::Max({ WORLD_SCALE.x, WORLD_SCALE.y, WORLD_SCALE.z }); + const float WORLD_RADIUS = radius * MAX_SCALE * 0.5f; - const auto* transformComponent = SHComponentManager::GetComponent_s(entityID); - if (transformComponent != nullptr) - { - const SHVec3 TF_WORLD_SCALE = transformComponent->GetWorldScale(); - const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z }); - - worldRadius *= MAX_SCALE * 0.5f; - } - - if (type == Type::SPHERE) - { - auto* sphere = reinterpret_cast(shape); - sphere->SetRadius(worldRadius); - } - else + if (type != Type::SPHERE) { type = Type::SPHERE; delete shape; - shape = new SHBoundingSphere{ positionOffset, worldRadius }; + shape = new SHBoundingSphere{ positionOffset, WORLD_RADIUS }; } - + + auto* sphere = reinterpret_cast(shape); + sphere->SetWorldRadius(WORLD_RADIUS); } - void SHCollider::SetIsTrigger(bool trigger) noexcept + void SHCollisionShape::SetIsTrigger(bool trigger) noexcept { dirty = true; isTrigger = trigger; } - void SHCollider::SetFriction(float friction) noexcept + void SHCollisionShape::SetFriction(float friction) noexcept { dirty = true; material.SetFriction(friction); } - void SHCollider::SetBounciness(float bounciness) noexcept + void SHCollisionShape::SetBounciness(float bounciness) noexcept { dirty = true; material.SetBounciness(bounciness); } - void SHCollider::SetDensity(float density) noexcept + void SHCollisionShape::SetDensity(float density) noexcept { dirty = true; material.SetDensity(density); } - void SHCollider::SetMaterial(const SHPhysicsMaterial& newMaterial) noexcept + void SHCollisionShape::SetMaterial(const SHPhysicsMaterial& newMaterial) noexcept { dirty = true; material = newMaterial; } - void SHCollider::SetPositionOffset(const SHVec3& posOffset) noexcept + void SHCollisionShape::SetPositionOffset(const SHVec3& posOffset) noexcept { dirty = true; positionOffset = posOffset; @@ -281,7 +268,7 @@ namespace SHADE } } - void SHCollider::SetRotationOffset(const SHVec3& rotOffset) noexcept + void SHCollisionShape::SetRotationOffset(const SHVec3& rotOffset) noexcept { dirty = true; rotationOffset = rotOffset; @@ -291,7 +278,7 @@ namespace SHADE /* Private Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHCollider::CopyShape(const SHShape* rhs) + void SHCollisionShape::CopyShape(const SHShape* rhs) { switch (type) { @@ -299,14 +286,14 @@ namespace SHADE { const auto* RHS_BOX = reinterpret_cast(rhs); - shape = new SHBoundingBox{ positionOffset, RHS_BOX->GetHalfExtents() }; + shape = new SHBoundingBox{ positionOffset, RHS_BOX->GetWorldExtents() }; break; } case Type::SPHERE: { const auto* RHS_SPHERE = reinterpret_cast(rhs); - shape = new SHBoundingSphere{ positionOffset, RHS_SPHERE->GetRadius() }; + shape = new SHBoundingSphere{ positionOffset, RHS_SPHERE->GetWorldRadius() }; break; } default: break; @@ -320,14 +307,14 @@ RTTR_REGISTRATION using namespace SHADE; using namespace rttr; - registration::enumeration("Collider Type") + registration::enumeration("Collider Type") ( - value("Box", SHCollider::Type::BOX), - value("Sphere", SHCollider::Type::SPHERE) + value("Box", SHCollisionShape::Type::BOX), + value("Sphere", SHCollisionShape::Type::SPHERE) // TODO(Diren): Add More Shapes ); - registration::class_("Collider") - .property("Position Offset", &SHCollider::GetPositionOffset, &SHCollider::SetPositionOffset) - .property("Rotation Offset", &SHCollider::GetRotationOffset, &SHCollider::SetRotationOffset) (metadata(META::angleInRad, true)); + registration::class_("Collider") + .property("Position Offset", &SHCollisionShape::GetPositionOffset, &SHCollisionShape::SetPositionOffset) + .property("Rotation Offset", &SHCollisionShape::GetRotationOffset, &SHCollisionShape::SetRotationOffset) (metadata(META::angleInRad, true)); } \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHCollider.h b/SHADE_Engine/src/Physics/SHCollisionShape.h similarity index 91% rename from SHADE_Engine/src/Physics/SHCollider.h rename to SHADE_Engine/src/Physics/SHCollisionShape.h index 8cc233c4..9c8c1d41 100644 --- a/SHADE_Engine/src/Physics/SHCollider.h +++ b/SHADE_Engine/src/Physics/SHCollisionShape.h @@ -24,7 +24,7 @@ namespace SHADE /* Type Definitions */ /*-----------------------------------------------------------------------------------*/ - class SH_API SHCollider + class SH_API SHCollisionShape { private: @@ -51,18 +51,18 @@ namespace SHADE /* Constructors & Destructor */ /*---------------------------------------------------------------------------------*/ - SHCollider (EntityID eid, Type colliderType = Type::BOX, const SHPhysicsMaterial& physicsMaterial = SHPhysicsMaterial::DEFAULT); + SHCollisionShape (EntityID eid, Type colliderType = Type::BOX, const SHPhysicsMaterial& physicsMaterial = SHPhysicsMaterial::DEFAULT); - SHCollider (const SHCollider& rhs) noexcept; - SHCollider (SHCollider&& rhs) noexcept; - ~SHCollider () noexcept; + SHCollisionShape (const SHCollisionShape& rhs) noexcept; + SHCollisionShape (SHCollisionShape&& rhs) noexcept; + ~SHCollisionShape () noexcept; /*---------------------------------------------------------------------------------*/ /* Operator Overloads */ /*---------------------------------------------------------------------------------*/ - SHCollider& operator=(const SHCollider& rhs) noexcept; - SHCollider& operator=(SHCollider&& rhs) noexcept; + SHCollisionShape& operator=(const SHCollisionShape& rhs) noexcept; + SHCollisionShape& operator=(SHCollisionShape&& rhs) noexcept; /*---------------------------------------------------------------------------------*/ /* Getter Functions */ diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp index 37c1269e..00c6943b 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp @@ -128,24 +128,24 @@ namespace SHADE /* Public Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ - int SHPhysicsObject::AddCollider(SHCollider* collider) + int SHPhysicsObject::AddCollider(SHCollisionShape* collider) { const rp3d::Transform OFFSETS{ collider->GetPositionOffset(), collider->GetRotationOffset() }; switch (collider->GetType()) { - case SHCollider::Type::BOX: + case SHCollisionShape::Type::BOX: { const auto* box = reinterpret_cast(collider->GetShape()); - rp3d::BoxShape* newBox = factory->createBoxShape(box->GetHalfExtents()); + rp3d::BoxShape* newBox = factory->createBoxShape(box->GetWorldExtents()); rp3dBody->addCollider(newBox, OFFSETS); break; } - case SHCollider::Type::SPHERE: + case SHCollisionShape::Type::SPHERE: { const auto* sphere = reinterpret_cast(collider->GetShape()); - rp3d::SphereShape* newSphere = factory->createSphereShape(sphere->GetRadius()); + rp3d::SphereShape* newSphere = factory->createSphereShape(sphere->GetWorldRadius()); rp3dBody->addCollider(newSphere, OFFSETS); break; @@ -173,7 +173,7 @@ namespace SHADE void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept { int index = 0; - for (auto& collider : c->colliders) + for (auto& collider : c->collisionShapes) { if (!collider.dirty) continue; @@ -188,21 +188,21 @@ namespace SHADE switch (collider.GetType()) { - case SHCollider::Type::BOX: + case SHCollisionShape::Type::BOX: { const auto* box = reinterpret_cast(collider.GetShape()); auto* rp3dBoxShape = reinterpret_cast(rp3dCollider->getCollisionShape()); - rp3dBoxShape->setHalfExtents(box->GetHalfExtents()); + rp3dBoxShape->setHalfExtents(box->GetWorldExtents()); break; } - case SHCollider::Type::SPHERE: + case SHCollisionShape::Type::SPHERE: { const auto* sphere = reinterpret_cast(collider.GetShape()); auto* rp3dSphereShape = reinterpret_cast(rp3dCollider->getCollisionShape()); - rp3dSphereShape->setRadius(sphere->GetRadius()); + rp3dSphereShape->setRadius(sphere->GetWorldRadius()); break; } diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.h b/SHADE_Engine/src/Physics/SHPhysicsObject.h index 64caacdb..09b70b11 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.h +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.h @@ -69,7 +69,7 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - int AddCollider (SHCollider* collider); + int AddCollider (SHCollisionShape* collider); void RemoveCollider (int index); void SyncColliders (SHColliderComponent* c) const noexcept; diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index bdee8ba1..437b5ff8 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -348,7 +348,7 @@ namespace SHADE factory.destroyPhysicsWorld(world); } - void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHCollider* collider) + void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHCollisionShape* collider) { auto* physicsObject = GetPhysicsObject(entityID); @@ -395,6 +395,7 @@ namespace SHADE { const auto WORLD_POS = transformComponent->GetWorldPosition(); const auto WORLD_ROT = transformComponent->GetWorldOrientation(); + const auto WORLD_SCL = transformComponent->GetWorldScale(); physicsObject.SetPosition(WORLD_POS); physicsObject.SetOrientation(WORLD_ROT); @@ -409,8 +410,11 @@ namespace SHADE if (colliderComponent) { - colliderComponent->position = WORLD_POS; - colliderComponent->orientation = WORLD_ROT; + colliderComponent->position = WORLD_POS; + colliderComponent->orientation = WORLD_ROT; + colliderComponent->scale = WORLD_SCL; + + colliderComponent->RecomputeCollisionShapes(); } } @@ -605,7 +609,6 @@ namespace SHADE if (rigidBodyComponent != nullptr) { - if (rigidBodyComponent->GetType() == SHRigidBodyComponent::Type::STATIC) continue; @@ -658,8 +661,10 @@ namespace SHADE { 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]; + const bool ENTITY_MATCH = (e.ids[0] == collisionEvent.ids[0] && e.ids[1] == collisionEvent.ids[1]) + || (e.ids[0] == collisionEvent.ids[1] && e.ids[1] == collisionEvent.ids[0]); + const bool COLLIDERS_MATCH = (e.ids[2] == collisionEvent.ids[2] && e.ids[3] == collisionEvent.ids[3]) + || (e.ids[2] == collisionEvent.ids[3] && e.ids[3] == collisionEvent.ids[2]); return ENTITY_MATCH && COLLIDERS_MATCH; }); @@ -734,7 +739,7 @@ namespace SHADE // Add collision shapes back into the body if (colliderComponent != nullptr) { - for (auto& collider : colliderComponent->colliders) + for (auto& collider : colliderComponent->collisionShapes) physicsObject->AddCollider(&collider); } } @@ -743,8 +748,9 @@ namespace SHADE { SHASSERT(colliderComponent != nullptr, "Collider Component was not added to Entity " + std::to_string(ENTITY_ID) + "!"); - colliderComponent->position = transformComponent->GetWorldPosition(); - colliderComponent->orientation = transformComponent->GetWorldOrientation(); + colliderComponent->position = transformComponent->GetWorldPosition(); + colliderComponent->orientation = transformComponent->GetWorldOrientation(); + colliderComponent->scale = transformComponent->GetWorldScale(); if (physicsObject->rp3dBody == nullptr) { @@ -755,7 +761,7 @@ namespace SHADE } // Add Collision Shapes - for (auto& collider : colliderComponent->colliders) + for (auto& collider : colliderComponent->collisionShapes) physicsObject->AddCollider(&collider); } } @@ -800,7 +806,7 @@ namespace SHADE rp3d::Transform{ colliderComponent->position, colliderComponent->orientation } ); - for (auto& collider : colliderComponent->colliders) + for (auto& collider : colliderComponent->collisionShapes) physicsObject->AddCollider(&collider); } } diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index 05e6e57e..55575c73 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -114,7 +114,7 @@ namespace SHADE void Init () override; void Exit () override; - void AddCollisionShape (EntityID entityID, SHCollider* collider); + void AddCollisionShape (EntityID entityID, SHCollisionShape* collider); void RemoveCollisionShape (EntityID entityID, int index); void onContact (const rp3d::CollisionCallback::CallbackData& callbackData) override; @@ -183,24 +183,24 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept; - SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept; - void DestroyPhysicsObject (EntityID entityID) 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 SyncActiveStates (SHPhysicsObject& physicsObject, bool componentActive) noexcept; + void SyncTransforms () noexcept; - static void UpdateEventContainers (const SHCollisionEvent& collisionEvent, CollisionEvents& container) noexcept; - void ClearInvalidCollisions () noexcept; + static void UpdateEventContainers (const SHCollisionEvent& collisionEvent, CollisionEvents& container) noexcept; + void ClearInvalidCollisions () noexcept; - SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent); - SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent); - SHEventHandle ResetWorld (SHEventPtr editorStopEvent); + SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent); + SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent); + SHEventHandle ResetWorld (SHEventPtr editorStopEvent); template || std::is_same_v>> - SHCollisionEvent GenerateCollisionEvent (const RP3DCollisionPair& cp) noexcept; + SHCollisionEvent GenerateCollisionEvent (const RP3DCollisionPair& cp) noexcept; }; } // namespace SHADE diff --git a/SHADE_Engine/src/Physics/SHPhysicsUtils.cpp b/SHADE_Engine/src/Physics/SHPhysicsUtils.cpp index 8d5bc956..14b6cc2f 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsUtils.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsUtils.cpp @@ -75,14 +75,14 @@ namespace SHADE return SHComponentManager::GetComponent_s(ids[ENTITY_B]); } - const SHCollider* SHCollisionEvent::GetColliderA() const noexcept + const SHCollisionShape* SHCollisionEvent::GetColliderA() const noexcept { - return &SHComponentManager::GetComponent(ids[ENTITY_A])->GetCollider(ids[COLLIDER_A]); + return &SHComponentManager::GetComponent(ids[ENTITY_A])->GetCollisionShape(ids[COLLIDER_A]); } - const SHCollider* SHCollisionEvent::GetColliderB() const noexcept + const SHCollisionShape* SHCollisionEvent::GetColliderB() const noexcept { - return &SHComponentManager::GetComponent(ids[ENTITY_B])->GetCollider(ids[COLLIDER_B]); + return &SHComponentManager::GetComponent(ids[ENTITY_B])->GetCollisionShape(ids[COLLIDER_B]); } SHCollisionEvent::State SHCollisionEvent::GetCollisionState() const noexcept diff --git a/SHADE_Engine/src/Physics/SHPhysicsUtils.h b/SHADE_Engine/src/Physics/SHPhysicsUtils.h index 57f9c6fc..753f8d3b 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsUtils.h +++ b/SHADE_Engine/src/Physics/SHPhysicsUtils.h @@ -24,7 +24,7 @@ namespace SHADE struct SHPhysicsColliderAddedEvent { EntityID entityID; - SHCollider::Type colliderType; + SHCollisionShape::Type colliderType; int colliderIndex; }; @@ -88,8 +88,8 @@ namespace SHADE [[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]] const SHCollisionShape* GetColliderA () const noexcept; + [[nodiscard]] const SHCollisionShape* GetColliderB () const noexcept; [[nodiscard]] State GetCollisionState () const noexcept; private: diff --git a/SHADE_Engine/src/Serialization/SHYAMLConverters.h b/SHADE_Engine/src/Serialization/SHYAMLConverters.h index d4b97244..1b93c63a 100644 --- a/SHADE_Engine/src/Serialization/SHYAMLConverters.h +++ b/SHADE_Engine/src/Serialization/SHYAMLConverters.h @@ -3,7 +3,7 @@ #include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h" #include "Math/Geometry/SHBoundingBox.h" #include "Math/Geometry/SHBoundingSphere.h" -#include "Physics/SHCollider.h" +#include "Physics/SHCollisionShape.h" #include "Resource/SHResourceManager.h" #include "Math/Vector/SHVec2.h" #include "Math/Vector/SHVec3.h" @@ -101,7 +101,7 @@ namespace YAML }; template<> - struct convert + struct convert { static constexpr const char* IsTrigger = "Is Trigger"; @@ -114,33 +114,33 @@ namespace YAML static constexpr const char* Density = "Density"; static constexpr const char* PositionOffset = "Position Offset"; - static Node encode(SHCollider& rhs) + static Node encode(SHCollisionShape& rhs) { Node node; node[IsTrigger] = rhs.IsTrigger(); - rttr::type const shapeRttrType = rttr::type::get(); + rttr::type const shapeRttrType = rttr::type::get(); rttr::enumeration const enumAlign = shapeRttrType.get_enumeration(); - SHCollider::Type colliderType = rhs.GetType(); + SHCollisionShape::Type colliderType = rhs.GetType(); node[Type] = enumAlign.value_to_name(colliderType).data(); switch (colliderType) { - case SHCollider::Type::BOX: + case SHCollisionShape::Type::BOX: { auto const bb = reinterpret_cast(rhs.GetShape()); - node[HalfExtents] = bb->GetHalfExtents(); + node[HalfExtents] = bb->GetRelativeExtents(); } break; - case SHCollider::Type::SPHERE: + case SHCollisionShape::Type::SPHERE: { auto const bs = reinterpret_cast(rhs.GetShape()); - node[Radius] = bs->GetRadius(); + node[Radius] = bs->GetRelativeRadius(); } break; - case SHCollider::Type::CAPSULE: break; + case SHCollisionShape::Type::CAPSULE: break; default:; } @@ -151,33 +151,33 @@ namespace YAML return node; } - static bool decode(Node const& node, SHCollider& rhs) + static bool decode(Node const& node, SHCollisionShape& rhs) { if (node[IsTrigger].IsDefined()) rhs.SetIsTrigger(node[IsTrigger].as()); if (!node[Type].IsDefined()) return false; - rttr::type const shapeRttrType = rttr::type::get(); + rttr::type const shapeRttrType = rttr::type::get(); rttr::enumeration const enumAlign = shapeRttrType.get_enumeration(); bool ok; - const SHCollider::Type colliderType = enumAlign.name_to_value(node[Type].as()).convert(&ok); + const SHCollisionShape::Type colliderType = enumAlign.name_to_value(node[Type].as()).convert(&ok); if (!ok) return false; switch (colliderType) { - case SHCollider::Type::BOX: + case SHCollisionShape::Type::BOX: { if (node[HalfExtents].IsDefined()) - rhs.SetBoundingBox(node[HalfExtents].as() * 2.0f); + rhs.SetBoundingBox(node[HalfExtents].as()); } break; - case SHCollider::Type::SPHERE: + case SHCollisionShape::Type::SPHERE: { if (node[Radius].IsDefined()) rhs.SetBoundingSphere(node[Radius].as()); } break; - case SHCollider::Type::CAPSULE: break; + case SHCollisionShape::Type::CAPSULE: break; default:; } if (node[Friction].IsDefined()) @@ -200,12 +200,12 @@ namespace YAML static Node encode(SHColliderComponent& rhs) { Node node, collidersNode; - auto const& colliders = rhs.GetColliders(); + auto const& colliders = rhs.GetCollisionShapes(); int const numColliders = static_cast(colliders.size()); for (int i = 0; i < numColliders; ++i) { - auto& collider = rhs.GetCollider(i); - Node colliderNode = convert::encode(collider); + auto& collider = rhs.GetCollisionShape(i); + Node colliderNode = convert::encode(collider); if (colliderNode.IsDefined()) collidersNode[i] = colliderNode; } @@ -219,21 +219,21 @@ namespace YAML int numColliders{}; for (auto const& colliderNode : node[Colliders]) { - rttr::type const shapeRttrType = rttr::type::get(); + rttr::type const shapeRttrType = rttr::type::get(); rttr::enumeration const enumAlign = shapeRttrType.get_enumeration(); bool ok = false; - const SHCollider::Type colliderType = enumAlign.name_to_value(colliderNode[convert::Type].as()).convert(&ok); + const SHCollisionShape::Type colliderType = enumAlign.name_to_value(colliderNode[convert::Type].as()).convert(&ok); if (!ok) return false; switch (colliderType) { - case SHCollider::Type::BOX: rhs.AddBoundingBox(); break; - case SHCollider::Type::SPHERE: rhs.AddBoundingSphere(); break; - case SHCollider::Type::CAPSULE: break; + case SHCollisionShape::Type::BOX: rhs.AddBoundingBox(); break; + case SHCollisionShape::Type::SPHERE: rhs.AddBoundingSphere(); break; + case SHCollisionShape::Type::CAPSULE: break; default:; } - YAML::convert::decode(colliderNode, rhs.GetCollider(numColliders++)); + YAML::convert::decode(colliderNode, rhs.GetCollisionShape(numColliders++)); } } return true; diff --git a/SHADE_Managed/src/Components/Collider.cxx b/SHADE_Managed/src/Components/Collider.cxx index f2119b43..0e916b7b 100644 --- a/SHADE_Managed/src/Components/Collider.cxx +++ b/SHADE_Managed/src/Components/Collider.cxx @@ -55,11 +55,11 @@ namespace SHADE } Vector3 BoxCollider::HalfExtents::get() { - return Convert::ToCLI(getNativeBoundObject().GetHalfExtents()); + return Convert::ToCLI(getNativeBoundObject().GetWorldExtents()); } void BoxCollider::HalfExtents::set(Vector3 value) { - getNativeBoundObject().SetHalfExtents(Convert::ToNative(value)); + getNativeBoundObject().SetWorldExtents(Convert::ToNative(value)); } Vector3 BoxCollider::Min::get() { @@ -103,11 +103,11 @@ namespace SHADE } float SphereCollider::Radius::get() { - return getNativeBoundObject().GetRadius(); + return getNativeBoundObject().GetWorldRadius(); } void SphereCollider::Radius::set(float value) { - getNativeBoundObject().SetRadius(value); + getNativeBoundObject().SetWorldRadius(value); } /*---------------------------------------------------------------------------------*/ @@ -150,7 +150,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ int Collider::CollisionShapeCount::get() { - return static_cast(GetNativeComponent()->GetColliders().size()); + return static_cast(GetNativeComponent()->GetCollisionShapes().size()); } /*---------------------------------------------------------------------------------*/ @@ -230,18 +230,18 @@ namespace SHADE // Populate the list int i = 0; - for (const auto& collider : GetNativeComponent()->GetColliders()) + for (const auto& collider : GetNativeComponent()->GetCollisionShapes()) { CollisionShape^ bound = nullptr; switch (collider.GetType()) { - case SHCollider::Type::BOX: + case SHCollisionShape::Type::BOX: bound = gcnew BoxCollider(i, Owner.GetEntity()); break; - case SHCollider::Type::SPHERE: + case SHCollisionShape::Type::SPHERE: bound = gcnew SphereCollider(i, Owner.GetEntity()); break; - case SHCollider::Type::CAPSULE: + case SHCollisionShape::Type::CAPSULE: // TODO break; default: diff --git a/SHADE_Managed/src/Components/Collider.h++ b/SHADE_Managed/src/Components/Collider.h++ index 1f8b43eb..6e165619 100644 --- a/SHADE_Managed/src/Components/Collider.h++ +++ b/SHADE_Managed/src/Components/Collider.h++ @@ -27,11 +27,11 @@ namespace SHADE try { - auto& bounds = collider->GetCollider(arrayIndex); - if (bounds.GetType() != SHCollider::Type::BOX) + auto& shape = collider->GetCollisionShape(arrayIndex); + if (shape.GetType() != SHCollisionShape::Type::BOX) throw gcnew System::InvalidOperationException("Attempted to retrieve invalid ColliderBound."); - return reinterpret_cast(bounds); + return reinterpret_cast(shape); } catch (std::invalid_argument&) {