//----------------------------------------------------------------------------- // Purpose: // Input : &follow - // *pBoneName - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CBoneFollowerManager::CreatePhysicsFollower( physfollower_t &follow, const char *pBoneName ) { studiohdr_t *pStudioHdr = m_hOuter->GetModelPtr(); matrix3x4_t boneToWorld; solid_t solid; Vector bonePosition; QAngle boneAngles; int boneIndex = Studio_BoneIndexByName( pStudioHdr, pBoneName ); if ( boneIndex >= 0 ) { mstudiobone_t *pBone = pStudioHdr->pBone( boneIndex ); int physicsBone = pBone->physicsbone; if ( !PhysModelParseSolidByIndex( solid, m_hOuter, m_hOuter->GetModelIndex(), physicsBone ) ) return false; // fixup in case ragdoll is assigned to a parent of the requested follower bone follow.boneIndex = Studio_BoneIndexByName( pStudioHdr, solid.name ); m_hOuter->GetBoneTransform( follow.boneIndex, boneToWorld ); MatrixAngles( boneToWorld, boneAngles, bonePosition ); follow.hFollower = CBoneFollower::Create( m_hOuter, STRING(m_hOuter->GetModelName()), solid, bonePosition, boneAngles ); } return false; }
//----------------------------------------------------------------------------- // Purpose: // Input : *pEntity - // modelIndex - // &origin - // &angles - // *pSolid - // Output : IPhysicsObject //----------------------------------------------------------------------------- IPhysicsObject *PhysModelCreate( CBaseEntity *pEntity, int modelIndex, const Vector &origin, const QAngle &angles, solid_t *pSolid ) { vcollide_t *pCollide = modelinfo->GetVCollide( modelIndex ); if ( !pCollide || !pCollide->solidCount ) return NULL; solid_t tmpSolid; if ( !pSolid ) { pSolid = &tmpSolid; if ( !PhysModelParseSolidByIndex( tmpSolid, pEntity, pCollide, -1 ) ) return NULL; } int surfaceProp = -1; if ( pSolid->surfaceprop[0] ) { surfaceProp = physprops->GetSurfaceIndex( pSolid->surfaceprop ); } IPhysicsObject *pObject = physenv->CreatePolyObject( pCollide->solids[pSolid->index], surfaceProp, origin, angles, &pSolid->params ); //PhysCheckAdd( pObject, STRING(pEntity->m_iClassname) ); if ( pObject ) { if ( modelinfo->GetModelType(modelinfo->GetModel(modelIndex)) == mod_brush ) { unsigned int contents = modelinfo->GetModelContents( modelIndex ); Assert(contents!=0); // HACKHACK: contents is used to filter collisions // HACKHACK: So keep solid on for water brushes since they should pass collision rules (as triggers) if ( contents & MASK_WATER ) { contents |= CONTENTS_SOLID; } if ( contents != pObject->GetContents() && contents != 0 ) { pObject->SetContents( contents ); pObject->RecheckCollisionFilter(); } } g_pPhysSaveRestoreManager->AssociateModel( pObject, modelIndex); } return pObject; }
//----------------------------------------------------------------------------- // Purpose: // Input : &follow - // *pBoneName - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CBoneFollowerManager::CreatePhysicsFollower( CBaseAnimating *pParentEntity, physfollower_t &follow, const char *pBoneName, solid_t *pSolid ) { CStudioHdr *pStudioHdr = pParentEntity->GetModelPtr(); matrix3x4_t boneToWorld; solid_t solidTmp; Vector bonePosition; QAngle boneAngles; int boneIndex = Studio_BoneIndexByName( pStudioHdr, pBoneName ); if ( boneIndex >= 0 ) { mstudiobone_t *pBone = pStudioHdr->pBone( boneIndex ); int physicsBone = pBone->physicsbone; if ( !pSolid ) { if ( !PhysModelParseSolidByIndex( solidTmp, pParentEntity, pParentEntity->GetModelIndex(), physicsBone ) ) return false; pSolid = &solidTmp; } // fixup in case ragdoll is assigned to a parent of the requested follower bone follow.boneIndex = Studio_BoneIndexByName( pStudioHdr, pSolid->name ); if ( follow.boneIndex < 0 ) { follow.boneIndex = boneIndex; } pParentEntity->GetBoneTransform( follow.boneIndex, boneToWorld ); MatrixAngles( boneToWorld, boneAngles, bonePosition ); follow.hFollower = CBoneFollower::Create( pParentEntity, STRING(pParentEntity->GetModelName()), *pSolid, bonePosition, boneAngles ); follow.hFollower->SetTraceData( physicsBone, HitGroupFromPhysicsBone( pParentEntity, physicsBone ) ); follow.hFollower->SetBlocksLOS( pParentEntity->BlocksLOS() ); return true; } else { Warning( "ERROR: Tried to create bone follower on invalid bone %s\n", pBoneName ); } return false; }
//----------------------------------------------------------------------------- // Purpose: // Input : *pEntity - // modelIndex - // &origin - // &angles - // Output : IPhysicsObject //----------------------------------------------------------------------------- IPhysicsObject *PhysModelCreateUnmoveable( CBaseEntity *pEntity, int modelIndex, const Vector &origin, const QAngle &angles ) { vcollide_t *pCollide = modelinfo->GetVCollide( modelIndex ); if ( !pCollide || !pCollide->solidCount ) return NULL; solid_t solid; if ( !PhysModelParseSolidByIndex( solid, pEntity, pCollide, -1 ) ) return NULL; // collisions are off by default solid.params.enableCollisions = true; //solid.params.mass = 1.0; int surfaceProp = -1; if ( solid.surfaceprop[0] ) { surfaceProp = physprops->GetSurfaceIndex( solid.surfaceprop ); } solid.params.pGameData = static_cast<void *>(pEntity); solid.params.pName = STRING(pEntity->GetModelName()); IPhysicsObject *pObject = physenv->CreatePolyObjectStatic( pCollide->solids[0], surfaceProp, origin, angles, &solid.params ); //PhysCheckAdd( pObject, STRING(pEntity->m_iClassname) ); if ( pObject ) { if ( modelinfo->GetModelType(modelinfo->GetModel(modelIndex)) == mod_brush ) { unsigned int contents = modelinfo->GetModelContents( modelIndex ); Assert(contents!=0); if ( contents != pObject->GetContents() && contents != 0 ) { pObject->SetContents( contents ); pObject->RecheckCollisionFilter(); } } g_pPhysSaveRestoreManager->AssociateModel( pObject, modelIndex); } return pObject; }
//----------------------------------------------------------------------------- // Purpose: // Input : &solid - // *pEntity - // modelIndex - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool PhysModelParseSolid( solid_t &solid, CBaseEntity *pEntity, int modelIndex ) { return PhysModelParseSolidByIndex( solid, pEntity, modelIndex, -1 ); }