Example #1
0
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
}
bool RagdollCreate( ragdoll_t &ragdoll, const ragdollparams_t &params, IPhysicsCollision *pPhysCollision, IPhysicsEnvironment *pPhysEnv, IPhysicsSurfaceProps *pSurfaceDatabase )
{
	RagdollCreateObjects( pPhysCollision, pPhysEnv, pSurfaceDatabase, ragdoll, params );

	if ( !ragdoll.listCount )
		return false;

	int forceBone = params.forceBoneIndex;
	
	int i;
	float totalMass = 0;
	for ( i = 0; i < ragdoll.listCount; i++ )
	{
		totalMass += ragdoll.list[i].pObject->GetMass();
	}
	totalMass = max(totalMass,1);

	// distribute half to the forced bone, half to the rest of the model
	Vector nudgeForce = params.forceVector;
	if ( forceBone >= 0 && forceBone <= ragdoll.listCount )
	{
		nudgeForce *= 0.5;
		ragdoll.list[forceBone].pObject->ApplyForceCenter( nudgeForce );
	}
	else if ( params.forcePosition != vec3_origin )
	{
		for ( i = 0; i < ragdoll.listCount; i++ )
		{
			float scale = ragdoll.list[i].pObject->GetMass() / totalMass;
			ragdoll.list[i].pObject->ApplyForceOffset( scale * nudgeForce, params.forcePosition );
		}
		nudgeForce.Init();
	}

	RagdollApplyAnimationAsVelocity( ragdoll, params.pPrevBones, params.pCurrentBones, params.boneDt );

	for ( i = 0; i < ragdoll.listCount; i++ )
	{
		float scale = ragdoll.list[i].pObject->GetMass() / totalMass;
		ragdoll.list[i].pObject->ApplyForceCenter( scale * nudgeForce );
		PhysSetGameFlags( ragdoll.list[i].pObject, FVPHYSICS_PART_OF_RAGDOLL );
	}
	return true;
}