diff --git a/Assets/Scenes/M2Scene.shade b/Assets/Scenes/M2Scene.shade index 0ca9eb31..cbcd34d4 100644 --- a/Assets/Scenes/M2Scene.shade +++ b/Assets/Scenes/M2Scene.shade @@ -56,177 +56,6 @@ Density: 1 Position Offset: {x: 0, y: 0, z: 0} Scripts: ~ -- EID: 2 - Name: Player - IsActive: true - NumberOfChildren: 3 - Components: - Transform Component: - Translate: {x: -3.06177855, y: -2, z: -5} - Rotate: {x: -0, y: 0, z: -0} - Scale: {x: 2, y: 2, z: 2} - Renderable Component: - Mesh: 149697411 - Material: 126974645 - RigidBody Component: - Type: Dynamic - Mass: 1 - Drag: 0 - Angular Drag: 0 - Use Gravity: true - Interpolate: true - Freeze Position X: false - Freeze Position Y: false - Freeze Position Z: false - Freeze Rotation X: true - Freeze Rotation Y: true - Freeze Rotation Z: 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.5, z: 0} - Scripts: ~ -- EID: 3 - Name: Default - IsActive: true - NumberOfChildren: 0 - Components: - Transform Component: - Translate: {x: -0.0094268322, y: 0, z: 0} - Rotate: {x: -0, y: 0, z: -0} - Scale: {x: 1, y: 1, z: 1} - Scripts: ~ -- EID: 4 - Name: Default - IsActive: true - NumberOfChildren: 0 - Components: - Transform Component: - Translate: {x: 0, y: 0, z: 0} - Rotate: {x: 0, y: 0, z: 0} - Scale: {x: 1, y: 1, z: 1} - Scripts: ~ -- EID: 9 - Name: Default - IsActive: true - NumberOfChildren: 0 - Components: - Transform Component: - Translate: {x: 0, y: 0, z: 0} - Rotate: {x: 0, y: 0, z: 0} - Scale: {x: 1, y: 1, z: 1} - Renderable Component: - Mesh: 144838771 - Material: 123745521 - Scripts: ~ -- EID: 6 - Name: AI - IsActive: true - NumberOfChildren: 0 - Components: - Transform Component: - Translate: {x: -8, y: -2, z: 2.5} - Rotate: {x: 0, y: 0, z: 0} - Scale: {x: 1, y: 1, z: 1} - Renderable Component: - Mesh: 149697411 - Material: 126974645 - RigidBody Component: - Type: Dynamic - Mass: 1 - Drag: 0 - Angular Drag: 0 - Use Gravity: true - Interpolate: false - Freeze Position X: false - Freeze Position Y: false - Freeze Position Z: false - Freeze Rotation X: true - Freeze Rotation Y: true - Freeze Rotation Z: true - Collider Component: - Colliders: - - Is Trigger: false - Type: Box - Half Extents: {x: 0.5, y: 0.5, z: 0.5} - Friction: 0.400000006 - Bounciness: 0 - Density: 1 - Position Offset: {x: 0, y: 0.5, z: 0} - Scripts: ~ -- EID: 7 - Name: Default - IsActive: true - NumberOfChildren: 0 - Components: - Transform Component: - 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} - Renderable Component: - Mesh: 149697411 - Material: 126974645 - Scripts: ~ -- EID: 8 - Name: Default - IsActive: true - NumberOfChildren: 0 - Components: - Light Component: - Position: {x: 0, y: 0, z: 0} - Type: Ambient - Direction: {x: 0, y: 0, z: 1} - Color: {x: 1, y: 1, z: 1, w: 1} - Layer: 4294967295 - Strength: 0.25 - Scripts: ~ -- EID: 5 - Name: item - IsActive: true - NumberOfChildren: 0 - Components: - Transform Component: - Translate: {x: 0, y: -2, z: -5} - Rotate: {x: 0, y: 0, z: 0} - Scale: {x: 2, y: 2, z: 2} - Renderable Component: - Mesh: 144838771 - Material: 123745521 - RigidBody Component: - Type: Dynamic - Mass: 1 - Drag: 0 - Angular Drag: 0 - Use Gravity: true - Interpolate: false - Freeze Position X: false - Freeze Position Y: false - Freeze Position Z: false - Freeze Rotation X: true - Freeze Rotation Y: true - Freeze Rotation Z: 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.5, z: 0} - - Is Trigger: true - Type: Box - Half Extents: {x: 2, y: 2, z: 2} - Friction: 0.400000006 - Bounciness: 0 - Density: 1 - Position Offset: {x: 0, y: 0.5, z: 0} - Scripts: ~ - EID: 10 Name: Default IsActive: true diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp index 549f84cb..0c9fa405 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp @@ -112,6 +112,9 @@ namespace SHADE default: break; } + rp3dBody->updateLocalCenterOfMassFromColliders(); + rp3dBody->updateLocalInertiaTensorFromColliders(); + return index; } @@ -134,9 +137,9 @@ namespace SHADE if (numColliders == 0) return; - while (numColliders >= 0) + while (numColliders - 1 >= 0) { - auto* collider = rp3dBody->getCollider(numColliders); + auto* collider = rp3dBody->getCollider(numColliders - 1); rp3dBody->removeCollider(collider); --numColliders; @@ -300,9 +303,6 @@ namespace SHADE rp3d::BoxShape* newBox = factory->createBoxShape(BOX->GetWorldExtents()); rp3dBody->addCollider(newBox, OFFSETS); - - rp3dBody->updateLocalCenterOfMassFromColliders(); - rp3dBody->updateLocalInertiaTensorFromColliders(); } void SHPhysicsObject::syncBoxShape(int index, SHCollisionShape& boxShape) const noexcept @@ -336,9 +336,6 @@ namespace SHADE rp3d::SphereShape* newSphere = factory->createSphereShape(SPHERE->GetWorldRadius()); rp3dBody->addCollider(newSphere, OFFSETS); - - rp3dBody->updateLocalCenterOfMassFromColliders(); - rp3dBody->updateLocalInertiaTensorFromColliders(); } void SHPhysicsObject::syncSphereShape(int index, SHCollisionShape& sphereShape) const noexcept diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObjectManager.cpp b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObjectManager.cpp index 8a381fcb..3820ccbe 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObjectManager.cpp +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObjectManager.cpp @@ -195,8 +195,29 @@ namespace SHADE SHPhysicsObject* SHPhysicsObjectManager::createPhysicsObject(EntityID eid) noexcept { - auto newObjIter = physicsObjects.emplace(eid, SHPhysicsObject{ eid, factory, world }); - return &(newObjIter.first->second); + auto& newPhysicsObject = physicsObjects.emplace(eid, SHPhysicsObject{ eid, factory, world }).first->second; + + // Force transforms to sync + const auto* TRANSFORM = SHComponentManager::GetComponent_s(eid); + + SHVec3 worldPos = SHVec3::Zero; + SHQuaternion worldRot = SHQuaternion::Identity; + + if (!TRANSFORM) + { + SHLOGV_ERROR("Unable to sync transforms with Physics Object for Entity {}", eid); + } + else + { + worldPos = TRANSFORM->GetWorldPosition(); + worldRot = TRANSFORM->GetWorldOrientation(); + } + + const rp3d::Transform RP3D_TRANSFORM{ worldPos, worldRot }; + newPhysicsObject.GetRigidBody()->setTransform(RP3D_TRANSFORM); + newPhysicsObject.prevTransform = RP3D_TRANSFORM; + + return &newPhysicsObject; } void SHPhysicsObjectManager::destroyPhysicsObject(EntityID eid) noexcept @@ -230,6 +251,10 @@ namespace SHADE return; } + const int NUM_SHAPES = static_cast(componentGroup.colliderComponent->GetCollisionShapes().size()); + for (int i = 0; i < NUM_SHAPES; ++i) + physicsObject->AddCollisionShape(i); + physicsObject->SyncColliders(*componentGroup.colliderComponent); } diff --git a/SHADE_Engine/src/Physics/SHPhysicsWorld.h b/SHADE_Engine/src/Physics/SHPhysicsWorld.h index bf788c0f..091ae062 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsWorld.h +++ b/SHADE_Engine/src/Physics/SHPhysicsWorld.h @@ -38,8 +38,8 @@ namespace SHADE /*-------------------------------------------------------------------------------*/ SHVec3 gravity = SHVec3{ 0.0f, -9.81f, 0.0f }; - uint16_t numVelocitySolverIterations = 8; - uint16_t numPositionSolverIterations = 3; + uint16_t numVelocitySolverIterations = 15; + uint16_t numPositionSolverIterations = 8; bool sleepingEnabled = true; }; diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp index 93ee0b11..361e7c9e 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp @@ -18,8 +18,12 @@ #include "ECS_Base/Managers/SHEntityManager.h" #include "ECS_Base/Managers/SHSystemManager.h" #include "Editor/SHEditor.h" -#include "Math/Transform/SHTransformComponent.h" #include "Physics/SHPhysicsEvents.h" +#include "Scene/SHSceneManager.h" + +/*-------------------------------------------------------------------------------------*/ +/* Local Helper Functions */ +/*-------------------------------------------------------------------------------------*/ namespace SHADE { @@ -124,29 +128,59 @@ namespace SHADE void SHPhysicsSystem::AddCollisionShape(EntityID eid, int shapeIndex) { - objectManager.AddCollisionShape(eid, shapeIndex); - - const SHPhysicsColliderAddedEvent COLLIDER_ADDED_EVENT_DATA + static const auto ADD_SHAPE = [&] { - .entityID = eid - , .colliderType = SHComponentManager::GetComponent(eid)->GetCollisionShape(shapeIndex).GetType() - , .colliderIndex = shapeIndex + objectManager.AddCollisionShape(eid, shapeIndex); + + const SHPhysicsColliderAddedEvent COLLIDER_ADDED_EVENT_DATA + { + .entityID = eid + , .colliderType = SHComponentManager::GetComponent(eid)->GetCollisionShape(shapeIndex).GetType() + , .colliderIndex = shapeIndex + }; + + SHEventManager::BroadcastEvent(COLLIDER_ADDED_EVENT_DATA, SH_PHYSICS_COLLIDER_ADDED_EVENT); }; - SHEventManager::BroadcastEvent(COLLIDER_ADDED_EVENT_DATA, SH_PHYSICS_COLLIDER_ADDED_EVENT); + #ifdef SHEDITOR + + auto* editor = SHSystemManager::GetSystem(); + if (editor && editor->editorState != SHEditor::State::STOP) + ADD_SHAPE(); + + #else + + ADD_SHAPE(); + + #endif } void SHPhysicsSystem::RemoveCollisionShape(EntityID eid, int shapeIndex) { - objectManager.RemoveCollisionShape(eid, shapeIndex); - - const SHPhysicsColliderRemovedEvent COLLIDER_REMOVED_EVENT_DATA + static const auto REMOVE_SHAPE = [&] { - .entityID = eid - , .colliderIndex = shapeIndex + objectManager.RemoveCollisionShape(eid, shapeIndex); + + const SHPhysicsColliderRemovedEvent COLLIDER_REMOVED_EVENT_DATA + { + .entityID = eid + , .colliderIndex = shapeIndex + }; + + SHEventManager::BroadcastEvent(COLLIDER_REMOVED_EVENT_DATA, SH_PHYSICS_COLLIDER_REMOVED_EVENT); }; - SHEventManager::BroadcastEvent(COLLIDER_REMOVED_EVENT_DATA, SH_PHYSICS_COLLIDER_REMOVED_EVENT); + #ifdef SHEDITOR + + auto* editor = SHSystemManager::GetSystem(); + if (editor && editor->editorState != SHEditor::State::STOP) + REMOVE_SHAPE(); + + #else + + REMOVE_SHAPE(); + + #endif } void SHPhysicsSystem::AddForce(EntityID eid, const SHVec3& force) noexcept @@ -210,18 +244,17 @@ namespace SHADE // We only add tell the physics object manager to add a component if the scene is played - #ifdef _PUBLISH - - ADDED_ID == RIGID_BODY_ID ? objectManager.AddRigidBody(EID) : objectManager.AddCollider(EID); - - #elif SHEDITOR + #ifdef SHEDITOR auto* editor = SHSystemManager::GetSystem(); - if (editor) - { - if (editor->editorState != SHEditor::State::STOP) - ADDED_ID == RIGID_BODY_ID ? objectManager.AddRigidBody(EID) : objectManager.AddCollider(EID); - } + + if (editor && editor->editorState != SHEditor::State::STOP) + ADDED_ID == RIGID_BODY_ID ? objectManager.AddRigidBody(EID) : objectManager.AddCollider(EID); + + + #else + + ADDED_ID == RIGID_BODY_ID ? objectManager.AddRigidBody(EID) : objectManager.AddCollider(EID); #endif } @@ -244,11 +277,7 @@ namespace SHADE // We only add tell the physics object manager to remove a component if the scene is played - #ifdef _PUBLISH - - REMOVED_ID == RIGID_BODY_ID ? objectManager.RemoveRigidBody(EID) : objectManager.RemoveCollider(EID); - - #elif SHEDITOR + #ifdef SHEDITOR auto* editor = SHSystemManager::GetSystem(); if (editor) @@ -257,6 +286,10 @@ namespace SHADE REMOVED_ID == RIGID_BODY_ID ? objectManager.RemoveRigidBody(EID) : objectManager.RemoveCollider(EID); } + #else + + REMOVED_ID == RIGID_BODY_ID ? objectManager.RemoveRigidBody(EID) : objectManager.RemoveCollider(EID); + #endif } @@ -266,6 +299,19 @@ namespace SHADE SHEventHandle SHPhysicsSystem::onPlay(SHEventPtr onPlayEvent) { + static const auto BUILD_PHYSICS_OBJECT = [&](SHSceneNode* node) + { + const EntityID EID = node->GetEntityID(); + + if (SHComponentManager::HasComponent(EID)) + objectManager.AddRigidBody(EID); + + if (SHComponentManager::HasComponent(EID)) + objectManager.AddCollider(EID); + }; + + //////////////////////////////// + // Create physics world worldState.CreateWorld(factory); @@ -275,14 +321,8 @@ namespace SHADE // Link with object manager & create all physics objects objectManager.SetWorld(worldState.world); - const auto& RIGIDBODY_DENSE = SHComponentManager::GetDense(); - const auto& COLLIDER_DENSE = SHComponentManager::GetDense(); - - for (auto& rigidBodyComponent : RIGIDBODY_DENSE) - objectManager.AddRigidBody(rigidBodyComponent.GetEID()); - - for (auto& colliderComponent : COLLIDER_DENSE) - objectManager.AddCollider(colliderComponent.GetEID()); + const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); + SCENE_GRAPH.Traverse(BUILD_PHYSICS_OBJECT); return onPlayEvent->handle; } @@ -300,7 +340,6 @@ namespace SHADE // Destroy the world worldState.DestroyWorld(factory); - return onStopEvent->handle; }