diff --git a/SHADE_Engine/src/Physics/Collision/CollisionShapes/SHCollisionShape.cpp b/SHADE_Engine/src/Physics/Collision/CollisionShapes/SHCollisionShape.cpp
index d0706ed0..5dd17d35 100644
--- a/SHADE_Engine/src/Physics/Collision/CollisionShapes/SHCollisionShape.cpp
+++ b/SHADE_Engine/src/Physics/Collision/CollisionShapes/SHCollisionShape.cpp
@@ -25,9 +25,10 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/
SHCollisionShape::SHCollisionShape(SHCollisionShapeID id, Type colliderType)
- : id { id }
- , flags { 0 }
- , collisionTag { SHCollisionTagMatrix::GetTag(0) }
+ : id { id }
+ , flags { 0 }
+ , parentTransform { nullptr }
+ , collisionTag { SHCollisionTagMatrix::GetTag(0) }
{
flags |= 1U << SHUtilities::ConvertEnum(colliderType);
}
@@ -58,7 +59,7 @@ namespace SHADE
const SHVec3& SHCollisionShape::GetPositionOffset() const noexcept
{
- return positionOffset;
+ return transform.position;
}
const SHVec3& SHCollisionShape::GetRotationOffset() const noexcept
@@ -95,15 +96,6 @@ namespace SHADE
return flags & FLAG_VALUE;
}
- bool SHCollisionShape::IsDirty() const noexcept
- {
- static constexpr int FLAG_POS = 6;
- static constexpr uint8_t FLAG_VALUE = 1U << FLAG_POS;
-
- return flags & FLAG_VALUE;
- }
-
-
const SHCollisionTag& SHCollisionShape::GetCollisionTag() const noexcept
{
return *collisionTag;
@@ -125,26 +117,32 @@ namespace SHADE
void SHCollisionShape::SetDensity(float density) noexcept
{
- setDirty(true);
material.SetDensity(density);
}
void SHCollisionShape::SetMaterial(const SHPhysicsMaterial& newMaterial) noexcept
{
- setDirty(true);
material = newMaterial;
}
+ void SHCollisionShape::SetParentTransform(SHTransform& parentTF) noexcept
+ {
+ parentTransform = &parentTF;
+ }
+
void SHCollisionShape::SetPositionOffset(const SHVec3& posOffset) noexcept
{
- setDirty(true);
- positionOffset = posOffset;
+ transform.position = posOffset;
+
+ ComputeTransforms();
}
void SHCollisionShape::SetRotationOffset(const SHVec3& rotOffset) noexcept
{
- setDirty(true);
rotationOffset = rotOffset;
+ transform.orientation = SHQuaternion::FromEuler(rotationOffset);
+
+ ComputeTransforms();
}
void SHCollisionShape::SetIsTrigger(bool isTrigger) noexcept
@@ -160,28 +158,6 @@ namespace SHADE
collisionTag = newCollisionTag;
}
- /*-----------------------------------------------------------------------------------*/
- /* Public Function Member Definitions */
- /*-----------------------------------------------------------------------------------*/
-
- void SHCollisionShape::ClearDirty() noexcept
- {
- setDirty(false);
- }
-
- /*-----------------------------------------------------------------------------------*/
- /* Private Function Member Definitions */
- /*-----------------------------------------------------------------------------------*/
-
- void SHCollisionShape::setDirty(bool isDirty) noexcept
- {
- static constexpr int FLAG_POS = 6;
- static constexpr uint8_t FLAG_VALUE = 1U << FLAG_POS;
-
- isDirty ? flags |= FLAG_VALUE : flags &= ~FLAG_VALUE;
- }
-
-
} // namespace SHADE
RTTR_REGISTRATION
diff --git a/SHADE_Engine/src/Physics/Collision/CollisionShapes/SHCollisionShape.h b/SHADE_Engine/src/Physics/Collision/CollisionShapes/SHCollisionShape.h
index 90020727..3c08e21a 100644
--- a/SHADE_Engine/src/Physics/Collision/CollisionShapes/SHCollisionShape.h
+++ b/SHADE_Engine/src/Physics/Collision/CollisionShapes/SHCollisionShape.h
@@ -14,11 +14,10 @@
// Project Headers
#include "ECS_Base/Entity/SHEntity.h"
-#include "Math/Geometry/SHShape.h"
-#include "Math/SHQuaternion.h"
#include "Physics/Collision/CollisionTags/SHCollisionTags.h"
#include "Physics/Collision/SHPhysicsMaterial.h"
#include "SHCollisionShapeID.h"
+#include "Math/Transform/SHTransform.h"
namespace SHADE
{
@@ -91,7 +90,6 @@ namespace SHADE
[[nodiscard]] Type GetType () const noexcept;
[[nodiscard]] bool IsTrigger () const noexcept;
[[nodiscard]] bool IsColliding () const noexcept;
- [[nodiscard]] bool IsDirty () const noexcept;
[[nodiscard]] const SHCollisionTag& GetCollisionTag () const noexcept;
@@ -104,6 +102,8 @@ namespace SHADE
void SetDensity (float density) noexcept;
void SetMaterial (const SHPhysicsMaterial& newMaterial) noexcept;
+ void SetParentTransform (SHTransform& parentTF) noexcept;
+
void SetPositionOffset (const SHVec3& posOffset) noexcept;
void SetRotationOffset (const SHVec3& rotOffset) noexcept;
@@ -117,13 +117,9 @@ namespace SHADE
/* Member Functions */
/*---------------------------------------------------------------------------------*/
- /**
- * @brief
- * Clears the dirty flag of the collider.
- */
- void ClearDirty () noexcept;
-
- [[nodiscard]] virtual SHMatrix GetInertiaTensor (float mass) const noexcept = 0;
+ virtual void ComputeTransforms () noexcept = 0;
+ [[nodiscard]] virtual SHMatrix GetInertiaTensor (float mass) const noexcept = 0;
+ [[nodiscard]] virtual SHMatrix ComputeWorldTransform () const noexcept = 0;
protected:
/*---------------------------------------------------------------------------------*/
@@ -134,20 +130,16 @@ namespace SHADE
SHPhysicsMaterial material;
- SHVec3 positionOffset;
+ SHTransform* parentTransform;
+ SHTransform transform;
+
+ // Needed for conversion to euler angles
SHVec3 rotationOffset;
- uint8_t flags; // 0 dirty wasColliding isColliding trigger capsule sphere box
+ uint8_t flags; // 0 0 wasColliding isColliding trigger capsule sphere box
SHCollisionTag* collisionTag;
RTTR_ENABLE()
-
- private:
- /*---------------------------------------------------------------------------------*/
- /* Member Functions */
- /*---------------------------------------------------------------------------------*/
-
- void setDirty (bool isDirty) noexcept;
};
} // namespace SHADE
diff --git a/SHADE_Engine/src/Physics/Collision/CollisionShapes/SHSphereCollisionShape.cpp b/SHADE_Engine/src/Physics/Collision/CollisionShapes/SHSphereCollisionShape.cpp
index 40671a96..e4bf68c3 100644
--- a/SHADE_Engine/src/Physics/Collision/CollisionShapes/SHSphereCollisionShape.cpp
+++ b/SHADE_Engine/src/Physics/Collision/CollisionShapes/SHSphereCollisionShape.cpp
@@ -14,6 +14,7 @@
#include "SHSphereCollisionShape.h"
// Project Headers
+#include "Math/SHMathHelpers.h"
#include "Math/SHMatrix.h"
namespace SHADE
@@ -37,7 +38,8 @@ namespace SHADE
{
material = rhs.material;
- positionOffset = rhs.positionOffset;
+ parentTransform = rhs.parentTransform;
+ transform = rhs.transform;
rotationOffset = rhs.rotationOffset;
flags = rhs.flags;
// Since all collision tags are taken from the matrix, we do not need to do a deep copy here.
@@ -52,7 +54,8 @@ namespace SHADE
{
material = rhs.material;
- positionOffset = rhs.positionOffset;
+ parentTransform = rhs.parentTransform;
+ transform = rhs.transform;
rotationOffset = rhs.rotationOffset;
flags = rhs.flags;
// Since all collision tags are taken from the matrix, we do not need to do a deep copy here.
@@ -72,7 +75,8 @@ namespace SHADE
id = rhs.id;
material = rhs.material;
- positionOffset = rhs.positionOffset;
+ parentTransform = rhs.parentTransform;
+ transform = rhs.transform;
rotationOffset = rhs.rotationOffset;
flags = rhs.flags;
// Since all collision tags are taken from the matrix, we do not need to do a deep copy here.
@@ -97,7 +101,8 @@ namespace SHADE
id = rhs.id;
material = rhs.material;
- positionOffset = rhs.positionOffset;
+ parentTransform = rhs.parentTransform;
+ transform = rhs.transform;
rotationOffset = rhs.rotationOffset;
flags = rhs.flags;
// Since all collision tags are taken from the matrix, we do not need to do a deep copy here.
@@ -172,6 +177,18 @@ namespace SHADE
/* Public Member Function Definitions */
/*-----------------------------------------------------------------------------------*/
+ void SHSphereCollisionShape::ComputeTransforms() noexcept
+ {
+ const float SPHERE_SCALE = std::fabs(SHMath::Max({ parentTransform->scale.x, parentTransform->scale.y, parentTransform->scale.z }));
+ SetScale(SPHERE_SCALE);
+
+ // Recompute center
+ const SHQuaternion FINAL_ROT = parentTransform->orientation * transform.orientation;
+ const SHMatrix TRS = SHMatrix::Rotate(FINAL_ROT) * SHMatrix::Translate(parentTransform->position);
+
+ Center = SHVec3::Transform(transform.position, TRS);
+ }
+
bool SHSphereCollisionShape::TestPoint(const SHVec3& point) const noexcept
{
return SHSphere::TestPoint(point);
@@ -193,6 +210,18 @@ namespace SHADE
return result;
}
+ SHMatrix SHSphereCollisionShape::ComputeWorldTransform() const noexcept
+ {
+ const SHQuaternion ROTATION = parentTransform->orientation * transform.orientation;
+ const SHVec3 SCALE{ Radius };
+
+ return SHMatrix::Transform
+ (
+ Center
+ , ROTATION
+ , SCALE
+);
+ }
} // namespace SHADE
\ No newline at end of file
diff --git a/SHADE_Engine/src/Physics/Collision/CollisionShapes/SHSphereCollisionShape.h b/SHADE_Engine/src/Physics/Collision/CollisionShapes/SHSphereCollisionShape.h
index 8276578e..798c70b6 100644
--- a/SHADE_Engine/src/Physics/Collision/CollisionShapes/SHSphereCollisionShape.h
+++ b/SHADE_Engine/src/Physics/Collision/CollisionShapes/SHSphereCollisionShape.h
@@ -88,6 +88,12 @@ namespace SHADE
/* Function Members */
/*---------------------------------------------------------------------------------*/
+ /**
+ * @brief
+ * Recomputes the transform of this sphere.
+ */
+ void ComputeTransforms () noexcept override;
+
/**
* @brief
* Tests if a point is inside the sphere.
@@ -96,7 +102,7 @@ namespace SHADE
* @return
* True if the point is inside the sphere.
*/
- [[nodiscard]] bool TestPoint (const SHVec3& point) const noexcept override;
+ [[nodiscard]] bool TestPoint (const SHVec3& point) const noexcept override;
/**
* @brief
@@ -107,7 +113,7 @@ namespace SHADE
* An object holding the results of the raycast.
* See the corresponding header for the contents of the object.
*/
- [[nodiscard]] SHRaycastResult Raycast (const SHRay& ray) const noexcept override;
+ [[nodiscard]] SHRaycastResult Raycast (const SHRay& ray) const noexcept override;
/**
* @brief
@@ -117,9 +123,9 @@ namespace SHADE
* @return
* The inertia tensor of the sphere.
*/
- [[nodiscard]] SHMatrix GetInertiaTensor (float mass) const noexcept override;
+ [[nodiscard]] SHMatrix GetInertiaTensor (float mass) const noexcept override;
-
+ [[nodiscard]] SHMatrix ComputeWorldTransform () const noexcept override;
private:
/*---------------------------------------------------------------------------------*/
diff --git a/SHADE_Engine/src/Physics/Collision/SHCollider.cpp b/SHADE_Engine/src/Physics/Collision/SHCollider.cpp
index 9aedef16..a6527e48 100644
--- a/SHADE_Engine/src/Physics/Collision/SHCollider.cpp
+++ b/SHADE_Engine/src/Physics/Collision/SHCollider.cpp
@@ -30,19 +30,15 @@ namespace SHADE
: entityID { eid }
, shapeIDCounter { 0 }
, debugDraw { false }
- , dirty { true }
, rigidBody { nullptr }
, shapeFactory { nullptr }
, transform { worldTransform }
- {
-
- }
+ {}
SHCollider::SHCollider(const SHCollider& rhs) noexcept
: entityID { rhs.entityID }
, shapeIDCounter { rhs.shapeIDCounter }
, debugDraw { rhs.debugDraw }
- , dirty { rhs.dirty }
, rigidBody { rhs.rigidBody }
, shapeFactory { rhs.shapeFactory }
, transform { rhs.transform }
@@ -60,7 +56,6 @@ namespace SHADE
: entityID { rhs.entityID }
, shapeIDCounter { rhs.shapeIDCounter }
, debugDraw { rhs.debugDraw }
- , dirty { rhs.dirty }
, rigidBody { rhs.rigidBody }
, shapeFactory { rhs.shapeFactory }
, transform { rhs.transform }
@@ -103,7 +98,6 @@ namespace SHADE
entityID = rhs.entityID;
debugDraw = rhs.debugDraw;
- dirty = rhs.dirty;
rigidBody = rhs.rigidBody;
shapeFactory = rhs.shapeFactory;
transform = rhs.transform;
@@ -123,7 +117,6 @@ namespace SHADE
entityID = rhs.entityID;
debugDraw = rhs.debugDraw;
- dirty = rhs.dirty;
rigidBody = rhs.rigidBody;
shapeFactory = rhs.shapeFactory;
transform = rhs.transform;
@@ -206,25 +199,21 @@ namespace SHADE
void SHCollider::SetTransform(const SHTransform& newTransform) noexcept
{
- dirty = true;
transform = newTransform;
}
void SHCollider::SetPosition(const SHVec3& newPosition) noexcept
{
- dirty = true;
transform.position = newPosition;
}
void SHCollider::SetOrientation(const SHQuaternion& newOrientation) noexcept
{
- dirty = true;
transform.orientation = newOrientation;
}
void SHCollider::SetScale(const SHVec3& newScale) noexcept
{
- dirty = true;
transform.scale = newScale;
}
@@ -272,8 +261,9 @@ namespace SHADE
++shapeIDCounter;
// Set offsets
- sphere->positionOffset = posOffset;
- sphere->rotationOffset = rotOffset;
+ sphere->SetParentTransform(transform);
+ sphere->SetPositionOffset(posOffset);
+ sphere->SetRotationOffset(rotOffset);
shapes.emplace_back(sphere);
@@ -293,28 +283,6 @@ namespace SHADE
return static_cast(shapes.size());
}
- void SHCollider::Update()
- {
- // Forcefully recompute everything since the transform was changed
- if (dirty)
- {
- RecomputeShapes();
- dirty = false;
- return;
- }
-
- // Recompute any shapes set to dirty
- for (auto* shape : shapes)
- {
- if (shape->IsDirty())
- {
- recomputeShape(shape);
- shape->ClearDirty();
- }
- }
- }
-
-
void SHCollider::RemoveCollisionShape(int index)
{
if (!shapeFactory)
@@ -360,7 +328,7 @@ namespace SHADE
void SHCollider::RecomputeShapes() noexcept
{
for (auto* shape : shapes)
- recomputeShape(shape);
+ shape->ComputeTransforms();
}
/*-----------------------------------------------------------------------------------*/
@@ -416,47 +384,4 @@ namespace SHADE
++shapeIDCounter;
}
- void SHCollider::recomputeShape(SHCollisionShape* shape) noexcept
- {
- if (!shape)
- {
- SHLOGV_ERROR_D("Shape missing from Collider {}", entityID)
- return;
- }
-
- switch (shape->GetType())
- {
- case SHCollisionShape::Type::SPHERE:
- {
- recomputeSphere(dynamic_cast(shape));
- break;
- }
- case SHCollisionShape::Type::BOX:
- {
- break;
- }
- case SHCollisionShape::Type::CAPSULE:
- {
- break;
- }
- default: break;
- }
- }
-
- void SHCollider::recomputeSphere(SHSphereCollisionShape* sphere) noexcept
- {
- // Recompute world radius
- const float SPHERE_SCALE = std::fabs(SHMath::Max({ transform.scale.x, transform.scale.y, transform.scale.z }));
- sphere->SetScale(SPHERE_SCALE);
-
- // Recompute center
- const SHQuaternion FINAL_ROT = transform.orientation * SHQuaternion::FromEuler(sphere->rotationOffset);
- const SHMatrix TRS = SHMatrix::Rotate(FINAL_ROT) * SHMatrix::Translate(transform.position);
-
- const SHVec3 NEW_CENTER = SHVec3::Transform(sphere->positionOffset, TRS);
-
- sphere->SetCenter(NEW_CENTER);
- }
-
-
} // namespace SHADE
\ No newline at end of file
diff --git a/SHADE_Engine/src/Physics/Collision/SHCollider.h b/SHADE_Engine/src/Physics/Collision/SHCollider.h
index 8a183dcc..566bae3e 100644
--- a/SHADE_Engine/src/Physics/Collision/SHCollider.h
+++ b/SHADE_Engine/src/Physics/Collision/SHCollider.h
@@ -132,12 +132,6 @@ namespace SHADE
// TODO: Add Box & Capsule
- /**
- * @brief
- * Recomputes any shapes that were set to dirty.
- */
- void Update ();
-
/**
* @brief
* Removes a shape from the container. Removal reduces the size of the container.
@@ -164,7 +158,6 @@ namespace SHADE
uint32_t shapeIDCounter; // This increments everytime a shape is added to differentiate shapes.
bool debugDraw;
- bool dirty;
SHRigidBody* rigidBody;
SHCollisionShapeFactory* shapeFactory;
@@ -179,9 +172,6 @@ namespace SHADE
void copyShapes (const SHCollider& rhsCollider);
void copyShape (const SHCollisionShape* rhsShape);
-
- void recomputeShape (SHCollisionShape* shape) noexcept;
- void recomputeSphere (SHSphereCollisionShape* sphere) noexcept;
};
} // namespace SHADE
diff --git a/SHADE_Engine/src/Physics/System/Routines/SHPhysicsPreUpdateRoutine.cpp b/SHADE_Engine/src/Physics/System/Routines/SHPhysicsPreUpdateRoutine.cpp
index 0094153e..88ea8d79 100644
--- a/SHADE_Engine/src/Physics/System/Routines/SHPhysicsPreUpdateRoutine.cpp
+++ b/SHADE_Engine/src/Physics/System/Routines/SHPhysicsPreUpdateRoutine.cpp
@@ -41,7 +41,7 @@ namespace SHADE
{
const auto* TRANSFORM_COMPONENT = SHComponentManager::GetComponent_s(entityID);
- if (!TRANSFORM_COMPONENT)
+ if (!TRANSFORM_COMPONENT || !TRANSFORM_COMPONENT->HasChanged())
continue;
const SHVec3& WORLD_POS = TRANSFORM_COMPONENT->GetWorldPosition();
@@ -50,7 +50,7 @@ namespace SHADE
// We assume that all engine components and physics object components have been successfully linked
- if (physicsObject.rigidBody && TRANSFORM_COMPONENT->HasChanged())
+ if (physicsObject.rigidBody)
{
SHMotionState& motionState = physicsObject.rigidBody->GetMotionState();
@@ -60,14 +60,11 @@ namespace SHADE
if (physicsObject.collider)
{
- if (TRANSFORM_COMPONENT->HasChanged())
- {
- physicsObject.collider->SetPosition(WORLD_POS);
- physicsObject.collider->SetOrientation(WORLD_ROT);
- physicsObject.collider->SetScale(WORLD_SCL);
- }
+ physicsObject.collider->SetPosition(WORLD_POS);
+ physicsObject.collider->SetOrientation(WORLD_ROT);
+ physicsObject.collider->SetScale(WORLD_SCL);
- physicsObject.collider->Update();
+ physicsObject.collider->RecomputeShapes();
}
}
}
diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp
index dda437bc..958ac61a 100644
--- a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp
+++ b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp
@@ -122,17 +122,7 @@ namespace SHADE
{
case SHCollisionShape::Type::SPHERE:
{
- const SHSphereCollisionShape* SPHERE = dynamic_cast(SHAPE);
-
- // Compute transforms of sphere
- const SHVec3 POSITION = SPHERE->GetCenter(); // Position offset is already computed here
- const SHVec3 ROTATION = collider.GetOrientation().ToEuler() + SPHERE->GetRotationOffset();
- const SHVec3 SCALE { SPHERE->GetWorldRadius() };
-
- // Compute TRS for the sphere
- const SHMatrix TRS = SHMatrix::Transform(POSITION, ROTATION, SCALE);
-
- debugDrawSystem->DrawWireSphere(TRS, DRAW_COLOUR, true);
+ debugDrawSystem->DrawWireSphere(SHAPE->ComputeWorldTransform(), DRAW_COLOUR, true);
break;
}