From c18d58cba35a7a9dade67a26e8222e447e3411c4 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Tue, 22 Nov 2022 19:25:40 +0800 Subject: [PATCH] Fixed various physics bugs Fixed bug where world was prebuilt and entity IDs were wrongly synced Fixed collider properties not being synced in the first frame during mass property computations Fixed static objects being wrongly updated post world update --- Assets/Scenes/M2Scene.shade | 337 +++++++++++++++++- SHADE_Application/src/Scenes/SBMainScene.cpp | 4 + .../Physics/PhysicsObject/SHPhysicsObject.cpp | 52 ++- .../Physics/PhysicsObject/SHPhysicsObject.h | 10 +- .../System/SHPhysicsSystemRoutines.cpp | 36 +- 5 files changed, 402 insertions(+), 37 deletions(-) diff --git a/Assets/Scenes/M2Scene.shade b/Assets/Scenes/M2Scene.shade index 8b61dc67..ff5e5fd6 100644 --- a/Assets/Scenes/M2Scene.shade +++ b/Assets/Scenes/M2Scene.shade @@ -4,7 +4,7 @@ NumberOfChildren: 0 Components: Camera Component: - Position: {x: 0, y: 0, z: 8} + Position: {x: 0, y: 3, z: 8} Pitch: 0 Yaw: 0 Roll: 0 @@ -13,6 +13,7 @@ Near: 0.00999999978 Far: 10000 Perspective: true + IsActive: true Light Component: Position: {x: 0, y: 0, z: 0} Type: Directional @@ -20,6 +21,7 @@ Color: {x: 0.951541841, y: 0.921719015, z: 0.553319454, w: 1} Layer: 4294967295 Strength: 0 + IsActive: true Scripts: ~ - EID: 7 Name: BigBoi @@ -30,9 +32,11 @@ Translate: {x: 0, y: -16.8647861, z: -14.039052} Rotate: {x: -0, y: 0, z: -0} Scale: {x: 28.1434975, y: 28.1434975, z: 28.1434975} + IsActive: true Renderable Component: Mesh: 149697411 Material: 126974645 + IsActive: true Scripts: ~ - EID: 8 Name: AmbientLight @@ -46,4 +50,335 @@ Color: {x: 1, y: 1, z: 1, w: 1} Layer: 4294967295 Strength: 0.25 + IsActive: true + Scripts: ~ +- EID: 65542 + Name: Default + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.5, y: 0.5, z: -2.5} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 5, y: 0.5, z: 5} + IsActive: true + Collider Component: + Colliders: + - Is Trigger: false + Type: Box + Half Extents: {x: 1, y: 1, z: 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: 65538 + Name: Movable + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0, y: 4.28833103, z: 0} + Rotate: {x: -0, y: 0, z: -0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + RigidBody Component: + Type: Dynamic + Drag: 0.00999999978 + Angular Drag: 0.00999999978 + Use Gravity: true + Interpolate: true + Sleeping Enabled: true + Freeze Position X: false + Freeze Position Y: false + Freeze Position Z: false + Freeze Rotation X: false + Freeze Rotation Y: false + Freeze Rotation Z: false + IsActive: true + Collider Component: + Colliders: + - Is Trigger: false + Type: Box + Half Extents: {x: 1, y: 1, z: 1} + Friction: 0.400000006 + Bounciness: 0 + Density: 1 + Position Offset: {x: 0, y: 0, z: 0} + Rotation Offset: {x: 0, y: 0, z: 0} + - Is Trigger: false + Type: Box + Half Extents: {x: 2, y: 2, z: 2} + 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: 65537 + Name: Default + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 5.25, y: 2.75, z: 2.5} + Rotate: {x: 0, y: 0, z: 1.57079637} + Scale: {x: 5, y: 0.5, z: 5} + IsActive: true + Collider Component: + Colliders: + - Is Trigger: false + Type: Box + Half Extents: {x: 1, y: 1, z: 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: 9 + Name: Default + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 5.25, y: 2.75, z: -2.5} + Rotate: {x: 0, y: 0, z: 1.57079637} + Scale: {x: 5, y: 0.5, z: 5} + IsActive: true + Collider Component: + Colliders: + - Is Trigger: false + Type: Box + Half Extents: {x: 1, y: 1, z: 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: 10 + Name: Default + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -5.25, y: 2.75, z: 2.5} + Rotate: {x: 0, y: 0, z: 1.57079637} + Scale: {x: 5, y: 0.5, z: 5} + IsActive: true + Collider Component: + Colliders: + - Is Trigger: false + Type: Box + Half Extents: {x: 1, y: 1, z: 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: 11 + Name: Default + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -5.25, y: 2.75, z: -2.5} + Rotate: {x: 0, y: 0, z: 1.57079637} + Scale: {x: 5, y: 0.5, z: 5} + IsActive: true + Collider Component: + Colliders: + - Is Trigger: false + Type: Box + Half Extents: {x: 1, y: 1, z: 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: 12 + Name: Default + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.5, y: 2.75, z: 5.25} + Rotate: {x: 7.15255737e-07, y: 1.57079566, z: 1.57079589} + Scale: {x: 4.99999809, y: 0.499999762, z: 4.99999809} + IsActive: true + Collider Component: + Colliders: + - Is Trigger: false + Type: Box + Half Extents: {x: 1, y: 1, z: 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: 65551 + Name: Default + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -2.5, y: 2.75, z: 5.25} + Rotate: {x: 7.15255737e-07, y: 1.57079566, z: 1.57079589} + Scale: {x: 4.99999809, y: 0.499999762, z: 4.99999809} + IsActive: true + Collider Component: + Colliders: + - Is Trigger: false + Type: Box + Half Extents: {x: 1, y: 1, z: 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: 65550 + Name: Default + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -2.5, y: 2.75, z: -5.25} + Rotate: {x: 7.15255737e-07, y: 1.57079566, z: 1.57079589} + Scale: {x: 4.99999809, y: 0.499999762, z: 4.99999809} + IsActive: true + Collider Component: + Colliders: + - Is Trigger: false + Type: Box + Half Extents: {x: 1, y: 1, z: 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: 65549 + Name: Default + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.5, y: 2.75, z: -5.25} + Rotate: {x: 7.15255737e-07, y: 1.57079566, z: 1.57079589} + Scale: {x: 4.99999809, y: 0.499999762, z: 4.99999809} + IsActive: true + Collider Component: + Colliders: + - Is Trigger: false + Type: Box + Half Extents: {x: 1, y: 1, z: 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: 16 + Name: Default + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0, y: 2.5, z: 0} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 2.5, y: 0.5, z: 2.5} + IsActive: true + Collider Component: + Colliders: + - Is Trigger: false + Type: Box + Half Extents: {x: 1, y: 1, z: 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: 5 + Name: Default + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 2.5, y: 0.5, z: 2.5} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 5, y: 0.5, z: 5} + IsActive: true + Collider Component: + Colliders: + - Is Trigger: false + Type: Box + Half Extents: {x: 1, y: 1, z: 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: 4 + Name: Default + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -2.5, y: 0.5, z: -2.5} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 5, y: 0.5, z: 5} + IsActive: true + Collider Component: + Colliders: + - Is Trigger: false + Type: Box + Half Extents: {x: 1, y: 1, z: 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: 3 + Name: Default + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -2.5, y: 0.5, z: 2.5} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 5, y: 0.5, z: 5} + IsActive: true + Collider Component: + Colliders: + - Is Trigger: false + Type: Box + Half Extents: {x: 1, y: 1, z: 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: ~ \ No newline at end of file diff --git a/SHADE_Application/src/Scenes/SBMainScene.cpp b/SHADE_Application/src/Scenes/SBMainScene.cpp index 929d28fa..0178cdd5 100644 --- a/SHADE_Application/src/Scenes/SBMainScene.cpp +++ b/SHADE_Application/src/Scenes/SBMainScene.cpp @@ -44,6 +44,8 @@ namespace Sandbox { sceneName = SHSerialization::DeserializeSceneFromFile(sceneAssetID); + #ifndef SHEDITOR + auto* physicsSystem = SHSystemManager::GetSystem(); if (!physicsSystem) { @@ -53,6 +55,8 @@ namespace Sandbox physicsSystem->BuildScene(SHSceneManager::GetCurrentSceneGraph()); + #endif + /*-----------------------------------------------------------------------*/ /* TESTING CODE */ /*-----------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp index 00f280e9..71b08831 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp @@ -123,12 +123,14 @@ namespace SHADE default: break; } + auto* rp3dCollider = rp3dBody->getCollider(rp3dBody->getNbColliders() - 1); + syncColliderProperties(collisionShape, rp3dCollider); + if (rp3dBody->getType() == rp3d::BodyType::DYNAMIC) { rp3dBody->updateMassPropertiesFromColliders(); - - auto* rigidBodyComponent = SHComponentManager::GetComponent_s(entityID); - if (rigidBodyComponent) + + if (auto* rigidBodyComponent = SHComponentManager::GetComponent_s(entityID); rigidBodyComponent) rigidBodyComponent->mass = rp3dBody->getMass(); } @@ -326,28 +328,42 @@ namespace SHADE default: break; } - // Sync material auto* rp3dCollider = rp3dBody->getCollider(i); - auto& rp3dMaterial = rp3dCollider->getMaterial(); - - rp3dMaterial.setFrictionCoefficient(collisionShape.GetFriction()); - rp3dMaterial.setBounciness(collisionShape.GetBounciness()); - rp3dMaterial.setMassDensity(collisionShape.GetDensity()); - - // Sync tags - const unsigned short MASK_BITS = collisionShape.GetCollisionTag(); - rp3dCollider->setCollisionCategoryBits(MASK_BITS); - rp3dCollider->setCollideWithMaskBits(MASK_BITS); + syncColliderProperties(collisionShape, rp3dCollider); collisionShape.dirty = false; } + + // Set rigidbody mass if dynamic + auto* rigidBodyComponent = SHComponentManager::GetComponent_s(entityID); + if (rigidBodyComponent) + { + // This is generally expensive, will be optimised in the future with my own engine. + rp3dBody->updateMassPropertiesFromColliders(); + rigidBodyComponent->mass = rp3dBody->getMass(); + } } /*-----------------------------------------------------------------------------------*/ /* Private Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHPhysicsObject::addBoxShape(SHCollisionShape& boxShape) const noexcept + void SHPhysicsObject::syncColliderProperties(const SHCollisionShape& collisionShape, rp3d::Collider* rp3dCollider) const noexcept + { + rp3dCollider->setIsTrigger(collisionShape.IsTrigger()); + + auto& rp3dMaterial = rp3dCollider->getMaterial(); + + rp3dMaterial.setFrictionCoefficient(collisionShape.GetFriction()); + rp3dMaterial.setBounciness(collisionShape.GetBounciness()); + rp3dMaterial.setMassDensity(collisionShape.GetDensity()); + + const unsigned short MASK_BITS = collisionShape.GetCollisionTag(); + rp3dCollider->setCollisionCategoryBits(MASK_BITS); + rp3dCollider->setCollideWithMaskBits(MASK_BITS); + } + + void SHPhysicsObject::addBoxShape(const SHCollisionShape& boxShape) const noexcept { const rp3d::Transform OFFSETS { @@ -361,7 +377,7 @@ namespace SHADE rp3dBody->addCollider(newBox, OFFSETS); } - void SHPhysicsObject::syncBoxShape(int index, SHCollisionShape& boxShape) const noexcept + void SHPhysicsObject::syncBoxShape(int index, const SHCollisionShape& boxShape) const noexcept { const auto* BOX = reinterpret_cast(boxShape.GetShape()); @@ -380,7 +396,7 @@ namespace SHADE rp3dBox->setHalfExtents(BOX->GetWorldExtents()); } - void SHPhysicsObject::addSphereShape(SHCollisionShape& sphereShape) const noexcept + void SHPhysicsObject::addSphereShape(const SHCollisionShape& sphereShape) const noexcept { const rp3d::Transform OFFSETS { @@ -394,7 +410,7 @@ namespace SHADE rp3dBody->addCollider(newSphere, OFFSETS); } - void SHPhysicsObject::syncSphereShape(int index, SHCollisionShape& sphereShape) const noexcept + void SHPhysicsObject::syncSphereShape(int index, const SHCollisionShape& sphereShape) const noexcept { const auto* SPHERE = reinterpret_cast(sphereShape.GetShape()); diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.h b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.h index 818e5471..c572ca2e 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.h +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.h @@ -96,14 +96,16 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ + void syncColliderProperties (const SHCollisionShape& collisionShape, rp3d::Collider* rp3dCollider) const noexcept; + // Box Shapes - void addBoxShape (SHCollisionShape& boxShape) const noexcept; - void syncBoxShape (int index, SHCollisionShape& boxShape) const noexcept; + void addBoxShape (const SHCollisionShape& boxShape) const noexcept; + void syncBoxShape (int index, const SHCollisionShape& boxShape) const noexcept; // Sphere Shapes - void addSphereShape (SHCollisionShape& sphereShape) const noexcept; - void syncSphereShape (int index, SHCollisionShape& sphereShape) const noexcept; + void addSphereShape (const SHCollisionShape& sphereShape) const noexcept; + void syncSphereShape (int index, const SHCollisionShape& sphereShape) const noexcept; }; } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp index 9d860bf9..8ddbbcc9 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp @@ -21,6 +21,7 @@ #include "Input/SHInputManager.h" + namespace SHADE { /*-----------------------------------------------------------------------------------*/ @@ -134,6 +135,8 @@ namespace SHADE const double FIXED_DT = physicsSystem->fixedDT; accumulatedTime += dt; + testFunction(); + int count = 0; while (accumulatedTime > FIXED_DT) { @@ -315,7 +318,7 @@ namespace SHADE if (physicsObject.GetRigidBody()->isActive()) physicsObject.prevTransform = CURRENT_TF; - // Sync with rigid bodies + // Sync with rigid bodies. If an object doesn't have a rigidbody, no update is needed here as it is done in pre-update. if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive(physicsObject.entityID)) { // Skip static bodies @@ -336,20 +339,25 @@ namespace SHADE rigidBodyComponent->position = CURRENT_TF.getPosition(); rigidBodyComponent->orientation = CURRENT_TF.getOrientation(); - } - // Sync with colliders - if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive(physicsObject.entityID)) - { - colliderComponent->position = CURRENT_TF.getPosition(); - colliderComponent->orientation = CURRENT_TF.getOrientation(); - } + // Sync with colliders + if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive(physicsObject.entityID)) + { + // Skip colliders without rigidbody components. If any transform was updated, it was done in pre-update. + + colliderComponent->position = CURRENT_TF.getPosition(); + colliderComponent->orientation = CURRENT_TF.getOrientation(); + } - // Set transform for rendering - if (transformComponent) - { - transformComponent->SetWorldPosition(renderPos); - transformComponent->SetWorldOrientation(renderRot); + // Set transform for rendering + if (transformComponent) + { + transformComponent->SetWorldPosition(renderPos); + transformComponent->SetWorldOrientation(renderRot); + } } } -} // namespace SHADE \ No newline at end of file +} // namespace SHADE + + +