bool RagdollCreate( ragdoll_t &ragdoll, const ragdollparams_t ¶ms, IPhysicsEnvironment *pPhysEnv ) { RagdollCreateObjects( pPhysEnv, 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); // apply force to the model Vector nudgeForce = params.forceVector; Vector forcePosition = params.forcePosition; // UNDONE: Test scaling the force by total mass on all bones Assert( forceBone < ragdoll.listCount ); if ( forceBone >= 0 && forceBone < ragdoll.listCount ) { ragdoll.list[forceBone].pObject->ApplyForceCenter( nudgeForce ); //nudgeForce *= 0.5; ragdoll.list[forceBone].pObject->GetPosition( &forcePosition, NULL ); } for ( i = 0; i < ragdoll.listCount; i++ ) { PhysSetGameFlags( ragdoll.list[i].pObject, FVPHYSICS_PART_OF_RAGDOLL ); } if ( forcePosition != vec3_origin ) { for ( i = 0; i < ragdoll.listCount; i++ ) { if ( forceBone != i ) { float scale = ragdoll.list[i].pObject->GetMass() / totalMass; ragdoll.list[i].pObject->ApplyForceOffset( scale * nudgeForce, forcePosition ); } } } return true; }
bool RagdollCreate( ragdoll_t &ragdoll, const ragdollparams_t ¶ms, 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; }
bool RagdollCreate( ragdoll_t &ragdoll, const ragdollparams_t ¶ms, IPhysicsEnvironment *pPhysEnv ) { RagdollCreateObjects( pPhysEnv, 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); // apply force to the model Vector nudgeForce = params.forceVector; Vector forcePosition = params.forcePosition; // UNDONE: Test scaling the force by total mass on all bones // UNDONE: forcebone can be out of range when a body part breaks off - it uses the shared force bone from the original model // UNDONE: Remap this? if ( forceBone >= 0 && forceBone < ragdoll.listCount ) { ragdoll.list[forceBone].pObject->ApplyForceCenter( nudgeForce ); //nudgeForce *= 0.5; ragdoll.list[forceBone].pObject->GetPosition( &forcePosition, NULL ); } if ( forcePosition != vec3_origin ) { for ( i = 0; i < ragdoll.listCount; i++ ) { if ( forceBone != i ) { float scale = ragdoll.list[i].pObject->GetMass() / totalMass; ragdoll.list[i].pObject->ApplyForceOffset( scale * nudgeForce, forcePosition ); } } } return true; }