本文整理汇总了C++中IPhysicsObject::ApplyForceCenter方法的典型用法代码示例。如果您正苦于以下问题:C++ IPhysicsObject::ApplyForceCenter方法的具体用法?C++ IPhysicsObject::ApplyForceCenter怎么用?C++ IPhysicsObject::ApplyForceCenter使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类IPhysicsObject
的用法示例。
在下文中一共展示了IPhysicsObject::ApplyForceCenter方法的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: CavernBounceThink
//---------------------------------------------------------
// A different bounce behavior for the citizen-modified mine. Detonates at the top of its apex,
// and does not attempt to track enemies.
//---------------------------------------------------------
void CBounceBomb::CavernBounceThink()
{
SetNextThink( gpGlobals->curtime + 0.1 );
StudioFrameAdvance();
IPhysicsObject *pPhysicsObject = VPhysicsGetObject();
if ( pPhysicsObject != NULL )
{
const float MINE_MAX_JUMP_HEIGHT = 78;
// Figure out how much headroom the mine has, and hop to within a few inches of that.
trace_t tr;
UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + Vector( 0, 0, MINE_MAX_JUMP_HEIGHT ), MASK_SHOT, this, COLLISION_GROUP_INTERACTIVE, &tr );
float height;
if( tr.m_pEnt && tr.m_pEnt->VPhysicsGetObject() )
{
// Physics object resting on me. Jump as hard as allowed to try to knock it away.
height = MINE_MAX_JUMP_HEIGHT;
}
else
{
height = tr.endpos.z - GetAbsOrigin().z;
height -= BOUNCEBOMB_RADIUS;
if ( height < 0.1 )
height = 0.1;
}
float time = sqrt( height / (0.5 * sv_gravity.GetFloat()) );
float velocity = sv_gravity.GetFloat() * time;
// or you can just AddVelocity to the object instead of ApplyForce
float force = velocity * pPhysicsObject->GetMass();
Vector up;
GetVectors( NULL, NULL, &up );
pPhysicsObject->Wake();
pPhysicsObject->ApplyForceCenter( up * force );
if( m_hNearestNPC )
{
Vector vecPredict = m_hNearestNPC->GetSmoothedVelocity();
pPhysicsObject->ApplyForceCenter( vecPredict * (pPhysicsObject->GetMass() * 0.65f) );
}
pPhysicsObject->ApplyTorqueCenter( AngularImpulse( random->RandomFloat( 15, 40 ), random->RandomFloat( 15, 40 ), random->RandomFloat( 30, 60 ) ) );
EmitSound( "NPC_CombineMine.Hop" );
SetThink( &CBounceBomb::ExplodeThink );
SetNextThink( gpGlobals->curtime + 0.33f );
}
}
示例2: VPhysicsGetObject
void C_HL2MPRagdoll::ImpactTrace( trace_t *pTrace, int iDamageType, char *pCustomImpactName )
{
IPhysicsObject *pPhysicsObject = VPhysicsGetObject();
if( !pPhysicsObject )
return;
Vector dir = pTrace->endpos - pTrace->startpos;
if ( iDamageType == DMG_BLAST )
{
dir *= 4000; // adjust impact strenght
// apply force at object mass center
pPhysicsObject->ApplyForceCenter( dir );
}
else
{
Vector hitpos;
VectorMA( pTrace->startpos, pTrace->fraction, dir, hitpos );
VectorNormalize( dir );
dir *= 4000; // adjust impact strenght
// apply force where we hit it
pPhysicsObject->ApplyForceOffset( dir, hitpos );
// Blood spray!
// FX_CS_BloodSpray( hitpos, dir, 10 );
}
m_pRagdoll->ResetRagdollSleepAfterTime();
}
示例3: TestForCollisionsAgainstWorld
void CEnvHeadcrabCanister::TestForCollisionsAgainstWorld( const Vector &vecEndPosition )
{
// Splash damage!
// Iterate on all entities in the vicinity.
float flDamageRadius = m_flDamageRadius;
float flDamage = m_flDamage;
CBaseEntity *pEntity;
for ( CEntitySphereQuery sphere( vecEndPosition, flDamageRadius ); ( pEntity = sphere.GetCurrentEntity() ) != NULL; sphere.NextEntity() )
{
if ( pEntity == this )
continue;
if ( !pEntity->IsSolid() )
continue;
// Get distance to object and use it as a scale value.
Vector vecSegment;
VectorSubtract( pEntity->GetAbsOrigin(), vecEndPosition, vecSegment );
float flDistance = VectorNormalize( vecSegment );
float flFactor = 1.0f / ( flDamageRadius * (INNER_RADIUS_FRACTION - 1) );
flFactor *= flFactor;
float flScale = flDistance - flDamageRadius;
flScale *= flScale * flFactor;
if ( flScale > 1.0f )
{
flScale = 1.0f;
}
// Check for a physics object and apply force!
Vector vecForceDir = vecSegment;
IPhysicsObject *pPhysObject = pEntity->VPhysicsGetObject();
if ( pPhysObject )
{
// Send it flying!!!
float flMass = PhysGetEntityMass( pEntity );
vecForceDir *= flMass * 750 * flScale;
pPhysObject->ApplyForceCenter( vecForceDir );
}
if ( pEntity->m_takedamage && ( m_flDamage != 0.0f ) )
{
CTakeDamageInfo info( this, this, flDamage * flScale, DMG_BLAST );
CalculateExplosiveDamageForce( &info, vecSegment, pEntity->GetAbsOrigin() );
pEntity->TakeDamage( info );
}
if ( pEntity->IsPlayer() && !(static_cast<CBasePlayer*>(pEntity)->IsInAVehicle()) )
{
if (vecSegment.z < 0.1f)
{
vecSegment.z = 0.1f;
VectorNormalize( vecSegment );
}
float flAmount = SimpleSplineRemapVal( flScale, 0.0f, 1.0f, 250.0f, 1000.0f );
pEntity->ApplyAbsVelocityImpulse( vecSegment * flAmount );
}
}
}
示例4: DropGrenade
void CNPC_Zombine::DropGrenade( Vector vDir )
{
if ( m_hGrenade == NULL )
return;
m_hGrenade->SetParent( NULL );
m_hGrenade->SetOwnerEntity( NULL );
Vector vGunPos;
QAngle angles;
GetAttachment( "grenade_attachment", vGunPos, angles );
IPhysicsObject *pPhysObj = m_hGrenade->VPhysicsGetObject();
if ( pPhysObj == NULL )
{
m_hGrenade->SetMoveType( MOVETYPE_VPHYSICS );
m_hGrenade->SetSolid( SOLID_VPHYSICS );
m_hGrenade->SetCollisionGroup( COLLISION_GROUP_WEAPON );
m_hGrenade->CreateVPhysics();
}
if ( pPhysObj )
{
pPhysObj->Wake();
pPhysObj->SetPosition( vGunPos, angles, true );
pPhysObj->ApplyForceCenter( vDir * 0.2f );
pPhysObj->RecheckCollisionFilter();
}
m_hGrenade = NULL;
}
示例5: Use
void CPlayerPickupController::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if ( ToBasePlayer(pActivator) == m_pPlayer )
{
CBaseEntity *pAttached = m_grabController.GetAttached();
// UNDONE: Use vphysics stress to decide to drop objects
// UNDONE: Must fix case of forcing objects into the ground you're standing on (causes stress) before that will work
if ( !pAttached || useType == USE_OFF || (m_pPlayer->m_nButtons & IN_ATTACK2) || m_grabController.ComputeError() > 12 )
{
Shutdown();
return;
}
//Adrian: Oops, our object became motion disabled, let go!
IPhysicsObject *pPhys = pAttached->VPhysicsGetObject();
if ( pPhys && pPhys->IsMoveable() == false )
{
Shutdown();
return;
}
#if STRESS_TEST
vphysics_objectstress_t stress;
CalculateObjectStress( pPhys, pAttached, &stress );
if ( stress.exertedStress > 250 )
{
Shutdown();
return;
}
#endif
#ifndef PLAYER_DISABLE_THROWING
// +ATTACK will throw phys objects
if ( m_pPlayer->m_nButtons & IN_ATTACK )
{
Shutdown( true );
Vector vecLaunch;
m_pPlayer->EyeVectors( &vecLaunch );
// JAY: Scale this with mass because some small objects really go flying
float massFactor = clamp( pPhys->GetMass(), 0.5, 15 );
massFactor = RemapVal( massFactor, 0.5, 15, 0.5, 4 );
vecLaunch *= player_throwforce.GetFloat() * massFactor;
pPhys->ApplyForceCenter( vecLaunch );
AngularImpulse aVel = RandomAngularImpulse( -10, 10 ) * massFactor;
pPhys->ApplyTorqueCenter( aVel );
return;
}
#endif
if ( useType == USE_SET )
{
// update position
m_grabController.UpdateObject( m_pPlayer, 12 );
}
}
}
示例6: EnumElement
//Actual work code
IterationRetval_t EnumElement( IHandleEntity *pHandleEntity )
{
C_BaseEntity *pEnt = ClientEntityList().GetBaseEntityFromHandle( pHandleEntity->GetRefEHandle() );
if ( pEnt == NULL )
return ITERATION_CONTINUE;
C_BaseAnimating *pModel = static_cast< C_BaseAnimating * >( pEnt );
if ( pModel == NULL )
return ITERATION_CONTINUE;
trace_t tr;
enginetrace->ClipRayToEntity( m_rayShot, MASK_SHOT, pModel, &tr );
IPhysicsObject *pPhysicsObject = pModel->VPhysicsGetObject();
if ( pPhysicsObject == NULL )
return ITERATION_CONTINUE;
if ( tr.fraction < 1.0 )
{
IPhysicsObject *pReference = GetWorldPhysObject();
if ( !pReference || !pPhysicsObject )
return ITERATION_CONTINUE;
constraint_ballsocketparams_t ballsocket;
ballsocket.Defaults();
Vector Origin;
pPhysicsObject->GetPosition( &Origin, NULL );
if ( ( Origin- m_vWorld).Length () < 64 )
{
pReference->WorldToLocal( ballsocket.constraintPosition[0], m_vWorld );
pPhysicsObject->WorldToLocal( ballsocket.constraintPosition[1], Origin );
GetBreakParams( ballsocket.constraint );
ballsocket.constraint.torqueLimit = 0;
m_pConstraint = physenv->CreateBallsocketConstraint( pReference, pPhysicsObject, NULL, ballsocket );
pPhysicsObject->ApplyForceCenter( Vector(0, 0, 1 ) * 100);
return ITERATION_STOP;
}
else
return ITERATION_CONTINUE;
}
return ITERATION_CONTINUE;
}
示例7: normal
CBaseEntity *CreateServerRagdoll( CBaseAnimating *pAnimating, int forceBone, const CTakeDamageInfo &info, int collisionGroup )
{
SyncAnimatingWithPhysics( pAnimating );
CRagdollProp *pRagdoll = (CRagdollProp *)CBaseEntity::CreateNoSpawn( "prop_ragdoll", pAnimating->GetAbsOrigin(), vec3_angle, NULL );
pRagdoll->CopyAnimationDataFrom( pAnimating );
pRagdoll->InitRagdollAnimation();
matrix3x4_t pBoneToWorld[MAXSTUDIOBONES];
pAnimating->SetupBones( pBoneToWorld, BONE_USED_BY_ANYTHING );
// Is this a vehicle / NPC collision?
if ( (info.GetDamageType() & DMG_VEHICLE) && pAnimating->MyNPCPointer() )
{
// init the ragdoll with no forces
pRagdoll->InitRagdoll( vec3_origin, -1, vec3_origin, pBoneToWorld, pBoneToWorld, 0.1, collisionGroup, true );
// apply vehicle forces
// Get a list of bones with hitboxes below the plane of impact
int boxList[128];
Vector normal(0,0,-1);
int count = pAnimating->GetHitboxesFrontside( boxList, ARRAYSIZE(boxList), normal, DotProduct( normal, info.GetDamagePosition() ) );
// distribute force over mass of entire character
float massScale = Studio_GetMass(pAnimating->GetModelPtr());
massScale = clamp( massScale, 1, 1e4 );
massScale = 1 / massScale;
// distribute the force
// BUGBUG: This will hit the same bone twice if it has two hitboxes!!!!
ragdoll_t *pRagInfo = pRagdoll->GetRagdoll();
for ( int i = 0; i < count; i++ )
{
int physBone = pAnimating->GetPhysicsBone( pAnimating->GetHitboxBone( boxList[i] ) );
IPhysicsObject *pPhysics = pRagInfo->list[physBone].pObject;
pPhysics->ApplyForceCenter( info.GetDamageForce() * pPhysics->GetMass() * massScale );
}
}
else
{
pRagdoll->InitRagdoll( info.GetDamageForce(), forceBone, info.GetDamagePosition(), pBoneToWorld, pBoneToWorld, 0.1, collisionGroup, true );
}
return pRagdoll;
}
示例8: TestForCollisionsAgainstEntities
//-----------------------------------------------------------------------------
// Test for impact!
//-----------------------------------------------------------------------------
void CEnvHeadcrabCanister::TestForCollisionsAgainstEntities( const Vector &vecEndPosition )
{
// Debugging!!
// NDebugOverlay::Box( GetAbsOrigin(), m_vecMin * 0.5f, m_vecMax * 0.5f, 255, 255, 0, 0, 5 );
// NDebugOverlay::Box( vecEndPosition, m_vecMin, m_vecMax, 255, 0, 0, 0, 5 );
float flRadius = CollisionProp()->BoundingRadius();
Vector vecMins( -flRadius, -flRadius, -flRadius );
Vector vecMaxs( flRadius, flRadius, flRadius );
Ray_t ray;
ray.Init( GetAbsOrigin(), vecEndPosition, vecMins, vecMaxs );
CCollideList collideList( &ray, this, MASK_SOLID );
enginetrace->EnumerateEntities( ray, false, &collideList );
float flDamage = m_flDamage;
// Now get each entity and react accordinly!
for( int iEntity = collideList.m_Entities.Count(); --iEntity >= 0; )
{
CBaseEntity *pEntity = collideList.m_Entities[iEntity];
Vector vecForceDir = m_Shared.m_vecDirection;
// Check for a physics object and apply force!
IPhysicsObject *pPhysObject = pEntity->VPhysicsGetObject();
if ( pPhysObject )
{
float flMass = PhysGetEntityMass( pEntity );
vecForceDir *= flMass * 750;
pPhysObject->ApplyForceCenter( vecForceDir );
}
if ( pEntity->m_takedamage && ( m_flDamage != 0.0f ) )
{
CTakeDamageInfo info( this, this, flDamage, DMG_BLAST );
CalculateExplosiveDamageForce( &info, vecForceDir, pEntity->GetAbsOrigin() );
pEntity->TakeDamage( info );
}
}
}
示例9: ImpactTrace
void C_GENPCRagdoll::ImpactTrace( trace_t *pTrace, int iDamageType, char *pCustomImpactName )
{
static bool bInTrace = false;
if ( bInTrace )
return;
IPhysicsObject *pPhysicsObject = VPhysicsGetObject();
if( !pPhysicsObject )
return;
Vector dir = pTrace->endpos - pTrace->startpos;
if ( iDamageType == DMG_BLAST )
{
dir *= 4000; // adjust impact strength
// apply force at object mass center
pPhysicsObject->ApplyForceCenter( dir );
}
else
{
Vector hitpos;
VectorMA( pTrace->startpos, pTrace->fraction, dir, hitpos );
VectorNormalize( dir );
dir *= 4000; // adjust impact strength
// apply force where we hit it
pPhysicsObject->ApplyForceOffset( dir, hitpos );
UTIL_BloodDrips( pTrace->endpos, dir, BLOOD_COLOR_RED, 20 );
bInTrace = true; //<-- Prevent infinite recursion!
C_BaseEntity::ImpactTrace( pTrace, iDamageType, pCustomImpactName );
bInTrace = false;
}
m_pRagdoll->ResetRagdollSleepAfterTime();
}
示例10: ImpactTrace
void C_SDKRagdoll::ImpactTrace( trace_t *pTrace, int iDamageType, char *pCustomImpactName )
{
// DevMsg("C_SDKRagDoll::ImpactTrace: %i\n", iDamageType);
IPhysicsObject *pPhysicsObject = VPhysicsGetObject();
if( !pPhysicsObject )
return;
Vector dir = pTrace->endpos - pTrace->startpos;
if ( iDamageType == DMG_BLAST )
{
dir *= 4000; // adjust impact strength
// apply force at object mass center
pPhysicsObject->ApplyForceCenter( dir );
}
else
{
Vector hitpos;
VectorMA( pTrace->startpos, pTrace->fraction, dir, hitpos );
VectorNormalize( dir );
// Blood spray!
FX_BloodSpray( hitpos, dir, 3, 72, 0, 0, FX_BLOODSPRAY_ALL );
dir *= 4000; // adjust impact strenght
// apply force where we hit it
pPhysicsObject->ApplyForceOffset( dir, hitpos );
//Tony; throw in some bleeds! - just use a generic value for damage.
TraceBleed( 40, dir, pTrace, iDamageType );
}
m_pRagdoll->ResetRagdollSleepAfterTime();
}
示例11: SonicAttack
//.........这里部分代码省略.........
}
Vector vFacingDir = EyeDirection3D( );
m_pEnergyWave = (CEnergyWave*)Create( "energy_wave", EyePosition(), GetLocalAngles() );
m_flEndEnergyWaveTime = gpGlobals->curtime + 1; //<<TEMP>> magic
m_pEnergyWave->SetAbsVelocity( 100*vFacingDir );
CBaseEntity *pEntity = NULL;
// iterate on all entities in the vicinity.
for ( CEntitySphereQuery sphere( GetAbsOrigin(), HOUNDEYE_MAX_ATTACK_RADIUS ); pEntity = sphere.GetCurrentEntity(); sphere.NextEntity() )
{
if (pEntity->Classify() == CLASS_HOUNDEYE)
{
continue;
}
if (pEntity->GetFlags() & FL_NOTARGET)
{
continue;
}
IPhysicsObject *pPhysicsObject = pEntity->VPhysicsGetObject();
if ( pEntity->m_takedamage != DAMAGE_NO || pPhysicsObject)
{
// --------------------------
// Adjust damage by distance
// --------------------------
float flDist = (pEntity->WorldSpaceCenter() - GetAbsOrigin()).Length();
float flDamageAdjuster = 1-( flDist / HOUNDEYE_MAX_ATTACK_RADIUS );
// --------------------------
// Adjust damage by direction
// --------------------------
Vector forward;
AngleVectors( GetAbsAngles(), &forward );
Vector vEntDir = (pEntity->GetAbsOrigin() - GetAbsOrigin());
VectorNormalize(vEntDir);
float flDotPr = DotProduct(forward,vEntDir);
flDamageAdjuster *= flDotPr;
if (flDamageAdjuster < 0)
{
continue;
}
// --------------------------
// Adjust damage by visibility
// --------------------------
if ( !FVisible( pEntity ) )
{
if ( pEntity->IsPlayer() )
{
// if this entity is a client, and is not in full view, inflict half damage. We do this so that players still
// take the residual damage if they don't totally leave the houndeye's effective radius. We restrict it to clients
// so that monsters in other parts of the level don't take the damage and get pissed.
flDamageAdjuster *= 0.5;
}
else if ( !FClassnameIs( pEntity, "func_breakable" ) && !FClassnameIs( pEntity, "func_pushable" ) )
{
// do not hurt nonclients through walls, but allow damage to be done to breakables
continue;
}
}
// ------------------------------
// Apply the damage
// ------------------------------
if (pEntity->m_takedamage != DAMAGE_NO)
{
CTakeDamageInfo info( this, this, flDamageAdjuster * sk_Houndeye_dmg_blast.GetFloat(), DMG_SONIC | DMG_ALWAYSGIB );
CalculateExplosiveDamageForce( &info, (pEntity->GetAbsOrigin() - GetAbsOrigin()), pEntity->GetAbsOrigin() );
pEntity->TakeDamage( info );
// Throw the player
if ( pEntity->IsPlayer() )
{
Vector forward;
AngleVectors( GetLocalAngles(), &forward );
Vector vecVelocity = pEntity->GetAbsVelocity();
vecVelocity += forward * 250 * flDamageAdjuster;
vecVelocity.z = 300 * flDamageAdjuster;
pEntity->SetAbsVelocity( vecVelocity );
pEntity->ViewPunch( QAngle(random->RandomInt(-20,20), 0, random->RandomInt(-20,20)) );
}
}
// ------------------------------
// Apply physics foces
// ------------------------------
IPhysicsObject *pPhysicsObject = pEntity->VPhysicsGetObject();
if (pPhysicsObject)
{
float flForce = flDamageAdjuster * 8000;
pPhysicsObject->ApplyForceCenter( (vEntDir+Vector(0,0,0.2)) * flForce );
pPhysicsObject->ApplyTorqueCenter( vEntDir * flForce );
}
}
}
}
示例12: ImpactTrace
void C_PhysPropClientside::ImpactTrace( trace_t *pTrace, int iDamageType, const char *pCustomImpactName )
{
VPROF( "C_PhysPropClientside::ImpactTrace" );
IPhysicsObject *pPhysicsObject = VPhysicsGetObject();
if( !pPhysicsObject )
return;
Vector dir = pTrace->endpos - pTrace->startpos;
int iDamage = 0;
if ( iDamageType == DMG_BLAST )
{
iDamage = VectorLength( dir );
dir *= 500; // adjust impact strenght
// apply force at object mass center
pPhysicsObject->ApplyForceCenter( dir );
}
else
{
Vector hitpos;
VectorMA( pTrace->startpos, pTrace->fraction, dir, hitpos );
VectorNormalize( dir );
// guess avg damage
if ( iDamageType == DMG_BULLET )
{
iDamage = 30;
}
else
{
iDamage = 50;
}
dir *= 4000; // adjust impact strenght
// apply force where we hit it
pPhysicsObject->ApplyForceOffset( dir, hitpos );
// Build the impact data
CEffectData data;
data.m_vOrigin = pTrace->endpos;
data.m_vStart = pTrace->startpos;
data.m_nSurfaceProp = pTrace->surface.surfaceProps;
data.m_nDamageType = iDamageType;
data.m_nHitBox = pTrace->hitbox;
data.m_hEntity = GetRefEHandle();
// Send it on its way
if ( !pCustomImpactName )
{
DispatchEffect( "Impact", data );
}
else
{
DispatchEffect( pCustomImpactName, data );
}
}
// Clone( dir ); // debug code
OnTakeDamage( iDamage );
}
示例13: UpdateVPhysicsObjects
void UpdateVPhysicsObjects()
{
int nPhysicsObjectInterval = sv_benchmark_numticks.GetInt() / s_nBenchmarkPhysicsObjects;
int nNextSpawnTick = m_nLastPhysicsObjectTick + nPhysicsObjectInterval;
if ( GetTickOffset() >= nNextSpawnTick )
{
m_nLastPhysicsObjectTick = nNextSpawnTick;
if ( m_PhysicsObjects.Count() < s_nBenchmarkPhysicsObjects )
{
// Find a bot to spawn it from.
CUtlVector<CBasePlayer*> curPlayers;
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
if ( pPlayer && (pPlayer->GetFlags() & FL_FAKECLIENT) )
{
curPlayers.AddToTail( pPlayer );
}
}
if ( curPlayers.Count() > 0 && m_PhysicsModelNames.Count() > 0 )
{
int iModelName = this->RandomInt( 0, m_PhysicsModelNames.Count() - 1 );
const char *pModelName = m_PhysicsModelNames[iModelName];
int iPlayer = this->RandomInt( 0, curPlayers.Count() - 1 );
Vector vSpawnPos = curPlayers[iPlayer]->EyePosition() + Vector( 0, 0, 50 );
// We'll try 15 locations around the player to spawn this thing.
for ( int i=0; i < 15; i++ )
{
Vector vOffset( this->RandomFloat( -2000, 2000 ), this->RandomFloat( -2000, 2000 ), 0 );
CPhysicsProp *pProp = CreatePhysicsProp( pModelName, vSpawnPos, vSpawnPos+vOffset, curPlayers[iPlayer], false, "prop_physics_multiplayer" );
if ( pProp )
{
m_PhysicsObjects.AddToTail( pProp );
pProp->SetAbsVelocity( Vector( this->RandomFloat(-500,500), this->RandomFloat(-500,500), this->RandomFloat(-500,500) ) );
break;
}
}
}
}
}
// Give them all a boost periodically.
int nPhysicsForceInterval = sv_benchmark_numticks.GetInt() / 20;
int nNextForceTick = m_nLastPhysicsForceTick + nPhysicsForceInterval;
if ( GetTickOffset() >= nNextForceTick )
{
m_nLastPhysicsForceTick = nNextForceTick;
for ( int i=0; i < m_PhysicsObjects.Count(); i++ )
{
CBaseEntity *pEnt = m_PhysicsObjects[i];
if ( pEnt )
{
IPhysicsObject *pPhysicsObject = pEnt->VPhysicsGetObject();
if ( pPhysicsObject )
{
float flAngImpulse = 300000;
float flForce = 500000;
AngularImpulse vAngularImpulse( this->RandomFloat(-flAngImpulse,flAngImpulse), this->RandomFloat(-flAngImpulse,flAngImpulse), this->RandomFloat(flAngImpulse,flAngImpulse) );
pPhysicsObject->ApplyForceCenter( Vector( this->RandomFloat(-flForce,flForce), this->RandomFloat(-flForce,flForce), this->RandomFloat(0,flForce) ) );
}
}
}
}
}
示例14: normal
CBaseEntity *CreateServerRagdoll( CBaseAnimating *pAnimating, int forceBone, const CTakeDamageInfo &info, int collisionGroup, bool bUseLRURetirement )
{
SyncAnimatingWithPhysics( pAnimating );
CRagdollProp *pRagdoll = (CRagdollProp *)CBaseEntity::CreateNoSpawn( "prop_ragdoll", pAnimating->GetAbsOrigin(), vec3_angle, NULL );
pRagdoll->CopyAnimationDataFrom( pAnimating );
pRagdoll->SetOwnerEntity( pAnimating );
pRagdoll->InitRagdollAnimation();
matrix3x4_t pBoneToWorld[MAXSTUDIOBONES], pBoneToWorldNext[MAXSTUDIOBONES];
const float dt = 0.1f;
// Copy over dissolve state...
if ( pAnimating->IsEFlagSet( EFL_NO_DISSOLVE ) )
{
pRagdoll->AddEFlags( EFL_NO_DISSOLVE );
}
// NOTE: This currently is only necessary to prevent manhacks from
// colliding with server ragdolls they kill
pRagdoll->SetKiller( info.GetInflictor() );
pRagdoll->SetSourceClassName( pAnimating->GetClassname() );
// NPC_STATE_DEAD npc's will have their COND_IN_PVS cleared, so this needs to force SetupBones to happen
unsigned short fPrevFlags = pAnimating->GetBoneCacheFlags();
pAnimating->SetBoneCacheFlags( BCF_NO_ANIMATION_SKIP );
// UNDONE: Extract velocity from bones via animation (like we do on the client)
// UNDONE: For now, just move each bone by the total entity velocity if set.
pAnimating->SetupBones( pBoneToWorld, BONE_USED_BY_ANYTHING );
// Reset previous bone flags
pAnimating->ClearBoneCacheFlags( BCF_NO_ANIMATION_SKIP );
pAnimating->SetBoneCacheFlags( fPrevFlags );
memcpy( pBoneToWorldNext, pBoneToWorld, sizeof(pBoneToWorld) );
Vector vel = pAnimating->GetAbsVelocity();
if ( vel.LengthSqr() > 0 )
{
int numbones = pAnimating->GetModelPtr()->numbones();
for ( int i = 0; i < numbones; i++ )
{
Vector pos;
MatrixGetColumn( pBoneToWorldNext[i], 3, pos );
pos += vel * dt;
MatrixSetColumn( pos, 3, pBoneToWorldNext[i] );
}
}
// Is this a vehicle / NPC collision?
if ( (info.GetDamageType() & DMG_VEHICLE) && pAnimating->MyNPCPointer() )
{
// init the ragdoll with no forces
pRagdoll->InitRagdoll( vec3_origin, -1, vec3_origin, pBoneToWorld, pBoneToWorldNext, dt, collisionGroup, true );
// apply vehicle forces
// Get a list of bones with hitboxes below the plane of impact
int boxList[128];
Vector normal(0,0,-1);
int count = pAnimating->GetHitboxesFrontside( boxList, ARRAYSIZE(boxList), normal, DotProduct( normal, info.GetDamagePosition() ) );
// distribute force over mass of entire character
float massScale = Studio_GetMass(pAnimating->GetModelPtr());
massScale = clamp( massScale, 1, 1e4 );
massScale = 1 / massScale;
// distribute the force
// BUGBUG: This will hit the same bone twice if it has two hitboxes!!!!
ragdoll_t *pRagInfo = pRagdoll->GetRagdoll();
for ( int i = 0; i < count; i++ )
{
int physBone = pAnimating->GetPhysicsBone( pAnimating->GetHitboxBone( boxList[i] ) );
IPhysicsObject *pPhysics = pRagInfo->list[physBone].pObject;
pPhysics->ApplyForceCenter( info.GetDamageForce() * pPhysics->GetMass() * massScale );
}
}
else
{
pRagdoll->InitRagdoll( info.GetDamageForce(), forceBone, info.GetDamagePosition(), pBoneToWorld, pBoneToWorldNext, dt, collisionGroup, true );
}
// Are we dissolving?
if ( pAnimating->IsDissolving() )
{
pRagdoll->TransferDissolveFrom( pAnimating );
}
else if ( bUseLRURetirement )
{
pRagdoll->AddSpawnFlags( SF_RAGDOLLPROP_USE_LRU_RETIREMENT );
s_RagdollLRU.MoveToTopOfLRU( pRagdoll );
}
// Tracker 22598: If we don't set the OBB mins/maxs to something valid here, then the client will have a zero sized hull
// for the ragdoll for one frame until Vphysics updates the real obb bounds after the first simulation frame. Having
// a zero sized hull makes the ragdoll think it should be faded/alpha'd to zero for a frame, so you get a blink where
// the ragdoll doesn't draw initially.
Vector mins, maxs;
mins = pAnimating->CollisionProp()->OBBMins();
maxs = pAnimating->CollisionProp()->OBBMaxs();
//.........这里部分代码省略.........