//----------------------------------------------------------------------------- // Purpose: // Input : *pEntity - // &mins - // &maxs - // &origin - // isStatic - // Output : static IPhysicsObject //----------------------------------------------------------------------------- IPhysicsObject *PhysModelCreateOBB( CBaseEntity *pEntity, const Vector &mins, const Vector &maxs, const Vector &origin, const QAngle &angle, bool isStatic ) { int modelIndex = pEntity->GetModelIndex(); const char *pSurfaceProps = "flesh"; solid_t solid; PhysGetDefaultAABBSolid( solid ); Vector dims = maxs - mins; solid.params.volume = dims.x * dims.y * dims.z; if ( modelIndex ) { const model_t *model = modelinfo->GetModel( modelIndex ); if ( model ) { CStudioHdr studioHdr( modelinfo->GetStudiomodel( model ), mdlcache ); if (studioHdr.IsValid()) { pSurfaceProps = Studio_GetDefaultSurfaceProps( &studioHdr ); } } } Q_strncpy( solid.surfaceprop, pSurfaceProps, sizeof( solid.surfaceprop ) ); CPhysCollide *pCollide = PhysCreateBbox( mins, maxs ); if ( !pCollide ) return NULL; return PhysModelCreateCustom( pEntity, pCollide, origin, angle, STRING(pEntity->GetModelName()), isStatic, &solid ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CPlayerClass::InitVCollision( void ) { CPhysCollide *pStandModel = PhysCreateBbox( PLAYERCLASS_HULL_STAND_MIN, PLAYERCLASS_HULL_STAND_MAX ); CPhysCollide *pCrouchModel = PhysCreateBbox( PLAYERCLASS_HULL_DUCK_MIN, PLAYERCLASS_HULL_DUCK_MAX ); solid_t solid; solid.params = g_PhysDefaultObjectParams; solid.params.mass = 85.0f; solid.params.inertia = 1e24f; solid.params.enableCollisions = false; //disable drag solid.params.dragCoefficient = 0; // create standing hull m_pPlayer->m_pShadowStand = PhysModelCreateCustom( m_pPlayer, pStandModel, m_pPlayer->GetLocalOrigin(), m_pPlayer->GetLocalAngles(), "tfplayer_generic", false, &solid ); m_pPlayer->m_pShadowStand->SetCallbackFlags( CALLBACK_SHADOW_COLLISION ); // create crouchig hull m_pPlayer->m_pShadowCrouch = PhysModelCreateCustom( m_pPlayer, pCrouchModel, m_pPlayer->GetLocalOrigin(), m_pPlayer->GetLocalAngles(), "tfplayer_generic", false, &solid ); m_pPlayer->m_pShadowCrouch->SetCallbackFlags( CALLBACK_SHADOW_COLLISION ); // default to stand m_pPlayer->VPhysicsSetObject( m_pPlayer->m_pShadowStand ); //disable drag m_pPlayer->m_pShadowStand->EnableDrag( false ); m_pPlayer->m_pShadowCrouch->EnableDrag( false ); // tell physics lists I'm a shadow controller object PhysAddShadow( m_pPlayer ); m_pPlayer->m_pPhysicsController = physenv->CreatePlayerController( m_pPlayer->m_pShadowStand ); // init state if ( m_pPlayer->GetFlags() & FL_DUCKING ) { m_pPlayer->SetVCollisionState( VPHYS_CROUCH ); } else { m_pPlayer->SetVCollisionState( VPHYS_WALK ); } }
// This creates a vphysics object with a shadow controller that follows the AI IPhysicsObject *C_RagdollShadow::VPhysicsInitShadow( bool allowPhysicsMovement, bool allowPhysicsRotation ) { studiohdr_t *hdr = GetModelPtr(); if ( !hdr ) { return NULL; } // If this entity already has a physics object, then it should have been deleted prior to making this call. Assert(!m_pPhysicsObject); // make sure m_vecOrigin / m_vecAngles are correct const Vector &origin = GetAbsOrigin(); QAngle angles = GetAbsAngles(); IPhysicsObject *pPhysicsObject = NULL; if ( GetSolid() == SOLID_BBOX ) { const char *pSurfaceProps = "flesh"; if ( GetModelIndex() && modelinfo->GetModelType( GetModel() ) == mod_studio ) { pSurfaceProps = Studio_GetDefaultSurfaceProps( hdr ); } angles = vec3_angle; CPhysCollide *pCollide = PhysCreateBbox( WorldAlignMins(), WorldAlignMaxs() ); if ( !pCollide ) return NULL; pPhysicsObject = PhysModelCreateCustom( this, pCollide, origin, angles, pSurfaceProps ); } else { pPhysicsObject = PhysModelCreateRagdoll( this, GetModelIndex(), origin, angles ); } VPhysicsSetObject( pPhysicsObject ); pPhysicsObject->SetShadow( Vector(1e4,1e4,1e4), AngularImpulse(1e4,1e4,1e4), allowPhysicsMovement, allowPhysicsRotation ); pPhysicsObject->UpdateShadow( GetAbsOrigin(), GetAbsAngles(), false, 0 ); // PhysAddShadow( this ); return pPhysicsObject; }
void RestorePhysicsObjectAndModel( IRestore *pRestore, const PhysObjectHeader_t &header, CPhysSaveRestoreBlockHandler::QueuedItem_t *pItem, int nObjects ) { if ( nObjects == 1 ) { pRestore->StartBlock(); CPhysCollide *pPhysCollide = NULL; int modelIndex = -1; bool fCustomCollide = false; if ( header.modelName != NULL_STRING ) { CBaseEntity *pGlobalEntity = header.hEntity; #if !defined( CLIENT_DLL ) if ( NULL_STRING != pGlobalEntity->m_iGlobalname ) { modelIndex = pGlobalEntity->GetModelIndex(); } else #endif { modelIndex = modelinfo->GetModelIndex( STRING( header.modelName ) ); pGlobalEntity = NULL; } if ( modelIndex != -1 ) { vcollide_t *pCollide = modelinfo->GetVCollide( modelIndex ); if ( pCollide ) { if ( pCollide->solidCount > 0 && pCollide->solids && header.iCollide < pCollide->solidCount ) pPhysCollide = pCollide->solids[header.iCollide]; } } } else if ( header.bbox.mins != vec3_origin || header.bbox.maxs != vec3_origin ) { pPhysCollide = PhysCreateBbox( header.bbox.mins, header.bbox.maxs ); fCustomCollide = true; } else if ( header.sphere.radius != 0 ) { // HACKHACK: Handle spheres here!!! if ( !(*pItem->ppPhysObj) ) { RestorePhysicsObject( pRestore, header, pItem->ppPhysObj, NULL ); } return; } if ( pPhysCollide ) { if ( !(*pItem->ppPhysObj) ) { RestorePhysicsObject( pRestore, header, pItem->ppPhysObj, pPhysCollide ); if ( (*pItem->ppPhysObj) ) { IPhysicsObject *pObject = (IPhysicsObject *)(*pItem->ppPhysObj); if ( !fCustomCollide ) { AssociateModel( pObject, modelIndex ); } else { AssociateModel( pObject, pPhysCollide ); } } else DevMsg( "Failed to restore physics object\n" ); } else DevMsg( "Physics object pointer unexpectedly non-null before restore. Should be creating physics object in CreatePhysics()?\n" ); } else DevMsg( "Failed to reestablish collision model for object\n" ); pRestore->EndBlock(); } else DevMsg( "Don't know how to reconsitite models for physobj array \n" ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CPlayerClassCommando::InitVCollision( void ) { CPhysCollide *pStandModel = PhysCreateBbox( COMMANDOCLASS_HULL_STAND_MIN, COMMANDOCLASS_HULL_STAND_MAX ); CPhysCollide *pCrouchModel = PhysCreateBbox( COMMANDOCLASS_HULL_DUCK_MIN, COMMANDOCLASS_HULL_DUCK_MAX ); m_pPlayer->SetupVPhysicsShadow( pStandModel, "tfplayer_commando_stand", pCrouchModel, "tfplayer_commando_crouch" ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CPlayerClassDefender::InitVCollision( void ) { CPhysCollide *pStandModel = PhysCreateBbox( DEFENDERCLASS_HULL_STAND_MIN, DEFENDERCLASS_HULL_STAND_MAX ); CPhysCollide *pCrouchModel = PhysCreateBbox( DEFENDERCLASS_HULL_DUCK_MIN, DEFENDERCLASS_HULL_DUCK_MAX ); m_pPlayer->SetupVPhysicsShadow( pStandModel, "tfplayer_defender_stand", pCrouchModel, "tfplayer_defender_crouch" ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CPlayerClassPyro::InitVCollision() { CPhysCollide *pStandModel = PhysCreateBbox( PYROCLASS_HULL_STAND_MIN, PYROCLASS_HULL_STAND_MAX ); CPhysCollide *pCrouchModel = PhysCreateBbox( PYROCLASS_HULL_DUCK_MIN, PYROCLASS_HULL_DUCK_MAX ); m_pPlayer->SetupVPhysicsShadow( pStandModel, "tfplayer_medic_stand", pCrouchModel, "tfplayer_medic_crouch" ); }