Fixed bug where collider offsets were not recomputed
This commit is contained in:
parent
2bd90e7c14
commit
a6e1064e64
|
@ -95,6 +95,15 @@ 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;
|
||||
|
@ -116,21 +125,25 @@ 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::SetPositionOffset(const SHVec3& posOffset) noexcept
|
||||
{
|
||||
setDirty(true);
|
||||
positionOffset = posOffset;
|
||||
}
|
||||
|
||||
void SHCollisionShape::SetRotationOffset(const SHVec3& rotOffset) noexcept
|
||||
{
|
||||
setDirty(true);
|
||||
rotationOffset = rotOffset;
|
||||
}
|
||||
|
||||
|
@ -147,10 +160,28 @@ 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
|
||||
|
|
|
@ -91,6 +91,7 @@ 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;
|
||||
|
||||
|
@ -107,6 +108,7 @@ namespace SHADE
|
|||
void SetRotationOffset (const SHVec3& rotOffset) noexcept;
|
||||
|
||||
// Flags
|
||||
|
||||
void SetIsTrigger (bool isTrigger) noexcept;
|
||||
|
||||
void SetCollisionTag (SHCollisionTag* newCollisionTag) noexcept;
|
||||
|
@ -115,6 +117,12 @@ namespace SHADE
|
|||
/* Member Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Clears the dirty flag of the collider.
|
||||
*/
|
||||
void ClearDirty () noexcept;
|
||||
|
||||
[[nodiscard]] virtual SHMatrix GetInertiaTensor (float mass) const noexcept = 0;
|
||||
|
||||
protected:
|
||||
|
@ -129,10 +137,17 @@ namespace SHADE
|
|||
SHVec3 positionOffset;
|
||||
SHVec3 rotationOffset;
|
||||
|
||||
uint8_t flags; // 0 0 wasColliding isColliding trigger capsule sphere box
|
||||
uint8_t flags; // 0 dirty wasColliding isColliding trigger capsule sphere box
|
||||
SHCollisionTag* collisionTag;
|
||||
|
||||
RTTR_ENABLE()
|
||||
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Member Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
void setDirty (bool isDirty) noexcept;
|
||||
};
|
||||
|
||||
} // namespace SHADE
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace SHADE
|
|||
* @brief
|
||||
* Encapsulate a Sphere Collision Shape used for Physics Simulations.
|
||||
*/
|
||||
class SH_API SHSphereCollisionShape : public SHCollisionShape
|
||||
class SH_API SHSphereCollisionShape final : public SHCollisionShape
|
||||
, private SHSphere
|
||||
{
|
||||
private:
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace SHADE
|
|||
: entityID { eid }
|
||||
, shapeIDCounter { 0 }
|
||||
, debugDraw { false }
|
||||
, dirty { true }
|
||||
, rigidBody { nullptr }
|
||||
, shapeFactory { nullptr }
|
||||
, transform { worldTransform }
|
||||
|
@ -41,6 +42,7 @@ namespace SHADE
|
|||
: entityID { rhs.entityID }
|
||||
, shapeIDCounter { rhs.shapeIDCounter }
|
||||
, debugDraw { rhs.debugDraw }
|
||||
, dirty { rhs.dirty }
|
||||
, rigidBody { rhs.rigidBody }
|
||||
, shapeFactory { rhs.shapeFactory }
|
||||
, transform { rhs.transform }
|
||||
|
@ -58,6 +60,7 @@ namespace SHADE
|
|||
: entityID { rhs.entityID }
|
||||
, shapeIDCounter { rhs.shapeIDCounter }
|
||||
, debugDraw { rhs.debugDraw }
|
||||
, dirty { rhs.dirty }
|
||||
, rigidBody { rhs.rigidBody }
|
||||
, shapeFactory { rhs.shapeFactory }
|
||||
, transform { rhs.transform }
|
||||
|
@ -100,6 +103,7 @@ namespace SHADE
|
|||
|
||||
entityID = rhs.entityID;
|
||||
debugDraw = rhs.debugDraw;
|
||||
dirty = rhs.dirty;
|
||||
rigidBody = rhs.rigidBody;
|
||||
shapeFactory = rhs.shapeFactory;
|
||||
transform = rhs.transform;
|
||||
|
@ -119,6 +123,7 @@ namespace SHADE
|
|||
|
||||
entityID = rhs.entityID;
|
||||
debugDraw = rhs.debugDraw;
|
||||
dirty = rhs.dirty;
|
||||
rigidBody = rhs.rigidBody;
|
||||
shapeFactory = rhs.shapeFactory;
|
||||
transform = rhs.transform;
|
||||
|
@ -201,21 +206,25 @@ 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;
|
||||
}
|
||||
|
||||
|
@ -284,6 +293,28 @@ namespace SHADE
|
|||
return static_cast<int>(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)
|
||||
|
@ -329,25 +360,7 @@ namespace SHADE
|
|||
void SHCollider::RecomputeShapes() noexcept
|
||||
{
|
||||
for (auto* shape : shapes)
|
||||
{
|
||||
switch (shape->GetType())
|
||||
{
|
||||
case SHCollisionShape::Type::SPHERE:
|
||||
{
|
||||
recomputeSphere(dynamic_cast<SHSphereCollisionShape*>(shape));
|
||||
break;
|
||||
}
|
||||
case SHCollisionShape::Type::BOX:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case SHCollisionShape::Type::CAPSULE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
recomputeShape(shape);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -403,6 +416,33 @@ 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<SHSphereCollisionShape*>(shape));
|
||||
break;
|
||||
}
|
||||
case SHCollisionShape::Type::BOX:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case SHCollisionShape::Type::CAPSULE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void SHCollider::recomputeSphere(SHSphereCollisionShape* sphere) noexcept
|
||||
{
|
||||
// Recompute world radius
|
||||
|
|
|
@ -132,6 +132,12 @@ 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.
|
||||
|
@ -158,6 +164,7 @@ namespace SHADE
|
|||
uint32_t shapeIDCounter; // This increments everytime a shape is added to differentiate shapes.
|
||||
|
||||
bool debugDraw;
|
||||
bool dirty;
|
||||
|
||||
SHRigidBody* rigidBody;
|
||||
SHCollisionShapeFactory* shapeFactory;
|
||||
|
@ -173,6 +180,7 @@ namespace SHADE
|
|||
void copyShapes (const SHCollider& rhsCollider);
|
||||
void copyShape (const SHCollisionShape* rhsShape);
|
||||
|
||||
void recomputeShape (SHCollisionShape* shape) noexcept;
|
||||
void recomputeSphere (SHSphereCollisionShape* sphere) noexcept;
|
||||
};
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace SHADE
|
|||
{
|
||||
const auto* TRANSFORM_COMPONENT = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
|
||||
|
||||
if (!TRANSFORM_COMPONENT || !TRANSFORM_COMPONENT->HasChanged())
|
||||
if (!TRANSFORM_COMPONENT)
|
||||
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)
|
||||
if (physicsObject.rigidBody && TRANSFORM_COMPONENT->HasChanged())
|
||||
{
|
||||
SHMotionState& motionState = physicsObject.rigidBody->GetMotionState();
|
||||
|
||||
|
@ -59,12 +59,15 @@ 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->RecomputeShapes();
|
||||
physicsObject.collider->Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue