void CRagdoll::VPhysicsUpdate( IPhysicsObject *pPhysics ) { if ( m_lastUpdate == gpGlobals->curtime ) return; m_lastUpdate = gpGlobals->curtime; m_allAsleep = RagdollIsAsleep( m_ragdoll ); if ( m_allAsleep ) { // NOTE: This is the bbox of the ragdoll's physics // It's not always correct to use for culling, but it sure beats // using the radius box! Vector origin = GetRagdollOrigin(); RagdollComputeExactBbox( m_ragdoll, origin, m_mins, m_maxs ); m_mins -= origin; m_maxs -= origin; } else { m_mins.Init(-m_radius,-m_radius,-m_radius); m_maxs.Init(m_radius,m_radius,m_radius); if ( m_ragdoll.pGroup->IsInErrorState() ) { C_BaseEntity *pEntity = static_cast<C_BaseEntity *>(m_ragdoll.list[0].pObject->GetGameData()); RagdollSolveSeparation( m_ragdoll, pEntity ); } } // See if we should go to sleep... CheckSettleStationaryRagdoll(); }
void CRagdollProp::VPhysicsUpdate( IPhysicsObject *pPhysics ) { if ( m_lastUpdateTickCount == (unsigned int)gpGlobals->tickcount ) return; m_lastUpdateTickCount = gpGlobals->tickcount; //NetworkStateChanged(); matrix3x4_t boneToWorld[MAXSTUDIOBONES]; QAngle angles; Vector surroundingMins, surroundingMaxs; if ( m_ragdoll.pGroup->IsInErrorState() ) { RagdollSolveSeparation( m_ragdoll, this ); } int i; for ( i = 0; i < m_ragdoll.listCount; i++ ) { CBoneAccessor boneaccessor( boneToWorld ); RagdollGetBoneMatrix( m_ragdoll, boneaccessor, i ); Vector vNewPos; MatrixAngles( boneToWorld[m_ragdoll.boneIndex[i]], angles, vNewPos ); m_ragPos.Set( i, vNewPos ); m_ragAngles.Set( i, angles ); } // BUGBUG: Use the ragdollmins/maxs to do this instead of the collides m_allAsleep = RagdollIsAsleep( m_ragdoll ); // Don't scream after you've come to rest if ( m_allAsleep ) { m_strSourceClassName = NULL_STRING; } // Interactive debris converts back to debris when it comes to rest if ( m_allAsleep && GetCollisionGroup() == COLLISION_GROUP_INTERACTIVE_DEBRIS ) { SetCollisionGroup( COLLISION_GROUP_DEBRIS ); RecheckCollisionFilter(); SetContextThink( NULL, gpGlobals->curtime, s_pDebrisContext ); } Vector vecFullMins, vecFullMaxs; vecFullMins = m_ragPos[0]; vecFullMaxs = m_ragPos[0]; for ( i = 0; i < m_ragdoll.listCount; i++ ) { Vector mins, maxs; matrix3x4_t update; m_ragdoll.list[i].pObject->GetPositionMatrix( &update ); TransformAABB( update, m_ragdollMins[i], m_ragdollMaxs[i], mins, maxs ); for ( int j = 0; j < 3; j++ ) { if ( mins[j] < vecFullMins[j] ) { vecFullMins[j] = mins[j]; } if ( maxs[j] > vecFullMaxs[j] ) { vecFullMaxs[j] = maxs[j]; } } } SetAbsOrigin( m_ragPos[0] ); SetAbsAngles( vec3_angle ); const Vector &vecOrigin = CollisionProp()->GetCollisionOrigin(); CollisionProp()->AddSolidFlags( FSOLID_FORCE_WORLD_ALIGNED ); CollisionProp()->SetSurroundingBoundsType( USE_COLLISION_BOUNDS_NEVER_VPHYSICS ); SetCollisionBounds( vecFullMins - vecOrigin, vecFullMaxs - vecOrigin ); CollisionProp()->MarkSurroundingBoundsDirty(); PhysicsTouchTriggers(); }