From 6f2dceadfd58709f46969d70201b804210108914 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 2 Sep 2022 08:42:41 +0100 Subject: [PATCH] environment: Add list of dirty static bodies Adds a vector of objects that were awake, and changed their motion type from Dynamic -> Static, so that they can be retrieved in GetActiveObjects, and have their visuals updated. If we don't do this, objects that get moved, woken, and their movement type changed to static will not get their transforms updated on the game side. Closes: #59 Closes: #63 --- vphysics_jolt/vjolt_environment.cpp | 36 ++++++++++++++++++++++------- vphysics_jolt/vjolt_environment.h | 11 +++++++++ vphysics_jolt/vjolt_object.cpp | 16 +++++++++++++ 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/vphysics_jolt/vjolt_environment.cpp b/vphysics_jolt/vjolt_environment.cpp index 4d87531..16e4fa1 100644 --- a/vphysics_jolt/vjolt_environment.cpp +++ b/vphysics_jolt/vjolt_environment.cpp @@ -878,16 +878,24 @@ void JoltPhysicsEnvironment::SetQuickDelete( bool bQuick ) int JoltPhysicsEnvironment::GetActiveObjectCount() const { - // If this is the first call, then some objects may have become - // asleep from the initial simulation have their visuals not match where they are. - if ( m_bActiveObjectCountFirst ) - m_PhysicsSystem.GetBodies( m_CachedActiveBodies ); - else + if ( !m_bActiveObjectCountFirst ) + { m_PhysicsSystem.GetActiveBodies( m_CachedActiveBodies ); + // Append any dirty static bodies we need the game side transforms + // to be updated for. + m_CachedActiveBodies.insert( m_CachedActiveBodies.end(), m_DirtyStaticBodies.begin(), m_DirtyStaticBodies.end() ); + } + else + { + // If this is the first call, then some objects may have become + // asleep from the initial simulation have their visuals not match where they are. + m_PhysicsSystem.GetBodies( m_CachedActiveBodies ); + m_bActiveObjectCountFirst = false; + } - m_bActiveObjectCountFirst = false; - const int nCount = int ( m_CachedActiveBodies.size() ); - return nCount; + m_DirtyStaticBodies.clear(); + + return int( m_CachedActiveBodies.size() ); } void JoltPhysicsEnvironment::GetActiveObjects( IPhysicsObject **pOutputObjectList ) const @@ -1374,6 +1382,18 @@ void JoltPhysicsEnvironment::NotifyConstraintDisabled( JoltPhysicsConstraint* pC //------------------------------------------------------------------------------------------------- +void JoltPhysicsEnvironment::AddDirtyStaticBody( const JPH::BodyID &id ) +{ + m_DirtyStaticBodies.push_back( id ); +} + +void JoltPhysicsEnvironment::RemoveDirtyStaticBody( const JPH::BodyID &id ) +{ + Erase( m_DirtyStaticBodies, id ); +} + +//------------------------------------------------------------------------------------------------- + void JoltPhysicsEnvironment::RemoveBodyAndDeleteObject( JoltPhysicsObject *pObject ) { JPH::BodyInterface &bodyInterface = m_PhysicsSystem.GetBodyInterfaceNoLock(); diff --git a/vphysics_jolt/vjolt_environment.h b/vphysics_jolt/vjolt_environment.h index ea3f517..e45baeb 100644 --- a/vphysics_jolt/vjolt_environment.h +++ b/vphysics_jolt/vjolt_environment.h @@ -164,6 +164,9 @@ public: void NotifyConstraintDisabled( JoltPhysicsConstraint* pConstraint ); + void AddDirtyStaticBody( const JPH::BodyID &id ); + void RemoveDirtyStaticBody( const JPH::BodyID &id ); + private: void RemoveBodyAndDeleteObject( JoltPhysicsObject* pObject ); @@ -196,6 +199,14 @@ private: JPH::PhysicsSystem m_PhysicsSystem; + // A vector of objects that were awake, and changed their + // motion type from Dynamic -> Static, so that they can be + // retrieved in GetActiveObjects, and have their visuals updated. + // If we don't do this, objects that get moved, woken, and their + // movement type changed to static will not get their transforms + // updated on the game side. + mutable JPH::BodyIDVector m_DirtyStaticBodies; + std::vector< JoltPhysicsObject * > m_pDeadObjects; std::vector< JoltPhysicsConstraint * > m_pDeadConstraints; std::vector< CPhysCollide * > m_pDeadObjectCollides; diff --git a/vphysics_jolt/vjolt_object.cpp b/vphysics_jolt/vjolt_object.cpp index 5f3b5fd..91a5f32 100644 --- a/vphysics_jolt/vjolt_object.cpp +++ b/vphysics_jolt/vjolt_object.cpp @@ -229,6 +229,11 @@ void JoltPhysicsObject::Wake() JPH::BodyInterface& bodyInterface = m_pPhysicsSystem->GetBodyInterfaceNoLock(); bodyInterface.ActivateBody( m_pBody->GetID() ); } + else + { + // See other comments in UpdateLayer. + m_pEnvironment->AddDirtyStaticBody( m_pBody->GetID() ); + } } void JoltPhysicsObject::Sleep() @@ -1222,6 +1227,17 @@ void JoltPhysicsObject::UpdateLayer() if ( !bStatic && !IsControlledByGame() ) { bool bStaticMotionType = bStaticSolid || bPinned; + + // If we are transfering to being static, and we were active + // add us to a list of bodies on the environment so we can be included in + // GetActiveObjects for the next step. + // This way the game can correctly update the transforms on the game side + // when move -> wake -> become pinned happens. + if ( bStaticMotionType && m_pBody->IsActive() ) + m_pEnvironment->AddDirtyStaticBody( m_pBody->GetID() ); + else if ( !bStaticMotionType ) + m_pEnvironment->RemoveDirtyStaticBody( m_pBody->GetID() ); + bodyInterface.SetMotionType( m_pBody->GetID(), bStaticMotionType ? JPH::EMotionType::Static : JPH::EMotionType::Dynamic, JPH::EActivation::Activate ); }