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 ); }