// OPTIMIZE: Slow, hopefully this is only called by save/load void RagdollSetupAnimatedFriction( IPhysicsEnvironment *pPhysEnv, ragdoll_t *ragdoll, int iModelIndex ) { vcollide_t* pCollide = modelinfo->GetVCollide( iModelIndex ); if ( pCollide ) { IVPhysicsKeyParser *pParse = physcollision->VPhysicsKeyParserCreate( pCollide ); while ( !pParse->Finished() ) { const char *pBlock = pParse->GetCurrentBlockName(); if ( !strcmpi( pBlock, "animatedfriction") ) { pParse->ParseRagdollAnimatedFriction( &ragdoll->animfriction, NULL ); } else { pParse->SkipBlock(); } } physcollision->VPhysicsKeyParserDestroy( pParse ); } }
static cache_ragdoll_t *ParseRagdollIntoCache( CStudioHdr *pStudioHdr, vcollide_t *pCollide, int modelIndex ) { IVPhysicsKeyParser *pParse = physcollision->VPhysicsKeyParserCreate( pCollide ); cache_ragdollsolid_t solidList[RAGDOLL_MAX_ELEMENTS]; cache_ragdollconstraint_t constraintList[RAGDOLL_MAX_ELEMENTS]; solid_t solid; int constraintCount = 0; int solidCount = 0; cache_ragdoll_t cache; V_memset( &cache, 0, sizeof(cache) ); while ( !pParse->Finished() ) { const char *pBlock = pParse->GetCurrentBlockName(); if ( !strcmpi( pBlock, "solid" ) ) { pParse->ParseSolid( &solid, &g_SolidSetup ); cache_ragdollsolid_t *pSolid = &solidList[solidCount]; pSolid->boneIndex = Studio_BoneIndexByName( pStudioHdr, solid.name ); if ( pSolid->boneIndex >= 0 ) { pSolid->collideIndex = solid.index; pSolid->surfacePropIndex = physprops->GetSurfaceIndex( solid.surfaceprop ); if ( pSolid->surfacePropIndex < 0 ) { pSolid->surfacePropIndex = physprops->GetSurfaceIndex( "default" ); } pSolid->params = solid.params; pSolid->params.enableCollisions = false; solidCount++; } else { Msg( "ParseRagdollIntoCache: Couldn't Lookup Bone %s\n", solid.name ); } } else if ( !strcmpi( pBlock, "ragdollconstraint" ) ) { constraint_ragdollparams_t constraint; pParse->ParseRagdollConstraint( &constraint, NULL ); if( constraint.childIndex != constraint.parentIndex && constraint.childIndex >= 0 && constraint.parentIndex >= 0) { cache_ragdollconstraint_t *pOut = &constraintList[constraintCount]; constraintCount++; V_memcpy( pOut->axes, constraint.axes, sizeof(constraint.axes) ); pOut->parentIndex = constraint.parentIndex; pOut->childIndex = constraint.childIndex; Studio_CalcBoneToBoneTransform( pStudioHdr, solidList[constraint.childIndex].boneIndex, solidList[constraint.parentIndex].boneIndex, pOut->constraintToAttached ); } } else if ( !strcmpi( pBlock, "collisionrules" ) ) { ragdollcollisionrules_t rules; IPhysicsCollisionSet *pSet = physics->FindOrCreateCollisionSet( modelIndex, pCollide->solidCount ); rules.Defaults(physics, pSet); pParse->ParseCollisionRules( &rules, NULL ); cache.pCollisionSet = rules.pCollisionSet; } else if ( !strcmpi( pBlock, "animatedfriction") ) { pParse->ParseRagdollAnimatedFriction( &cache.animfriction, NULL ); } else { pParse->SkipBlock(); } } physcollision->VPhysicsKeyParserDestroy( pParse ); cache.solidCount = solidCount; cache.constraintCount = constraintCount; return CreateRagdollCache( pCollide, solidList, constraintList, &cache ); }