void CStickyProjectile::CalculateLocationForStick( const IEntity& projectile, const Vec3& collPos, const Vec3& collNormal, QuatT& outLocation ) const
{
	if(m_flags&eSF_OrientateToCollNormal)
	{
		const float bigz = cry_fabsf(collNormal.z)-cry_fabsf(collNormal.y);
		const Vec3 temp(0.f,(float)__fsel(bigz,1.f,0.f),(float)__fsel(bigz,0.f,1.f));
		outLocation.q = Quat(Matrix33::CreateOrientation( temp.Cross(collNormal), -collNormal, 0));

		AABB aabb;
		projectile.GetLocalBounds(aabb);
		outLocation.t = collPos + (outLocation.q.GetColumn2() * ((aabb.max.y-aabb.min.y)*0.5f));
	}
	else
	{
		outLocation.q = projectile.GetRotation();
		outLocation.t = collPos + (outLocation.q.GetColumn1() * 0.1f);
	}
}
Ejemplo n.º 2
0
void CNetPlayerInput::UpdateErrorSnap(const Vec3 &entPos, const Vec3 &desiredPos, f32 netPosDist, const Vec3 &desPosOffset, const CTimeValue &curTime)
{
	if (g_pGameCVars->pl_velocityInterpAlwaysSnap)
	{
		//--- Snap to target
		m_pPlayer->GetEntity()->SetPos(desiredPos);
		m_passedNetPos = true;
		m_passedPredictionPos = true;
	}
	else if (curTime > m_nextBCTime && !(m_pPlayer->m_stats.inFreefall.Value() > 0))
	{
		//--- Breadcrumbs dropped for simulated annealing, whilst the player is blocked we reduce the maximum
		//--- allowed offset until the character is snapped to the last net position
		Vec3 prevOffset = entPos - m_breadCrumb;
		bool blocked = false;
		if (!m_passedNetPos)
		{
			float moveDist = prevOffset.Dot(desPosOffset) / netPosDist;
			float moveSpeed  = moveDist / k_timePerBC;
			blocked = ((moveSpeed / m_netLerpSpeed) <= k_BCMovingRatio);
		}
		if (blocked)
		{
			m_blockedTime += k_timePerBC;
		}
		else
		{
			m_blockedTime = 0.0f;
		}

		m_breadCrumb = entPos;
		m_nextBCTime = curTime+k_timePerBC;

		Vec3 v0(desiredPos.x, desiredPos.y, 0.0f);
		Vec3 v1(m_predictedPosition.x, m_predictedPosition.y, 0.0f);
		Vec3 pt(entPos.x, entPos.y, 0.0f);
		Lineseg validPath(v0, v1);
		float t;
		float distSqrXY = Distance::Point_LinesegSq(pt, validPath, t);

		float heightDiff = m_predictedPosition.z - entPos.z;
		float blockedFactor = (1.0f - (m_blockedTime / k_maxBlockTime));
		float maxDistXY = !m_passedNetPos ? blockedFactor * k_maxInterpolateDist : k_reachedTargetAllowedDeviation;
		float timeOnGround = m_pPlayer->GetActorStats()->onGround;
		float allowedHeightDiff = (float)__fsel(timeOnGround - k_onGroundTime, k_allowedHeightDiff, k_allowedHeightDiffInAir);
		if ((distSqrXY > (maxDistXY * maxDistXY)) || (cry_fabsf(heightDiff) > allowedHeightDiff))
		{
			//--- Snap to target
			m_pPlayer->GetEntity()->SetPos(desiredPos);
			m_passedNetPos = true;
			const bool isfallen = m_pPlayer->m_stats.inFreefall.Value()==1;
		}
	}
}
Ejemplo n.º 3
0
//------------------------------------------------------------------------
bool CGunTurret::IsAiming(const Vec3 &pos, float treshold) const
{
	Vec3 tdir=(pos-GetWeaponPos()).normalized();

	float dot = GetWeaponDir().Dot(tdir);
	float angle=RAD2DEG(cry_acosf(CLAMP(dot,-1.f,1.f)));

	if(cry_fabsf(angle)>treshold)
		return false;

	return true;
}
void CVehicleMovementMPVTOL::ReceivedServerPathingData( const SVTOLPathPosParams& data )
{
    CryAutoCriticalSection lk(m_lock);

    //CryLog( "[VTOL] CLUPDATE: path[%d] loc[%f]", data.pathId, data.location );

    float netError = 0.f;
    if( m_pathing.pathingData.pathId==data.pathId && m_pathing.pCachedPathPtr )
    {
        netError = m_pathing.pCachedPathPtr->GetDistance( m_pathing.pathingData.location, data.location, m_pathing.shouldLoop );
        if(cry_fabsf(netError) > g_pGameCVars->v_MPVTOLNetworkSnapThreshold)
        {
            SnapToPathLoc(data);
            netError = 0.0f;
        }
    }
    // Let it out of a wait, if the server VTOL is moving on (avoids a snap)
    if(netError>(g_pGameCVars->v_MPVTOLNetworkSnapThreshold*0.4f) && m_pathing.waitTime)
    {
        m_pathing.waitTime = 0.f;
        m_pathing.targetSpeed = m_pathing.defaultSpeed;
    }
    m_pathing.networkError = netError;
}
void CVehicleMovementHelicopter::ProcessAI(const float deltaTime)
{
	FUNCTION_PROFILER( GetISystem(), PROFILE_GAME );

	CryAutoCriticalSection lk(m_lock);
	SVehiclePhysicsStatus* physStatus = &m_physStatus[k_physicsThread];
		
	if (m_arcade.m_handling.maxSpeedForward>0.f) // Use the new handling code
	{
		//ResetActions();
		m_movementAction.Clear();
		m_movementAction.isAI = true;

		SVehiclePhysicsHelicopterProcessAIParams params;
		params.pPhysStatus = physStatus;
		params.pInputAction = &m_inputAction;
		params.pAiRequest = &m_aiRequest;
		params.dt = deltaTime;
		params.aiRequiredVel = m_CurrentVel;
		params.aiCurrentSpeed = m_CurrentSpeed;
		params.aiYawResponseScalar = m_yawResponseScalar;
		m_yawResponseScalar = 1.f;
	
		// Use helper class to process the AI input
		// It will return a requested velocity, and change the input
		m_arcade.ProcessAI(params);

		// Get the output velocity
		m_CurrentVel = params.aiRequiredVel;
		m_CurrentSpeed = params.aiCurrentSpeed;
		return;
	}
	////////////////////// OLD DEPRECATED CODE :( //////////////////////////////////

	m_movementAction.Clear();
	ResetActions();

	// Our current state
	const Vec3 worldPos =  physStatus->pos;
	const Matrix33 worldMat( physStatus->q);
	const Matrix33 localMat( physStatus->q.GetInverted());
	const Ang3 worldAngles = Ang3::GetAnglesXYZ(worldMat);
	const Ang3 localAngles = Ang3::GetAnglesXYZ(localMat);

	const Vec3 currentVel = physStatus->v;
	const Vec3 currentVel2D(currentVel.x, currentVel.y, 0.0f);
	m_CurrentSpeed = m_CurrentVel.len(); //currentVel.len();
  float currentSpeed2d = currentVel2D.len();

	// +ve direction mean rotation anti-clocwise about the z axis - 0 means along y
	float currentDir = worldAngles.z;

	// to avoid singularity
	const Vec3 vWorldDir = worldMat.GetRow(1);
	const Vec3 vSideWays = worldMat.GetRow(0);
	const Vec3 vWorldDir2D =  Vec3( vWorldDir.x,  vWorldDir.y, 0.0f ).GetNormalizedSafe();

	// Our inputs
	float desiredSpeed = m_aiRequest.HasDesiredSpeed() ? m_aiRequest.GetDesiredSpeed() : 0.0f;
	Limit(desiredSpeed, -m_maxSpeed, m_maxSpeed);

	const Vec3 desiredMoveDir = m_aiRequest.HasMoveTarget() ? (m_aiRequest.GetMoveTarget() - worldPos).GetNormalizedSafe() : vWorldDir;
	Vec3 desiredMoveDir2D = Vec3(desiredMoveDir.x, desiredMoveDir.y, 0.0f);
	desiredMoveDir2D = desiredMoveDir2D.GetNormalizedSafe(desiredMoveDir2D);

	const Vec3 desiredVel = desiredMoveDir * desiredSpeed; 
	const Vec3 desiredVel2D(desiredVel.x, desiredVel.y, 0.0f);

  Vec3 desiredLookDir(desiredMoveDir);

  if (m_aiRequest.HasDesiredBodyDirectionAtTarget())
  {
	    desiredLookDir = m_aiRequest.GetDesiredBodyDirectionAtTarget().GetNormalizedSafe(desiredMoveDir);
  }
  else if (m_aiRequest.HasLookTarget())
  {
    desiredLookDir = (m_aiRequest.GetLookTarget() - worldPos).GetNormalizedSafe(desiredMoveDir);  
  }


	//const Vec3 desiredLookDir = m_aiRequest.HasLookTarget() ? (m_aiRequest.GetLookTarget() - worldPos).GetNormalizedSafe() : desiredMoveDir;
	const Vec3 desiredLookDir2D = Vec3(desiredLookDir.x, desiredLookDir.y, 0.0f).GetNormalizedSafe(vWorldDir2D);

  Vec3 prediction = m_aiRequest.HasBodyTarget() ? m_aiRequest.GetBodyTarget() : ZERO;

  prediction = (prediction.IsEquivalent(ZERO)) ? desiredMoveDir2D : prediction - worldPos;
  prediction.z = 0.0f;

  float speedLimit = prediction.GetLength2D();

	if(speedLimit > 0.0f)
	{
		prediction *= 1.0f / speedLimit;
	}

  Vec3 tempDir = currentVel2D.IsEquivalent(ZERO) ? localMat.GetRow(1) : currentVel2D;
  tempDir.z = 0.0f;
  tempDir.NormalizeFast();

	float dotProd = tempDir.dot(prediction);
	Limit(dotProd, FLT_EPSILON, 1.0f);

	float accel = m_enginePowerMax * min(2.0f,  1.0f / dotProd); // * dotProd;

	if (!m_aiRequest.HasDesiredBodyDirectionAtTarget())
	{
		dotProd *= dotProd;
		dotProd *= dotProd;
		float tempf = min(max(speedLimit * speedLimit, 2.0f), m_maxSpeed * dotProd);
		Limit(desiredSpeed, -tempf, tempf);
	}
	else if (dotProd < 0.0125f)
	{
		Limit(desiredSpeed, -m_maxSpeed * 0.25f, m_maxSpeed * 0.25f);
	}
  
  float posNeg = (float)__fsel(desiredSpeed - m_CurrentSpeed, 1.0f, -5.0f);

  if (desiredVel2D.GetLengthSquared() > FLT_EPSILON)
  {
	  m_CurrentSpeed = m_CurrentSpeed + posNeg * accel * deltaTime;
  }
  else
  {
    m_CurrentSpeed = m_CurrentSpeed + posNeg * accel * deltaTime;
  }

	if (posNeg > 0.0f && m_CurrentSpeed > desiredSpeed)
	{
		m_CurrentSpeed = desiredSpeed;
	}
	else if (posNeg < 0.0f && m_CurrentSpeed < desiredSpeed)
	{
		m_CurrentSpeed = desiredSpeed;
	}

	
	// ---------------------------- Rotation ----------------------------
	
	float desiredDir = (desiredLookDir2D.GetLengthSquared() > 0.0f) ? atan2f(-desiredLookDir2D.x, desiredLookDir2D.y) : atan2f(-vWorldDir2D.x, vWorldDir2D.y);
	while (currentDir < desiredDir - gf_PI)
		currentDir += 2.0f * gf_PI;
	while (currentDir > desiredDir + gf_PI)
		currentDir -= 2.0f * gf_PI;

	// ---------------------------- Yaw ----------------------------

	Ang3 dirDiff(0.0f, 0.0f, desiredDir - currentDir);
	dirDiff.RangePI();
	float absDiff   = fabsf(dirDiff.z);

	float rotSpeed		= (float)__fsel(dirDiff.z, m_yawPerRoll, -m_yawPerRoll);
	m_actionYaw		= m_actionYaw + deltaTime * (rotSpeed - m_actionYaw);

	float temp = fabsf(m_actionYaw);

	float multiplier = ((absDiff / (temp + 0.001f)) + 1.0f) * 0.5f;
	
	m_actionYaw	*= (float)__fsel(absDiff - temp, 1.0f, multiplier);

	// ---------------------------- Yaw ------------------------------

	m_CurrentVel = desiredMoveDir * m_CurrentSpeed;

  // ---------------------------- Pitch ----------------------------

  if (m_CurrentVel.GetLengthSquared2D() > 0.1f)
  {
    CalculatePitch(worldAngles, desiredMoveDir, currentSpeed2d, desiredSpeed, deltaTime);
  }
  else
  {
    Quat rot;
    rot.SetRotationVDir(desiredLookDir, 0.0f);
    float desiredXRot = Ang3::GetAnglesXYZ(rot).x + m_steeringDamage.x;

    m_actionPitch = worldAngles.x + (desiredXRot - worldAngles.x) * deltaTime/* * 10.0f*/;
    Limit(m_actionPitch, -m_maxPitchAngle * 2.0f, m_maxPitchAngle * 2.0f);
  }


	// ---------------------------- Roll ----------------------------
	float rollSpeed = GetRollSpeed();

	rollSpeed *= deltaTime;
	rollSpeed		= (float)__fsel(absDiff - rollSpeed, rollSpeed, absDiff);
	float roll		=(float) __fsel(dirDiff.z, -rollSpeed, rollSpeed);

	float speedPerUnit	   = 1.5f;
	float desiredRollSpeed = absDiff * speedPerUnit * (float)__fsel(dirDiff.z, 1.0f, -1.0f);
  
	desiredRollSpeed = -m_actionYaw * 2.5f;
  desiredRollSpeed += m_steeringDamage.y;

	m_actionRoll = m_actionRoll + deltaTime * (desiredRollSpeed - m_actionRoll);
	Limit(m_actionRoll, -m_maxRollAngle + m_steeringDamage.y, m_maxRollAngle - m_steeringDamage.y);
	m_actionRoll *= m_rollDamping;
	// ---------------------------- Roll ----------------------------


	// ---------------------------- Convert and apply ----------------------------
	Ang3 angles(m_actionPitch, m_actionRoll, worldAngles.z + deltaTime * m_actionYaw);
	
	pe_params_pos paramPos;
	paramPos.q.SetRotationXYZ(angles);
	paramPos.q.Normalize();

	IPhysicalEntity * pPhysicalEntity = GetPhysics();
	pPhysicalEntity->SetParams(&paramPos, 1);

	pe_action_set_velocity vel;
	vel.v = m_CurrentVel + m_netPosAdjust;
	pPhysicalEntity->Action(&vel, 1);

	// ---------------------------- Convert and apply ----------------------------

  m_rpmScale = max(0.2f, cry_fabsf(m_CurrentSpeed / m_maxSpeed));
}
Ejemplo n.º 6
0
//------------------------------------------------------------------------
void CProjectile::Ricochet(EventPhysCollision *pCollision)
{
	IActor *pActor = g_pGame->GetIGameFramework()->GetClientActor();
	if (!pActor)
		return;

	Vec3 dir=pCollision->vloc[0];
	dir.NormalizeSafe();

	float dot=pCollision->n.Dot(dir);

	if (dot>=0.0f) // backface
		return;

	float b=0,f=0;
	uint matPierceability=0;
	if (!gEnv->pPhysicalWorld->GetSurfaceParameters(pCollision->idmat[1], b, f, matPierceability))
		return;

	matPierceability&=sf_pierceable_mask;
	float probability=0.25+0.25*(MAX(0,7-matPierceability)/7.0f);
	if ((matPierceability && matPierceability>=8) || Random()>probability)
		return;

	f32 cosine = dir.Dot(-pCollision->n);
	if (cosine>1.0f)cosine=1.0f;
	if (cosine<-1.0f)	cosine=-1.0f;
	float angle=RAD2DEG( cry_fabsf(cry_acosf(cosine)) );
	if (angle<10.0f)
		return;

	Vec3 ricochetDir = -2.0f*dot*pCollision->n+dir;
	ricochetDir.NormalizeSafe();

	Ang3 angles=Ang3::GetAnglesXYZ(Matrix33::CreateRotationVDir(ricochetDir));

	float rx=Random()-0.5f;
	float rz=Random()-0.5f;

	angles.x+=rx*DEG2RAD(10.0f);
	angles.z+=rz*DEG2RAD(10.0f);

	ricochetDir=Matrix33::CreateRotationXYZ(angles).GetColumn(1).normalized();

	Lineseg line(pCollision->pt, pCollision->pt+ricochetDir*20.0f);
	Vec3 player = pActor->GetEntity()->GetWorldPos();

	float t;
	float distanceSq=Distance::Point_LinesegSq(player, line, t);

	if (distanceSq < 7.5*7.5 && (t>=0.0f && t<=1.0f))
	{
		if (distanceSq >= 0.25*0.25)
		{
			Sphere s;
			s.center = player;
			s.radius = 6.0f;

			Vec3 entry,exit;
			int intersect=Intersect::Lineseg_Sphere(line, s, entry,exit);
			if (intersect) // one entry or one entry and one exit
			{
				if (intersect==0x2)
					entry=pCollision->pt;
				RicochetSound(entry, ricochetDir);

				//gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(entry, ColorB(255, 255, 255, 255), entry+ricochetDir, ColorB(255, 255, 255, 255), 2);
			}
		}
	}
}
//------------------------------------------------------------------------
void CRapid::Update(float frameTime, uint32 frameId)
{
	FUNCTION_PROFILER( GetISystem(), PROFILE_GAME );

	PlayStopRapidFireIfNeeded();

	BaseClass::Update(frameTime, frameId);

	if (m_speed <= 0.0f && m_acceleration < 0.0001f)
	{
		FinishDeceleration();
		return;
	}

	CActor* pOwnerActor = m_pWeapon->GetOwnerActor();
	const bool isOwnerClient = pOwnerActor ? pOwnerActor->IsClient() : false;
	const bool isOwnerPlayer = pOwnerActor ? pOwnerActor->IsPlayer() : false;

	m_pWeapon->RequireUpdate(eIUS_FireMode);

	m_speed = m_speed + m_acceleration*frameTime;

	if (m_speed > m_fireParams->rapidparams.max_speed)
	{
		m_speed = m_fireParams->rapidparams.max_speed;
		m_rapidFlags &= ~eRapidFlag_accelerating;
	}

	if ((m_speed >= m_fireParams->rapidparams.min_speed) && !(m_rapidFlags & eRapidFlag_decelerating))
	{
		float dt = 1.0f;
		if (cry_fabsf(m_speed)>0.001f && cry_fabsf(m_fireParams->rapidparams.max_speed)>0.001f)
		{
			dt = m_speed * (float)__fres(m_fireParams->rapidparams.max_speed);
		}
		CRY_ASSERT(m_fireParams->fireparams.rate > 0);
		
		m_next_shot_dt = 60.0f* (float)__fres((m_fireParams->fireparams.rate*dt));

		if (CanFire(false))
		{
			if (!OutOfAmmo())
			{
				const bool firing = (m_rapidFlags & eRapidFlag_netShooting) || Shoot(true, m_fireParams->fireparams.autoReload);
				Firing(firing);
			}
			else
			{
				StopFire();
			}
		}
	}
	else if (m_firing)
	{
		StopFire();
		if (OutOfAmmo() && isOwnerPlayer)
		{
			m_pWeapon->Reload();
		}
	}

	if ((m_speed < m_fireParams->rapidparams.min_speed) && (m_acceleration < 0.0f) && !(m_rapidFlags & eRapidFlag_decelerating))
		Accelerate(m_fireParams->rapidparams.deceleration);

	UpdateRotation(frameTime);
	UpdateFiring(pOwnerActor, isOwnerClient, isOwnerPlayer, frameTime);
}
//------------------------------------------------------------------------
void CScriptControlledPhysics::OnPostStep(EventPhysPostStep *pPostStep)
{
	pe_action_set_velocity av;

	bool moving=m_moving;
	bool rotating=m_rotating;

	float dt=pPostStep->dt;

	if(m_moving)
	{
		Vec3 current=pPostStep->pos;
		Vec3 target=m_moveTarget;
		Vec3 delta=target-current;
		float distance=delta.len();
		Vec3 dir=delta;

		if(distance>0.01f)
			dir *= (1.0f/distance);

		if(distance<0.01f)
		{
			m_speed=0.0f;
			m_moving=false;

			pPostStep->pos=target;

			av.v=ZERO;
		}
		else
		{
			float a=m_speed/m_stopTime;
			float d=m_speed*m_stopTime-0.5f*a*m_stopTime*m_stopTime;

			if(distance<=(d+0.01f))
				m_acceleration=(distance-m_speed*m_stopTime)/(m_stopTime*m_stopTime);

			m_speed=m_speed+m_acceleration*dt;

			if(m_speed>=m_maxSpeed)
			{
				m_speed=m_maxSpeed;
				m_acceleration=0.0f;
			}
			else if(m_speed*dt>distance)
				m_speed=distance/dt;
			else if(m_speed<0.05f)
				m_speed=0.05f;

			av.v=dir*m_speed;
		}
	}

	if(m_rotating)
	{
		Quat current=pPostStep->q;
		Quat target=m_rotationTarget;

		Quat rotation=target*!current;
		float angle=cry_acosf(CLAMP(rotation.w, -1.0f, 1.0f))*2.0f;
		float original=angle;

		if(angle>gf_PI)
			angle=angle-gf_PI2;
		else if(angle<-gf_PI)
			angle=angle+gf_PI2;

		if(cry_fabsf(angle)<0.001f)
		{
			m_rotationSpeed=0.0f;
			m_rotating=false;
			pPostStep->q=m_rotationTarget;
			av.w=ZERO;
		}
		else
		{
			float a=m_rotationSpeed/m_rotationStopTime;
			float d=m_rotationSpeed*m_stopTime-0.5f*a*m_rotationStopTime*m_rotationStopTime;

			if(cry_fabsf(angle)<d+0.001f)
				m_rotationAcceleration=(angle-m_rotationSpeed*m_rotationStopTime)/(m_rotationStopTime*m_rotationStopTime);

			m_rotationSpeed=m_rotationSpeed+sgn(angle)*m_rotationAcceleration*dt;

			if(cry_fabsf(m_rotationSpeed*dt)>cry_fabsf(angle))
				m_rotationSpeed=angle/dt;
			else if(cry_fabsf(m_rotationSpeed)<0.001f)
				m_rotationSpeed=sgn(m_rotationSpeed)*0.001f;
			else if(cry_fabsf(m_rotationSpeed)>=m_rotationMaxSpeed)
			{
				m_rotationSpeed=sgn(m_rotationSpeed)*m_rotationMaxSpeed;
				m_rotationAcceleration=0.0f;
			}

		}

		if(cry_fabsf(angle)>=0.001f)
			av.w=(rotation.v/cry_sinf(original*0.5f)).normalized();

		av.w*=m_rotationSpeed;
	}

	if(moving || rotating)
	{
		if(IPhysicalEntity *pPE=GetEntity()->GetPhysics())
			pPE->Action(&av);
	}

	if((moving && !m_moving) || (rotating && !m_rotating))
		GetEntity()->SetWorldTM(Matrix34::Create(GetEntity()->GetScale(), pPostStep->q, pPostStep->pos));
}
Ejemplo n.º 9
0
//------------------------------------------------------------------------
void CRapid::Update(float frameTime, uint32 frameId)
{
  FUNCTION_PROFILER( GetISystem(), PROFILE_GAME );

  CSingle::Update(frameTime, frameId);

	if (m_speed <= 0.0f && m_acceleration < 0.0001f)
	{
		FinishDeceleration();
		return;
	}

	m_pWeapon->RequireUpdate(eIUS_FireMode);

	m_speed = m_speed + m_acceleration*frameTime;

	if (m_speed > m_pShared->rapidparams.max_speed)
	{
		m_speed = m_pShared->rapidparams.max_speed;
		m_accelerating = false;
	}

	if ((m_speed >= m_pShared->rapidparams.min_speed) && (!m_decelerating))
	{
		float dt = 1.0f;
		if (cry_fabsf(m_speed)>0.001f && cry_fabsf(m_pShared->rapidparams.max_speed>0.001f))
			dt=m_speed/m_pShared->rapidparams.max_speed;
		m_next_shot_dt = 60.0f/(m_pShared->fireparams.rate*dt);

		bool canShoot = CanFire(false);

		if (canShoot)
		{
			if (!OutOfAmmo())
			{
				if (m_netshooting)
					Firing(true);
				else
					Firing(Shoot(true, false));

				if (m_firing && !(m_pShared->rapidparams.camshake_rotate.IsZero() && m_pShared->rapidparams.camshake_shift.IsZero()))
				{
					CActor *act = m_pWeapon->GetOwnerActor();
					if (act && act->IsClient())
					{
						IView *pView = g_pGame->GetIGameFramework()->GetIViewSystem()->GetActiveView();
						if (pView)            
							pView->SetViewShake(Ang3(m_pShared->rapidparams.camshake_rotate), m_pShared->rapidparams.camshake_shift, m_next_shot_dt/m_pShared->rapidparams.camshake_perShot, m_next_shot_dt/m_pShared->rapidparams.camshake_perShot, 0, 1);            
					}
				}
			}
			else
			{
				Firing(false);
				Accelerate(m_pShared->rapidparams.deceleration);
				if (m_pWeapon->GetOwnerActor() && m_pWeapon->GetOwnerActor()->IsPlayer())
				{
					SmokeEffect();
					m_pWeapon->Reload();
				}
			}
		}
	}
	else if (m_firing)
	{
		Firing(false);
		if (OutOfAmmo() && m_pWeapon->GetOwnerActor() && m_pWeapon->GetOwnerActor()->IsPlayer())
		{
			SmokeEffect();
			m_pWeapon->Reload();
		}
	}

	if ((m_speed < m_pShared->rapidparams.min_speed) && (m_acceleration < 0.0f) && (!m_decelerating))
		Accelerate(m_pShared->rapidparams.deceleration);

	UpdateRotation(frameTime);
	UpdateSound(frameTime);
}
Ejemplo n.º 10
0
//------------------------------------------------------------------------
void CScriptControlledPhysics::OnPostStep(EventPhysPostStep *pPostStep)
{
    pe_action_set_velocity av;

    const bool moving = m_moving;
    const bool rotating = m_rotating;

    const float deltaTime = pPostStep->dt;

    if (m_moving)
        {
            const Vec3 current = pPostStep->pos;
            const Vec3 target = m_moveTarget;
            const Vec3 delta = target - current;
            const float distanceSq = delta.len2();

            if (distanceSq <= sqr(0.025f) || (delta.dot(m_lastVelocity) < 0.0f))
                {
                    m_speed = 0.0f;
                    m_moving = false;
                    m_lastVelocity.zero();

                    pPostStep->pos = target;

                    av.v = ZERO;
                }
            else
                {
                    float velocity = m_speed;
                    float acceleration = m_acceleration;
                    Vec3 direction = delta;
                    const float distanceToEnd = direction.NormalizeSafe();

                    // Accelerate
                    velocity = std::min(velocity + acceleration * deltaTime, m_maxSpeed);

                    // Calculate acceleration and time needed to stop
                    const float accelerationNeededToStop = (-(velocity*velocity) / distanceToEnd) / 2;
                    if (fabsf(accelerationNeededToStop) > 0.0f)
                        {
                            const float timeNeededToStop = sqrtf((distanceToEnd / 0.5f) / fabsf(accelerationNeededToStop));

                            if (timeNeededToStop < m_stopTime)
                                {
                                    acceleration = accelerationNeededToStop;
                                }
                        }

                    // Prevent overshooting
                    if ((velocity * deltaTime) > distanceToEnd)
                        {
                            const float multiplier = distanceToEnd / fabsf(velocity * deltaTime);
                            velocity *= multiplier;
                            acceleration *= multiplier;
                        }

                    m_acceleration = acceleration;
                    m_speed = velocity;

                    m_lastVelocity = direction * velocity;
                    av.v = direction * velocity;
                }
        }

    if (m_rotating)
        {
            Quat current=pPostStep->q;
            Quat target=m_rotationTarget;

            Quat rotation=target*!current;
            float angle=cry_acosf(CLAMP(rotation.w, -1.0f, 1.0f))*2.0f;
            float original=angle;
            if (angle>gf_PI)
                angle=angle-gf_PI2;
            else if (angle<-gf_PI)
                angle=angle+gf_PI2;

            if (cry_fabsf(angle)<0.01f)
                {
                    m_rotationSpeed=0.0f;
                    m_rotating=false;
                    pPostStep->q=m_rotationTarget;
                    av.w=ZERO;
                }
            else
                {
                    float a=m_rotationSpeed/m_rotationStopTime;
                    float d=m_rotationSpeed*m_stopTime-0.5f*a*m_rotationStopTime*m_rotationStopTime;

                    if (cry_fabsf(angle)<d+0.001f)
                        m_rotationAcceleration=(angle-m_rotationSpeed*m_rotationStopTime)/(m_rotationStopTime*m_rotationStopTime);

                    m_rotationSpeed=m_rotationSpeed+sgn(angle)*m_rotationAcceleration*deltaTime;
                    if (cry_fabsf(m_rotationSpeed*deltaTime)>cry_fabsf(angle))
                        m_rotationSpeed=angle/deltaTime;
                    else if (cry_fabsf(m_rotationSpeed)<0.001f)
                        m_rotationSpeed=sgn(m_rotationSpeed)*0.001f;
                    else if (cry_fabsf(m_rotationSpeed)>=m_rotationMaxSpeed)
                        {
                            m_rotationSpeed=sgn(m_rotationSpeed)*m_rotationMaxSpeed;
                            m_rotationAcceleration=0.0f;
                        }
                }

            if(cry_fabsf(angle)>=0.001f)
                av.w=(rotation.v/cry_sinf(original*0.5f)).normalized();
            av.w*=m_rotationSpeed;
        }

    if (moving || rotating)
        {
            if (IPhysicalEntity *pPE=GetEntity()->GetPhysics())
                pPE->Action(&av, 1);
        }
    /*
    	if ((moving && !m_moving) || (rotating && !m_rotating))
    		GetEntity()->SetWorldTM(Matrix34::Create(GetEntity()->GetScale(), pPostStep->q, pPostStep->pos));
    */
}
QuatT CStrafeOffset::Compute(float frameTime)
{
	const float STAP_MF_Front				= 1.0f;
	const float STAP_MF_Back				= 1.0f;
	const float STAP_MF_StrafeLeft			= 1.0f;
	const float STAP_MF_StrafeRight			= 1.0f;

	static const float MIN_VERT_DIR = 0.2f;
	static const float MAX_VERT_DIR = 1.0f;
	static const float MIN_HORIZ_DIR  = 0.2f;
	static const float MAX_HORIZ_DIR  = 3.0f;
	static const float runEaseFactor = 0.2f;

	const float MIN_SPEED = 0.2f;
	const float MAX_SPEED = 4.0f;

	float rotationFactor = 1.0f;
	float strafeFactor = 1.0f;

	Ang3 inputRot = m_gameParams.inputRot;
	float absInputRotHoriz = cry_fabsf(inputRot.z) * rotationFactor;

	float horizSpeed = m_gameParams.velocity.GetLength2D();
	float runFactor	= (horizSpeed - MIN_SPEED) / (MAX_SPEED - MIN_SPEED);
	const float horizRotFactor = clamp(-m_gameParams.aimDirection.z * (absInputRotHoriz - MIN_HORIZ_DIR) / (MAX_HORIZ_DIR - MIN_HORIZ_DIR), 0.0f, 1.0f);
	runFactor = max(runFactor, horizRotFactor);
	runFactor = clamp(runFactor, 0.0f, 1.0f);
	m_runFactor = ((runFactor * runEaseFactor) + (m_runFactor * (1.0f - runEaseFactor)));

	//--- Calculate movement acceleration
	const float invFrontAugmentation = m_staticParams.accelerationFrontAugmentation != 0.0 ? (1.0f / m_staticParams.accelerationFrontAugmentation) : 1.0f;
	const Vec3 inputMoveAugmented = Vec3(
		m_gameParams.inputMove.x * invFrontAugmentation,
		m_gameParams.inputMove.y * m_staticParams.accelerationFrontAugmentation,
		0.0f);
	Interpolate(m_smoothedVelocity, inputMoveAugmented, m_staticParams.velocityLowPassFilter, frameTime);

	const Vec3 velocityDerivative = (frameTime > 0.0) ? ((m_smoothedVelocity - m_lastVelocity) / frameTime) : Vec3(ZERO);
	m_lastVelocity = m_smoothedVelocity;

	float interpFront = SignedPow(clamp(velocityDerivative.y * m_staticParams.velocityInterpolationMultiplier, -1, 1), m_staticParams.accelerationSmoothing);
	interpFront *= (float)__fsel(interpFront, STAP_MF_Front, STAP_MF_Back) * strafeFactor;
	Interpolate(m_interpFront, interpFront, m_staticParams.velocityLowPassFilter, frameTime);
	float interpSide = SignedPow(clamp(velocityDerivative.x * m_staticParams.velocityInterpolationMultiplier, -1, 1), m_staticParams.accelerationSmoothing);
	interpSide *= (float)__fsel(interpSide, STAP_MF_StrafeLeft, STAP_MF_StrafeRight) * strafeFactor;
	Interpolate(m_interpSide, interpSide, m_staticParams.velocityLowPassFilter, frameTime);

	// create offsets
	QuatT strafeOffset(IDENTITY);

	Vec3 posSize = m_staticParams.strafe_offset;
	Ang3 sideRotSize = m_staticParams.side_strafe_rot;
	Ang3 frontRotSize = m_staticParams.front_strafe_rot;

	const float cmToMeter = 1.0f / 100.0f;
	const float degreeToRadians = 3.14159f / 180.0f;

	strafeOffset.t.x -= m_interpSide * posSize.x * cmToMeter;
	strafeOffset.t.y -= m_interpFront * posSize.y * cmToMeter;
	strafeOffset.t.z -= max(std::abs(m_interpFront), std::abs(m_interpSide)) * posSize.z * cmToMeter;
	strafeOffset.q *= Quat(sideRotSize * m_interpSide * degreeToRadians);
	strafeOffset.q *= Quat(frontRotSize * m_interpFront * degreeToRadians);

	return strafeOffset;
}
Ejemplo n.º 12
0
//------------------------------------------------------------------------
void CGunTurret::UpdateOrientation(float deltaTime)
{
	FUNCTION_PROFILER(GetISystem(), PROFILE_GAME);

	bool changed = false;
	bool searching = (m_targetId==0 && m_turretparams.searching);
	float speed	= searching ? m_turretparams.search_speed : m_turretparams.turn_speed;

	assert(m_goalYaw >= 0.f && m_goalYaw <= gf_PI2);

	// update turret
	Matrix34 turretTM = GetEntity()->GetSlotLocalTM(eIGS_Aux0, false);
	Ang3 turretAngles(turretTM);

	if(turretAngles.z < 0.0f)
		turretAngles.z+=gf_PI2;

	if(cry_fabsf(m_goalYaw-turretAngles.z) > gf_PI)
	{
		if(m_goalYaw >= gf_PI)
			turretAngles.z += gf_PI2;
		else
			turretAngles.z -= gf_PI2;
	}

	if(m_turretparams.yaw_range < 360.f)
	{
		// reverse, to avoid forbidden range
		if(m_goalYaw > gf_PI && turretAngles.z < gf_PI)
			turretAngles.z += gf_PI2;
		else if(m_goalYaw < gf_PI && turretAngles.z > gf_PI)
			turretAngles.z -= gf_PI2;
	}

	if(cry_fabsf(turretAngles.z-m_goalYaw) > 0.001f)
	{
		Interp(turretAngles.z, m_goalYaw, speed, deltaTime, 0.25f*speed);

		if(m_turretSound == INVALID_SOUNDID && gEnv->IsClient())
			m_turretSound = PlayAction(g_pItemStrings->turret);

		changed = true;
	}
	else if(m_turretSound != INVALID_SOUNDID)
	{
		StopSound(m_turretSound);
		m_turretSound = INVALID_SOUNDID;
	}

	if(changed)
	{
		turretTM.SetRotationXYZ(turretAngles,turretTM.GetTranslation());
		GetEntity()->SetSlotLocalTM(eIGS_Aux0, turretTM);
	}

	// update weapon
	Matrix34 weaponTM = GetEntity()->GetSlotLocalTM(eIGS_ThirdPerson, false);
	Ang3 weaponAngles(weaponTM);

	weaponAngles.z = turretAngles.z;

	if(cry_fabsf(weaponAngles.x-m_goalPitch) > 0.001f)
	{
		Interp(weaponAngles.x, m_goalPitch, speed, deltaTime, 0.25f*speed);

		if(m_cannonSound == INVALID_SOUNDID && gEnv->IsClient())
			m_cannonSound = PlayAction(g_pItemStrings->cannon);

		changed = true;
	}
	else if(m_cannonSound != INVALID_SOUNDID)
	{
		StopSound(m_cannonSound);
		m_cannonSound = INVALID_SOUNDID;
	}

	if(changed)
	{
		weaponTM.SetRotationXYZ(weaponAngles);
		Vec3 w_trans = turretTM.TransformPoint(m_radarHelperPos);
		//Vec3 w_trans = GetSlotHelperPos(eIGS_Aux0,m_radarHelper.c_str(),false);
		weaponTM.SetTranslation(w_trans);

		GetEntity()->SetSlotLocalTM(eIGS_ThirdPerson, weaponTM);

		if(GetEntity()->IsSlotValid(eIGS_Aux1))
		{
			Vec3 b_trans = weaponTM.TransformPoint(m_barrelHelperPos);
			//Vec3 b_trans = GetSlotHelperPos(eIGS_ThirdPerson,m_barrelHelper.c_str(),false);
			weaponTM.SetTranslation(b_trans);
			GetEntity()->SetSlotLocalTM(eIGS_Aux1, weaponTM*m_barrelRotation);
		}

		if(gEnv->IsClient())
		{
			for(TEffectInfoMap::const_iterator it=m_effects.begin(); it!=m_effects.end(); ++it)
			{
				Matrix34 tm(GetSlotHelperRotation(eIGS_ThirdPerson,it->second.helper.c_str(),true), GetSlotHelperPos(eIGS_ThirdPerson,it->second.helper.c_str(),true));
				SetEffectWorldTM(it->first, tm);
			}
		}
	}

	UpdatePhysics();

	if(g_pGameCVars->i_debug_turrets == eGTD_Basic)
	{
		DrawDebug();
		//gEnv->pRenderer->DrawLabel(GetEntity()->GetWorldPos(), 1.4f, "%s yaw: %.2f, goalYaw: %.2f (%.2f), goalPitch: %.2f (%.2f/%.2f)", searching?"[search]":"", RAD2DEG(turretAngles.z), RAD2DEG(m_goalYaw), 0.5f*(m_turretparams.yaw_range), RAD2DEG(m_goalPitch), m_turretparams.min_pitch, m_turretparams.max_pitch);
	}
}