void CRagdoll::Init( C_BaseEntity *ent, CStudioHdr *pstudiohdr, const Vector &forceVector, int forceBone, const matrix3x4_t *pDeltaBones0, const matrix3x4_t *pDeltaBones1, const matrix3x4_t *pCurrentBonePosition, float dt, bool bFixedConstraints ) { ragdollparams_t params; params.pGameData = static_cast<void *>( ent ); params.modelIndex = ent->GetModelIndex(); params.pCollide = modelinfo->GetVCollide( params.modelIndex ); params.pStudioHdr = pstudiohdr; params.forceVector = forceVector; params.forceBoneIndex = forceBone; params.forcePosition.Init(); params.pCurrentBones = pCurrentBonePosition; params.jointFrictionScale = 1.0; params.allowStretch = false; params.fixedConstraints = bFixedConstraints; RagdollCreate( m_ragdoll, params, physenv ); ent->VPhysicsSetObject( NULL ); ent->VPhysicsSetObject( m_ragdoll.list[0].pObject ); // Mark the ragdoll as debris. //ent->SetCollisionGroup( COLLISION_GROUP_DEBRIS ); ent->SetCollisionGroup( COLLISION_GROUP_WEAPON ); RagdollApplyAnimationAsVelocity( m_ragdoll, pDeltaBones0, pDeltaBones1, dt ); RagdollActivate( m_ragdoll, params.pCollide, ent->GetModelIndex() ); // It's moving now... m_flLastOriginChangeTime = gpGlobals->curtime; // So traces hit it. ent->AddEFlags( EFL_USE_PARTITION_WHEN_NOT_SOLID ); if ( !m_ragdoll.listCount ) return; BuildRagdollBounds( ent ); for ( int i = 0; i < m_ragdoll.listCount; i++ ) { g_pPhysSaveRestoreManager->AssociateModel( m_ragdoll.list[i].pObject, ent->GetModelIndex() ); } #if RAGDOLL_VISUALIZE memcpy( m_savedBone1, &pDeltaBones0[0], sizeof(matrix3x4_t) * pstudiohdr->numbones() ); memcpy( m_savedBone2, &pDeltaBones1[0], sizeof(matrix3x4_t) * pstudiohdr->numbones() ); memcpy( m_savedBone3, &pCurrentBonePosition[0], sizeof(matrix3x4_t) * pstudiohdr->numbones() ); #endif }
void CRagdoll::Init( C_BaseEntity *ent, CStudioHdr *pstudiohdr, const Vector &forceVector, int forceBone, const CBoneAccessor &pPrevBones, const CBoneAccessor &pBoneToWorld, float dt ) { ragdollparams_t params; params.pGameData = static_cast<void *>( ent ); params.modelIndex = ent->GetModelIndex(); params.pCollide = modelinfo->GetVCollide( params.modelIndex ); params.pStudioHdr = pstudiohdr; params.forceVector = forceVector; params.forceBoneIndex = forceBone; params.forcePosition.Init(); params.pPrevBones = pPrevBones; params.pCurrentBones = pBoneToWorld; params.boneDt = dt; params.jointFrictionScale = 1.0; RagdollCreate( m_ragdoll, params, physenv ); RagdollActivate( m_ragdoll, params.pCollide, ent->GetModelIndex() ); // It's moving now... m_flLastOriginChangeTime = gpGlobals->curtime; // So traces hit it. ent->AddEFlags( EFL_USE_PARTITION_WHEN_NOT_SOLID ); if ( !m_ragdoll.listCount ) return; ent->VPhysicsSetObject( NULL ); ent->VPhysicsSetObject( m_ragdoll.list[0].pObject ); BuildRagdollBounds( ent ); for ( int i = 0; i < m_ragdoll.listCount; i++ ) { g_pPhysSaveRestoreManager->AssociateModel( m_ragdoll.list[i].pObject, ent->GetModelIndex() ); } #if RAGDOLL_VISUALIZE memcpy( m_savedBone1, &pPrevBones[0], sizeof(matrix3x4_t) * pstudiohdr->numbones() ); memcpy( m_savedBone2, &pBoneToWorld[0], sizeof(matrix3x4_t) * pstudiohdr->numbones() ); #endif }
void CRagdollProp::InitRagdoll( const Vector &forceVector, int forceBone, const Vector &forcePos, matrix3x4_t *pPrevBones, matrix3x4_t *pBoneToWorld, float dt, int collisionGroup, bool activateRagdoll ) { SetCollisionGroup( collisionGroup ); if ( collisionGroup == COLLISION_GROUP_INTERACTIVE_DEBRIS ) { SetThink( &CRagdollProp::SetDebrisThink ); SetNextThink( gpGlobals->curtime + 5 ); } SetMoveType( MOVETYPE_VPHYSICS ); SetSolid( SOLID_VPHYSICS ); AddSolidFlags( FSOLID_CUSTOMRAYTEST | FSOLID_CUSTOMBOXTEST ); m_takedamage = DAMAGE_EVENTS_ONLY; ragdollparams_t params; params.pGameData = static_cast<void *>( static_cast<CBaseEntity *>(this) ); params.pCollide = modelinfo->GetVCollide( GetModelIndex() ); params.pStudioHdr = GetModelPtr(); params.forceVector = forceVector; params.forceBoneIndex = forceBone; params.forcePosition = forcePos; params.pPrevBones = pPrevBones; params.pCurrentBones = pBoneToWorld; params.boneDt = dt; params.jointFrictionScale = 1.0; RagdollCreate( m_ragdoll, params, physcollision, physenv, physprops ); if ( activateRagdoll ) { RagdollActivate( m_ragdoll ); } for ( int i = 0; i < m_ragdoll.listCount; i++ ) { UpdateNetworkDataFromVPhysics( m_ragdoll.list[i].pObject, i ); } VPhysicsSetObject( m_ragdoll.list[0].pObject ); CalcRagdollSize(); }
void CRagdollProp::InitRagdoll( const Vector &forceVector, int forceBone, const Vector &forcePos, matrix3x4_t *pPrevBones, matrix3x4_t *pBoneToWorld, float dt, int collisionGroup, bool activateRagdoll ) { SetCollisionGroup( collisionGroup ); // Make sure it's interactive debris for at most 5 seconds if ( collisionGroup == COLLISION_GROUP_INTERACTIVE_DEBRIS ) { SetContextThink( &CRagdollProp::SetDebrisThink, gpGlobals->curtime + 5, s_pDebrisContext ); } SetMoveType( MOVETYPE_VPHYSICS ); SetSolid( SOLID_VPHYSICS ); AddSolidFlags( FSOLID_CUSTOMRAYTEST | FSOLID_CUSTOMBOXTEST ); m_takedamage = DAMAGE_EVENTS_ONLY; ragdollparams_t params; params.pGameData = static_cast<void *>( static_cast<CBaseEntity *>(this) ); params.modelIndex = GetModelIndex(); params.pCollide = modelinfo->GetVCollide( params.modelIndex ); params.pStudioHdr = GetModelPtr(); params.forceVector = forceVector; params.forceBoneIndex = forceBone; params.forcePosition = forcePos; params.pPrevBones = pPrevBones; params.pCurrentBones = pBoneToWorld; params.boneDt = dt; params.jointFrictionScale = 1.0; RagdollCreate( m_ragdoll, params, physenv ); if ( m_anglesOverrideString != NULL_STRING && Q_strlen(m_anglesOverrideString.ToCStr()) > 0 ) { char szToken[2048]; const char *pStr = nexttoken(szToken, STRING(m_anglesOverrideString), ','); // anglesOverride is index,angles,index,angles (e.g. "1, 22.5 123.0 0.0, 2, 0 0 0, 3, 0 0 180.0") while ( szToken[0] != 0 ) { int objectIndex = atoi(szToken); // sanity check to make sure this token is an integer Assert( atof(szToken) == ((float)objectIndex) ); pStr = nexttoken(szToken, pStr, ','); Assert( szToken[0] ); if ( objectIndex >= m_ragdoll.listCount ) { Warning("Bad ragdoll pose in entity %s, model (%s) at %s, model changed?\n", GetDebugName(), GetModelName().ToCStr(), VecToString(GetAbsOrigin()) ); } else if ( szToken[0] != 0 ) { QAngle angles; Assert( objectIndex >= 0 && objectIndex < RAGDOLL_MAX_ELEMENTS ); UTIL_StringToVector( angles.Base(), szToken ); int boneIndex = m_ragdoll.boneIndex[objectIndex]; AngleMatrix( angles, pBoneToWorld[boneIndex] ); const ragdollelement_t &element = m_ragdoll.list[objectIndex]; Vector out; if ( element.parentIndex >= 0 ) { int parentBoneIndex = m_ragdoll.boneIndex[element.parentIndex]; VectorTransform( element.originParentSpace, pBoneToWorld[parentBoneIndex], out ); } else { out = GetAbsOrigin(); } MatrixSetColumn( out, 3, pBoneToWorld[boneIndex] ); element.pObject->SetPositionMatrix( pBoneToWorld[boneIndex], true ); } pStr = nexttoken(szToken, pStr, ','); } } if ( activateRagdoll ) { MEM_ALLOC_CREDIT(); RagdollActivate( m_ragdoll, params.pCollide, GetModelIndex() ); } for ( int i = 0; i < m_ragdoll.listCount; i++ ) { UpdateNetworkDataFromVPhysics( m_ragdoll.list[i].pObject, i ); g_pPhysSaveRestoreManager->AssociateModel( m_ragdoll.list[i].pObject, GetModelIndex() ); physcollision->CollideGetAABB( m_ragdollMins[i], m_ragdollMaxs[i], m_ragdoll.list[i].pObject->GetCollide(), vec3_origin, vec3_angle ); } VPhysicsSetObject( m_ragdoll.list[0].pObject ); CalcRagdollSize(); }