SP3-2 Fixed physics bugs and collider improvements #184
|
@ -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,7 +226,4 @@
|
||||||
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:
|
Scripts: ~
|
||||||
- Type: PickAndThrow
|
|
||||||
throwForce: [100, 200, 100]
|
|
||||||
item: 1
|
|
|
@ -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>();
|
||||||
|
@ -114,8 +114,8 @@ namespace Sandbox
|
||||||
racoonTransform.SetWorldPosition({ -3.0f, -2.0f, -5.0f });
|
racoonTransform.SetWorldPosition({ -3.0f, -2.0f, -5.0f });
|
||||||
|
|
||||||
racoonCollider.AddBoundingBox();
|
racoonCollider.AddBoundingBox();
|
||||||
racoonCollider.GetCollider(0).SetPositionOffset(SHVec3(0.0f,0.5f,0.0f));
|
racoonCollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f,0.5f,0.0f));
|
||||||
racoonCollider.GetCollider(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
racoonCollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
||||||
|
|
||||||
auto racoonItemLocation = SHEntityManager::CreateEntity<SHTransformComponent>();
|
auto racoonItemLocation = SHEntityManager::CreateEntity<SHTransformComponent>();
|
||||||
auto& racoonItemLocationTransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(racoonItemLocation);
|
auto& racoonItemLocationTransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(racoonItemLocation);
|
||||||
|
@ -140,13 +140,13 @@ namespace Sandbox
|
||||||
|
|
||||||
itemCollider.AddBoundingBox();
|
itemCollider.AddBoundingBox();
|
||||||
itemCollider.AddBoundingBox(SHVec3(2.0f,2.0f,2.0f));
|
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.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
||||||
itemCollider.GetCollider(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
itemCollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
||||||
|
|
||||||
itemCollider.GetCollider(1).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
itemCollider.GetCollisionShape(1).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
||||||
itemCollider.GetCollider(1).SetBoundingBox(SHVec3(1.0f, 1.0f, 1.0f));
|
itemCollider.GetCollisionShape(1).SetBoundingBox(SHVec3(1.0f, 1.0f, 1.0f));
|
||||||
|
|
||||||
itemRigidBody.SetInterpolate(false);
|
itemRigidBody.SetInterpolate(false);
|
||||||
itemRigidBody.SetFreezeRotationX(true);
|
itemRigidBody.SetFreezeRotationX(true);
|
||||||
|
@ -168,8 +168,8 @@ namespace Sandbox
|
||||||
AITransform.SetWorldPosition({ -8.0f, -2.0f, 2.5f });
|
AITransform.SetWorldPosition({ -8.0f, -2.0f, 2.5f });
|
||||||
|
|
||||||
AICollider.AddBoundingBox();
|
AICollider.AddBoundingBox();
|
||||||
AICollider.GetCollider(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
AICollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
||||||
AICollider.GetCollider(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
AICollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
||||||
|
|
||||||
AIRigidBody.SetInterpolate(false);
|
AIRigidBody.SetInterpolate(false);
|
||||||
AIRigidBody.SetFreezeRotationX(true);
|
AIRigidBody.SetFreezeRotationX(true);
|
||||||
|
|
|
@ -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();
|
||||||
|
@ -234,46 +231,39 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
DrawContextMenu(component);
|
DrawContextMenu(component);
|
||||||
|
|
||||||
auto& colliders = component->GetColliders();
|
auto& colliders = component->GetCollisionShapes();
|
||||||
int const size = static_cast<int>(colliders.size());
|
int const size = static_cast<int>(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<int> colliderToDelete{ std::nullopt };
|
std::optional<int> colliderToDelete{ std::nullopt };
|
||||||
for (int i{}; i < size; ++i)
|
for (int i{}; i < size; ++i)
|
||||||
{
|
{
|
||||||
ImGui::PushID(i);
|
ImGui::PushID(i);
|
||||||
SHCollider* collider = &component->GetCollider(i);
|
SHCollisionShape* collider = &component->GetCollisionShape(i);
|
||||||
auto cursorPos = ImGui::GetCursorPos();
|
auto cursorPos = ImGui::GetCursorPos();
|
||||||
|
|
||||||
//collider->IsTrigger
|
//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::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() == 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::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() == SHCollider::Type::CAPSULE)
|
else if (collider->GetType() == SHCollisionShape::Type::CAPSULE)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
@ -47,6 +49,7 @@ namespace SHADE
|
||||||
|
|
||||||
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
|
||||||
|
@ -55,6 +58,7 @@ namespace SHADE
|
||||||
|
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Extents = rhs.Extents;
|
Extents = rhs.Extents;
|
||||||
|
RelativeExtents = rhs.RelativeExtents;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -71,6 +75,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Extents = rhs.Extents;
|
Extents = rhs.Extents;
|
||||||
|
RelativeExtents = rhs.RelativeExtents;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -86,6 +91,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
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
|
||||||
|
|
|
@ -55,7 +55,8 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
[[nodiscard]] SHVec3 GetCenter () const noexcept;
|
[[nodiscard]] SHVec3 GetCenter () const noexcept;
|
||||||
[[nodiscard]] SHVec3 GetHalfExtents() const noexcept;
|
[[nodiscard]] SHVec3 GetWorldExtents () const noexcept;
|
||||||
|
[[nodiscard]] const SHVec3& GetRelativeExtents () const noexcept;
|
||||||
[[nodiscard]] SHVec3 GetMin () const noexcept;
|
[[nodiscard]] SHVec3 GetMin () const noexcept;
|
||||||
[[nodiscard]] SHVec3 GetMax () const noexcept;
|
[[nodiscard]] SHVec3 GetMax () const noexcept;
|
||||||
[[nodiscard]] std::vector<SHVec3> GetVertices () const noexcept;
|
[[nodiscard]] std::vector<SHVec3> GetVertices () const noexcept;
|
||||||
|
@ -65,7 +66,8 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
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 SetRelativeExtents (const SHVec3& newRelativeExtents) noexcept;
|
||||||
void SetMin (const SHVec3& min) noexcept;
|
void SetMin (const SHVec3& min) noexcept;
|
||||||
void SetMax (const SHVec3& max) noexcept;
|
void SetMax (const SHVec3& max) noexcept;
|
||||||
void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept;
|
void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept;
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
@ -46,6 +48,7 @@ namespace SHADE
|
||||||
|
|
||||||
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
|
||||||
|
@ -54,6 +57,7 @@ namespace SHADE
|
||||||
|
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Radius = rhs.Radius;
|
Radius = rhs.Radius;
|
||||||
|
RelativeRadius = rhs.RelativeRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -70,6 +74,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Radius = rhs.Radius;
|
Radius = rhs.Radius;
|
||||||
|
RelativeRadius = rhs.RelativeRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -85,6 +90,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -49,14 +49,16 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
[[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
|
||||||
|
|
|
@ -231,12 +231,12 @@ namespace SHADE
|
||||||
tf.worldRotation = tf.localRotation + (parent ? parent->GetLocalRotation() : SHVec3::Zero);
|
tf.worldRotation = tf.localRotation + (parent ? parent->GetLocalRotation() : SHVec3::Zero);
|
||||||
|
|
||||||
// Set the orientation
|
// 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;
|
SHVec3 worldRotRad, localRotRad;
|
||||||
for (size_t i = 0; i < SHVec3::SIZE; ++i)
|
for (size_t i = 0; i < SHVec3::SIZE; ++i)
|
||||||
{
|
{
|
||||||
worldRotRad[i] = SHMath::Wrap(tf.worldRotation[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], -SHMath::TWO_PI, 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);
|
tf.world.orientation = SHQuaternion::FromEuler(worldRotRad);
|
||||||
|
|
|
@ -48,17 +48,22 @@ namespace SHADE
|
||||||
return orientation.ToEuler();
|
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<size_t>(index) >= colliders.size())
|
return collisionShapes;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHCollisionShape& SHColliderComponent::GetCollisionShape(int index)
|
||||||
|
{
|
||||||
|
if (index < 0 || static_cast<size_t>(index) >= collisionShapes.size())
|
||||||
throw std::invalid_argument("Out-of-range access!");
|
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<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 = 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.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 = 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.entityID = GetEID();
|
||||||
collider.SetPositionOffset(posOffset);
|
collider.SetPositionOffset(posOffset);
|
||||||
|
@ -116,17 +156,17 @@ 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)
|
||||||
{
|
{
|
||||||
if (index < 0 || static_cast<size_t>(index) >= colliders.size())
|
if (index < 0 || static_cast<size_t>(index) >= collisionShapes.size())
|
||||||
throw std::invalid_argument("Out-of-range access!");
|
throw std::invalid_argument("Out-of-range access!");
|
||||||
|
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
auto it = colliders.begin();
|
auto it = collisionShapes.begin();
|
||||||
for (; it != colliders.end(); ++it)
|
for (; it != collisionShapes.end(); ++it)
|
||||||
{
|
{
|
||||||
if (idx == index)
|
if (idx == index)
|
||||||
break;
|
break;
|
||||||
|
@ -134,7 +174,7 @@ namespace SHADE
|
||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
it = colliders.erase(it);
|
it = collisionShapes.erase(it);
|
||||||
|
|
||||||
// Notify Physics System
|
// Notify Physics System
|
||||||
if (!system)
|
if (!system)
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "ECS_Base/Components/SHComponent.h"
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
#include "Physics/SHCollider.h"
|
#include "Physics/SHCollisionShape.h"
|
||||||
#include "Math/Geometry/SHBoundingBox.h"
|
#include "Math/Geometry/SHBoundingBox.h"
|
||||||
#include "Math/Geometry/SHBoundingSphere.h"
|
#include "Math/Geometry/SHBoundingSphere.h"
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ namespace SHADE
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
using Colliders = std::vector<SHCollider>;
|
using CollisionShapes = std::vector<SHCollisionShape>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -72,9 +72,10 @@ 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 Colliders& GetColliders () const noexcept;
|
[[nodiscard]] const CollisionShapes& GetCollisionShapes() const noexcept;
|
||||||
[[nodiscard]] SHCollider& GetCollider (int index);
|
[[nodiscard]] SHCollisionShape& GetCollisionShape (int index);
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
|
@ -83,10 +84,12 @@ namespace SHADE
|
||||||
void OnCreate () override;
|
void OnCreate () override;
|
||||||
void OnDestroy () override;
|
void OnDestroy () override;
|
||||||
|
|
||||||
|
void RecomputeCollisionShapes () noexcept;
|
||||||
|
|
||||||
void RemoveCollider (int index);
|
void RemoveCollider (int index);
|
||||||
|
|
||||||
SHBoundingBox* AddBoundingBox (const SHVec3& halfExtents = SHVec3::One, const SHVec3& posOffset = SHVec3::Zero) noexcept;
|
int AddBoundingBox (const SHVec3& halfExtents = SHVec3::One, const SHVec3& posOffset = SHVec3::Zero, const SHVec3& rotOffset = SHVec3::Zero) noexcept;
|
||||||
SHBoundingSphere* AddBoundingSphere (float radius = 1.0f, const SHVec3& posOffset = SHVec3::Zero) noexcept;
|
int AddBoundingSphere (float radius = 1.0f, const SHVec3& posOffset = SHVec3::Zero) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -98,7 +101,8 @@ namespace SHADE
|
||||||
|
|
||||||
SHVec3 position;
|
SHVec3 position;
|
||||||
SHQuaternion orientation;
|
SHQuaternion orientation;
|
||||||
Colliders colliders;
|
SHVec3 scale;
|
||||||
|
CollisionShapes collisionShapes;
|
||||||
|
|
||||||
RTTR_ENABLE()
|
RTTR_ENABLE()
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,12 +11,12 @@
|
||||||
#include <SHpch.h>
|
#include <SHpch.h>
|
||||||
|
|
||||||
// Primary Header
|
// Primary Header
|
||||||
#include "SHCollider.h"
|
#include "SHCollisionShape.h"
|
||||||
// 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
|
||||||
|
@ -25,7 +25,7 @@ namespace SHADE
|
||||||
/* Constructors & Destructor Definitions */
|
/* Constructors & Destructor Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHCollider::SHCollider(EntityID eid, Type colliderType, const SHPhysicsMaterial& physicsMaterial)
|
SHCollisionShape::SHCollisionShape(EntityID eid, Type colliderType, const SHPhysicsMaterial& physicsMaterial)
|
||||||
: type { colliderType }
|
: type { colliderType }
|
||||||
, entityID { eid }
|
, entityID { eid }
|
||||||
, isTrigger { false }
|
, isTrigger { false }
|
||||||
|
@ -49,7 +49,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SHCollider::SHCollider(const SHCollider& rhs) noexcept
|
SHCollisionShape::SHCollisionShape(const SHCollisionShape& rhs) noexcept
|
||||||
: type { rhs.type}
|
: type { rhs.type}
|
||||||
, entityID { rhs.entityID }
|
, entityID { rhs.entityID }
|
||||||
, isTrigger { rhs.isTrigger }
|
, isTrigger { rhs.isTrigger }
|
||||||
|
@ -61,7 +61,7 @@ namespace SHADE
|
||||||
CopyShape(rhs.shape);
|
CopyShape(rhs.shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHCollider::SHCollider(SHCollider&& rhs) noexcept
|
SHCollisionShape::SHCollisionShape(SHCollisionShape&& rhs) noexcept
|
||||||
: type { rhs.type}
|
: type { rhs.type}
|
||||||
, entityID { rhs.entityID }
|
, entityID { rhs.entityID }
|
||||||
, isTrigger { rhs.isTrigger }
|
, isTrigger { rhs.isTrigger }
|
||||||
|
@ -73,7 +73,7 @@ namespace SHADE
|
||||||
CopyShape(rhs.shape);
|
CopyShape(rhs.shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHCollider::~SHCollider() noexcept
|
SHCollisionShape::~SHCollisionShape() noexcept
|
||||||
{
|
{
|
||||||
shape = nullptr;
|
shape = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ namespace SHADE
|
||||||
/* Operator Overload Definitions */
|
/* Operator Overload Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHCollider& SHCollider::operator=(const SHCollider& rhs) noexcept
|
SHCollisionShape& SHCollisionShape::operator=(const SHCollisionShape& rhs) noexcept
|
||||||
{
|
{
|
||||||
if (this == &rhs)
|
if (this == &rhs)
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -100,7 +100,7 @@ namespace SHADE
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHCollider& SHCollider::operator=(SHCollider&& rhs) noexcept
|
SHCollisionShape& SHCollisionShape::operator=(SHCollisionShape&& rhs) noexcept
|
||||||
{
|
{
|
||||||
type = rhs.type;
|
type = rhs.type;
|
||||||
entityID = rhs.entityID;
|
entityID = rhs.entityID;
|
||||||
|
@ -119,52 +119,52 @@ namespace SHADE
|
||||||
/* Getter Function Definitions */
|
/* Getter Function Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
bool SHCollider::HasChanged() const noexcept
|
bool SHCollisionShape::HasChanged() const noexcept
|
||||||
{
|
{
|
||||||
return dirty;
|
return dirty;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHCollider::IsTrigger() const noexcept
|
bool SHCollisionShape::IsTrigger() const noexcept
|
||||||
{
|
{
|
||||||
return isTrigger;
|
return isTrigger;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHCollider::Type SHCollider::GetType() const noexcept
|
SHCollisionShape::Type SHCollisionShape::GetType() const noexcept
|
||||||
{
|
{
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
float SHCollider::GetFriction() const noexcept
|
float SHCollisionShape::GetFriction() const noexcept
|
||||||
{
|
{
|
||||||
return material.GetFriction();
|
return material.GetFriction();
|
||||||
}
|
}
|
||||||
|
|
||||||
float SHCollider::GetBounciness() const noexcept
|
float SHCollisionShape::GetBounciness() const noexcept
|
||||||
{
|
{
|
||||||
return material.GetBounciness();
|
return material.GetBounciness();
|
||||||
}
|
}
|
||||||
|
|
||||||
float SHCollider::GetDensity() const noexcept
|
float SHCollisionShape::GetDensity() const noexcept
|
||||||
{
|
{
|
||||||
return material.GetDensity();
|
return material.GetDensity();
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHPhysicsMaterial& SHCollider::GetMaterial() const noexcept
|
const SHPhysicsMaterial& SHCollisionShape::GetMaterial() const noexcept
|
||||||
{
|
{
|
||||||
return material;
|
return material;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHVec3& SHCollider::GetPositionOffset() const noexcept
|
const SHVec3& SHCollisionShape::GetPositionOffset() const noexcept
|
||||||
{
|
{
|
||||||
return positionOffset;
|
return positionOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHVec3& SHCollider::GetRotationOffset() const noexcept
|
const SHVec3& SHCollisionShape::GetRotationOffset() const noexcept
|
||||||
{
|
{
|
||||||
return rotationOffset;
|
return rotationOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHShape* SHCollider::GetShape() noexcept
|
SHShape* SHCollisionShape::GetShape() noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
return shape;
|
return shape;
|
||||||
|
@ -174,93 +174,80 @@ namespace SHADE
|
||||||
/* Setter Function Definitions */
|
/* Setter Function Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SHCollider::SetBoundingBox(const SHVec3& halfExtents)
|
void SHCollisionShape::SetBoundingBox(const SHVec3& halfExtents)
|
||||||
{
|
{
|
||||||
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 };
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetBoundingSphere(float radius)
|
auto* box = reinterpret_cast<SHBoundingBox*>(shape);
|
||||||
|
box->SetWorldExtents(WORLD_EXTENTS);
|
||||||
|
box->SetRelativeExtents(halfExtents);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 SHCollider::SetIsTrigger(bool trigger) noexcept
|
void SHCollisionShape::SetIsTrigger(bool trigger) noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
isTrigger = trigger;
|
isTrigger = trigger;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetFriction(float friction) noexcept
|
void SHCollisionShape::SetFriction(float friction) noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
material.SetFriction(friction);
|
material.SetFriction(friction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetBounciness(float bounciness) noexcept
|
void SHCollisionShape::SetBounciness(float bounciness) noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
material.SetBounciness(bounciness);
|
material.SetBounciness(bounciness);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetDensity(float density) noexcept
|
void SHCollisionShape::SetDensity(float density) noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
material.SetDensity(density);
|
material.SetDensity(density);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetMaterial(const SHPhysicsMaterial& newMaterial) noexcept
|
void SHCollisionShape::SetMaterial(const SHPhysicsMaterial& newMaterial) noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
material = newMaterial;
|
material = newMaterial;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetPositionOffset(const SHVec3& posOffset) noexcept
|
void SHCollisionShape::SetPositionOffset(const SHVec3& posOffset) noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
positionOffset = posOffset;
|
positionOffset = posOffset;
|
||||||
|
@ -281,7 +268,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetRotationOffset(const SHVec3& rotOffset) noexcept
|
void SHCollisionShape::SetRotationOffset(const SHVec3& rotOffset) noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
rotationOffset = rotOffset;
|
rotationOffset = rotOffset;
|
||||||
|
@ -291,7 +278,7 @@ namespace SHADE
|
||||||
/* Private Function Member Definitions */
|
/* Private Function Member Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SHCollider::CopyShape(const SHShape* rhs)
|
void SHCollisionShape::CopyShape(const SHShape* rhs)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
|
@ -320,14 +307,14 @@ RTTR_REGISTRATION
|
||||||
using namespace SHADE;
|
using namespace SHADE;
|
||||||
using namespace rttr;
|
using namespace rttr;
|
||||||
|
|
||||||
registration::enumeration<SHCollider::Type>("Collider Type")
|
registration::enumeration<SHCollisionShape::Type>("Collider Type")
|
||||||
(
|
(
|
||||||
value("Box", SHCollider::Type::BOX),
|
value("Box", SHCollisionShape::Type::BOX),
|
||||||
value("Sphere", SHCollider::Type::SPHERE)
|
value("Sphere", SHCollisionShape::Type::SPHERE)
|
||||||
// TODO(Diren): Add More Shapes
|
// TODO(Diren): Add More Shapes
|
||||||
);
|
);
|
||||||
|
|
||||||
registration::class_<SHCollider>("Collider")
|
registration::class_<SHCollisionShape>("Collider")
|
||||||
.property("Position Offset", &SHCollider::GetPositionOffset, &SHCollider::SetPositionOffset)
|
.property("Position Offset", &SHCollisionShape::GetPositionOffset, &SHCollisionShape::SetPositionOffset)
|
||||||
.property("Rotation Offset", &SHCollider::GetRotationOffset, &SHCollider::SetRotationOffset) (metadata(META::angleInRad, true));
|
.property("Rotation Offset", &SHCollisionShape::GetRotationOffset, &SHCollisionShape::SetRotationOffset) (metadata(META::angleInRad, true));
|
||||||
}
|
}
|
|
@ -24,7 +24,7 @@ namespace SHADE
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class SH_API SHCollider
|
class SH_API SHCollisionShape
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -51,18 +51,18 @@ namespace SHADE
|
||||||
/* Constructors & Destructor */
|
/* 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;
|
SHCollisionShape (const SHCollisionShape& rhs) noexcept;
|
||||||
SHCollider (SHCollider&& rhs) noexcept;
|
SHCollisionShape (SHCollisionShape&& rhs) noexcept;
|
||||||
~SHCollider () noexcept;
|
~SHCollisionShape () noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Operator Overloads */
|
/* Operator Overloads */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHCollider& operator=(const SHCollider& rhs) noexcept;
|
SHCollisionShape& operator=(const SHCollisionShape& rhs) noexcept;
|
||||||
SHCollider& operator=(SHCollider&& rhs) noexcept;
|
SHCollisionShape& operator=(SHCollisionShape&& rhs) noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
|
@ -128,24 +128,24 @@ namespace SHADE
|
||||||
/* Public Function Member Definitions */
|
/* Public Function Member Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
int SHPhysicsObject::AddCollider(SHCollider* collider)
|
int SHPhysicsObject::AddCollider(SHCollisionShape* collider)
|
||||||
{
|
{
|
||||||
const rp3d::Transform OFFSETS{ collider->GetPositionOffset(), collider->GetRotationOffset() };
|
const rp3d::Transform OFFSETS{ collider->GetPositionOffset(), collider->GetRotationOffset() };
|
||||||
|
|
||||||
switch (collider->GetType())
|
switch (collider->GetType())
|
||||||
{
|
{
|
||||||
case SHCollider::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;
|
||||||
}
|
}
|
||||||
case SHCollider::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;
|
||||||
|
@ -173,7 +173,7 @@ namespace SHADE
|
||||||
void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept
|
void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (auto& collider : c->colliders)
|
for (auto& collider : c->collisionShapes)
|
||||||
{
|
{
|
||||||
if (!collider.dirty)
|
if (!collider.dirty)
|
||||||
continue;
|
continue;
|
||||||
|
@ -188,21 +188,21 @@ namespace SHADE
|
||||||
|
|
||||||
switch (collider.GetType())
|
switch (collider.GetType())
|
||||||
{
|
{
|
||||||
case SHCollider::Type::BOX:
|
case SHCollisionShape::Type::BOX:
|
||||||
{
|
{
|
||||||
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;
|
||||||
}
|
}
|
||||||
case SHCollider::Type::SPHERE:
|
case SHCollisionShape::Type::SPHERE:
|
||||||
{
|
{
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ namespace SHADE
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
int AddCollider (SHCollider* collider);
|
int AddCollider (SHCollisionShape* collider);
|
||||||
void RemoveCollider (int index);
|
void RemoveCollider (int index);
|
||||||
|
|
||||||
void SyncColliders (SHColliderComponent* c) const noexcept;
|
void SyncColliders (SHColliderComponent* c) const noexcept;
|
||||||
|
|
|
@ -348,7 +348,7 @@ namespace SHADE
|
||||||
factory.destroyPhysicsWorld(world);
|
factory.destroyPhysicsWorld(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHCollider* collider)
|
void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHCollisionShape* collider)
|
||||||
{
|
{
|
||||||
auto* physicsObject = GetPhysicsObject(entityID);
|
auto* physicsObject = GetPhysicsObject(entityID);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -411,6 +412,9 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
colliderComponent->position = WORLD_POS;
|
colliderComponent->position = WORLD_POS;
|
||||||
colliderComponent->orientation = WORLD_ROT;
|
colliderComponent->orientation = WORLD_ROT;
|
||||||
|
colliderComponent->scale = WORLD_SCL;
|
||||||
|
|
||||||
|
colliderComponent->RecomputeCollisionShapes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -605,7 +609,6 @@ namespace SHADE
|
||||||
|
|
||||||
if (rigidBodyComponent != nullptr)
|
if (rigidBodyComponent != nullptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (rigidBodyComponent->GetType() == SHRigidBodyComponent::Type::STATIC)
|
if (rigidBodyComponent->GetType() == SHRigidBodyComponent::Type::STATIC)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -658,8 +661,10 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
const auto IT = std::ranges::find_if(container.begin(), container.end(), [&](const SHCollisionEvent& e)
|
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 ENTITY_MATCH = (e.ids[0] == collisionEvent.ids[0] && e.ids[1] == collisionEvent.ids[1])
|
||||||
const bool COLLIDERS_MATCH = e.value[1] == collisionEvent.value[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;
|
return ENTITY_MATCH && COLLIDERS_MATCH;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -734,7 +739,7 @@ namespace SHADE
|
||||||
// Add collision shapes back into the body
|
// Add collision shapes back into the body
|
||||||
if (colliderComponent != nullptr)
|
if (colliderComponent != nullptr)
|
||||||
{
|
{
|
||||||
for (auto& collider : colliderComponent->colliders)
|
for (auto& collider : colliderComponent->collisionShapes)
|
||||||
physicsObject->AddCollider(&collider);
|
physicsObject->AddCollider(&collider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -745,6 +750,7 @@ namespace SHADE
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
@ -755,7 +761,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add Collision Shapes
|
// Add Collision Shapes
|
||||||
for (auto& collider : colliderComponent->colliders)
|
for (auto& collider : colliderComponent->collisionShapes)
|
||||||
physicsObject->AddCollider(&collider);
|
physicsObject->AddCollider(&collider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -800,7 +806,7 @@ namespace SHADE
|
||||||
rp3d::Transform{ colliderComponent->position, colliderComponent->orientation }
|
rp3d::Transform{ colliderComponent->position, colliderComponent->orientation }
|
||||||
);
|
);
|
||||||
|
|
||||||
for (auto& collider : colliderComponent->colliders)
|
for (auto& collider : colliderComponent->collisionShapes)
|
||||||
physicsObject->AddCollider(&collider);
|
physicsObject->AddCollider(&collider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,7 @@ namespace SHADE
|
||||||
void Init () override;
|
void Init () override;
|
||||||
void Exit () override;
|
void Exit () override;
|
||||||
|
|
||||||
void AddCollisionShape (EntityID entityID, SHCollider* collider);
|
void AddCollisionShape (EntityID entityID, SHCollisionShape* collider);
|
||||||
void RemoveCollisionShape (EntityID entityID, int index);
|
void RemoveCollisionShape (EntityID entityID, int index);
|
||||||
|
|
||||||
void onContact (const rp3d::CollisionCallback::CallbackData& callbackData) override;
|
void onContact (const rp3d::CollisionCallback::CallbackData& callbackData) override;
|
||||||
|
|
|
@ -75,14 +75,14 @@ namespace SHADE
|
||||||
return SHComponentManager::GetComponent_s<SHRigidBodyComponent>(ids[ENTITY_B]);
|
return SHComponentManager::GetComponent_s<SHRigidBodyComponent>(ids[ENTITY_B]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHCollider* SHCollisionEvent::GetColliderA() const noexcept
|
const SHCollisionShape* SHCollisionEvent::GetColliderA() const noexcept
|
||||||
{
|
{
|
||||||
return &SHComponentManager::GetComponent<SHColliderComponent>(ids[ENTITY_A])->GetCollider(ids[COLLIDER_A]);
|
return &SHComponentManager::GetComponent<SHColliderComponent>(ids[ENTITY_A])->GetCollisionShape(ids[COLLIDER_A]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHCollider* SHCollisionEvent::GetColliderB() const noexcept
|
const SHCollisionShape* SHCollisionEvent::GetColliderB() const noexcept
|
||||||
{
|
{
|
||||||
return &SHComponentManager::GetComponent<SHColliderComponent>(ids[ENTITY_B])->GetCollider(ids[COLLIDER_B]);
|
return &SHComponentManager::GetComponent<SHColliderComponent>(ids[ENTITY_B])->GetCollisionShape(ids[COLLIDER_B]);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHCollisionEvent::State SHCollisionEvent::GetCollisionState() const noexcept
|
SHCollisionEvent::State SHCollisionEvent::GetCollisionState() const noexcept
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace SHADE
|
||||||
struct SHPhysicsColliderAddedEvent
|
struct SHPhysicsColliderAddedEvent
|
||||||
{
|
{
|
||||||
EntityID entityID;
|
EntityID entityID;
|
||||||
SHCollider::Type colliderType;
|
SHCollisionShape::Type colliderType;
|
||||||
int colliderIndex;
|
int colliderIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -88,8 +88,8 @@ namespace SHADE
|
||||||
[[nodiscard]] EntityID GetEntityB () const noexcept;
|
[[nodiscard]] EntityID GetEntityB () const noexcept;
|
||||||
[[nodiscard]] const SHRigidBodyComponent* GetRigidBodyA () const noexcept;
|
[[nodiscard]] const SHRigidBodyComponent* GetRigidBodyA () const noexcept;
|
||||||
[[nodiscard]] const SHRigidBodyComponent* GetRigidBodyB () const noexcept;
|
[[nodiscard]] const SHRigidBodyComponent* GetRigidBodyB () const noexcept;
|
||||||
[[nodiscard]] const SHCollider* GetColliderA () const noexcept;
|
[[nodiscard]] const SHCollisionShape* GetColliderA () const noexcept;
|
||||||
[[nodiscard]] const SHCollider* GetColliderB () const noexcept;
|
[[nodiscard]] const SHCollisionShape* GetColliderB () const noexcept;
|
||||||
[[nodiscard]] State GetCollisionState () const noexcept;
|
[[nodiscard]] State GetCollisionState () const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||||
#include "Math/Geometry/SHBoundingBox.h"
|
#include "Math/Geometry/SHBoundingBox.h"
|
||||||
#include "Math/Geometry/SHBoundingSphere.h"
|
#include "Math/Geometry/SHBoundingSphere.h"
|
||||||
#include "Physics/SHCollider.h"
|
#include "Physics/SHCollisionShape.h"
|
||||||
#include "Resource/SHResourceManager.h"
|
#include "Resource/SHResourceManager.h"
|
||||||
#include "Math/Vector/SHVec2.h"
|
#include "Math/Vector/SHVec2.h"
|
||||||
#include "Math/Vector/SHVec3.h"
|
#include "Math/Vector/SHVec3.h"
|
||||||
|
@ -101,7 +101,7 @@ namespace YAML
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct convert<SHCollider>
|
struct convert<SHCollisionShape>
|
||||||
{
|
{
|
||||||
static constexpr const char* IsTrigger = "Is Trigger";
|
static constexpr const char* IsTrigger = "Is Trigger";
|
||||||
|
|
||||||
|
@ -114,33 +114,33 @@ namespace YAML
|
||||||
static constexpr const char* Density = "Density";
|
static constexpr const char* Density = "Density";
|
||||||
static constexpr const char* PositionOffset = "Position Offset";
|
static constexpr const char* PositionOffset = "Position Offset";
|
||||||
|
|
||||||
static Node encode(SHCollider& rhs)
|
static Node encode(SHCollisionShape& rhs)
|
||||||
{
|
{
|
||||||
Node node;
|
Node node;
|
||||||
|
|
||||||
node[IsTrigger] = rhs.IsTrigger();
|
node[IsTrigger] = rhs.IsTrigger();
|
||||||
|
|
||||||
rttr::type const shapeRttrType = rttr::type::get<SHCollider::Type>();
|
rttr::type const shapeRttrType = rttr::type::get<SHCollisionShape::Type>();
|
||||||
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
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();
|
node[Type] = enumAlign.value_to_name(colliderType).data();
|
||||||
|
|
||||||
switch (colliderType)
|
switch (colliderType)
|
||||||
{
|
{
|
||||||
case SHCollider::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 SHCollider::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 SHCollider::Type::CAPSULE: break;
|
case SHCollisionShape::Type::CAPSULE: break;
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,33 +151,33 @@ namespace YAML
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
static bool decode(Node const& node, SHCollider& rhs)
|
static bool decode(Node const& node, SHCollisionShape& rhs)
|
||||||
{
|
{
|
||||||
if (node[IsTrigger].IsDefined())
|
if (node[IsTrigger].IsDefined())
|
||||||
rhs.SetIsTrigger(node[IsTrigger].as<bool>());
|
rhs.SetIsTrigger(node[IsTrigger].as<bool>());
|
||||||
if (!node[Type].IsDefined())
|
if (!node[Type].IsDefined())
|
||||||
return false;
|
return false;
|
||||||
rttr::type const shapeRttrType = rttr::type::get<SHCollider::Type>();
|
rttr::type const shapeRttrType = rttr::type::get<SHCollisionShape::Type>();
|
||||||
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
||||||
bool ok;
|
bool ok;
|
||||||
const SHCollider::Type colliderType = enumAlign.name_to_value(node[Type].as<std::string>()).convert<SHCollider::Type>(&ok);
|
const SHCollisionShape::Type colliderType = enumAlign.name_to_value(node[Type].as<std::string>()).convert<SHCollisionShape::Type>(&ok);
|
||||||
if (!ok)
|
if (!ok)
|
||||||
return false;
|
return false;
|
||||||
switch (colliderType)
|
switch (colliderType)
|
||||||
{
|
{
|
||||||
case SHCollider::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 SHCollider::Type::SPHERE:
|
case SHCollisionShape::Type::SPHERE:
|
||||||
{
|
{
|
||||||
if (node[Radius].IsDefined())
|
if (node[Radius].IsDefined())
|
||||||
rhs.SetBoundingSphere(node[Radius].as<float>());
|
rhs.SetBoundingSphere(node[Radius].as<float>());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHCollider::Type::CAPSULE: break;
|
case SHCollisionShape::Type::CAPSULE: break;
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
if (node[Friction].IsDefined())
|
if (node[Friction].IsDefined())
|
||||||
|
@ -200,12 +200,12 @@ namespace YAML
|
||||||
static Node encode(SHColliderComponent& rhs)
|
static Node encode(SHColliderComponent& rhs)
|
||||||
{
|
{
|
||||||
Node node, collidersNode;
|
Node node, collidersNode;
|
||||||
auto const& colliders = rhs.GetColliders();
|
auto const& colliders = rhs.GetCollisionShapes();
|
||||||
int const numColliders = static_cast<int>(colliders.size());
|
int const numColliders = static_cast<int>(colliders.size());
|
||||||
for (int i = 0; i < numColliders; ++i)
|
for (int i = 0; i < numColliders; ++i)
|
||||||
{
|
{
|
||||||
auto& collider = rhs.GetCollider(i);
|
auto& collider = rhs.GetCollisionShape(i);
|
||||||
Node colliderNode = convert<SHCollider>::encode(collider);
|
Node colliderNode = convert<SHCollisionShape>::encode(collider);
|
||||||
if (colliderNode.IsDefined())
|
if (colliderNode.IsDefined())
|
||||||
collidersNode[i] = colliderNode;
|
collidersNode[i] = colliderNode;
|
||||||
}
|
}
|
||||||
|
@ -219,21 +219,21 @@ namespace YAML
|
||||||
int numColliders{};
|
int numColliders{};
|
||||||
for (auto const& colliderNode : node[Colliders])
|
for (auto const& colliderNode : node[Colliders])
|
||||||
{
|
{
|
||||||
rttr::type const shapeRttrType = rttr::type::get<SHCollider::Type>();
|
rttr::type const shapeRttrType = rttr::type::get<SHCollisionShape::Type>();
|
||||||
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
const SHCollider::Type colliderType = enumAlign.name_to_value(colliderNode[convert<SHCollider>::Type].as<std::string>()).convert<SHCollider::Type>(&ok);
|
const SHCollisionShape::Type colliderType = enumAlign.name_to_value(colliderNode[convert<SHCollisionShape>::Type].as<std::string>()).convert<SHCollisionShape::Type>(&ok);
|
||||||
if (!ok)
|
if (!ok)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch (colliderType)
|
switch (colliderType)
|
||||||
{
|
{
|
||||||
case SHCollider::Type::BOX: rhs.AddBoundingBox(); break;
|
case SHCollisionShape::Type::BOX: rhs.AddBoundingBox(); break;
|
||||||
case SHCollider::Type::SPHERE: rhs.AddBoundingSphere(); break;
|
case SHCollisionShape::Type::SPHERE: rhs.AddBoundingSphere(); break;
|
||||||
case SHCollider::Type::CAPSULE: break;
|
case SHCollisionShape::Type::CAPSULE: break;
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
YAML::convert<SHCollider>::decode(colliderNode, rhs.GetCollider(numColliders++));
|
YAML::convert<SHCollisionShape>::decode(colliderNode, rhs.GetCollisionShape(numColliders++));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -150,7 +150,7 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
int Collider::CollisionShapeCount::get()
|
int Collider::CollisionShapeCount::get()
|
||||||
{
|
{
|
||||||
return static_cast<int>(GetNativeComponent()->GetColliders().size());
|
return static_cast<int>(GetNativeComponent()->GetCollisionShapes().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -230,18 +230,18 @@ namespace SHADE
|
||||||
|
|
||||||
// Populate the list
|
// Populate the list
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (const auto& collider : GetNativeComponent()->GetColliders())
|
for (const auto& collider : GetNativeComponent()->GetCollisionShapes())
|
||||||
{
|
{
|
||||||
CollisionShape^ bound = nullptr;
|
CollisionShape^ bound = nullptr;
|
||||||
switch (collider.GetType())
|
switch (collider.GetType())
|
||||||
{
|
{
|
||||||
case SHCollider::Type::BOX:
|
case SHCollisionShape::Type::BOX:
|
||||||
bound = gcnew BoxCollider(i, Owner.GetEntity());
|
bound = gcnew BoxCollider(i, Owner.GetEntity());
|
||||||
break;
|
break;
|
||||||
case SHCollider::Type::SPHERE:
|
case SHCollisionShape::Type::SPHERE:
|
||||||
bound = gcnew SphereCollider(i, Owner.GetEntity());
|
bound = gcnew SphereCollider(i, Owner.GetEntity());
|
||||||
break;
|
break;
|
||||||
case SHCollider::Type::CAPSULE:
|
case SHCollisionShape::Type::CAPSULE:
|
||||||
// TODO
|
// TODO
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -27,11 +27,11 @@ namespace SHADE
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto& bounds = collider->GetCollider(arrayIndex);
|
auto& shape = collider->GetCollisionShape(arrayIndex);
|
||||||
if (bounds.GetType() != SHCollider::Type::BOX)
|
if (shape.GetType() != SHCollisionShape::Type::BOX)
|
||||||
throw gcnew System::InvalidOperationException("Attempted to retrieve invalid ColliderBound.");
|
throw gcnew System::InvalidOperationException("Attempted to retrieve invalid ColliderBound.");
|
||||||
|
|
||||||
return reinterpret_cast<CollisionShapeType&>(bounds);
|
return reinterpret_cast<CollisionShapeType&>(shape);
|
||||||
}
|
}
|
||||||
catch (std::invalid_argument&)
|
catch (std::invalid_argument&)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue