//----------------------------------------------------------------------------- // 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 ); }
// 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; }
//----------------------------------------------------------------------------- // Purpose: // Input : *pEntity - // &mins - // &maxs - // &origin - // isStatic - // Output : static IPhysicsObject //----------------------------------------------------------------------------- IPhysicsObject *PhysModelCreateSphere( CBaseEntity *pEntity, float radius, const Vector &origin, bool isStatic ) { int modelIndex = pEntity->GetModelIndex(); const char *pSurfaceProps = "flesh"; solid_t solid; //PhysGetDefaultAABBSolid( solid ); solid.params = g_PhysDefaultObjectParams; 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 ) ); return PhysSphereCreate( pEntity, radius, origin, isStatic, solid ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CPhysMagnet::Touch( CBaseEntity *pOther ) { // Ignore triggers if ( pOther->IsSolidFlagSet( FSOLID_NOT_SOLID ) ) return; m_bHasHitSomething = true; // Don't pickup if we're not active if ( !m_bActive ) return; // Hit our maximum? if ( m_iMaxObjectsAttached && m_iMaxObjectsAttached <= GetNumAttachedObjects() ) return; // Make sure it's made of metal trace_t tr = GetTouchTrace(); char cTexType = TEXTURETYPE_Find( &tr ); if ( cTexType != CHAR_TEX_METAL && cTexType != CHAR_TEX_COMPUTER ) { // See if the model is set to be metal if ( Q_strncmp( Studio_GetDefaultSurfaceProps( GetModelPtr() ), "metal", 5 ) ) return; } IPhysicsObject *pPhysics = pOther->VPhysicsGetObject(); if ( pPhysics && pOther->GetMoveType() == MOVETYPE_VPHYSICS && pPhysics->IsMoveable() ) { // Make sure we haven't already got this sucker on the magnet int iCount = m_MagnettedEntities.Count(); for ( int i = 0; i < iCount; i++ ) { if ( m_MagnettedEntities[i].hEntity == pOther ) return; } // We want to cast a long way to ensure our shadow shows up pOther->SetShadowCastDistance( 2048 ); // Create a constraint between the magnet and this sucker IPhysicsObject *pMagnetPhysObject = VPhysicsGetObject(); Assert( pMagnetPhysObject ); magnetted_objects_t newEntityOnMagnet; newEntityOnMagnet.hEntity = pOther; // Use the right constraint if ( HasSpawnFlags( SF_MAGNET_ALLOWROTATION ) ) { constraint_ballsocketparams_t ballsocket; ballsocket.Defaults(); ballsocket.constraint.Defaults(); ballsocket.constraint.forceLimit = lbs2kg(m_forceLimit); ballsocket.constraint.torqueLimit = lbs2kg(m_torqueLimit); pMagnetPhysObject->WorldToLocal( ballsocket.constraintPosition[0], tr.endpos ); pPhysics->WorldToLocal( ballsocket.constraintPosition[1], tr.endpos ); //newEntityOnMagnet.pConstraint = physenv->CreateBallsocketConstraint( pMagnetPhysObject, pPhysics, m_pConstraintGroup, ballsocket ); newEntityOnMagnet.pConstraint = physenv->CreateBallsocketConstraint( pMagnetPhysObject, pPhysics, NULL, ballsocket ); } else { constraint_fixedparams_t fixed; fixed.Defaults(); fixed.InitWithCurrentObjectState( pMagnetPhysObject, pPhysics ); fixed.constraint.Defaults(); fixed.constraint.forceLimit = lbs2kg(m_forceLimit); fixed.constraint.torqueLimit = lbs2kg(m_torqueLimit); // FIXME: Use the magnet's constraint group. //newEntityOnMagnet.pConstraint = physenv->CreateFixedConstraint( pMagnetPhysObject, pPhysics, m_pConstraintGroup, fixed ); newEntityOnMagnet.pConstraint = physenv->CreateFixedConstraint( pMagnetPhysObject, pPhysics, NULL, fixed ); } newEntityOnMagnet.pConstraint->SetGameData( (void *) this ); m_MagnettedEntities.AddToTail( newEntityOnMagnet ); m_flTotalMass += pPhysics->GetMass(); } DoMagnetSuck( pOther ); m_OnMagnetAttach.FireOutput( this, this ); }