Fixed collider shape serialisation

This commit is contained in:
Diren D Bharwani 2023-02-02 20:15:59 +08:00
parent 71f4cdd29e
commit 3593df3ada
10 changed files with 144 additions and 62 deletions

View File

@ -12,7 +12,7 @@
Type: Dynamic Type: Dynamic
Drag: 0.00999999978 Drag: 0.00999999978
Angular Drag: 0.100000001 Angular Drag: 0.100000001
Use Gravity: true Use Gravity: false
Interpolate: true Interpolate: true
Sleeping Enabled: false Sleeping Enabled: false
Freeze Position X: false Freeze Position X: false
@ -22,4 +22,33 @@
Freeze Rotation Y: false Freeze Rotation Y: false
Freeze Rotation Z: false Freeze Rotation Z: false
IsActive: true IsActive: true
Collider Component:
Colliders:
- Is Trigger: false
Collision Tag: 1
Type: Sphere
Radius: 1
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0, z: 0}
Rotation Offset: {x: 0, y: 0, z: 0}
IsActive: true
Scripts: ~
- EID: 1
Name: Default
IsActive: true
NumberOfChildren: 0
Components:
Camera Component:
Position: {x: 0, y: 0, z: -10}
Pitch: 0
Yaw: 0
Roll: 0
Width: 1920
Height: 1080
Near: 0.00999999978
Far: 10000
Perspective: true
IsActive: true
Scripts: ~ Scripts: ~

View File

@ -161,9 +161,6 @@ namespace SHADE
SHTransformComponent* transform = SHComponentManager::GetComponent_s<SHTransformComponent>(pivot.GetEID()); SHTransformComponent* transform = SHComponentManager::GetComponent_s<SHTransformComponent>(pivot.GetEID());
auto physicsSystem = SHSystemManager::GetSystem<SHPhysicsSystem>(); auto physicsSystem = SHSystemManager::GetSystem<SHPhysicsSystem>();
if (camera == nullptr || transform == nullptr) if (camera == nullptr || transform == nullptr)
return; return;
@ -179,13 +176,12 @@ namespace SHADE
camera->dirtyView = true; camera->dirtyView = true;
}*/ }*/
pivot.ray.position = camera->GetPosition() + pivot.targetOffset; pivot.ray.position = camera->GetPosition() + pivot.targetOffset;
pivot.ray.direction = SHVec3::Normalise((camera->position + offset)- pivot.ray.position); pivot.ray.direction = SHVec3::Normalise((camera->position + offset)- pivot.ray.position);
//SHLOG_INFO("Ray position: {},{},{} direction:{},{},{}",pivot.ray.position.x, pivot.ray.position.y, pivot.ray.position.z,pivot.ray.direction.x, pivot.ray.direction.y, pivot.ray.direction.z) //SHLOG_INFO("Ray position: {},{},{} direction:{},{},{}",pivot.ray.position.x, pivot.ray.position.y, pivot.ray.position.z,pivot.ray.direction.x, pivot.ray.direction.y, pivot.ray.direction.z)
//auto result = physicsSystem->Raycast(pivot.ray ); //auto result = physicsSystem->Raycast(pivot.ray);
//if (result && result.distance < pivot.GetArmLength()) //if (result && result.distance < pivot.GetArmLength())
//{ //{
// //
@ -203,7 +199,7 @@ namespace SHADE
// //
// //
//// pivot.rtMatrix = SHMatrix::Inverse(pivot.rtMatrix); // pivot.rtMatrix = SHMatrix::Inverse(pivot.rtMatrix);
} }

View File

@ -246,8 +246,6 @@ namespace SHADE
tf.world.position = SHVec3::Transform(tf.local.position, localToWorld); tf.world.position = SHVec3::Transform(tf.local.position, localToWorld);
tf.world.scale = tf.local.scale * (parent ? parent->GetLocalScale() : SHVec3::One); tf.world.scale = tf.local.scale * (parent ? parent->GetLocalScale() : SHVec3::One);
if (convertRotation) if (convertRotation)
{ {
tf.worldRotation = tf.localRotation + (parent ? parent->GetLocalRotation() : SHVec3::Zero); tf.worldRotation = tf.localRotation + (parent ? parent->GetLocalRotation() : SHVec3::Zero);

View File

@ -44,7 +44,10 @@ namespace SHADE
SHVec3 SHBox::GetWorldExtents() const noexcept SHVec3 SHBox::GetWorldExtents() const noexcept
{ {
return SHVec3{ dynamic_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape())->getHalfExtents() }; if (rp3dCollider)
return SHVec3{ dynamic_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape())->getHalfExtents() };
return relativeExtents * scale * 0.5f;
} }
SHVec3 SHBox::GetRelativeExtents() const noexcept SHVec3 SHBox::GetRelativeExtents() const noexcept
@ -65,7 +68,8 @@ namespace SHADE
void SHBox::SetWorldExtents(const SHVec3& newWorldExtents) noexcept void SHBox::SetWorldExtents(const SHVec3& newWorldExtents) noexcept
{ {
dynamic_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape())->setHalfExtents(newWorldExtents); if (rp3dCollider)
dynamic_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape())->setHalfExtents(newWorldExtents);
// Recompute Relative radius // Recompute Relative radius
relativeExtents = 2.0f * newWorldExtents / scale; relativeExtents = 2.0f * newWorldExtents / scale;
@ -76,7 +80,8 @@ namespace SHADE
relativeExtents = newRelativeExtents; relativeExtents = newRelativeExtents;
// Recompute world radius // Recompute world radius
dynamic_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape())->setHalfExtents(relativeExtents * scale * 0.5f); if (rp3dCollider)
dynamic_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape())->setHalfExtents(relativeExtents * scale * 0.5f);
} }
void SHBox::SetScale(const SHVec3& newScale) noexcept void SHBox::SetScale(const SHVec3& newScale) noexcept
@ -84,7 +89,8 @@ namespace SHADE
scale = SHVec3::Abs(newScale); scale = SHVec3::Abs(newScale);
// Recompute world radius // Recompute world radius
dynamic_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape())->setHalfExtents(relativeExtents * scale * 0.5f); if (rp3dCollider)
dynamic_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape())->setHalfExtents(relativeExtents * scale * 0.5f);
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/

View File

@ -123,29 +123,38 @@ namespace SHADE
void SHCollisionShape::SetFriction(float friction) noexcept void SHCollisionShape::SetFriction(float friction) noexcept
{ {
material.SetFriction(friction); material.SetFriction(friction);
rp3dCollider->getMaterial().setFrictionCoefficient(material.GetFriction());
if (rp3dCollider)
rp3dCollider->getMaterial().setFrictionCoefficient(material.GetFriction());
} }
void SHCollisionShape::SetBounciness(float bounciness) noexcept void SHCollisionShape::SetBounciness(float bounciness) noexcept
{ {
material.SetBounciness(bounciness); material.SetBounciness(bounciness);
rp3dCollider->getMaterial().setBounciness(material.GetBounciness());
if (rp3dCollider)
rp3dCollider->getMaterial().setBounciness(material.GetBounciness());
} }
void SHCollisionShape::SetDensity(float density) noexcept void SHCollisionShape::SetDensity(float density) noexcept
{ {
material.SetDensity(density); material.SetDensity(density);
rp3dCollider->getMaterial().setMassDensity(material.GetDensity());
if (rp3dCollider)
rp3dCollider->getMaterial().setMassDensity(material.GetDensity());
} }
void SHCollisionShape::SetMaterial(const SHPhysicsMaterial& newMaterial) noexcept void SHCollisionShape::SetMaterial(const SHPhysicsMaterial& newMaterial) noexcept
{ {
material = newMaterial; material = newMaterial;
auto& rp3dMaterial = rp3dCollider->getMaterial(); if (rp3dCollider)
rp3dMaterial.setFrictionCoefficient(material.GetFriction()); {
rp3dMaterial.setBounciness(material.GetBounciness()); auto& rp3dMaterial = rp3dCollider->getMaterial();
rp3dMaterial.setMassDensity(material.GetDensity()); rp3dMaterial.setFrictionCoefficient(material.GetFriction());
rp3dMaterial.setBounciness(material.GetBounciness());
rp3dMaterial.setMassDensity(material.GetDensity());
}
} }
void SHCollisionShape::SetPositionOffset(const SHVec3& posOffset) noexcept void SHCollisionShape::SetPositionOffset(const SHVec3& posOffset) noexcept
@ -167,7 +176,8 @@ namespace SHADE
isTrigger ? flags |= FLAG_VALUE : flags &= ~FLAG_VALUE; isTrigger ? flags |= FLAG_VALUE : flags &= ~FLAG_VALUE;
rp3dCollider->setIsTrigger(isTrigger); if (rp3dCollider)
rp3dCollider->setIsTrigger(isTrigger);
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -176,8 +186,11 @@ namespace SHADE
void SHCollisionShape::Update() noexcept void SHCollisionShape::Update() noexcept
{ {
const rp3d::Transform OFFSETS{ positionOffset, SHQuaternion::FromEuler(rotationOffset) }; if (rp3dCollider)
rp3dCollider->setLocalToBodyTransform(OFFSETS); {
const rp3d::Transform OFFSETS{ positionOffset, SHQuaternion::FromEuler(rotationOffset) };
rp3dCollider->setLocalToBodyTransform(OFFSETS);
}
} }
SHMatrix SHCollisionShape::GetTRS() const noexcept SHMatrix SHCollisionShape::GetTRS() const noexcept

View File

@ -41,6 +41,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
friend class SHPhysicsSystem; friend class SHPhysicsSystem;
friend class SHPhysicsObjectManager;
friend class SHColliderComponent; friend class SHColliderComponent;
public: public:

View File

@ -45,7 +45,10 @@ namespace SHADE
float SHSphere::GetWorldRadius() const noexcept float SHSphere::GetWorldRadius() const noexcept
{ {
return dynamic_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape())->getRadius(); if (rp3dCollider)
return dynamic_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape())->getRadius();
return relativeRadius * scale * 0.5f;
} }
float SHSphere::GetRelativeRadius() const noexcept float SHSphere::GetRelativeRadius() const noexcept
@ -66,7 +69,8 @@ namespace SHADE
void SHSphere::SetWorldRadius(float newWorldRadius) noexcept void SHSphere::SetWorldRadius(float newWorldRadius) noexcept
{ {
dynamic_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape())->setRadius(newWorldRadius); if (rp3dCollider)
dynamic_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape())->setRadius(newWorldRadius);
// Recompute Relative radius // Recompute Relative radius
relativeRadius = 2.0f * newWorldRadius / scale; relativeRadius = 2.0f * newWorldRadius / scale;
@ -77,7 +81,8 @@ namespace SHADE
relativeRadius = newRelativeRadius; relativeRadius = newRelativeRadius;
// Recompute world radius // Recompute world radius
dynamic_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape())->setRadius(relativeRadius * scale * 0.5f); if (rp3dCollider)
dynamic_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape())->setRadius(relativeRadius * scale * 0.5f);
} }
void SHSphere::SetScale(float maxScale) noexcept void SHSphere::SetScale(float maxScale) noexcept
@ -85,7 +90,8 @@ namespace SHADE
scale = std::fabs(maxScale); scale = std::fabs(maxScale);
// Recompute world radius // Recompute world radius
dynamic_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape())->setRadius(relativeRadius * scale * 0.5f); if (rp3dCollider)
dynamic_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape())->setRadius(relativeRadius * scale * 0.5f);
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/

View File

@ -176,8 +176,6 @@ namespace SHADE
void SHPhysicsObjectManager::RemoveCollider(EntityID entityID) noexcept void SHPhysicsObjectManager::RemoveCollider(EntityID entityID) noexcept
{ {
auto* colliderComponent = SHComponentManager::GetComponent<SHColliderComponent>(entityID);
const auto PHYSICS_OBJECT_ITERATOR = physicsObjects.find(entityID); const auto PHYSICS_OBJECT_ITERATOR = physicsObjects.find(entityID);
if (PHYSICS_OBJECT_ITERATOR != physicsObjects.end()) if (PHYSICS_OBJECT_ITERATOR != physicsObjects.end())
{ {
@ -189,13 +187,8 @@ namespace SHADE
{ {
auto* rp3dCollider = physicsObject->body->getCollider(numShapes); auto* rp3dCollider = physicsObject->body->getCollider(numShapes);
physicsObject->body->removeCollider(rp3dCollider); physicsObject->body->removeCollider(rp3dCollider);
delete colliderComponent->shapes[numShapes];
colliderComponent->shapes[numShapes] = nullptr;
} }
colliderComponent->shapes.clear();
// Destroy if no rigidbody component // Destroy if no rigidbody component
if (!SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID)) if (!SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID))
destroyPhysicsObject(entityID); destroyPhysicsObject(entityID);
@ -356,25 +349,48 @@ namespace SHADE
colliderComponent->SetCollisionBody(physicsObject->body); colliderComponent->SetCollisionBody(physicsObject->body);
// Add all shapes // Add all shapes
for (auto& shapeDef : DEF.shapes) for (size_t i = 0; i < colliderComponent->shapes.size(); ++i)
{ {
switch (shapeDef.type) // Get the currrent shape
auto& collisionShape = colliderComponent->shapes[i];
// Add the rp3d collider to the shade collision shape
switch (collisionShape->GetType())
{ {
case SHCollisionShape::Type::SPHERE: case SHCollisionShape::Type::SPHERE:
{ {
colliderComponent->AddSphereCollisionShape(shapeDef.size.x); auto* sphereShape = dynamic_cast<SHSphere*>(collisionShape);
const float SPHERE_SCALE = std::fabs(SHMath::Max({ colliderComponent->transform.scale.x, colliderComponent->transform.scale.y, colliderComponent->transform.scale.z }));
rp3d::SphereShape* rp3dSphere = factory->createSphereShape(sphereShape->GetRelativeRadius() * SPHERE_SCALE * 0.5f);
const rp3d::Transform OFFSETS{ sphereShape->GetPositionOffset(), SHQuaternion::FromEuler(sphereShape->GetRotationOffset()) };
sphereShape->rp3dCollider = physicsObject->body->addCollider(rp3dSphere, OFFSETS);
sphereShape->rp3dCollider->setIsTrigger(sphereShape->IsTrigger());
break; break;
} }
case SHCollisionShape::Type::BOX: case SHCollisionShape::Type::BOX:
{ {
colliderComponent->AddBoxCollisionShape(shapeDef.size); auto* boxShape = dynamic_cast<SHBox*>(collisionShape);
rp3d::BoxShape* rp3dBox = factory->createBoxShape(boxShape->GetRelativeExtents() * colliderComponent->transform.scale * 0.5f);
const rp3d::Transform OFFSETS{ boxShape->GetPositionOffset(), SHQuaternion::FromEuler(boxShape->GetRotationOffset()) };
boxShape->rp3dCollider = physicsObject->body->addCollider(rp3dBox, OFFSETS);
boxShape->rp3dCollider->setIsTrigger(boxShape->IsTrigger());
break; break;
} }
default: break; default: break;
} }
} }
}
physicsObject->body->updateMassPropertiesFromColliders();
colliderQueue.pop();
}
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/

View File

@ -29,9 +29,23 @@ namespace SHADE
SHColliderComponent::SHColliderComponent() noexcept SHColliderComponent::SHColliderComponent() noexcept
: flags { ACTIVE_FLAG | MOVED_FLAG } : flags { ACTIVE_FLAG | MOVED_FLAG }
, factory { nullptr }
, collisionBody { nullptr } , collisionBody { nullptr }
{} {}
SHColliderComponent::~SHColliderComponent()
{
int32_t numShapes = static_cast<int32_t>(shapes.size());
while (--numShapes >= 0)
{
delete shapes[numShapes];
shapes[numShapes] = nullptr;
}
shapes.clear();
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Getter Function Definitions */ /* Getter Function Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -143,10 +157,10 @@ namespace SHADE
int SHColliderComponent::AddSphereCollisionShape(float relativeRadius, const SHVec3& posOffset, const SHVec3& rotOffset) int SHColliderComponent::AddSphereCollisionShape(float relativeRadius, const SHVec3& posOffset, const SHVec3& rotOffset)
{ {
SHASSERT(factory, "Physics factory missing from Collider Component! Unable to add colliders!")
const float SPHERE_SCALE = std::fabs(SHMath::Max({ transform.scale.x, transform.scale.y, transform.scale.z })); const float SPHERE_SCALE = std::fabs(SHMath::Max({ transform.scale.x, transform.scale.y, transform.scale.z }));
const uint32_t NEW_INDEX = static_cast<uint32_t>(shapes.size());
// Create collision shape // Create collision shape
shapes.emplace_back(new SHSphere{}); shapes.emplace_back(new SHSphere{});
auto* newSphere = dynamic_cast<SHSphere*>(shapes.back()); auto* newSphere = dynamic_cast<SHSphere*>(shapes.back());
@ -156,14 +170,6 @@ namespace SHADE
newSphere->rotationOffset = rotOffset; newSphere->rotationOffset = rotOffset;
newSphere->relativeRadius = relativeRadius; newSphere->relativeRadius = relativeRadius;
newSphere->scale = SPHERE_SCALE; newSphere->scale = SPHERE_SCALE;
rp3d::SphereShape* rp3dSphere = factory->createSphereShape(relativeRadius * SPHERE_SCALE * 0.5f);
const rp3d::Transform OFFSETS{ posOffset, SHQuaternion::FromEuler(rotOffset) };
newSphere->rp3dCollider = collisionBody->addCollider(rp3dSphere, OFFSETS);
const uint32_t NEW_INDEX = static_cast<uint32_t>(shapes.size());
// Broadcast Event for adding a shape // Broadcast Event for adding a shape
const SHPhysicsColliderAddedEvent EVENT_DATA const SHPhysicsColliderAddedEvent EVENT_DATA
@ -175,7 +181,17 @@ namespace SHADE
SHEventManager::BroadcastEvent<SHPhysicsColliderAddedEvent>(EVENT_DATA, SH_PHYSICS_COLLIDER_ADDED_EVENT); SHEventManager::BroadcastEvent<SHPhysicsColliderAddedEvent>(EVENT_DATA, SH_PHYSICS_COLLIDER_ADDED_EVENT);
dynamic_cast<rp3d::RigidBody*>(collisionBody)->updateMassPropertiesFromColliders(); // Only link with react if a factory is present.
// Otherwise, it will be linked through the physics object manager once the definitions are flushed.
if (factory)
{
rp3d::SphereShape* rp3dSphere = factory->createSphereShape(relativeRadius * SPHERE_SCALE * 0.5f);
const rp3d::Transform OFFSETS{ posOffset, SHQuaternion::FromEuler(rotOffset) };
newSphere->rp3dCollider = collisionBody->addCollider(rp3dSphere, OFFSETS);
dynamic_cast<rp3d::RigidBody*>(collisionBody)->updateMassPropertiesFromColliders();
}
return static_cast<int>(NEW_INDEX); return static_cast<int>(NEW_INDEX);
} }
@ -184,6 +200,8 @@ namespace SHADE
{ {
SHASSERT(factory, "Physics factory missing from Collider Component! Unable to add colliders!") SHASSERT(factory, "Physics factory missing from Collider Component! Unable to add colliders!")
const uint32_t NEW_INDEX = static_cast<uint32_t>(shapes.size());
// Create collision shape // Create collision shape
shapes.emplace_back(new SHBox{}); shapes.emplace_back(new SHBox{});
auto* newBox = dynamic_cast<SHBox*>(shapes.back()); auto* newBox = dynamic_cast<SHBox*>(shapes.back());
@ -194,15 +212,6 @@ namespace SHADE
newBox->relativeExtents = relativeExtents; newBox->relativeExtents = relativeExtents;
newBox->scale = SHVec3::Abs(transform.scale); newBox->scale = SHVec3::Abs(transform.scale);
rp3d::BoxShape* rp3dBox = factory->createBoxShape(relativeExtents * newBox->scale * 0.5f);
const rp3d::Transform OFFSETS{ posOffset, SHQuaternion::FromEuler(rotOffset) };
newBox->rp3dCollider = collisionBody->addCollider(rp3dBox, OFFSETS);
const uint32_t NEW_INDEX = static_cast<uint32_t>(shapes.size());
// Broadcast Event for adding a shape // Broadcast Event for adding a shape
const SHPhysicsColliderAddedEvent EVENT_DATA const SHPhysicsColliderAddedEvent EVENT_DATA
{ {
@ -213,7 +222,15 @@ namespace SHADE
SHEventManager::BroadcastEvent<SHPhysicsColliderAddedEvent>(EVENT_DATA, SH_PHYSICS_COLLIDER_ADDED_EVENT); SHEventManager::BroadcastEvent<SHPhysicsColliderAddedEvent>(EVENT_DATA, SH_PHYSICS_COLLIDER_ADDED_EVENT);
dynamic_cast<rp3d::RigidBody*>(collisionBody)->updateMassPropertiesFromColliders(); if (factory)
{
rp3d::BoxShape* rp3dBox = factory->createBoxShape(relativeExtents * newBox->scale * 0.5f);
const rp3d::Transform OFFSETS{ posOffset, SHQuaternion::FromEuler(rotOffset) };
newBox->rp3dCollider = collisionBody->addCollider(rp3dBox, OFFSETS);
dynamic_cast<rp3d::RigidBody*>(collisionBody)->updateMassPropertiesFromColliders();
}
return static_cast<int>(NEW_INDEX); return static_cast<int>(NEW_INDEX);
} }

View File

@ -60,7 +60,7 @@ namespace SHADE
SHColliderComponent () noexcept; SHColliderComponent () noexcept;
SHColliderComponent (const SHColliderComponent& rhs) noexcept = default; SHColliderComponent (const SHColliderComponent& rhs) noexcept = default;
SHColliderComponent (SHColliderComponent&& rhs) noexcept = default; SHColliderComponent (SHColliderComponent&& rhs) noexcept = default;
~SHColliderComponent () override = default; ~SHColliderComponent () override;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Operator Overloads */ /* Operator Overloads */