void CRagdollProp::SetupBones( matrix3x4_t *pBoneToWorld, int boneMask ) { studiohdr_t *pStudioHdr = GetModelPtr( ); bool sim[MAXSTUDIOBONES]; memset( sim, 0, pStudioHdr->numbones ); int i; for ( i = 0; i < m_ragdoll.listCount; i++ ) { if ( RagdollGetBoneMatrix( m_ragdoll, pBoneToWorld, i ) ) { sim[m_ragdoll.boneIndex[i]] = true; } } mstudiobone_t *pbones = pStudioHdr->pBone( 0 ); for ( i = 0; i < pStudioHdr->numbones; i++ ) { if ( sim[i] ) continue; MatrixCopy( pBoneToWorld[pbones[i].parent], pBoneToWorld[ i ] ); } }
void CRagdoll::RagdollBone( C_BaseEntity *ent, mstudiobone_t *pbones, int boneCount, bool *boneSimulated, CBoneAccessor &pBoneToWorld ) { for ( int i = 0; i < m_ragdoll.listCount; i++ ) { if ( RagdollGetBoneMatrix( m_ragdoll, pBoneToWorld, i ) ) { boneSimulated[m_ragdoll.boneIndex[i]] = true; } } }
void CRagdollProp::SetupBones( matrix3x4_t *pBoneToWorld, int boneMask ) { // no ragdoll, fall through to base class if ( !m_ragdoll.listCount ) { BaseClass::SetupBones( pBoneToWorld, boneMask ); return; } // Not really ideal, but it'll work for now UpdateModelWidthScale(); MDLCACHE_CRITICAL_SECTION(); CStudioHdr *pStudioHdr = GetModelPtr( ); bool sim[MAXSTUDIOBONES]; memset( sim, 0, pStudioHdr->numbones() ); int i; CBoneAccessor boneaccessor( pBoneToWorld ); for ( i = 0; i < m_ragdoll.listCount; i++ ) { // during restore this may be NULL if ( !m_ragdoll.list[i].pObject ) continue; if ( RagdollGetBoneMatrix( m_ragdoll, boneaccessor, i ) ) { sim[m_ragdoll.boneIndex[i]] = true; } } mstudiobone_t *pbones = pStudioHdr->pBone( 0 ); for ( i = 0; i < pStudioHdr->numbones(); i++ ) { if ( sim[i] ) continue; if ( !(pbones[i].flags & boneMask) ) continue; matrix3x4_t matBoneLocal; AngleMatrix( pbones[i].rot, pbones[i].pos, matBoneLocal ); ConcatTransforms( pBoneToWorld[pbones[i].parent], matBoneLocal, pBoneToWorld[i]); } }
void CRagdollProp::VPhysicsUpdate( IPhysicsObject *pPhysics ) { if ( m_lastUpdateTickCount == (unsigned int)gpGlobals->tickcount ) return; m_lastUpdateTickCount = gpGlobals->tickcount; NetworkStateChanged(); matrix3x4_t boneToWorld[MAXSTUDIOBONES]; QAngle angles; for ( int i = 0; i < m_ragdoll.listCount; i++ ) { RagdollGetBoneMatrix( m_ragdoll, boneToWorld, i ); Vector vNewPos; MatrixAngles( boneToWorld[m_ragdoll.boneIndex[i]], angles, vNewPos ); m_ragPos.Set( i, vNewPos ); m_ragAngles.Set( i, angles ); } m_allAsleep = RagdollIsAsleep( m_ragdoll ); SetAbsOrigin( m_ragPos[0] ); engine->RelinkEntity( pev, true ); }
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(); }