Added Relative Sizes to Shapes

This commit is contained in:
Diren D Bharwani 2022-11-08 00:46:09 +08:00
parent 70dcad1313
commit 8fbd32a144
14 changed files with 211 additions and 146 deletions

View File

@ -50,7 +50,7 @@
Colliders: Colliders:
- Is Trigger: false - Is Trigger: false
Type: Box Type: Box
Half Extents: {x: 24.7399445, y: 0.25, z: 8.75} Half Extents: {x: 1, y: 1, z: 1}
Friction: 0.400000006 Friction: 0.400000006
Bounciness: 0 Bounciness: 0
Density: 1 Density: 1
@ -90,23 +90,7 @@
Bounciness: 0 Bounciness: 0
Density: 1 Density: 1
Position Offset: {x: 0, y: 0.5, z: 0} Position Offset: {x: 0, y: 0.5, z: 0}
Scripts: 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
- EID: 3 - EID: 3
Name: Default Name: Default
IsActive: true IsActive: true
@ -126,12 +110,7 @@
Translate: {x: 0, y: 0, z: 0} Translate: {x: 0, y: 0, z: 0}
Rotate: {x: 0, y: 0, z: 0} Rotate: {x: 0, y: 0, z: 0}
Scale: {x: 1, y: 1, z: 1} Scale: {x: 1, y: 1, z: 1}
Scripts: Scripts: ~
- Type: SHADE_Scripting.ThirdPersonCamera
armLength: 2
turnSpeedPitch: 0.300000012
turnSpeedYaw: 0.5
pitchClamp: 45
- EID: 9 - EID: 9
Name: Default Name: Default
IsActive: true IsActive: true
@ -186,9 +165,7 @@
Bounciness: 0 Bounciness: 0
Density: 1 Density: 1
Position Offset: {x: 0, y: 0.5, z: 0} Position Offset: {x: 0, y: 0.5, z: 0}
Scripts: Scripts: ~
- Type: Item
currCategory: 0
- EID: 6 - EID: 6
Name: AI Name: AI
IsActive: true IsActive: true
@ -223,14 +200,7 @@
Bounciness: 0 Bounciness: 0
Density: 1 Density: 1
Position Offset: {x: 0, y: 0.5, z: 0} Position Offset: {x: 0, y: 0.5, z: 0}
Scripts: Scripts: ~
- Type: AIPrototype
movementForceMultiplier: 100
patrolSpeed: 0.400000006
chaseSpeed: 0.800000012
distanceToCapture: 1.20000005
distanceToStartChase: 2
distanceToEndChase: 2.5
- EID: 7 - EID: 7
Name: Default Name: Default
IsActive: true IsActive: true
@ -256,4 +226,23 @@
Color: {x: 1, y: 1, z: 1, w: 1} Color: {x: 1, y: 1, z: 1, w: 1}
Layer: 4294967295 Layer: 4294967295
Strength: 0.25 Strength: 0.25
Scripts: ~
- EID: 10
Name: Default
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: 0, y: 2.45315814, z: -5}
Rotate: {x: -0, y: 0, z: -0}
Scale: {x: 2, y: 1, z: 1}
Collider Component:
Colliders:
- Is Trigger: false
Type: Box
Half Extents: {x: 2, y: 1, z: 1}
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0, z: 0}
Scripts: ~ Scripts: ~

View File

@ -92,7 +92,7 @@ namespace Sandbox
floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC); floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC);
auto* floorBox = floorCollider.AddBoundingBox(); floorCollider.AddBoundingBox();
// Create blank entity with a script // Create blank entity with a script
//testObj = SHADE::SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>(); //testObj = SHADE::SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();

View File

@ -224,9 +224,6 @@ namespace SHADE
if (!component) if (!component)
return; return;
// Get transform component for extrapolating relative sizes
auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(component->GetEID());
const auto componentType = rttr::type::get(*component); const auto componentType = rttr::type::get(*component);
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active"); SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
ImGui::SameLine(); ImGui::SameLine();
@ -249,28 +246,21 @@ namespace SHADE
if (collider->GetType() == SHCollisionShape::Type::BOX) if (collider->GetType() == SHCollisionShape::Type::BOX)
{ {
SHEditorWidgets::BeginPanel(std::format("{} Box #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); SHEditorWidgets::BeginPanel(std::format("{} Box #{}", 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");
auto box = reinterpret_cast<SHBoundingBox*>(collider->GetShape()); auto box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
SHEditorWidgets::DragVec3 SHEditorWidgets::DragVec3
( (
"Half Extents", { "X", "Y", "Z" }, "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); }); [collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); });
} }
else if (collider->GetType() == SHCollisionShape::Type::SPHERE) else if (collider->GetType() == SHCollisionShape::Type::SPHERE)
{ {
SHEditorWidgets::BeginPanel(std::format("{} Sphere #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); SHEditorWidgets::BeginPanel(std::format("{} Sphere #{}", 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");
auto sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape()); auto sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
SHEditorWidgets::DragFloat SHEditorWidgets::DragFloat
( (
"Radius", "Radius",
[sphere, transformComponent] [sphere] { return sphere->GetRelativeRadius(); },
{
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;
},
[collider](float const& value) { collider->SetBoundingSphere(value); }); [collider](float const& value) { collider->SetBoundingSphere(value); });
} }
else if (collider->GetType() == SHCollisionShape::Type::CAPSULE) else if (collider->GetType() == SHCollisionShape::Type::CAPSULE)

View File

@ -25,11 +25,13 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHBoundingBox::SHBoundingBox() noexcept SHBoundingBox::SHBoundingBox() noexcept
: RelativeExtents { SHVec3::One }
{ {
type = Type::BOX; type = Type::BOX;
} }
SHBoundingBox::SHBoundingBox(const SHVec3& c, const SHVec3& hE) noexcept SHBoundingBox::SHBoundingBox(const SHVec3& c, const SHVec3& hE) noexcept
: RelativeExtents { SHVec3::One }
{ {
type = Type::BOX; type = Type::BOX;
@ -45,16 +47,18 @@ namespace SHADE
type = Type::BOX; type = Type::BOX;
Center = rhs.Center; Center = rhs.Center;
Extents = rhs.Extents; Extents = rhs.Extents;
RelativeExtents = rhs.RelativeExtents;
} }
SHBoundingBox::SHBoundingBox(SHBoundingBox&& rhs) noexcept SHBoundingBox::SHBoundingBox(SHBoundingBox&& rhs) noexcept
{ {
type = Type::BOX; type = Type::BOX;
Center = rhs.Center; Center = rhs.Center;
Extents = rhs.Extents; Extents = rhs.Extents;
RelativeExtents = rhs.RelativeExtents;
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -69,8 +73,9 @@ namespace SHADE
} }
else if (this != &rhs) else if (this != &rhs)
{ {
Center = rhs.Center; Center = rhs.Center;
Extents = rhs.Extents; Extents = rhs.Extents;
RelativeExtents = rhs.RelativeExtents;
} }
return *this; return *this;
@ -84,8 +89,9 @@ namespace SHADE
} }
else else
{ {
Center = rhs.Center; Center = rhs.Center;
Extents = rhs.Extents; Extents = rhs.Extents;
RelativeExtents = rhs.RelativeExtents;
} }
return *this; return *this;
@ -100,11 +106,16 @@ namespace SHADE
return Center; return Center;
} }
SHVec3 SHBoundingBox::GetHalfExtents() const noexcept SHVec3 SHBoundingBox::GetWorldExtents() const noexcept
{ {
return Extents; return Extents;
} }
const SHVec3& SHBoundingBox::GetRelativeExtents() const noexcept
{
return RelativeExtents;
}
SHVec3 SHBoundingBox::GetMin() const noexcept SHVec3 SHBoundingBox::GetMin() const noexcept
{ {
return SHVec3{ Center.x - Extents.x, Center.y - Extents.y, Center.z - Extents.z }; return SHVec3{ Center.x - Extents.x, Center.y - Extents.y, Center.z - Extents.z };
@ -124,9 +135,14 @@ namespace SHADE
Center = newCenter; 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 void SHBoundingBox::SetMin(const SHVec3& min) noexcept

View File

@ -54,21 +54,23 @@ namespace SHADE
/* Getter Functions */ /* Getter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
[[nodiscard]] SHVec3 GetCenter () const noexcept; [[nodiscard]] SHVec3 GetCenter () const noexcept;
[[nodiscard]] SHVec3 GetHalfExtents() const noexcept; [[nodiscard]] SHVec3 GetWorldExtents () const noexcept;
[[nodiscard]] SHVec3 GetMin () const noexcept; [[nodiscard]] const SHVec3& GetRelativeExtents () const noexcept;
[[nodiscard]] SHVec3 GetMax () const noexcept; [[nodiscard]] SHVec3 GetMin () const noexcept;
[[nodiscard]] std::vector<SHVec3> GetVertices () const noexcept; [[nodiscard]] SHVec3 GetMax () const noexcept;
[[nodiscard]] std::vector<SHVec3> GetVertices () const noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Setter Functions */ /* Setter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void SetCenter (const SHVec3& newCenter) noexcept; void SetCenter (const SHVec3& newCenter) noexcept;
void SetHalfExtents (const SHVec3& newHalfExtents) noexcept; void SetWorldExtents (const SHVec3& newWorldExtents) noexcept;
void SetMin (const SHVec3& min) noexcept; void SetRelativeExtents (const SHVec3& newRelativeExtents) noexcept;
void SetMax (const SHVec3& max) noexcept; void SetMin (const SHVec3& min) noexcept;
void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept; void SetMax (const SHVec3& max) noexcept;
void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Function Members */ /* Function Members */
@ -89,6 +91,13 @@ namespace SHADE
[[nodiscard]] static bool Intersect (const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept; [[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 BuildFromBoxes (const SHBoundingBox* boxes, size_t numBoxes) noexcept;
[[nodiscard]] static SHBoundingBox BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept; [[nodiscard]] static SHBoundingBox BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept;
private:
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
SHVec3 RelativeExtents;
}; };

View File

@ -25,11 +25,13 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHBoundingSphere::SHBoundingSphere() noexcept SHBoundingSphere::SHBoundingSphere() noexcept
: RelativeRadius { 1.0f }
{ {
type = Type::SPHERE; type = Type::SPHERE;
} }
SHBoundingSphere::SHBoundingSphere(const SHVec3& center, float radius) noexcept SHBoundingSphere::SHBoundingSphere(const SHVec3& center, float radius) noexcept
: RelativeRadius { 1.0f }
{ {
type = Type::SPHERE; type = Type::SPHERE;
@ -44,16 +46,18 @@ namespace SHADE
type = Type::SPHERE; type = Type::SPHERE;
Center = rhs.Center; Center = rhs.Center;
Radius = rhs.Radius; Radius = rhs.Radius;
RelativeRadius = rhs.RelativeRadius;
} }
SHBoundingSphere::SHBoundingSphere(SHBoundingSphere&& rhs) noexcept SHBoundingSphere::SHBoundingSphere(SHBoundingSphere&& rhs) noexcept
{ {
type = Type::SPHERE; type = Type::SPHERE;
Center = rhs.Center; Center = rhs.Center;
Radius = rhs.Radius; Radius = rhs.Radius;
RelativeRadius = rhs.RelativeRadius;
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -68,8 +72,9 @@ namespace SHADE
} }
else if (this != &rhs) else if (this != &rhs)
{ {
Center = rhs.Center; Center = rhs.Center;
Radius = rhs.Radius; Radius = rhs.Radius;
RelativeRadius = rhs.RelativeRadius;
} }
return *this; return *this;
@ -83,8 +88,9 @@ namespace SHADE
} }
else else
{ {
Center = rhs.Center; Center = rhs.Center;
Radius = rhs.Radius; Radius = rhs.Radius;
RelativeRadius = rhs.RelativeRadius;
} }
return *this; return *this;
@ -99,11 +105,16 @@ namespace SHADE
return Center; return Center;
} }
float SHBoundingSphere::GetRadius() const noexcept float SHBoundingSphere::GetWorldRadius() const noexcept
{ {
return Radius; return Radius;
} }
float SHBoundingSphere::GetRelativeRadius() const noexcept
{
return RelativeRadius;
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Setter Function Definitions */ /* Setter Function Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -113,9 +124,14 @@ namespace SHADE
Center = center; 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;
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/

View File

@ -48,15 +48,17 @@ namespace SHADE
/* Getter Functions */ /* Getter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
[[nodiscard]] SHVec3 GetCenter () const noexcept; [[nodiscard]] SHVec3 GetCenter () const noexcept;
[[nodiscard]] float GetRadius () const noexcept; [[nodiscard]] float GetWorldRadius () const noexcept;
[[nodiscard]] float GetRelativeRadius () const noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Setter Functions */ /* Setter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void SetCenter (const SHVec3& center) noexcept; void SetCenter (const SHVec3& center) noexcept;
void SetRadius (float radius) noexcept; void SetWorldRadius (float newWorldRadius) noexcept;
void SetRelativeRadius (float newRelativeRadius) noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Function Members */ /* Function Members */
@ -79,5 +81,12 @@ namespace SHADE
[[nodiscard]] static SHBoundingSphere BuildFromSpheres (const SHBoundingSphere* spheres, size_t numSpheres) noexcept; [[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; [[nodiscard]] static SHBoundingSphere BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept;
private:
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
float RelativeRadius;
}; };
} // namespace SHADE } // namespace SHADE

View File

@ -48,6 +48,11 @@ namespace SHADE
return orientation.ToEuler(); return orientation.ToEuler();
} }
const SHVec3& SHColliderComponent::GetScale() const noexcept
{
return scale;
}
const SHColliderComponent::CollisionShapes& SHColliderComponent::GetCollisionShapes() const noexcept const SHColliderComponent::CollisionShapes& SHColliderComponent::GetCollisionShapes() const noexcept
{ {
return collisionShapes; return collisionShapes;
@ -75,12 +80,46 @@ 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<SHBoundingBox*>(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<SHBoundingSphere*>(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) if (!system)
{ {
SHLOG_ERROR("Physics system does not exist, unable to add Box Collider!") SHLOG_ERROR("Physics system does not exist, unable to add Box Collider!")
return nullptr; return -1;
} }
static constexpr auto TYPE = SHCollisionShape::Type::BOX; static constexpr auto TYPE = SHCollisionShape::Type::BOX;
@ -89,20 +128,21 @@ namespace SHADE
collider.entityID = GetEID(); collider.entityID = GetEID();
collider.SetPositionOffset(posOffset); collider.SetPositionOffset(posOffset);
collider.SetRotationOffset(rotOffset);
collider.SetBoundingBox(halfExtents); collider.SetBoundingBox(halfExtents);
// Notify Physics System // Notify Physics System
system->AddCollisionShape(GetEID(), &collider); system->AddCollisionShape(GetEID(), &collider);
return reinterpret_cast<SHBoundingBox*>(collider.GetShape()); return static_cast<int>(collisionShapes.size()) - 1;
} }
SHBoundingSphere* SHColliderComponent::AddBoundingSphere(float radius, const SHVec3& posOffset) noexcept int SHColliderComponent::AddBoundingSphere(float radius, const SHVec3& posOffset) noexcept
{ {
if (!system) if (!system)
{ {
SHLOG_ERROR("Physics system does not exist, unable to add Sphere Collider!") SHLOG_ERROR("Physics system does not exist, unable to add Sphere Collider!")
return nullptr; return -1;
} }
static constexpr auto TYPE = SHCollisionShape::Type::SPHERE; static constexpr auto TYPE = SHCollisionShape::Type::SPHERE;
@ -116,7 +156,7 @@ namespace SHADE
// Notify Physics System // Notify Physics System
system->AddCollisionShape(GetEID(), &collider); system->AddCollisionShape(GetEID(), &collider);
return reinterpret_cast<SHBoundingSphere*>(collider.GetShape()); return static_cast<int>(collisionShapes.size()) - 1;
} }
void SHColliderComponent::RemoveCollider(int index) void SHColliderComponent::RemoveCollider(int index)

View File

@ -72,6 +72,7 @@ namespace SHADE
[[nodiscard]] const SHVec3& GetPosition () const noexcept; [[nodiscard]] const SHVec3& GetPosition () const noexcept;
[[nodiscard]] const SHQuaternion& GetOrientation () const noexcept; [[nodiscard]] const SHQuaternion& GetOrientation () const noexcept;
[[nodiscard]] SHVec3 GetRotation () const noexcept; [[nodiscard]] SHVec3 GetRotation () const noexcept;
[[nodiscard]] const SHVec3& GetScale () const noexcept;
[[nodiscard]] const CollisionShapes& GetCollisionShapes() const noexcept; [[nodiscard]] const CollisionShapes& GetCollisionShapes() const noexcept;
[[nodiscard]] SHCollisionShape& GetCollisionShape (int index); [[nodiscard]] SHCollisionShape& GetCollisionShape (int index);
@ -80,13 +81,15 @@ namespace SHADE
/* Function Members */ /* Function Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void OnCreate () override; void OnCreate () override;
void OnDestroy () override; void OnDestroy () override;
void RemoveCollider (int index); void RecomputeCollisionShapes () noexcept;
SHBoundingBox* AddBoundingBox (const SHVec3& halfExtents = SHVec3::One, const SHVec3& posOffset = SHVec3::Zero) noexcept; void RemoveCollider (int index);
SHBoundingSphere* AddBoundingSphere (float radius = 1.0f, const SHVec3& posOffset = SHVec3::Zero) noexcept;
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: private:
@ -98,6 +101,7 @@ namespace SHADE
SHVec3 position; SHVec3 position;
SHQuaternion orientation; SHQuaternion orientation;
SHVec3 scale;
CollisionShapes collisionShapes; CollisionShapes collisionShapes;
RTTR_ENABLE() RTTR_ENABLE()

View File

@ -15,8 +15,8 @@
// Project Headers // Project Headers
#include "Math/Geometry/SHBoundingBox.h" #include "Math/Geometry/SHBoundingBox.h"
#include "Math/Geometry/SHBoundingSphere.h" #include "Math/Geometry/SHBoundingSphere.h"
#include "Math/Transform/SHTransformComponent.h"
#include "Math/SHMathHelpers.h" #include "Math/SHMathHelpers.h"
#include "Physics/Components/SHColliderComponent.h"
#include "Reflection/SHReflectionMetadata.h" #include "Reflection/SHReflectionMetadata.h"
namespace SHADE namespace SHADE
@ -178,56 +178,43 @@ namespace SHADE
{ {
dirty = true; dirty = true;
// Set the half extents relative to transform const auto* colliderComponent = SHComponentManager::GetComponent<SHColliderComponent>(entityID);
SHVec3 worldHalfExtents = halfExtents; // Set the half extents relative to world scale
const SHVec3 WORLD_EXTENTS = halfExtents * colliderComponent->GetScale() * 0.5f;
const auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID); if (type != Type::BOX)
if (transformComponent != nullptr)
worldHalfExtents *= (transformComponent->GetWorldScale() * 0.5f);
if (type == Type::BOX)
{
auto* box = reinterpret_cast<SHBoundingBox*>(shape);
box->SetHalfExtents(worldHalfExtents);
}
else
{ {
type = Type::BOX; type = Type::BOX;
delete shape; delete shape;
shape = new SHBoundingBox{ positionOffset, worldHalfExtents }; shape = new SHBoundingBox{ positionOffset, WORLD_EXTENTS };
} }
auto* box = reinterpret_cast<SHBoundingBox*>(shape);
box->SetWorldExtents(WORLD_EXTENTS);
box->SetRelativeExtents(halfExtents);
} }
void SHCollisionShape::SetBoundingSphere(float radius) void SHCollisionShape::SetBoundingSphere(float radius)
{ {
dirty = true; dirty = true;
// Set the radius relative to transform const auto* colliderComponent = SHComponentManager::GetComponent<SHColliderComponent>(entityID);
float worldRadius = radius; // 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<SHTransformComponent>(entityID); if (type != Type::SPHERE)
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<SHBoundingSphere*>(shape);
sphere->SetRadius(worldRadius);
}
else
{ {
type = Type::SPHERE; type = Type::SPHERE;
delete shape; delete shape;
shape = new SHBoundingSphere{ positionOffset, worldRadius }; shape = new SHBoundingSphere{ positionOffset, WORLD_RADIUS };
} }
auto* sphere = reinterpret_cast<SHBoundingSphere*>(shape);
sphere->SetWorldRadius(WORLD_RADIUS);
} }
void SHCollisionShape::SetIsTrigger(bool trigger) noexcept void SHCollisionShape::SetIsTrigger(bool trigger) noexcept
@ -299,14 +286,14 @@ namespace SHADE
{ {
const auto* RHS_BOX = reinterpret_cast<const SHBoundingBox*>(rhs); const auto* RHS_BOX = reinterpret_cast<const SHBoundingBox*>(rhs);
shape = new SHBoundingBox{ positionOffset, RHS_BOX->GetHalfExtents() }; shape = new SHBoundingBox{ positionOffset, RHS_BOX->GetWorldExtents() };
break; break;
} }
case Type::SPHERE: case Type::SPHERE:
{ {
const auto* RHS_SPHERE = reinterpret_cast<const SHBoundingSphere*>(rhs); const auto* RHS_SPHERE = reinterpret_cast<const SHBoundingSphere*>(rhs);
shape = new SHBoundingSphere{ positionOffset, RHS_SPHERE->GetRadius() }; shape = new SHBoundingSphere{ positionOffset, RHS_SPHERE->GetWorldRadius() };
break; break;
} }
default: break; default: break;

View File

@ -137,7 +137,7 @@ namespace SHADE
case SHCollisionShape::Type::BOX: case SHCollisionShape::Type::BOX:
{ {
const auto* box = reinterpret_cast<SHBoundingBox*>(collider->GetShape()); const auto* box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
rp3d::BoxShape* newBox = factory->createBoxShape(box->GetHalfExtents()); rp3d::BoxShape* newBox = factory->createBoxShape(box->GetWorldExtents());
rp3dBody->addCollider(newBox, OFFSETS); rp3dBody->addCollider(newBox, OFFSETS);
break; break;
@ -145,7 +145,7 @@ namespace SHADE
case SHCollisionShape::Type::SPHERE: case SHCollisionShape::Type::SPHERE:
{ {
const auto* sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape()); const auto* sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
rp3d::SphereShape* newSphere = factory->createSphereShape(sphere->GetRadius()); rp3d::SphereShape* newSphere = factory->createSphereShape(sphere->GetWorldRadius());
rp3dBody->addCollider(newSphere, OFFSETS); rp3dBody->addCollider(newSphere, OFFSETS);
break; break;
@ -193,7 +193,7 @@ namespace SHADE
const auto* box = reinterpret_cast<SHBoundingBox*>(collider.GetShape()); const auto* box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
auto* rp3dBoxShape = reinterpret_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape()); auto* rp3dBoxShape = reinterpret_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape());
rp3dBoxShape->setHalfExtents(box->GetHalfExtents()); rp3dBoxShape->setHalfExtents(box->GetWorldExtents());
break; break;
} }
@ -202,7 +202,7 @@ namespace SHADE
const auto* sphere = reinterpret_cast<SHBoundingSphere*>(collider.GetShape()); const auto* sphere = reinterpret_cast<SHBoundingSphere*>(collider.GetShape());
auto* rp3dSphereShape = reinterpret_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape()); auto* rp3dSphereShape = reinterpret_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape());
rp3dSphereShape->setRadius(sphere->GetRadius()); rp3dSphereShape->setRadius(sphere->GetWorldRadius());
break; break;
} }

View File

@ -395,6 +395,7 @@ namespace SHADE
{ {
const auto WORLD_POS = transformComponent->GetWorldPosition(); const auto WORLD_POS = transformComponent->GetWorldPosition();
const auto WORLD_ROT = transformComponent->GetWorldOrientation(); const auto WORLD_ROT = transformComponent->GetWorldOrientation();
const auto WORLD_SCL = transformComponent->GetWorldScale();
physicsObject.SetPosition(WORLD_POS); physicsObject.SetPosition(WORLD_POS);
physicsObject.SetOrientation(WORLD_ROT); physicsObject.SetOrientation(WORLD_ROT);
@ -409,8 +410,11 @@ namespace SHADE
if (colliderComponent) if (colliderComponent)
{ {
colliderComponent->position = WORLD_POS; colliderComponent->position = WORLD_POS;
colliderComponent->orientation = WORLD_ROT; colliderComponent->orientation = WORLD_ROT;
colliderComponent->scale = WORLD_SCL;
colliderComponent->RecomputeCollisionShapes();
} }
} }
@ -744,8 +748,9 @@ namespace SHADE
{ {
SHASSERT(colliderComponent != nullptr, "Collider Component was not added to Entity " + std::to_string(ENTITY_ID) + "!"); SHASSERT(colliderComponent != nullptr, "Collider Component was not added to Entity " + std::to_string(ENTITY_ID) + "!");
colliderComponent->position = transformComponent->GetWorldPosition(); colliderComponent->position = transformComponent->GetWorldPosition();
colliderComponent->orientation = transformComponent->GetWorldOrientation(); colliderComponent->orientation = transformComponent->GetWorldOrientation();
colliderComponent->scale = transformComponent->GetWorldScale();
if (physicsObject->rp3dBody == nullptr) if (physicsObject->rp3dBody == nullptr)
{ {

View File

@ -131,13 +131,13 @@ namespace YAML
case SHCollisionShape::Type::BOX: case SHCollisionShape::Type::BOX:
{ {
auto const bb = reinterpret_cast<SHBoundingBox*>(rhs.GetShape()); auto const bb = reinterpret_cast<SHBoundingBox*>(rhs.GetShape());
node[HalfExtents] = bb->GetHalfExtents(); node[HalfExtents] = bb->GetRelativeExtents();
} }
break; break;
case SHCollisionShape::Type::SPHERE: case SHCollisionShape::Type::SPHERE:
{ {
auto const bs = reinterpret_cast<SHBoundingSphere*>(rhs.GetShape()); auto const bs = reinterpret_cast<SHBoundingSphere*>(rhs.GetShape());
node[Radius] = bs->GetRadius(); node[Radius] = bs->GetRelativeRadius();
} }
break; break;
case SHCollisionShape::Type::CAPSULE: break; case SHCollisionShape::Type::CAPSULE: break;
@ -168,7 +168,7 @@ namespace YAML
case SHCollisionShape::Type::BOX: case SHCollisionShape::Type::BOX:
{ {
if (node[HalfExtents].IsDefined()) if (node[HalfExtents].IsDefined())
rhs.SetBoundingBox(node[HalfExtents].as<SHVec3>() * 2.0f); rhs.SetBoundingBox(node[HalfExtents].as<SHVec3>());
} }
break; break;
case SHCollisionShape::Type::SPHERE: case SHCollisionShape::Type::SPHERE:

View File

@ -55,11 +55,11 @@ namespace SHADE
} }
Vector3 BoxCollider::HalfExtents::get() Vector3 BoxCollider::HalfExtents::get()
{ {
return Convert::ToCLI(getNativeBoundObject<SHBoundingBox>().GetHalfExtents()); return Convert::ToCLI(getNativeBoundObject<SHBoundingBox>().GetWorldExtents());
} }
void BoxCollider::HalfExtents::set(Vector3 value) void BoxCollider::HalfExtents::set(Vector3 value)
{ {
getNativeBoundObject<SHBoundingBox>().SetHalfExtents(Convert::ToNative(value)); getNativeBoundObject<SHBoundingBox>().SetWorldExtents(Convert::ToNative(value));
} }
Vector3 BoxCollider::Min::get() Vector3 BoxCollider::Min::get()
{ {
@ -103,11 +103,11 @@ namespace SHADE
} }
float SphereCollider::Radius::get() float SphereCollider::Radius::get()
{ {
return getNativeBoundObject<SHBoundingSphere>().GetRadius(); return getNativeBoundObject<SHBoundingSphere>().GetWorldRadius();
} }
void SphereCollider::Radius::set(float value) void SphereCollider::Radius::set(float value)
{ {
getNativeBoundObject<SHBoundingSphere>().SetRadius(value); getNativeBoundObject<SHBoundingSphere>().SetWorldRadius(value);
} }
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/