From 3593df3ada5fb8ac8f8448bb0955f0848bb26628 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 2 Feb 2023 20:15:59 +0800 Subject: [PATCH] Fixed collider shape serialisation --- Assets/Scenes/x.shade | 31 +++++++++- SHADE_Engine/src/Camera/SHCameraSystem.cpp | 10 +--- .../src/Math/Transform/SHTransformSystem.cpp | 2 - .../src/Physics/Collision/Shapes/SHBox.cpp | 14 +++-- .../Collision/Shapes/SHCollisionShape.cpp | 33 +++++++---- .../Collision/Shapes/SHCollisionShape.h | 1 + .../src/Physics/Collision/Shapes/SHSphere.cpp | 14 +++-- .../PhysicsObject/SHPhysicsObjectManager.cpp | 40 +++++++++---- .../Physics/Interface/SHColliderComponent.cpp | 59 ++++++++++++------- .../Physics/Interface/SHColliderComponent.h | 2 +- 10 files changed, 144 insertions(+), 62 deletions(-) diff --git a/Assets/Scenes/x.shade b/Assets/Scenes/x.shade index 7a59d350..d7aaee0e 100644 --- a/Assets/Scenes/x.shade +++ b/Assets/Scenes/x.shade @@ -12,7 +12,7 @@ Type: Dynamic Drag: 0.00999999978 Angular Drag: 0.100000001 - Use Gravity: true + Use Gravity: false Interpolate: true Sleeping Enabled: false Freeze Position X: false @@ -22,4 +22,33 @@ Freeze Rotation Y: false Freeze Rotation Z: false 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: ~ \ No newline at end of file diff --git a/SHADE_Engine/src/Camera/SHCameraSystem.cpp b/SHADE_Engine/src/Camera/SHCameraSystem.cpp index b31345cd..01c599ca 100644 --- a/SHADE_Engine/src/Camera/SHCameraSystem.cpp +++ b/SHADE_Engine/src/Camera/SHCameraSystem.cpp @@ -161,9 +161,6 @@ namespace SHADE SHTransformComponent* transform = SHComponentManager::GetComponent_s(pivot.GetEID()); auto physicsSystem = SHSystemManager::GetSystem(); - - - if (camera == nullptr || transform == nullptr) return; @@ -179,13 +176,12 @@ namespace SHADE camera->dirtyView = true; }*/ - pivot.ray.position = camera->GetPosition() + pivot.targetOffset; 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()) //{ // @@ -203,7 +199,7 @@ namespace SHADE // // - //// pivot.rtMatrix = SHMatrix::Inverse(pivot.rtMatrix); + // pivot.rtMatrix = SHMatrix::Inverse(pivot.rtMatrix); } diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp index 03de360d..0a0ec092 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp @@ -246,8 +246,6 @@ namespace SHADE tf.world.position = SHVec3::Transform(tf.local.position, localToWorld); tf.world.scale = tf.local.scale * (parent ? parent->GetLocalScale() : SHVec3::One); - - if (convertRotation) { tf.worldRotation = tf.localRotation + (parent ? parent->GetLocalRotation() : SHVec3::Zero); diff --git a/SHADE_Engine/src/Physics/Collision/Shapes/SHBox.cpp b/SHADE_Engine/src/Physics/Collision/Shapes/SHBox.cpp index 1e2a4a22..f8049451 100644 --- a/SHADE_Engine/src/Physics/Collision/Shapes/SHBox.cpp +++ b/SHADE_Engine/src/Physics/Collision/Shapes/SHBox.cpp @@ -44,7 +44,10 @@ namespace SHADE SHVec3 SHBox::GetWorldExtents() const noexcept { - return SHVec3{ dynamic_cast(rp3dCollider->getCollisionShape())->getHalfExtents() }; + if (rp3dCollider) + return SHVec3{ dynamic_cast(rp3dCollider->getCollisionShape())->getHalfExtents() }; + + return relativeExtents * scale * 0.5f; } SHVec3 SHBox::GetRelativeExtents() const noexcept @@ -65,7 +68,8 @@ namespace SHADE void SHBox::SetWorldExtents(const SHVec3& newWorldExtents) noexcept { - dynamic_cast(rp3dCollider->getCollisionShape())->setHalfExtents(newWorldExtents); + if (rp3dCollider) + dynamic_cast(rp3dCollider->getCollisionShape())->setHalfExtents(newWorldExtents); // Recompute Relative radius relativeExtents = 2.0f * newWorldExtents / scale; @@ -76,7 +80,8 @@ namespace SHADE relativeExtents = newRelativeExtents; // Recompute world radius - dynamic_cast(rp3dCollider->getCollisionShape())->setHalfExtents(relativeExtents * scale * 0.5f); + if (rp3dCollider) + dynamic_cast(rp3dCollider->getCollisionShape())->setHalfExtents(relativeExtents * scale * 0.5f); } void SHBox::SetScale(const SHVec3& newScale) noexcept @@ -84,7 +89,8 @@ namespace SHADE scale = SHVec3::Abs(newScale); // Recompute world radius - dynamic_cast(rp3dCollider->getCollisionShape())->setHalfExtents(relativeExtents * scale * 0.5f); + if (rp3dCollider) + dynamic_cast(rp3dCollider->getCollisionShape())->setHalfExtents(relativeExtents * scale * 0.5f); } /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Physics/Collision/Shapes/SHCollisionShape.cpp b/SHADE_Engine/src/Physics/Collision/Shapes/SHCollisionShape.cpp index 2acffe29..8147c94a 100644 --- a/SHADE_Engine/src/Physics/Collision/Shapes/SHCollisionShape.cpp +++ b/SHADE_Engine/src/Physics/Collision/Shapes/SHCollisionShape.cpp @@ -123,29 +123,38 @@ namespace SHADE void SHCollisionShape::SetFriction(float friction) noexcept { material.SetFriction(friction); - rp3dCollider->getMaterial().setFrictionCoefficient(material.GetFriction()); + + if (rp3dCollider) + rp3dCollider->getMaterial().setFrictionCoefficient(material.GetFriction()); } void SHCollisionShape::SetBounciness(float bounciness) noexcept { material.SetBounciness(bounciness); - rp3dCollider->getMaterial().setBounciness(material.GetBounciness()); + + if (rp3dCollider) + rp3dCollider->getMaterial().setBounciness(material.GetBounciness()); } void SHCollisionShape::SetDensity(float density) noexcept { material.SetDensity(density); - rp3dCollider->getMaterial().setMassDensity(material.GetDensity()); + + if (rp3dCollider) + rp3dCollider->getMaterial().setMassDensity(material.GetDensity()); } void SHCollisionShape::SetMaterial(const SHPhysicsMaterial& newMaterial) noexcept { material = newMaterial; - auto& rp3dMaterial = rp3dCollider->getMaterial(); - rp3dMaterial.setFrictionCoefficient(material.GetFriction()); - rp3dMaterial.setBounciness(material.GetBounciness()); - rp3dMaterial.setMassDensity(material.GetDensity()); + if (rp3dCollider) + { + auto& rp3dMaterial = rp3dCollider->getMaterial(); + rp3dMaterial.setFrictionCoefficient(material.GetFriction()); + rp3dMaterial.setBounciness(material.GetBounciness()); + rp3dMaterial.setMassDensity(material.GetDensity()); + } } void SHCollisionShape::SetPositionOffset(const SHVec3& posOffset) noexcept @@ -167,7 +176,8 @@ namespace SHADE 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 { - const rp3d::Transform OFFSETS{ positionOffset, SHQuaternion::FromEuler(rotationOffset) }; - rp3dCollider->setLocalToBodyTransform(OFFSETS); + if (rp3dCollider) + { + const rp3d::Transform OFFSETS{ positionOffset, SHQuaternion::FromEuler(rotationOffset) }; + rp3dCollider->setLocalToBodyTransform(OFFSETS); + } } SHMatrix SHCollisionShape::GetTRS() const noexcept diff --git a/SHADE_Engine/src/Physics/Collision/Shapes/SHCollisionShape.h b/SHADE_Engine/src/Physics/Collision/Shapes/SHCollisionShape.h index 44c4d479..b9b42daa 100644 --- a/SHADE_Engine/src/Physics/Collision/Shapes/SHCollisionShape.h +++ b/SHADE_Engine/src/Physics/Collision/Shapes/SHCollisionShape.h @@ -41,6 +41,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ friend class SHPhysicsSystem; + friend class SHPhysicsObjectManager; friend class SHColliderComponent; public: diff --git a/SHADE_Engine/src/Physics/Collision/Shapes/SHSphere.cpp b/SHADE_Engine/src/Physics/Collision/Shapes/SHSphere.cpp index f8c73f90..46fbc7db 100644 --- a/SHADE_Engine/src/Physics/Collision/Shapes/SHSphere.cpp +++ b/SHADE_Engine/src/Physics/Collision/Shapes/SHSphere.cpp @@ -45,7 +45,10 @@ namespace SHADE float SHSphere::GetWorldRadius() const noexcept { - return dynamic_cast(rp3dCollider->getCollisionShape())->getRadius(); + if (rp3dCollider) + return dynamic_cast(rp3dCollider->getCollisionShape())->getRadius(); + + return relativeRadius * scale * 0.5f; } float SHSphere::GetRelativeRadius() const noexcept @@ -66,7 +69,8 @@ namespace SHADE void SHSphere::SetWorldRadius(float newWorldRadius) noexcept { - dynamic_cast(rp3dCollider->getCollisionShape())->setRadius(newWorldRadius); + if (rp3dCollider) + dynamic_cast(rp3dCollider->getCollisionShape())->setRadius(newWorldRadius); // Recompute Relative radius relativeRadius = 2.0f * newWorldRadius / scale; @@ -77,7 +81,8 @@ namespace SHADE relativeRadius = newRelativeRadius; // Recompute world radius - dynamic_cast(rp3dCollider->getCollisionShape())->setRadius(relativeRadius * scale * 0.5f); + if (rp3dCollider) + dynamic_cast(rp3dCollider->getCollisionShape())->setRadius(relativeRadius * scale * 0.5f); } void SHSphere::SetScale(float maxScale) noexcept @@ -85,7 +90,8 @@ namespace SHADE scale = std::fabs(maxScale); // Recompute world radius - dynamic_cast(rp3dCollider->getCollisionShape())->setRadius(relativeRadius * scale * 0.5f); + if (rp3dCollider) + dynamic_cast(rp3dCollider->getCollisionShape())->setRadius(relativeRadius * scale * 0.5f); } /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Physics/Interface/PhysicsObject/SHPhysicsObjectManager.cpp b/SHADE_Engine/src/Physics/Interface/PhysicsObject/SHPhysicsObjectManager.cpp index 8aec29b1..8c88e4ae 100644 --- a/SHADE_Engine/src/Physics/Interface/PhysicsObject/SHPhysicsObjectManager.cpp +++ b/SHADE_Engine/src/Physics/Interface/PhysicsObject/SHPhysicsObjectManager.cpp @@ -176,8 +176,6 @@ namespace SHADE void SHPhysicsObjectManager::RemoveCollider(EntityID entityID) noexcept { - auto* colliderComponent = SHComponentManager::GetComponent(entityID); - const auto PHYSICS_OBJECT_ITERATOR = physicsObjects.find(entityID); if (PHYSICS_OBJECT_ITERATOR != physicsObjects.end()) { @@ -189,13 +187,8 @@ namespace SHADE { auto* rp3dCollider = physicsObject->body->getCollider(numShapes); physicsObject->body->removeCollider(rp3dCollider); - - delete colliderComponent->shapes[numShapes]; - colliderComponent->shapes[numShapes] = nullptr; } - colliderComponent->shapes.clear(); - // Destroy if no rigidbody component if (!SHComponentManager::GetComponent_s(entityID)) destroyPhysicsObject(entityID); @@ -356,25 +349,48 @@ namespace SHADE colliderComponent->SetCollisionBody(physicsObject->body); // 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: { - colliderComponent->AddSphereCollisionShape(shapeDef.size.x); + auto* sphereShape = dynamic_cast(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; } case SHCollisionShape::Type::BOX: { - colliderComponent->AddBoxCollisionShape(shapeDef.size); + auto* boxShape = dynamic_cast(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; } default: break; } } - } + physicsObject->body->updateMassPropertiesFromColliders(); + + colliderQueue.pop(); + } } /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Physics/Interface/SHColliderComponent.cpp b/SHADE_Engine/src/Physics/Interface/SHColliderComponent.cpp index 15d01042..36af4592 100644 --- a/SHADE_Engine/src/Physics/Interface/SHColliderComponent.cpp +++ b/SHADE_Engine/src/Physics/Interface/SHColliderComponent.cpp @@ -29,9 +29,23 @@ namespace SHADE SHColliderComponent::SHColliderComponent() noexcept : flags { ACTIVE_FLAG | MOVED_FLAG } + , factory { nullptr } , collisionBody { nullptr } {} + SHColliderComponent::~SHColliderComponent() + { + int32_t numShapes = static_cast(shapes.size()); + while (--numShapes >= 0) + { + delete shapes[numShapes]; + shapes[numShapes] = nullptr; + } + + shapes.clear(); + } + + /*-----------------------------------------------------------------------------------*/ /* Getter Function Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -143,10 +157,10 @@ namespace SHADE 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 uint32_t NEW_INDEX = static_cast(shapes.size()); + // Create collision shape shapes.emplace_back(new SHSphere{}); auto* newSphere = dynamic_cast(shapes.back()); @@ -156,14 +170,6 @@ namespace SHADE newSphere->rotationOffset = rotOffset; newSphere->relativeRadius = relativeRadius; 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(shapes.size()); // Broadcast Event for adding a shape const SHPhysicsColliderAddedEvent EVENT_DATA @@ -175,7 +181,17 @@ namespace SHADE SHEventManager::BroadcastEvent(EVENT_DATA, SH_PHYSICS_COLLIDER_ADDED_EVENT); - dynamic_cast(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(collisionBody)->updateMassPropertiesFromColliders(); + } return static_cast(NEW_INDEX); } @@ -184,6 +200,8 @@ namespace SHADE { SHASSERT(factory, "Physics factory missing from Collider Component! Unable to add colliders!") + const uint32_t NEW_INDEX = static_cast(shapes.size()); + // Create collision shape shapes.emplace_back(new SHBox{}); auto* newBox = dynamic_cast(shapes.back()); @@ -194,15 +212,6 @@ namespace SHADE newBox->relativeExtents = relativeExtents; 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(shapes.size()); - // Broadcast Event for adding a shape const SHPhysicsColliderAddedEvent EVENT_DATA { @@ -213,7 +222,15 @@ namespace SHADE SHEventManager::BroadcastEvent(EVENT_DATA, SH_PHYSICS_COLLIDER_ADDED_EVENT); - dynamic_cast(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(collisionBody)->updateMassPropertiesFromColliders(); + } return static_cast(NEW_INDEX); } diff --git a/SHADE_Engine/src/Physics/Interface/SHColliderComponent.h b/SHADE_Engine/src/Physics/Interface/SHColliderComponent.h index 63a59e55..6b971e23 100644 --- a/SHADE_Engine/src/Physics/Interface/SHColliderComponent.h +++ b/SHADE_Engine/src/Physics/Interface/SHColliderComponent.h @@ -60,7 +60,7 @@ namespace SHADE SHColliderComponent () noexcept; SHColliderComponent (const SHColliderComponent& rhs) noexcept = default; SHColliderComponent (SHColliderComponent&& rhs) noexcept = default; - ~SHColliderComponent () override = default; + ~SHColliderComponent () override; /*---------------------------------------------------------------------------------*/ /* Operator Overloads */