当前位置: 首页>>代码示例>>C++>>正文


C++ IPhysicsObject::IsMoveable方法代码示例

本文整理汇总了C++中IPhysicsObject::IsMoveable方法的典型用法代码示例。如果您正苦于以下问题:C++ IPhysicsObject::IsMoveable方法的具体用法?C++ IPhysicsObject::IsMoveable怎么用?C++ IPhysicsObject::IsMoveable使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在IPhysicsObject的用法示例。


在下文中一共展示了IPhysicsObject::IsMoveable方法的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1:

static CBaseEntity *FindPhysicsBlocker( IPhysicsObject *pPhysics )
{
	IPhysicsFrictionSnapshot *pSnapshot = pPhysics->CreateFrictionSnapshot();
	CBaseEntity *pBlocker = NULL;
	float maxVel = 10.0f;
	while ( pSnapshot->IsValid() )
	{
		IPhysicsObject *pOther = pSnapshot->GetObject(1);
		if ( pOther->IsMoveable() )
		{
			CBaseEntity *pOtherEntity = static_cast<CBaseEntity *>(pOther->GetGameData());
			// dot with this if you have a direction
			//Vector normal;
			//pSnapshot->GetSurfaceNormal(normal);
			float force = pSnapshot->GetNormalForce();
			float vel = force * pOther->GetInvMass();
			if ( vel > maxVel )
			{
				pBlocker = pOtherEntity;
				maxVel = vel;
			}

		}
		pSnapshot->NextFrictionData();
	}
	pPhysics->DestroyFrictionSnapshot( pSnapshot );

	return pBlocker;
}
开发者ID:SCell555,项目名称:hl2-asw-port,代码行数:29,代码来源:physics.cpp

示例2: Event_Killed

void CStatueProp::Event_Killed( const CTakeDamageInfo &info )
{
	IPhysicsObject *pPhysics = VPhysicsGetObject();

	if ( pPhysics && !pPhysics->IsMoveable() )
	{
		pPhysics->EnableMotion( true );
		VPhysicsTakeDamage( info );
	}
	
	m_nShatterFlags = 0; // If you have some flags to network for the shatter effect, put them here!
	m_vShatterPosition = info.GetDamagePosition();
	m_vShatterForce = info.GetDamageForce();
	m_bShatter = true;

	// Skip over breaking code!
	//Break( info.GetInflictor(), info );
	//BaseClass::Event_Killed( info );

	// FIXME: Short delay before we actually remove so that the client statue gets a network update before we need it
	// This isn't a reliable way to do this and needs to be rethought.
	AddSolidFlags( FSOLID_NOT_SOLID );

	SetNextThink( gpGlobals->curtime + 0.2f );
	SetThink( &CBaseEntity::SUB_Remove );
}
开发者ID:BenLubar,项目名称:SwarmDirector2,代码行数:26,代码来源:physics_prop_statue.cpp

示例3: 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 );
		}
	}
}
开发者ID:gamenew09,项目名称:SourceSDK2010,代码行数:57,代码来源:player_pickup_controller.cpp

示例4: Event_Killed

void CASW_Barrel_Explosive::Event_Killed( const CTakeDamageInfo &info )
{
	IPhysicsObject *pPhysics = VPhysicsGetObject();
	if ( pPhysics && !pPhysics->IsMoveable() )
	{
		pPhysics->EnableMotion( true );
		VPhysicsTakeDamage( info );
	}

	QueueForExplode( info );

	// Break( info.GetInflictor(), info );
	// DoExplosion();
}
开发者ID:BenLubar,项目名称:SwarmDirector2,代码行数:14,代码来源:asw_barrel_explosive.cpp

示例5:

void CHL1_Player::Touch( CBaseEntity *pOther )
{
	if ( pOther == GetGroundEntity() )
		return;

	if ( pOther->GetMoveType() != MOVETYPE_VPHYSICS || pOther->GetSolid() != SOLID_VPHYSICS )
		return;

	IPhysicsObject *pPhys = pOther->VPhysicsGetObject();
	if ( !pPhys || !pPhys->IsMoveable() )
		return;

	SetTouchedPhysics( true );
}
开发者ID:RaisingTheDerp,项目名称:raisingthebar,代码行数:14,代码来源:hl1_player.cpp

示例6: InContactWithHeavyObject

static bool InContactWithHeavyObject( IPhysicsObject *pObject, float heavyMass )
{
	bool contact = false;
	IPhysicsFrictionSnapshot *pSnapshot = pObject->CreateFrictionSnapshot();
	while ( pSnapshot->IsValid() )
	{
		IPhysicsObject *pOther = pSnapshot->GetObject( 1 );
		if ( !pOther->IsMoveable() || pOther->GetMass() > heavyMass )
		{
			contact = true;
			break;
		}
		pSnapshot->NextFrictionData();
	}
	pObject->DestroyFrictionSnapshot( pSnapshot );
	return contact;
}
开发者ID:gamenew09,项目名称:SourceSDK2010,代码行数:17,代码来源:player_pickup_controller.cpp

示例7: UpdateObject

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// adnan
// want to add an angles modifier key
bool CGravControllerPoint::UpdateObject( CBasePlayer *pPlayer, CBaseEntity *pEntity )
{
	if ( !pEntity || pPlayer->GetGroundEntity() == pEntity || !pEntity->VPhysicsGetObject() )
	{
		return false;
	}

	//Adrian: Oops, our object became motion disabled, let go!
	IPhysicsObject *pPhys = pEntity->VPhysicsGetObject();
	if ( pPhys && pPhys->IsMoveable() == false )
	{
		return false;
	}

	SetTargetPosition( m_targetPosition, m_targetRotation );

	return true;
}
开发者ID:AluminumKen,项目名称:hl2sb-src,代码行数:22,代码来源:weapon_physgun_valve.cpp

示例8: Event_Killed

void CGEPropDynamic::Event_Killed(const CTakeDamageInfo &info)
{
	// More or less just the kill event copied straight from prop_physics_respawnable, though it does not teleport as it cannot move on its own.

	IPhysicsObject *pPhysics = VPhysicsGetObject();
	if (pPhysics && !pPhysics->IsMoveable())
	{
		pPhysics->EnableMotion(true);
		VPhysicsTakeDamage(info);
	}

	Break(info.GetInflictor(), info);

	PhysCleanupFrictionSounds(this);

	VPhysicsDestroyObject();

	CBaseEntity::PhysicsRemoveTouchedList(this);
	CBaseEntity::PhysicsRemoveGroundList(this);
	DestroyAllDataObjects();

	AddEffects(EF_NODRAW);

	if (IsOnFire() || IsDissolving())
	{
		UTIL_Remove(GetEffectEntity());
	}

	SetContextThink(NULL, 0, "PROP_CLEARFLAGS");

	if (m_flRespawnTime > 0)
	{
		SetThink(&CGEPropDynamic::Materialize);
		SetNextThink(gpGlobals->curtime + m_flRespawnTime);
	}
}
开发者ID:djoslin0,项目名称:ges-legacy-code,代码行数:36,代码来源:prop_ge_dynamic.cpp

示例9: UpdateObject

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
bool CGrabController::UpdateObject( CBasePlayer *pPlayer, float flError )
{
 	CBaseEntity *pEntity = GetAttached();
	if ( !pEntity || ComputeError() > flError || pPlayer->GetGroundEntity() == pEntity || !pEntity->VPhysicsGetObject() )
	{
		return false;
	}

	//Adrian: Oops, our object became motion disabled, let go!
	IPhysicsObject *pPhys = pEntity->VPhysicsGetObject();
	if ( pPhys && pPhys->IsMoveable() == false )
	{
		return false;
	}

	Vector forward, right, up;
	QAngle playerAngles = pPlayer->EyeAngles();
	AngleVectors( playerAngles, &forward, &right, &up );
	
	float pitch = AngleDistance(playerAngles.x,0);

	if( !m_bAllowObjectOverhead )
	{
		playerAngles.x = clamp( pitch, -75, 75 );
	}
	else
	{
		playerAngles.x = clamp( pitch, -90, 75 );
	}

	
	
	// Now clamp a sphere of object radius at end to the player's bbox
	Vector radial = physcollision->CollideGetExtent( pPhys->GetCollide(), vec3_origin, pEntity->GetAbsAngles(), -forward );
	Vector player2d = pPlayer->CollisionProp()->OBBMaxs();
	float playerRadius = player2d.Length2D();
	float radius = playerRadius + fabs(DotProduct( forward, radial ));

	float distance = 24 + ( radius * 2.0f );

	// Add the prop's distance offset
	distance += m_flDistanceOffset;

	Vector start = pPlayer->Weapon_ShootPosition();
	Vector end = start + ( forward * distance );

	trace_t	tr;
	CTraceFilterSkipTwoEntities traceFilter( pPlayer, pEntity, COLLISION_GROUP_NONE );
	Ray_t ray;
	ray.Init( start, end );
	enginetrace->TraceRay( ray, MASK_SOLID_BRUSHONLY, &traceFilter, &tr );

	if ( tr.fraction < 0.5 )
	{
		end = start + forward * (radius*0.5f);
	}
	else if ( tr.fraction <= 1.0f )
	{
		end = start + forward * ( distance - radius );
	}
	Vector playerMins, playerMaxs, nearest;
	pPlayer->CollisionProp()->WorldSpaceAABB( &playerMins, &playerMaxs );
	Vector playerLine = pPlayer->CollisionProp()->WorldSpaceCenter();
	CalcClosestPointOnLine( end, playerLine+Vector(0,0,playerMins.z), playerLine+Vector(0,0,playerMaxs.z), nearest, NULL );

	if( !m_bAllowObjectOverhead )
	{
		Vector delta = end - nearest;
		float len = VectorNormalize(delta);
		if ( len < radius )
		{
			end = nearest + radius * delta;
		}
	}

	//Show overlays of radius
	if ( g_debug_physcannon.GetBool() )
	{
		NDebugOverlay::Box( end, -Vector( 2,2,2 ), Vector(2,2,2), 0, 255, 0, true, 0 );

		NDebugOverlay::Box( GetAttached()->WorldSpaceCenter(), 
							-Vector( radius, radius, radius), 
							Vector( radius, radius, radius ),
							255, 0, 0,
							true,
							0.0f );
	}

	QAngle angles = TransformAnglesFromPlayerSpace( m_attachedAnglesPlayerSpace, pPlayer );
	
	// If it has a preferred orientation, update to ensure we're still oriented correctly.
	Pickup_GetPreferredCarryAngles( pEntity, pPlayer, pPlayer->EntityToWorldTransform(), angles );

	// We may be holding a prop that has preferred carry angles
	if ( m_bHasPreferredCarryAngles )
	{
		matrix3x4_t tmp;
		ComputePlayerMatrix( pPlayer, tmp );
//.........这里部分代码省略.........
开发者ID:gamenew09,项目名称:SourceSDK2010,代码行数:101,代码来源:player_pickup_controller.cpp

示例10: CalculateObjectStress

float CalculateObjectStress( IPhysicsObject *pObject, CBaseEntity *pInputOwnerEntity, vphysics_objectstress_t *pOutput )
{
	CUtlVector< CBaseEntity * > pObjectList;
	CUtlVector< Vector >		objectForce;
	bool hasLargeObject = false;

	// add a slot for static objects
	pObjectList.AddToTail( NULL );
	objectForce.AddToTail( vec3_origin );
	// add a slot for friendly objects
	pObjectList.AddToTail( NULL );
	objectForce.AddToTail( vec3_origin );

	CBaseCombatCharacter *pBCC = pInputOwnerEntity->MyCombatCharacterPointer();

	IPhysicsFrictionSnapshot *pSnapshot = pObject->CreateFrictionSnapshot();
	float objMass = pObject->GetMass();
	while ( pSnapshot->IsValid() )
	{
		float force = pSnapshot->GetNormalForce();
		if ( force > 0.0f )
		{
			IPhysicsObject *pOther = pSnapshot->GetObject(1);
			CBaseEntity *pOtherEntity = static_cast<CBaseEntity *>(pOther->GetGameData());
			if ( !pOtherEntity )
			{
				// object was just deleted, but we still have a contact point this frame...
				// just assume it came from the world.
				pOtherEntity = GetWorldEntity();
			}
			CBaseEntity *pOtherOwner = pOtherEntity;
			if ( pOtherEntity->GetOwnerEntity() )
			{
				pOtherOwner = pOtherEntity->GetOwnerEntity();
			}

			int outIndex = 0;
			if ( !pOther->IsMoveable() )
			{
				outIndex = 0;
			}
			// NavIgnored objects are often being pushed by a friendly
			else if ( pBCC && (pBCC->IRelationType( pOtherOwner ) == D_LI || pOtherEntity->IsNavIgnored()) )
			{
				outIndex = 1;
			}
			// player held objects do no stress
			else if ( pOther->GetGameFlags() & FVPHYSICS_PLAYER_HELD )
			{
				outIndex = 1;
			}
			else
			{
				if ( pOther->GetMass() >= VPHYSICS_LARGE_OBJECT_MASS )
				{
					if ( pInputOwnerEntity->GetGroundEntity() != pOtherEntity)
					{
						hasLargeObject = true;
					}
				}
				// moveable, non-friendly
				
				// aggregate contacts over each object to avoid greater stress in multiple contact cases
				// NOTE: Contacts should be in order, so this shouldn't ever search, but just in case
				outIndex = pObjectList.Count();
				for ( int i = pObjectList.Count()-1; i >= 2; --i )
				{
					if ( pObjectList[i] == pOtherOwner )
					{
						outIndex = i;
						break;
					}
				}
				if ( outIndex == pObjectList.Count() )
				{
					pObjectList.AddToTail( pOtherOwner );
					objectForce.AddToTail( vec3_origin );
				}
			}

			if ( outIndex != 0 && pInputOwnerEntity->GetMoveType() != MOVETYPE_VPHYSICS && !IsPhysicallyControlled(pOtherEntity, pOther) )
			{
				// UNDONE: Test this!  This is to remove any shadow/shadow stress.  The game should handle this with blocked/damage
				force = 0.0f;
			}

			Vector normal;
			pSnapshot->GetSurfaceNormal( normal );
			objectForce[outIndex] += normal * force;
		}
		pSnapshot->NextFrictionData();
	}
	pObject->DestroyFrictionSnapshot( pSnapshot );
	pSnapshot = NULL;

	// clear out all friendly force
	objectForce[1].Init();

	float sum = 0;
	Vector negativeForce = vec3_origin;
//.........这里部分代码省略.........
开发者ID:hlstriker,项目名称:source-sdk-2013,代码行数:101,代码来源:physics_impact_damage.cpp

示例11: ApplyShake

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CASWEnvShake::ApplyShake( ShakeCommand_t command )
{
	if ( !HasSpawnFlags( SF_ASW_SHAKE_NO_VIEW ) )
	{
		bool air = (GetSpawnFlags() & SF_ASW_SHAKE_INAIR) ? true : false;
		UTIL_ASW_ScreenShake( GetAbsOrigin(), Amplitude(), Frequency(), Duration(), Radius(), command, air );
	}
		
	if ( GetSpawnFlags() & SF_ASW_SHAKE_ROPES )
	{
		CRopeKeyframe::ShakeRopes( GetAbsOrigin(), Radius(), Frequency() );
	}

	if ( GetSpawnFlags() & SF_ASW_SHAKE_PHYSICS )
	{
		if ( !m_pShakeController )
		{
			m_pShakeController = physenv->CreateMotionController( &m_shakeCallback );
		}
		// do physics shake
		switch( command )
		{
		case SHAKE_START:
			{
				m_stopTime = gpGlobals->curtime + Duration();
				m_nextShake = 0;
				m_pShakeController->ClearObjects();
				SetNextThink( gpGlobals->curtime );
				m_currentAmp = Amplitude();
				CBaseEntity *list[1024];
				float radius = Radius();
				
				// probably checked "Shake Everywhere" do a big radius
				if ( !radius )
				{
					radius = MAX_COORD_INTEGER;
				}
				Vector extents = Vector(radius, radius, radius);
				Vector mins = GetAbsOrigin() - extents;
				Vector maxs = GetAbsOrigin() + extents;
				int count = UTIL_EntitiesInBox( list, 1024, mins, maxs, 0 );

				for ( int i = 0; i < count; i++ )
				{
					//
					// Only shake physics entities that players can see. This is one frame out of date
					// so it's possible that we could miss objects if a player changed PVS this frame.
					//
					if ( ( list[i]->GetMoveType() == MOVETYPE_VPHYSICS ) )
					{
						IPhysicsObject *pPhys = list[i]->VPhysicsGetObject();
						if ( pPhys && pPhys->IsMoveable() )
						{
							m_pShakeController->AttachObject( pPhys, false );
							pPhys->Wake();
						}
					}
				}
			}
			break;
		case SHAKE_STOP:
			m_pShakeController->ClearObjects();
			break;
		case SHAKE_AMPLITUDE:
			m_currentAmp = Amplitude();
		case SHAKE_FREQUENCY:
			m_pShakeController->WakeObjects();
			break;
		}
	}
}
开发者ID:BenLubar,项目名称:SwarmDirector2,代码行数:74,代码来源:asw_env_shake.cpp

示例12: FindPhysicsObject

bool CNPC_Dog::FindPhysicsObject( const char *pPickupName, CBaseEntity *pIgnore )
{
	CBaseEntity		*pEnt = NULL;
	CBaseEntity		*pNearest = NULL;
	float			flDist;
	IPhysicsObject	*pPhysObj = NULL;
	float			flNearestDist = 99999;

	if ( pPickupName != NULL && strlen( pPickupName ) > 0 )
	{
		pEnt = gEntList.FindEntityByName( NULL, pPickupName );
		
		if ( m_hUnreachableObjects.Find( pEnt ) == -1  )
		{
			m_bHasObject = false;
			m_hPhysicsEnt = pEnt;
			return true;
		}
	}
	
	while ( ( pEnt = gEntList.FindEntityByClassname( pEnt, "prop_physics" ) ) != NULL )
	{
		//We don't want this one.
		if ( pEnt == pIgnore )
			 continue;

		if ( m_hUnreachableObjects.Find( pEnt ) != -1 )
			 continue;

		pPhysObj = pEnt->VPhysicsGetObject();

		if( pPhysObj == NULL )
			continue;

		if ( pPhysObj->GetMass() > DOG_MAX_THROW_MASS )
			 continue;
		
		Vector center = pEnt->WorldSpaceCenter();
		flDist = UTIL_DistApprox2D( GetAbsOrigin(), center );

		vcollide_t *pCollide = modelinfo->GetVCollide( pEnt->GetModelIndex() );

		if ( pCollide == NULL )
			 continue;

		if ( pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD )
			 continue;

		if ( pPhysObj->IsMoveable() == false )
			 continue;

		if ( pEnt->GetCollisionGroup() == COLLISION_GROUP_DEBRIS || 
			 pEnt->GetCollisionGroup() == COLLISION_GROUP_INTERACTIVE_DEBRIS )
			 continue;

		if ( center.z > EyePosition().z )
			 continue;

		if ( flDist >= flNearestDist )
			 continue;

		if ( FVisible( pEnt ) == false )
			 continue;
		
		pNearest = pEnt;
		flNearestDist = flDist;
	}

	m_bHasObject = false;
	m_hPhysicsEnt = pNearest;

	if ( dog_debug.GetBool() == true )
	{
		if ( pNearest )
			 NDebugOverlay::Box( pNearest->WorldSpaceCenter(), pNearest->CollisionProp()->OBBMins(), pNearest->CollisionProp()->OBBMaxs(), 255, 0, 255, true, 3 );
	}

	if( m_hPhysicsEnt == NULL )
	{
		return false;
	}
	else
	{
		return true;
	}
}
开发者ID:WorldGamers,项目名称:Mobile-Forces-Source,代码行数:86,代码来源:npc_dog.cpp

示例13: PhysComputeSlideDirection

void PhysComputeSlideDirection( IPhysicsObject *pPhysics, const Vector &inputVelocity, const AngularImpulse &inputAngularVelocity, 
							   Vector *pOutputVelocity, Vector *pOutputAngularVelocity, float minMass )
{
	Vector velocity = inputVelocity;
	AngularImpulse angVel = inputAngularVelocity;
	Vector pos;

	IPhysicsFrictionSnapshot *pSnapshot = pPhysics->CreateFrictionSnapshot();
	while ( pSnapshot->IsValid() )
	{
		IPhysicsObject *pOther = pSnapshot->GetObject( 1 );
		if ( !pOther->IsMoveable() || pOther->GetMass() > minMass )
		{
			Vector normal;
			pSnapshot->GetSurfaceNormal( normal );

			// BUGBUG: Figure out the correct rotation clipping equation
			if ( pOutputAngularVelocity )
			{
				angVel = normal * DotProduct( angVel, normal );
#if 0
				pSnapshot->GetContactPoint( point );
				Vector point, dummy;
				AngularImpulse angularClip, clip2;

				pPhysics->CalculateVelocityOffset( normal, point, dummy, angularClip );
				VectorNormalize( angularClip );
				float proj = DotProduct( angVel, angularClip );
				if ( proj > 0 )
				{
					angVel -= angularClip * proj;
				}
				CrossProduct( angularClip, normal, clip2 );
				proj = DotProduct( angVel, clip2 );
				if ( proj > 0 )
				{
					angVel -= clip2 * proj;
				}
				//NDebugOverlay::Line( point, point - normal * 20, 255, 0, 0, true, 0.1 );
#endif
			}

			// Determine how far along plane to slide based on incoming direction.
			// NOTE: Normal points away from this object
			float proj = DotProduct( velocity, normal );
			if ( proj > 0.0f )
			{
				velocity -= normal * proj;
			}
		}
		pSnapshot->NextFrictionData();
	}
	pPhysics->DestroyFrictionSnapshot( pSnapshot );

	//NDebugOverlay::Line( pos, pos + unitVel * 20, 0, 0, 255, true, 0.1 );
	
	if ( pOutputVelocity )
	{
		*pOutputVelocity = velocity;
	}
	if ( pOutputAngularVelocity )
	{
		*pOutputAngularVelocity = angVel;
	}
}
开发者ID:detoxhby,项目名称:lambdawars,代码行数:65,代码来源:physics_shared.cpp

示例14: Touch

//-----------------------------------------------------------------------------
// 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 );
}
开发者ID:RaisingTheDerp,项目名称:raisingthebar,代码行数:89,代码来源:physobj.cpp


注:本文中的IPhysicsObject::IsMoveable方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。