From 2197a3bcb9015dc30eee0ee4ab578859732eb628 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Tue, 7 Mar 2023 04:51:58 +0800 Subject: [PATCH] Added capsule collider Debug draw is a bit wonky. Further polish needed, --- Assets/Scenes/PhysicsTest.shade | 9 +- .../Inspector/SHEditorComponentView.hpp | 45 +++-- .../src/Physics/Collision/Shapes/SHBox.cpp | 6 +- .../src/Physics/Collision/Shapes/SHBox.h | 4 - .../Physics/Collision/Shapes/SHCapsule.cpp | 166 ++++++++++++++++++ .../src/Physics/Collision/Shapes/SHCapsule.h | 82 +++++++++ .../Collision/Shapes/SHCollisionShape.cpp | 4 +- .../Collision/Shapes/SHCollisionShape.h | 1 + .../PhysicsObject/SHPhysicsObjectManager.cpp | 19 +- .../Physics/Interface/SHColliderComponent.cpp | 44 +++++ .../Physics/Interface/SHColliderComponent.h | 18 ++ .../System/SHPhysicsDebugDrawSystem.cpp | 23 ++- .../Physics/System/SHPhysicsDebugDrawSystem.h | 14 +- .../src/Serialization/SHYAMLConverters.h | 24 ++- 14 files changed, 404 insertions(+), 55 deletions(-) create mode 100644 SHADE_Engine/src/Physics/Collision/Shapes/SHCapsule.cpp create mode 100644 SHADE_Engine/src/Physics/Collision/Shapes/SHCapsule.h diff --git a/Assets/Scenes/PhysicsTest.shade b/Assets/Scenes/PhysicsTest.shade index 982556af..91afbfa3 100644 --- a/Assets/Scenes/PhysicsTest.shade +++ b/Assets/Scenes/PhysicsTest.shade @@ -5,14 +5,14 @@ Components: Transform Component: Translate: {x: 0, y: 7, z: 0} - Rotate: {x: 1.48352981, y: 0, z: 0} + Rotate: {x: 0, y: 0, z: 0} Scale: {x: 0.999999344, y: 0.999999821, z: 0.999999523} IsActive: true RigidBody Component: Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 - Gravity Scale: 0.100000001 + Gravity Scale: 1 Use Gravity: true Interpolate: false Sleeping Enabled: true @@ -27,8 +27,9 @@ Colliders: - Is Trigger: false Collision Tag: 0 - Type: Box - Half Extents: {x: 1, y: 1, z: 1} + Type: Capsule + Radius: 1 + Height: 2 Friction: 0.400000006 Bounciness: 0 Density: 1 diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index fe84db31..b671baf4 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -15,6 +15,7 @@ #include "Editor/SHEditorWidgets.hpp" #include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Graphics/MiddleEnd/Lights/SHLightComponent.h" +#include "Physics/Interface/SHRigidBodyComponent.h" #include "Physics/Interface/SHColliderComponent.h" #include "Reflection/SHReflectionMetadata.h" #include "Resource/SHResourceManager.h" @@ -25,6 +26,7 @@ #include "Animation/SHAnimatorComponent.h" #include "Physics/Collision/Shapes/SHBox.h" #include "Physics/Collision/Shapes/SHSphere.h" +#include "Physics/Collision/Shapes/SHCapsule.h" #include "../SHEditorWindowManager.h" #include "../AssetBrowser/SHAssetBrowser.h" #include "Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.h" @@ -375,12 +377,26 @@ namespace SHADE ( "Radius", [sphereShape] { return sphereShape->GetRelativeRadius(); }, - [sphereShape](float const& value) { sphereShape->SetRelativeRadius(value); }); + [sphereShape](float const& value) { sphereShape->SetRelativeRadius(value); } + ); + } + else if (collisionShape->GetType() == SHCollisionShape::Type::CAPSULE) + { + SHEditorWidgets::BeginPanel(std::format("{} Capsule #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); + auto* capsuleShape = dynamic_cast(collisionShape); + SHEditorWidgets::DragFloat + ( + "Radius", + [capsuleShape] { return capsuleShape->GetRelativeRadius(); }, + [capsuleShape](float const& value) { capsuleShape->SetRelativeRadius(value); } + ); + SHEditorWidgets::DragFloat + ( + "Height", + [capsuleShape] { return capsuleShape->GetRelativeHeight(); }, + [capsuleShape](float const& value) { capsuleShape->SetRelativeHeight(value); } + ); } - //else if (collisionShape->GetType() == SHCollisionShape::Type::CAPSULE) - //{ - - //} { SHEditorWidgets::CheckBox("Is Trigger", [collisionShape] { return collisionShape->IsTrigger(); }, [collisionShape](bool value) { collisionShape->SetIsTrigger(value); }); @@ -423,25 +439,20 @@ namespace SHADE if (ImGui::BeginMenu("Add Collider")) { - int newColl = -1; + int newCollider = -1; if (ImGui::Selectable("Box Collider")) { - newColl = component->AddBoxCollisionShape(SHVec3::One); + newCollider = component->AddBoxCollisionShape(SHVec3::One); } if (ImGui::Selectable("Sphere Collider")) { - newColl = component->AddSphereCollisionShape(1.0f); + newCollider = component->AddSphereCollisionShape(1.0f); + } + if (ImGui::Selectable("Capsule Collider")) + { + newCollider = component->AddCapsuleCollisionShape(1.0f, 2.0f); } - - //No idea why this doesn't work - //if (newColl > 0) - //{ - // auto newCollisionShape = component->GetCollisionShape(newColl); - // auto prevCollisionShapeInSeq = component->GetCollisionShape(newColl - 1); - // newCollisionShape.SetCollisionTag(SHCollisionTagMatrix::GetTag(prevCollisionShapeInSeq.GetCollisionTag().GetName())); - - //} ImGui::EndMenu(); } diff --git a/SHADE_Engine/src/Physics/Collision/Shapes/SHBox.cpp b/SHADE_Engine/src/Physics/Collision/Shapes/SHBox.cpp index e45d6ef3..6b6921f8 100644 --- a/SHADE_Engine/src/Physics/Collision/Shapes/SHBox.cpp +++ b/SHADE_Engine/src/Physics/Collision/Shapes/SHBox.cpp @@ -1,5 +1,5 @@ /**************************************************************************************** - * \file SHBoxCollisionShape.cpp + * \file SHBox.cpp * \author Diren D Bharwani, diren.dbharwani, 390002520 * \brief Implementation for a Box Collision Shape. * @@ -34,10 +34,6 @@ namespace SHADE dynamic_cast(rp3dCollider->getCollisionShape())->setHalfExtents(SHVec3::One * 0.5f); } - /*-----------------------------------------------------------------------------------*/ - /* Operator Overload Definitions */ - /*-----------------------------------------------------------------------------------*/ - /*-----------------------------------------------------------------------------------*/ /* Getter Function Definitions */ /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Physics/Collision/Shapes/SHBox.h b/SHADE_Engine/src/Physics/Collision/Shapes/SHBox.h index 7cb425d5..fe7cd40d 100644 --- a/SHADE_Engine/src/Physics/Collision/Shapes/SHBox.h +++ b/SHADE_Engine/src/Physics/Collision/Shapes/SHBox.h @@ -40,10 +40,6 @@ namespace SHADE SHBox () noexcept; ~SHBox () override = default; - /*---------------------------------------------------------------------------------*/ - /* Operator Overloads */ - /*---------------------------------------------------------------------------------*/ - /*---------------------------------------------------------------------------------*/ /* Getter Functions */ /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Physics/Collision/Shapes/SHCapsule.cpp b/SHADE_Engine/src/Physics/Collision/Shapes/SHCapsule.cpp new file mode 100644 index 00000000..767b8507 --- /dev/null +++ b/SHADE_Engine/src/Physics/Collision/Shapes/SHCapsule.cpp @@ -0,0 +1,166 @@ +/**************************************************************************************** + * \file SHCapsule.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for a Capsule Collision Shape. + * + * \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 + +#include + +// Primary Header +#include "SHCapsule.h" + +// Project Headers +#include "Math/SHMathHelpers.h" +#include "Math/SHMatrix.h" +#include "Physics/Interface/SHColliderComponent.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHCapsule::SHCapsule() noexcept + : SHCollisionShape ( Type::CAPSULE) + , relativeRadius { 1.0f } + , relativeHeight { 2.0f } + , scale { SHVec3::One } + { + if (rp3dCollider) + { + auto* rp3dCapsule = dynamic_cast(rp3dCollider->getCollisionShape()); + rp3dCapsule->setRadius(0.5f); + rp3dCapsule->setHeight(2.0f); + } + } + + /*-----------------------------------------------------------------------------------*/ + /* Getter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + float SHCapsule::GetWorldRadius() const noexcept + { + if (rp3dCollider) + return dynamic_cast(rp3dCollider->getCollisionShape())->getRadius(); + + const float MAX_SCALE = SHMath::Max(scale.x, scale.z); + return relativeRadius * MAX_SCALE * 0.5f; + } + + float SHCapsule::GetRelativeRadius() const noexcept + { + return relativeRadius; + } + + float SHCapsule::GetWorldHeight() const noexcept + { + if (rp3dCollider) + return dynamic_cast(rp3dCollider->getCollisionShape())->getHeight(); + + return relativeHeight * scale.y; + } + + float SHCapsule::GetRelativeHeight() const noexcept + { + return relativeHeight; + } + + SHVec3 SHCapsule::GetWorldCentroid() const noexcept + { + const SHQuaternion ROTATION = collider->GetTransform().orientation * SHQuaternion::FromEuler(rotationOffset); + const SHMatrix TRS = SHMatrix::Rotate(ROTATION) * SHMatrix::Translate(collider->GetTransform().position); + return SHVec3::Transform(positionOffset, TRS); + } + + /*-----------------------------------------------------------------------------------*/ + /* Setter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHCapsule::SetWorldRadius(float newWorldRadius) noexcept + { + if (rp3dCollider) + dynamic_cast(rp3dCollider->getCollisionShape())->setRadius(newWorldRadius); + + // Recompute Relative radius + const float MAX_SCALE = SHMath::Max(scale.x, scale.z); + relativeRadius = 2.0f * newWorldRadius / MAX_SCALE; + } + + void SHCapsule::SetRelativeRadius(float newRelativeRadius) noexcept + { + relativeRadius = newRelativeRadius; + + // Recompute world radius + if (rp3dCollider) + { + auto* rp3dCapsule = dynamic_cast(rp3dCollider->getCollisionShape()); + + const float MAX_SCALE = SHMath::Max(scale.x, scale.z); + rp3dCapsule->setRadius(relativeRadius * MAX_SCALE * 0.5f); + } + } + + void SHCapsule::SetWorldHeight(float newWorldHeight) noexcept + { + if (rp3dCollider) + dynamic_cast(rp3dCollider->getCollisionShape())->setHeight(newWorldHeight); + + relativeHeight = newWorldHeight / scale.y; + } + + void SHCapsule::SetRelativeHeight(float newRelativeHeight) noexcept + { + relativeHeight = newRelativeHeight; + + if (rp3dCollider) + dynamic_cast(rp3dCollider->getCollisionShape())->setHeight(relativeHeight * scale.y); + } + + void SHCapsule::SetScale(const SHVec3& newScale) noexcept + { + scale = SHVec3::Abs(newScale); + + // Recompute world radius & Height + if (rp3dCollider) + { + // Get max scale component + const float MAX_SCALE = SHMath::Max(scale.x, scale.z); + + auto* rp3dCapsule = dynamic_cast(rp3dCollider->getCollisionShape()); + rp3dCapsule->setRadius(relativeRadius * MAX_SCALE * 0.5f); + rp3dCapsule->setHeight(relativeHeight * scale.y); + } + } + + /*-----------------------------------------------------------------------------------*/ + /* Public Member Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHCapsule::Update() noexcept + { + const SHTransform& PARENT_TRANSFORM = collider->GetTransform(); + SetScale(PARENT_TRANSFORM.scale); + + SHCollisionShape::Update(); + } + + SHMatrix SHCapsule::GetTRS() const noexcept + { + // The scale of a Capsule would probably be the radius set in the x and z axis, with the height set in the y axis. + // Arbitrary for debug drawing as we specify the position, rotation, height and radius instead. + + const SHQuaternion ROTATION = collider->GetTransform().orientation * SHQuaternion::FromEuler(rotationOffset); + const SHVec3 SCALE = SHVec3{ GetWorldRadius(), GetWorldHeight(), GetWorldRadius() }; + + const SHMatrix TRS = SHMatrix::Rotate(ROTATION) * SHMatrix::Translate(collider->GetTransform().position); + const SHVec3 POSITION = SHVec3::Transform(positionOffset, TRS); + + return SHMatrix::Transform(POSITION, ROTATION, SCALE); + } +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/Collision/Shapes/SHCapsule.h b/SHADE_Engine/src/Physics/Collision/Shapes/SHCapsule.h new file mode 100644 index 00000000..06d5fffb --- /dev/null +++ b/SHADE_Engine/src/Physics/Collision/Shapes/SHCapsule.h @@ -0,0 +1,82 @@ +/**************************************************************************************** + * \file SHCapsule.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for a Capsule Collision Shape. + * + * \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 "SHCollisionShape.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + /** + * @brief + * Encapsulate a Capsule Shape used for Physics Simulations. + */ + class SH_API SHCapsule final : public SHCollisionShape + { + private: + /*---------------------------------------------------------------------------------*/ + /* Friends */ + /*---------------------------------------------------------------------------------*/ + + friend class SHColliderComponent; + + public: + /*---------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*---------------------------------------------------------------------------------*/ + + SHCapsule () noexcept; + ~SHCapsule () override = default; + + /*---------------------------------------------------------------------------------*/ + /* Getter Functions */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] float GetWorldRadius () const noexcept; + [[nodiscard]] float GetRelativeRadius () const noexcept; + [[nodiscard]] float GetWorldHeight () const noexcept; + [[nodiscard]] float GetRelativeHeight () const noexcept; + + [[nodiscard]] SHVec3 GetWorldCentroid () const noexcept override; + + /*---------------------------------------------------------------------------------*/ + /* Setter Functions */ + /*---------------------------------------------------------------------------------*/ + + void SetWorldRadius (float newWorldRadius) noexcept; + void SetRelativeRadius (float newRelativeRadius) noexcept; + void SetWorldHeight (float newWorldHeight) noexcept; + void SetRelativeHeight (float newRelativeHeight) noexcept; + void SetScale (const SHVec3& newScale) noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + void Update () noexcept override; + [[nodiscard]] SHMatrix GetTRS () const noexcept override; + + private: + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + + float relativeRadius; + float relativeHeight; + SHVec3 scale; + }; + + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/Collision/Shapes/SHCollisionShape.cpp b/SHADE_Engine/src/Physics/Collision/Shapes/SHCollisionShape.cpp index bd67d42f..7cd8bd4d 100644 --- a/SHADE_Engine/src/Physics/Collision/Shapes/SHCollisionShape.cpp +++ b/SHADE_Engine/src/Physics/Collision/Shapes/SHCollisionShape.cpp @@ -237,9 +237,9 @@ RTTR_REGISTRATION registration::enumeration("Collider Type") ( + value("Sphere", SHCollisionShape::Type::SPHERE), value("Box", SHCollisionShape::Type::BOX), - value("Sphere", SHCollisionShape::Type::SPHERE) - // TODO(Diren): Add More Shapes + value("Capsule", SHCollisionShape::Type::CAPSULE) ); registration::class_("Collider") diff --git a/SHADE_Engine/src/Physics/Collision/Shapes/SHCollisionShape.h b/SHADE_Engine/src/Physics/Collision/Shapes/SHCollisionShape.h index 8c5fdc22..c7fb7156 100644 --- a/SHADE_Engine/src/Physics/Collision/Shapes/SHCollisionShape.h +++ b/SHADE_Engine/src/Physics/Collision/Shapes/SHCollisionShape.h @@ -53,6 +53,7 @@ namespace SHADE { SPHERE , BOX + , CAPSULE , COUNT , INVALID = -1 diff --git a/SHADE_Engine/src/Physics/Interface/PhysicsObject/SHPhysicsObjectManager.cpp b/SHADE_Engine/src/Physics/Interface/PhysicsObject/SHPhysicsObjectManager.cpp index a0b2f7cc..4043d88d 100644 --- a/SHADE_Engine/src/Physics/Interface/PhysicsObject/SHPhysicsObjectManager.cpp +++ b/SHADE_Engine/src/Physics/Interface/PhysicsObject/SHPhysicsObjectManager.cpp @@ -18,6 +18,7 @@ #include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h" #include "Physics/Collision/Shapes/SHSphere.h" #include "Physics/Collision/Shapes/SHBox.h" +#include "Physics/Collision/Shapes/SHCapsule.h" #include "Physics/Interface/SHColliderComponent.h" #include "Physics/Interface/SHRigidBodyComponent.h" #include "Tools/Utilities/SHUtilities.h" @@ -228,7 +229,7 @@ namespace SHADE { SHColliderDef::ShapeDef shapeDef { - .type = shape->GetType() + .type = shape->GetType() }; colliderDef.shapes.emplace_back(shapeDef); @@ -368,6 +369,22 @@ namespace SHADE break; } + case SHCollisionShape::Type::CAPSULE: + { + auto* capsuleShape = dynamic_cast(collisionShape); + + const float MAX_SCALE = SHMath::Max({ colliderComponent->transform.scale.x, colliderComponent->transform.scale.y, colliderComponent->transform.scale.z }); + const float WORLD_RADIUS = capsuleShape->GetRelativeRadius() * MAX_SCALE * 0.5f; + const float WORLD_HEIGHT = capsuleShape->GetRelativeHeight() * colliderComponent->transform.scale.y; + + rp3d::CapsuleShape* rp3dCapsule = factory->createCapsuleShape(WORLD_RADIUS, WORLD_HEIGHT); + + const rp3d::Transform OFFSETS{ capsuleShape->GetPositionOffset(), SHQuaternion::FromEuler(capsuleShape->GetRotationOffset()) }; + capsuleShape->rp3dCollider = physicsObject->body->addCollider(rp3dCapsule, OFFSETS); + capsuleShape->rp3dCollider->setIsTrigger(capsuleShape->IsTrigger()); + + break; + } default: break; } diff --git a/SHADE_Engine/src/Physics/Interface/SHColliderComponent.cpp b/SHADE_Engine/src/Physics/Interface/SHColliderComponent.cpp index 895f57d0..9cefe40e 100644 --- a/SHADE_Engine/src/Physics/Interface/SHColliderComponent.cpp +++ b/SHADE_Engine/src/Physics/Interface/SHColliderComponent.cpp @@ -20,6 +20,7 @@ #include "Physics/SHPhysicsEvents.h" #include "Physics/Collision/Shapes/SHSphere.h" #include "Physics/Collision/Shapes/SHBox.h" +#include "Physics/Collision/Shapes/SHCapsule.h" namespace SHADE { @@ -232,6 +233,49 @@ namespace SHADE return static_cast(NEW_INDEX); } + int SHColliderComponent::AddCapsuleCollisionShape(float relativeRadius, float relativeHeight, const SHVec3& posOffset, const SHVec3& rotOffset) + { + const uint32_t NEW_INDEX = static_cast(shapes.size()); + + // Create collision shape + shapes.emplace_back(new SHCapsule{}); + auto* newCapsule = dynamic_cast(shapes.back()); + + newCapsule->collider = this; + newCapsule->positionOffset = posOffset; + newCapsule->rotationOffset = rotOffset; + newCapsule->relativeRadius = relativeRadius; + newCapsule->relativeHeight = relativeHeight; + newCapsule->scale = SHVec3::Abs(transform.scale); + + // Broadcast Event for adding a shape + const SHPhysicsColliderAddedEvent EVENT_DATA + { + .entityID = GetEID() + , .colliderType = SHCollisionShape::Type::CAPSULE + , .colliderIndex = static_cast(NEW_INDEX) + }; + + SHEventManager::BroadcastEvent(EVENT_DATA, SH_PHYSICS_COLLIDER_ADDED_EVENT); + + if (factory) + { + const float MAX_SCALE = SHMath::Max(newCapsule->scale.x, newCapsule->scale.z); + const float WORLD_RADIUS = relativeRadius * MAX_SCALE * 0.5f; + const float WORLD_HEIGHT = relativeHeight * newCapsule->scale.y; + + rp3d::CapsuleShape* rp3dCapsule = factory->createCapsuleShape(WORLD_RADIUS, WORLD_HEIGHT); + + const rp3d::Transform OFFSETS{ posOffset, SHQuaternion::FromEuler(rotOffset) }; + newCapsule->rp3dCollider = collisionBody->addCollider(rp3dCapsule, OFFSETS); + + dynamic_cast(collisionBody)->updateMassPropertiesFromColliders(); + } + + return static_cast(NEW_INDEX); + } + + void SHColliderComponent::RemoveCollisionShape(int index) { const int NUM_SHAPES = static_cast(shapes.size()); diff --git a/SHADE_Engine/src/Physics/Interface/SHColliderComponent.h b/SHADE_Engine/src/Physics/Interface/SHColliderComponent.h index 9a141964..1ec534cb 100644 --- a/SHADE_Engine/src/Physics/Interface/SHColliderComponent.h +++ b/SHADE_Engine/src/Physics/Interface/SHColliderComponent.h @@ -142,6 +142,24 @@ namespace SHADE */ int AddBoxCollisionShape (const SHVec3& relativeExtents, const SHVec3& posOffset = SHVec3::Zero, const SHVec3& rotOffset = SHVec3::Zero); + /** + * @brief + * Adds a capsule collision shape. + * @param relativeRadius + * The relative radius is constructed with respect to the world scale.
+ * Radius = max(scale.x, scale.y, scale.z) * 0.5 * relativeRadius + * @param relativeHeight + * The relative height is constructed with respect to the scale in the y-axis
+ * Height = relativeHeight * scale.y + * @param posOffset + * The position offset of the box from the center of the collider. Defaults to a Zero Vector. + * @param rotOffset + * The rotation offset of the box from the rotation of the collider. Defaults to a Zero Vector. + * @return + * The index of the newly added shape. + */ + int AddCapsuleCollisionShape (float relativeRadius, float relativeHeight, const SHVec3& posOffset = SHVec3::Zero, const SHVec3& rotOffset = SHVec3::Zero); + /** * @brief * Removes a shape from the container. Removal reduces the size of the container. diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp index cff3933e..8fde0249 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp @@ -17,6 +17,7 @@ #include "ECS_Base/Managers/SHSystemManager.h" #include "Math/Transform/SHTransformComponent.h" #include "Physics/SHPhysicsEvents.h" +#include "Physics/Collision/Shapes/SHCapsule.h" #include "Tools/Utilities/SHUtilities.h" namespace SHADE @@ -88,11 +89,6 @@ namespace SHADE } - void SHPhysicsDebugDrawSystem::AddRaycast(const SHRay& ray, const SHPhysicsRaycastResult& result) noexcept - { - - } - /*-----------------------------------------------------------------------------------*/ /* Private Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -139,10 +135,19 @@ namespace SHADE debugDrawSystem->DrawWireCube(SHAPE->GetTRS(), DRAW_COLOUR, true); break; } - //case SHCollisionShape::Type::CAPSULE: - //{ - // break; - //} + case SHCollisionShape::Type::CAPSULE: + { + + const auto* CAPSULE_SHAPE = dynamic_cast(SHAPE); + + SHVec3 position, scale; + SHQuaternion rotation; + SHAPE->GetTRS().Decompose(position, rotation, scale); + + debugDrawSystem->DrawWireCapsule(position, rotation, CAPSULE_SHAPE->GetWorldHeight(), CAPSULE_SHAPE->GetWorldRadius(), DRAW_COLOUR, true); + + break; + } default: break; } } diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.h b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.h index 8c2c9b78..252ff682 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.h +++ b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.h @@ -64,8 +64,6 @@ namespace SHADE void Init () override; void Exit () override; - void AddRaycast (const SHRay& ray, const SHPhysicsRaycastResult& result) noexcept; - /*---------------------------------------------------------------------------------*/ /* System Routines */ /*---------------------------------------------------------------------------------*/ @@ -119,13 +117,11 @@ namespace SHADE /* Data Members */ /*---------------------------------------------------------------------------------*/ - static constexpr uint8_t ACTIVE_FLAG = 0x01; + static constexpr uint8_t ACTIVE_FLAG = 0x01; + static const SHColour DEBUG_DRAW_COLOURS[static_cast(Colours::COUNT)]; - static const SHColour DEBUG_DRAW_COLOURS[static_cast(Colours::COUNT)]; - - // 0 0 0 drawBroadphase drawRaycasts drawContacts drawAllColliders debugDrawActive + // 0 0 0 0 drawRaycasts drawContacts drawAllColliders debugDrawActive uint8_t flags; - Colliders collidersToDraw; /*---------------------------------------------------------------------------------*/ @@ -133,9 +129,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ SHEventHandle onColliderDraw(SHEventPtr onColliderDrawEvent); - - static void drawCollider (SHDebugDrawSystem* debugDrawSystem, const SHColliderComponent& collider) noexcept; - static void drawRaycast (SHDebugDrawSystem* debugDrawSystem, const DebugDrawInfo::Raycast& raycastInfo) noexcept; + static void drawCollider (SHDebugDrawSystem* debugDrawSystem, const SHColliderComponent& collider) noexcept; }; diff --git a/SHADE_Engine/src/Serialization/SHYAMLConverters.h b/SHADE_Engine/src/Serialization/SHYAMLConverters.h index bd714fd3..b1ae92e0 100644 --- a/SHADE_Engine/src/Serialization/SHYAMLConverters.h +++ b/SHADE_Engine/src/Serialization/SHYAMLConverters.h @@ -16,6 +16,7 @@ #include "Animation/SHAnimatorComponent.h" #include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h" #include "Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.h" +#include "Physics/Collision/Shapes/SHCapsule.h" namespace YAML { @@ -127,6 +128,7 @@ namespace YAML static constexpr const char* Type = "Type"; static constexpr const char* HalfExtents = "Half Extents"; static constexpr const char* Radius = "Radius"; + static constexpr const char* Height = "Height"; static constexpr const char* Friction = "Friction"; static constexpr const char* Bounciness = "Bounciness"; @@ -161,7 +163,13 @@ namespace YAML node[Radius] = SPHERE_SHAPE.GetRelativeRadius(); } break; - //case SHCollisionShape::Type::CAPSULE: break; + case SHCollisionShape::Type::CAPSULE: + { + const auto& CAPSULE_SHAPE = dynamic_cast(rhs); + node[Radius] = CAPSULE_SHAPE.GetRelativeRadius(); + node[Height] = CAPSULE_SHAPE.GetRelativeHeight(); + } + break; default:; } @@ -203,7 +211,17 @@ namespace YAML dynamic_cast(rhs).SetRelativeRadius(node[Radius].as()); } break; - //case SHCollisionShape::Type::CAPSULE: break; + case SHCollisionShape::Type::CAPSULE: + { + auto& capsule = dynamic_cast(rhs); + + if (node[Radius].IsDefined()) + capsule.SetRelativeRadius(node[Radius].as()); + + if (node[Height].IsDefined()) + capsule.SetRelativeHeight(node[Height].as()); + } + break; default:; } if (node[Friction].IsDefined()) @@ -258,7 +276,7 @@ namespace YAML { case SHCollisionShape::Type::BOX: rhs.AddBoxCollisionShape(SHVec3::One); break; case SHCollisionShape::Type::SPHERE: rhs.AddSphereCollisionShape(1.0f); break; - //case SHCollisionShape::Type::CAPSULE: break; + case SHCollisionShape::Type::CAPSULE: rhs.AddCapsuleCollisionShape(1.0f, 2.0f); break; default:; } YAML::convert::decode(colliderNode, rhs.GetCollisionShape(numColliders++));