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
This commit is contained in:
Joshua Ashton 2022-09-02 08:42:41 +01:00
parent 260d6edb12
commit 6f2dceadfd
3 changed files with 55 additions and 8 deletions

View File

@ -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();

View File

@ -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;

View File

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