//------------------------------------------------------------------------------------
// Adjust the aim dir before we pass it to the torsoAim pose modifier, this allows us
// to have the weapon deviate from the camera in certain circumstances
// Should only be called once per frame as it time-steps internal vars
//------------------------------------------------------------------------------------
void CLocalPlayerComponent::AdjustTorsoAimDir(float fFrameTime, Vec3 &aimDir)
{
	const f32 HALF_PI = gf_PI * 0.5f;
	float newElevLimit = HALF_PI;

	const f32 MIN_FLATTEN_LEVEL		= -0.3f;
	const f32 MAX_FLATTEN_LEVEL		= -0.1f;
	const f32 TARGET_FLATTEN_ELEV	= -0.2f;
	const f32 LIMIT_CHANGE_RATE		= HALF_PI;

	if (g_pGameCVars->pl_swimAlignArmsToSurface && m_rPlayer.IsSwimming() && (m_rPlayer.m_playerStateSwim_WaterTestProxy.GetRelativeWaterLevel() > MIN_FLATTEN_LEVEL))
	{
		newElevLimit = (m_rPlayer.m_playerStateSwim_WaterTestProxy.GetRelativeWaterLevel() - MIN_FLATTEN_LEVEL) / (MAX_FLATTEN_LEVEL - MIN_FLATTEN_LEVEL);
		newElevLimit = LERP(gf_PI * 0.5f, TARGET_FLATTEN_ELEV, clamp_tpl(newElevLimit, 0.0f, 1.0f));
	}

	float limitDelta = LIMIT_CHANGE_RATE * fFrameTime;
	float limitDiff	 = newElevLimit - m_stapElevLimit;
	float smoothedLimit = (float) fsel(fabs_tpl(limitDiff) - limitDelta, m_stapElevLimit + (fsgnf(limitDiff) * limitDelta), newElevLimit);
	m_stapElevLimit = smoothedLimit;

	if (smoothedLimit < HALF_PI)
	{
		//--- Need to limit, convert to yaw & elev, limit & then convert back
		float yaw, elev;
		float xy = aimDir.GetLengthSquared2D();
		if (xy > 0.001f)
		{
			yaw = atan2_tpl(aimDir.y,aimDir.x);
			elev = asin_tpl(clamp_tpl(aimDir.z, -1.f, +1.f));
		}
		else
		{
			yaw = 0.f;
			elev = (float)fsel(aimDir.z, +1.f, -1.f) * (gf_PI*0.5f);
		}

		elev = min(elev, smoothedLimit);

		float sinYaw, cosYaw;
		float sinElev, cosElev;

		sincos_tpl(yaw, &sinYaw, &cosYaw);
		sincos_tpl(elev, &sinElev, &cosElev);

		aimDir.x = cosYaw * cosElev;
		aimDir.y = sinYaw * cosElev;
		aimDir.z = sinElev;
	}
}
Esempio n. 2
0
//------------------------------------------------------------------------
void CVehicleViewSteer::Update(float dt)
{
	IEntity* pEntity = m_pVehicle->GetEntity();
	assert(pEntity);

	IVehicleMovement* pVehicleMovement = m_pVehicle->GetMovement();
	if (pVehicleMovement == NULL)
		return;

	IPhysicalEntity* pPhysEntity = pEntity->GetPhysics();
	if (!pPhysEntity)
		return;

	pe_status_dynamics dynStatus;
	pPhysEntity->GetStatus(&dynStatus);

	SMovementState movementState;
	pVehicleMovement->GetMovementState(movementState);
	const float     pedal        = pVehicleMovement->GetEnginePedal();
	const float     maxSpeed     = movementState.maxSpeed;
	const Matrix34 &pose         = m_pAimPart ? m_pAimPart->GetWorldTM() : pEntity->GetWorldTM();
	const Vec3      entityPos    = pose.GetColumn3();
	const Vec3      xAxis        = pose.GetColumn0();
	const Vec3      yAxis        = pose.GetColumn1();
	const Vec3      zAxis        = pose.GetColumn2();
	const float     forwardSpeed = dynStatus.v.dot(yAxis);
	const float     speedNorm    = clamp_tpl(forwardSpeed / maxSpeed, 0.0f, 1.0f);
	const Vec3      maxRotation  = m_maxRotation + speedNorm * (m_maxRotation2 - m_maxRotation);

	CalcLookAt(pose);
	if (m_lookAt.IsValid())
	{
		if (!m_lastOffset.IsValid())
		{
			m_position             = pose * m_localSpaceCameraOffset;
			m_lastOffset           = m_position - m_lookAt;
			m_lastOffsetBeforeElev = m_lastOffset;
		}

		Vec3 offset = m_lastOffsetBeforeElev;

		if (pedal < 0.1f && forwardSpeed < 1.0f)
		{
			// Going Backwards
			m_flags &= ~(eVCam_goingForwards | m_forwardFlags);
			m_flags |= m_backwardsFlags;
		}

		if (offset.dot(yAxis) < 0.8f && forwardSpeed > 1.f)
		{
			// Going Forwards
			m_flags &= ~m_backwardsFlags;
			m_flags |= eVCam_goingForwards | m_forwardFlags;
		}

		float sensitivity = (1.f - speedNorm) * m_stickSensitivity.z + speedNorm * m_stickSensitivity2.z;
		float rotate      = -m_rotatingAction.z * sensitivity;
		rotate = rotate * dt;

		if (zAxis.z > 0.1f)
		{
			// Safe to update curYaw
			Vec3 projectedX = xAxis;
			projectedX.z = 0.f;
			Vec3 projectedY = yAxis;
			projectedY.z = 0.f;
			const float newYaw    = atan2_tpl(offset.dot(projectedX), -(offset.dot(projectedY)));
			const float maxChange = DEG2RAD(270.f) * dt;
			const float delta     = clamp_tpl(newYaw - m_curYaw, -maxChange, +maxChange);
			m_curYaw += delta;
		}

		// Rotation Action
		{
			if (m_flags & eVCam_rotationClamp)
			{
				float newYaw = clamp_tpl(m_curYaw + rotate, -maxRotation.z, +maxRotation.z);
				rotate        = newYaw - m_curYaw;
				rotate        = clamp_tpl(newYaw - m_curYaw, -fabsf(rotate), +fabsf(rotate));
				m_rotation.z += rotate;
			}
			else
			{
				m_rotation.z = 0.f;
			}

			if (speedNorm > 0.1f)
			{
				float reduce = dt * 1.f;
				m_rotation.z = m_rotation.z - reduce * m_rotation.z / (fabsf(m_rotation.z) + reduce);
			}
		}

		// Ang Spring
		{
			float angSpeedCorrection = dt * dt * m_angSpeedCorrection / (dt * m_angSpeedCorrection + 1.f) * dynStatus.w.z;
			if ((m_flags & eVCam_rotationSpring) == 0)
			{
				m_angReturnSpeed   = 0.f;
				angSpeedCorrection = 0.f;
			}

			float difference = m_rotation.z - m_curYaw;
			float relax      = difference * (m_angReturnSpeed * dt) / ((m_angReturnSpeed * dt) + 1.f);

			const float delta = +relax + angSpeedCorrection + rotate;
			m_curYaw += delta;

			Matrix33 rot = Matrix33::CreateRotationZ(delta);
			offset = rot * offset;

			// Lerp the spring speed
			float angSpeedTarget = m_angReturnSpeed1 + speedNorm * (m_angReturnSpeed2 - m_angReturnSpeed1);
			m_angReturnSpeed     += (angSpeedTarget - m_angReturnSpeed) * (dt / (dt + 0.3f));
			m_angSpeedCorrection += (m_angSpeedCorrection0 - m_angSpeedCorrection) * (dt / (dt + 0.3f));
		}

		if (!offset.IsValid()) offset = m_lastOffset;

		// Velocity influence
		Vec3 displacement = -((2.f - speedNorm) * dt) * dynStatus.v;// - yAxis*(0.0f*speedNorm*(yAxis.dot(dynStatus.v))));

		float dot = offset.dot(displacement);
		if (dot < 0.f)
		{
			displacement = displacement + offset * -0.1f * (offset.dot(displacement) / offset.GetLengthSquared());
		}
		offset = offset + displacement;

		const float radius0   = fabsf(m_localSpaceCameraOffset.y);
		const float minRadius = radius0 * m_radiusMin;
		const float maxRadius = radius0 * m_radiusMax;
		float       radiusXY  = sqrtf(sqr(offset.x) + sqr(offset.y));

		Vec3 offsetXY = offset;
		offsetXY.z = 0.f;
		Vec3  accelerationV = (dynStatus.v - m_lastVehVel);
		float acceleration  = offsetXY.dot(accelerationV) / radiusXY;

		m_lastVehVel = dynStatus.v;
		m_radiusVel -= acceleration;
		m_radius    += m_radiusVel * dt - dt * m_radiusVelInfluence * offsetXY.dot(dynStatus.v) / radiusXY;
		m_radiusVel *= expf(-dt * m_radiusDampRate);
		m_radius    += (radius0 - m_radius) * (dt * m_radiusRelaxRate) / (dt * m_radiusRelaxRate + 1.f);
		m_radius     = clamp_tpl(m_radius, minRadius, maxRadius);
		offset       = offset * (m_radius / radiusXY);

		// Vertical motion
		float targetOffsetHeight = m_localSpaceCameraOffset.z * (m_radius / radius0);
		float oldOffsetHeight    = offset.z;
		offset.z += (targetOffsetHeight - offset.z) * (dt / (dt + 0.3f));
		Limit(offset.z, targetOffsetHeight - 2.f, targetOffsetHeight + 2.f);
		float verticalChange = offset.z - oldOffsetHeight;

		m_lastOffsetBeforeElev = offset;

		// Add up and down camera tilt
		{
			offset.z     -= verticalChange;
			m_rotation.x += dt * m_stickSensitivity.x * m_rotatingAction.x;
			m_rotation.x  = clamp_tpl(m_rotation.x, -maxRotation.x, +maxRotation.x);

			float elevAngleVehicle = m_inheritedElev * yAxis.z;     // yAxis.z == approx elevation angle

			float elevationAngle = m_rotation.x - elevAngleVehicle;

			float sinElev, cosElev;
			sincos_tpl(elevationAngle, &sinElev, &cosElev);
			float horizLen    = sqrtf(offset.GetLengthSquared2D());
			float horizLenNew = horizLen * cosElev - sinElev * offset.z;
			if (horizLen > 1e-4f)
			{
				horizLenNew /= horizLen;
				offset.x    *= horizLenNew;
				offset.y    *= horizLenNew;
				offset.z     = offset.z * cosElev + sinElev * horizLen;
			}
			offset.z += verticalChange;
		}

		if (!offset.IsValid()) offset = m_lastOffset;

		m_position = m_lookAt + offset;

		// Perform world intersection test.
		{
			// Initialise sphere and direction.
			primitives::sphere sphere;

			sphere.center = m_lookAt;
			sphere.r      = g_SteerCameraRadius;

			Vec3 direction = m_position - m_lookAt;

			// Calculate camera bounds.
			AABB localBounds;

			m_pVehicle->GetEntity()->GetLocalBounds(localBounds);

			const float cameraBoundsScale = 0.75f;

			localBounds.min *= cameraBoundsScale;
			localBounds.max *= cameraBoundsScale;

			OBB cameraBounds;

			Matrix34 worldTM = m_pVehicle->GetEntity()->GetWorldTM();

			cameraBounds.SetOBBfromAABB(Matrix33(worldTM), localBounds);

			// Try to find point on edge of camera bounds to begin swept sphere intersection test.
			Vec3 rayBoxIntersect;

			if (Intersect::Ray_OBB(Ray(m_position, -direction), worldTM.GetTranslation(), cameraBounds, rayBoxIntersect) > 0)
			{
				Vec3 temp = m_position - rayBoxIntersect;

				if (direction.Dot(temp) > 0.0f)
				{
					sphere.center = rayBoxIntersect;
					direction     = temp;
				}
			}

			// Perform swept sphere intersection test against world.
			geom_contact* pContact = NULL;

			IPhysicalEntity* pSkipEntities[10];

			float distance = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(sphere.type, &sphere, direction, ent_static | ent_terrain | ent_rigid | ent_sleeping_rigid,
			                                                                  &pContact, 0, (geom_colltype_player << rwi_colltype_bit) | rwi_stop_at_pierceable, 0, 0, 0,
			                                                                  pSkipEntities, m_pVehicle->GetSkipEntities(pSkipEntities, 10));

			if (distance > 0.0f)
			{
				// Sweep intersects world so calculate new offset.
				offset = (sphere.center + (direction.GetNormalizedSafe() * distance)) - m_lookAt;
			}
		}

		Interpolate(m_lastOffset, offset, 10.f, dt);

		m_position = m_lookAt + m_lastOffset;
	}
	else
	{
		CRY_ASSERT_MESSAGE(0, "camera will fail because lookat position is invalid");
	}

	m_rotatingAction.zero();
}
Esempio n. 3
0
//------------------------------------------------------------------------
void CIronSight::UpdateDepthOfField(CActor *pActor, float frameTime, float t)
{
	if(pActor)
	{
		CPlayer *pPlayer = static_cast<CPlayer *>(pActor);

		if(IMovementController *pMV = pActor->GetMovementController())
		{
			SMovementState ms;
			pMV->GetMovementState(ms);
			Vec3 start = ms.eyePosition;
			Vec3 dir = ms.eyeDirection;
			static ray_hit hit;

			IPhysicalEntity *pSkipEntities[10];
			int nSkip = CSingle::GetSkipEntities(m_pWeapon, pSkipEntities, 10);
			// jitter the direction (non-uniform disk sampling ... we want to bias the center in this case)
			f32 cosTheta, sinTheta;
			f32 theta = Random() * gf_PI2;
			f32 spreadAngle = DEG2RAD(g_pGameCVars->g_dof_sampleAngle)/2.0f;
			f32 scale = tan_tpl(spreadAngle);
			f32 radiusSqrt = scale * Random();
			sincos_tpl(theta, &cosTheta, &sinTheta);
			f32 x = radiusSqrt * cosTheta;
			f32 y = radiusSqrt * sinTheta;

			Matrix33 viewRotation(pPlayer->GetViewQuatFinal());

			Vec3 xOff = x * viewRotation.GetColumn0();
			Vec3 yOff = y * viewRotation.GetColumn2();

			// jitter
			if(true)
			{
				dir += xOff + yOff;
				dir.Normalize();
			}

			const float maxRelaxSpeed = 1.0f;

			f32 delta;

			if(gEnv->pPhysicalWorld->RayWorldIntersection(start, 1000.0f*dir, ent_all,
					rwi_pierceability(10)|rwi_ignore_back_faces, &hit, 1, pSkipEntities, nSkip))
			{
				delta = g_pGameCVars->g_dof_minHitScale*hit.dist - m_minDoF;
				Limit(delta, -g_pGameCVars->g_dof_minAdjustSpeed, g_pGameCVars->g_dof_minAdjustSpeed);
				//delta *= fabs(delta/minAdjustSpeed);
				m_minDoF += delta * frameTime;

				delta = g_pGameCVars->g_dof_maxHitScale*hit.dist - m_maxDoF;
				Limit(delta, -g_pGameCVars->g_dof_maxAdjustSpeed, g_pGameCVars->g_dof_maxAdjustSpeed);
				//delta *= fabs(delta/maxAdjustSpeed);
				m_maxDoF += delta * frameTime;
			}

			if(m_maxDoF - g_pGameCVars->g_dof_distAppart < m_minDoF)
			{
				m_maxDoF = m_minDoF + g_pGameCVars->g_dof_distAppart;
			}
			else
			{
				// relax max to min
				delta = m_minDoF - m_maxDoF;
				Limit(delta, -maxRelaxSpeed, maxRelaxSpeed);
				//delta *= fabs(delta/maxRelaxSpeed);
				m_maxDoF += delta * frameTime;
			}

			// the average is relaxed to the center between min and max
			m_averageDoF = (m_maxDoF - m_minDoF)/2.0f;
			Limit(delta, -g_pGameCVars->g_dof_averageAdjustSpeed, g_pGameCVars->g_dof_averageAdjustSpeed);
			//delta *= fabs(delta/averageAdjustSpeed);
			m_averageDoF += delta * frameTime;
		}
	}
}
Esempio n. 4
0
void CPlayerStateGround::OnPrePhysicsUpdate( CPlayer& player, const SActorFrameMovementParams &movement, float frameTime, const bool isHeavyWeapon, const bool isPlayer )
{
	const Matrix34A baseMtx = Matrix34A(player.GetBaseQuat());
	Matrix34A baseMtxZ(baseMtx * Matrix33::CreateScale(Vec3Constants<float>::fVec3_OneZ));
	baseMtxZ.SetTranslation(Vec3Constants<float>::fVec3_Zero);

	const CAutoAimManager& autoAimManager = g_pGame->GetAutoAimManager();
	const EntityId closeCombatTargetId = autoAimManager.GetCloseCombatSnapTarget();
	const IActor* pCloseCombatTarget = isPlayer && closeCombatTargetId && player.IsClient() ? g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(closeCombatTargetId) : NULL;

	if (pCloseCombatTarget)
	{
		ProcessAlignToTarget(autoAimManager, player, pCloseCombatTarget);
	}
	else
	{
		// This is to restore inertia if the ProcessAlignToTarget set it previously.
		if( m_inertiaIsZero )
		{
			CPlayerStateUtil::RestorePlayerPhysics( player );

			m_inertiaIsZero = false;
		}

		//process movement
		const bool isRemote = isPlayer && !player.IsClient();

		Vec3 move(ZERO);
		CPlayerStateUtil::CalculateGroundOrJumpMovement( player, movement, isHeavyWeapon, move );
		player.GetMoveRequest().type = eCMT_Normal;






		//apply movement
		Vec3 desiredVel(ZERO);
		Vec3 entityPos = player.GetEntity()->GetWorldPos();
		Vec3 entityRight(player.GetBaseQuat().GetColumn0());

		hwvec3 xmDesiredVel = HWV3Zero();

		hwmtx33 xmBaseMtxZ;
		HWMtx33LoadAligned(xmBaseMtxZ, baseMtxZ);
		hwmtx33 xmBaseMtxZOpt = HWMtx33GetOptimized(xmBaseMtxZ);

		hwvec3 xmMove					= HWVLoadVecUnaligned(&move);	
		simdf fGroundNormalZ;

#ifdef STATE_DEBUG
		bool debugJumping = (g_pGameCVars->pl_debug_jumping != 0);
#endif

		const SPlayerStats& stats = *player.GetActorStats();

		{
			xmDesiredVel = xmMove;

			Vec3 groundNormal = player.GetActorPhysics().groundNormal;

			if(!gEnv->bMultiplayer)
			{
				if (player.IsAIControlled())
					fGroundNormalZ = SIMDFLoadFloat(square(groundNormal.z));
				else
					fGroundNormalZ = SIMDFLoadFloat(groundNormal.z);
			}
			else
			{
				//If the hill steepness is greater than our minimum threshold
				if(groundNormal.z > 1.f - cosf(g_pGameCVars->pl_movement.mp_slope_speed_multiplier_minHill))
				{
					//Check if we are trying to move up or downhill
					groundNormal.z = 0.f;
					groundNormal.Normalize();

					Vec3 moveDir = move;
					moveDir.z = 0.f;
					moveDir.Normalize();

					float normalDotMove = groundNormal.Dot(moveDir);
					//Apply speed multiplier based on moving up/down hill and hill steepness
					float multiplier = normalDotMove < 0.f ? g_pGameCVars->pl_movement.mp_slope_speed_multiplier_uphill : g_pGameCVars->pl_movement.mp_slope_speed_multiplier_downhill;
					fGroundNormalZ = SIMDFLoadFloat(1.f - (1.f - player.GetActorPhysics().groundNormal.z) * multiplier);
				}
				else
				{
					fGroundNormalZ = SIMDFLoadFloat(1.0f);
				}
			}

			const float depthHi = g_pGameCVars->cl_shallowWaterDepthHi;
			const float depthLo = g_pGameCVars->cl_shallowWaterDepthLo;
			const float relativeBottomDepth = player.m_playerStateSwim_WaterTestProxy.GetRelativeBottomDepth();

			if( relativeBottomDepth > depthLo )
			{ // Shallow water speed slowdown
				float shallowWaterMultiplier = 1.0f;

				shallowWaterMultiplier = isPlayer
					? g_pGameCVars->cl_shallowWaterSpeedMulPlayer
					: g_pGameCVars->cl_shallowWaterSpeedMulAI;

				shallowWaterMultiplier = max(shallowWaterMultiplier, 0.1f);
				assert(shallowWaterMultiplier <= 1.0f);


				float shallowWaterDepthSpan = (depthHi - depthLo);
				shallowWaterDepthSpan = max(0.1f, shallowWaterDepthSpan);

				float slowdownFraction = (relativeBottomDepth - depthLo) / shallowWaterDepthSpan;
				slowdownFraction = clamp_tpl(slowdownFraction, 0.0f, 1.0f);
				shallowWaterMultiplier = LERP(1.0f, shallowWaterMultiplier, slowdownFraction);

				//avoid branch if m_stats.relativeBottomDepth <= 0.0f;
				shallowWaterMultiplier = (float)__fsel(-relativeBottomDepth, 1.0f, shallowWaterMultiplier);

				simdf vfShallowWaterMultiplier = SIMDFLoadFloat(shallowWaterMultiplier);

				xmDesiredVel = HWVMultiplySIMDF(xmDesiredVel, vfShallowWaterMultiplier);
			}
		}





		// Slow down on sloped terrain, simply proportional to the slope. 
		xmDesiredVel = HWVMultiplySIMDF(xmDesiredVel, fGroundNormalZ);

		//be sure desired velocity is flat to the ground
		hwvec3 vDesiredVelVert = HWMtx33RotateVecOpt(xmBaseMtxZOpt, xmDesiredVel);

		xmDesiredVel = HWVSub(xmDesiredVel, vDesiredVelVert);

		HWVSaveVecUnaligned(&desiredVel, xmDesiredVel);

		if (isPlayer)
		{
			Vec3 modifiedSlopeNormal = player.GetActorPhysics().groundNormal;
			float h = Vec2(modifiedSlopeNormal.x, modifiedSlopeNormal.y).GetLength(); // TODO: OPT: sqrt(x*x+y*y)
			float v = modifiedSlopeNormal.z;
			float slopeAngleCur = RAD2DEG(atan2_tpl(h, v));

			const float divisorH = (float)__fsel(-h, 1.0f, h);
			const float divisorV = (float)__fsel(-v, 1.0f, v);

			const float invV = __fres(divisorV);
			const float invH = __fres(divisorH);

			const float slopeAngleHor = 10.0f;
			const float slopeAngleVer = 50.0f;
			float slopeAngleFraction = clamp_tpl((slopeAngleCur - slopeAngleHor) * __fres(slopeAngleVer - slopeAngleHor), 0.0f, 1.0f);

			slopeAngleFraction = slopeAngleFraction * slopeAngleFraction * slopeAngleFraction;

			float slopeAngleMod = LERP(0.0f, 90.0f, slopeAngleFraction);

			float s, c;

			sincos_tpl(DEG2RAD(slopeAngleMod), &s, &c);

			const float hMultiplier = (float)__fsel(-h, 1.0f, s * invH);
			const float vMultiplier = (float)__fsel(-v, 1.0f, c * invV);

			modifiedSlopeNormal.x *= hMultiplier;
			modifiedSlopeNormal.y *= hMultiplier;
			modifiedSlopeNormal.z *= vMultiplier;

			//Normalize the slope normal if possible
			const float fSlopeNormalLength = modifiedSlopeNormal.len();
			const float fSlopeNormalLengthSafe = (float)__fsel(fSlopeNormalLength - 0.000001f, fSlopeNormalLength, 1.0f);
			modifiedSlopeNormal = modifiedSlopeNormal * __fres(fSlopeNormalLengthSafe);

			float alignment = min(modifiedSlopeNormal * desiredVel, 0.0f);

			// Also affect air control (but not as much), to prevent jumping up against steep slopes.

			alignment *= (float)__fsel(-fabsf(stats.onGround), LERP(0.7f, 1.0f, 1.0f - clamp_tpl(modifiedSlopeNormal.z * 100.0f, 0.0f, 1.0f)), 1.0f);

			modifiedSlopeNormal.z = modifiedSlopeNormal.z;

			desiredVel -= modifiedSlopeNormal * alignment;


#ifdef STATE_DEBUG
			if (debugJumping)
			{
				player.DebugGraph_AddValue("GroundSlope", slopeAngleCur);
				player.DebugGraph_AddValue("GroundSlopeMod", slopeAngleMod);
			}
#endif
		}





		Vec3 newVelocity = desiredVel;

		const float fNewSpeed = newVelocity.len();

		const float fVelocityMultiplier = (float)__fsel(fNewSpeed - 22.0f, __fres(fNewSpeed+FLT_EPSILON) * 22.0f, 1.0f);

		// TODO: Maybe we should tell physics about this new velocity ? Or maybe SPlayerStats::velocity ? (stephenn).
		player.GetMoveRequest().velocity = newVelocity * (stats.flashBangStunMult * fVelocityMultiplier);

#ifdef STATE_DEBUG
		if(g_pGameCVars->pl_debug_movement > 0)
		{
			const char* filter = g_pGameCVars->pl_debug_filter->GetString();
			const char* name = player.GetEntity()->GetName();
			if ((strcmp(filter, "0") == 0) || (strcmp(filter, name) == 0))
			{
				float white[] = {1.0f,1.0f,1.0f,1.0f};
				gEnv->pRenderer->Draw2dLabel(20, 450, 2.0f, white, false, "Speed: %.3f m/s", player.GetMoveRequest().velocity.len());

				if(g_pGameCVars->pl_debug_movement > 1)
				{
					gEnv->pRenderer->Draw2dLabel(35, 470, 1.8f, white, false, "Stance Speed: %.3f m/s - (%sSprinting)", player.GetStanceMaxSpeed(player.GetStance()), player.IsSprinting() ? "" : "Not ");
				}
			}
		}
#endif


























	}

	if( isPlayer )
	{
		CheckForVaultTrigger(player, frameTime);
	}
}