//------------------------------------------------------------------------
void CVehicleMovementStdBoat::UpdateRunSound(const float deltaTime)
{
	Vec3 localAccel(ZERO);
	m_measureSpeedTimer+=deltaTime;

	if (m_measureSpeedTimer > 0.25f)
	{
		const Vec3& v = m_physStatus[k_mainThread].v;
		Vec3 accel = (v - m_lastMeasuredVel) * (1.f/m_measureSpeedTimer);
		localAccel = accel * m_physStatus[k_mainThread].q;

		m_lastMeasuredVel = v;
		m_measureSpeedTimer = 0.f;
	}

	if (m_pVehicle->IsProbablyDistant())
		return;

  // rpm dropdown for waves
  if (m_rpmPitchDir != 0)    
  { 
    float speed = (m_rpmPitchDir > 0) ? 0.1f : -0.8f; // quick down, slow up
    m_waveSoundPitch += deltaTime * speed;

    if (m_waveSoundPitch < -m_waveSoundAmount) // dropdown amount
    {
      m_waveSoundPitch = -m_waveSoundAmount;
      m_rpmPitchDir = 1;
    }      
    else if (m_waveSoundPitch > 0.f)
    {
      m_waveSoundPitch = 0.f;
      m_rpmPitchDir = 0;
    }
  }

  if (m_rpmPitchSpeed>0.f)
  {    
    const float maxPedal = (!m_inWater) ? 1.f : Boosting() ? 0.8f : 0.7f;

    // pitch rpm with pedal          
    float pedal = GetEnginePedal();
    pedal = sgnnz(pedal)*max(ms_engineSoundIdleRatio, min(maxPedal, abs(pedal))); // clamp "pedal" to [0.2..0.7] range

    float delta = pedal - m_rpmScaleSgn;
    m_rpmScaleSgn = max(-1.f, min(1.f, m_rpmScaleSgn + sgn(delta)*min(abs(delta), m_rpmPitchSpeed*deltaTime)));

    // skip transition around 0 when on pedal (sounds more realistic)
    if (abs(GetEnginePedal()) > 0.001f && abs(delta) > 0.001f && sgn(m_rpmScaleSgn) != sgn(delta) && abs(m_rpmScaleSgn) <= 0.3f)
      m_rpmScaleSgn = sgn(delta)*0.3f;

    // for normal driving, rpm is clamped at max defined by sound dept
    m_rpmScale = abs(m_rpmScaleSgn);
    m_rpmScale = min(1.f, max(ms_engineSoundIdleRatio, m_rpmScale + m_waveSoundPitch));

		m_pIEntityAudioProxy->SetRtpcValue(m_audioControlIDs[eSID_VehicleRPM], m_rpmScale);
  }
}
示例#2
0
//------------------------------------------------------------------------
bool CGunTurret::GetTargetAngles(const Vec3 &targetPos, float &z, float &x) const
{
	// turret rotation reachability check
	Vec3 weaponPos = GetWeaponPos();
	Vec3 targetDir = targetPos - weaponPos;

	if(targetDir.len2() < minLenSqr)
		return false;

	// local dir to target
	Vec3 targetDirLocal = GetEntity()->GetWorldTM().GetInverted().TransformVector(targetDir);

	// angle around z
	Vec3 targetDirZ(targetDirLocal.x, targetDirLocal.y, 0.f);

	if(targetDirZ.len2() < minLenSqr)
		z = 0.f;
	else
	{
		targetDirZ.Normalize();
		float cosZ = max(-1.f, min(1.f, FORWARD_DIRECTION * targetDirZ));
		z = acos_tpl(cosZ) * -sgnnz(targetDirZ.x);

		if(z<0.0f)
			z+=gf_PI2;
	}

	// angle around x
	Vec3 targetDirX(targetDirLocal);
	Vec3 targetDirBase(targetDirLocal.x, targetDirLocal.y, 0);

	if(targetDirBase.len2() < minLenSqr)
		x = 0.0f;
	else
	{
		targetDirX.Normalize();
		targetDirBase.Normalize();

		float cosX = max(-1.f, min(1.f, targetDirBase * targetDirX));
		x = acos_tpl(cosX) * sgnnz(targetDirX.z);
	}

	return true;
}
示例#3
0
//----------------------------------------------------------------------------
void CHomingMissile::UpdateCruiseMissile(float frameTime)
{

	IRenderer* pRenderer = gEnv->pRenderer;
	IRenderAuxGeom* pGeom = pRenderer->GetIRenderAuxGeom();
	float color[4] = {1,1,1,1};
	const static float step = 15.f;  
	float y = 20.f;    

	bool bDebug = g_pGameCVars->i_debug_projectiles > 0;

	if (m_targetId)
	{
		IEntity* pTarget = gEnv->pEntitySystem->GetEntity(m_targetId);
		if (pTarget)
		{
			AABB box;
			pTarget->GetWorldBounds(box);
			SetDestination( box.GetCenter() );

			//if (bDebug)
				//pRenderer->Draw2dLabel(5.0f, y+=step, 1.5f, color, false, "Target Entity: %s", pTarget->GetName());
		}    
	}
	else 
	{
		// update destination pos from weapon
		static IItemSystem* pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem();
		IItem* pItem = pItemSystem->GetItem(m_weaponId);
		if (pItem && pItem->GetIWeapon())
		{
			const Vec3& dest = pItem->GetIWeapon()->GetDestination();
			SetDestination( dest );

			//if (bDebug)
				//pRenderer->Draw2dLabel(5.0f, y+=step, 1.5f, color, false, "Weapon Destination: (%.1f %.1f %.1f)", dest.x, dest.y, dest.z);
		}
	}

	pe_status_dynamics status;
	if (!GetEntity()->GetPhysics()->GetStatus(&status))
		return;

	float currentSpeed = status.v.len();
	Vec3 currentPos = GetEntity()->GetWorldPos();
	Vec3 goalDir(ZERO);

	if (!m_destination.IsZero())
	{

		if((currentPos-m_destination).len2()<(m_detonationRadius*m_detonationRadius))
		{
			Explode(true, true, m_destination, -status.v.normalized(), status.v, m_targetId);
			return;
		}

		if (bDebug)
			pGeom->DrawCone(m_destination, Vec3(0,0,-1), 2.5f, 7.f, ColorB(255,0,0,255));

		float heightDiff = (m_cruiseAltitude-m_alignAltitude) - currentPos.z;

		if (!m_isCruising && heightDiff * sgn(status.v.z) > 0.f)
		{
			// if heading towards align altitude (but not yet reached) accelerate to max speed    
			if (bDebug)
				pRenderer->Draw2dLabel(5.0f,  y+=step,   1.5f, color, false, "[HomingMissile] accelerating (%.1f / %.1f)", currentSpeed, m_maxSpeed);    
		}
		else if (!m_isCruising && heightDiff * sgnnz(status.v.z) < 0.f && (status.v.z<0 || status.v.z>0.25f))
		{
			// align to cruise
			if (currentSpeed != 0)
			{
				goalDir = status.v;
				goalDir.z = 0;
				goalDir.normalize();
			}    

			if (bDebug)
				pRenderer->Draw2dLabel(5.0f,  y+=step, 1.5f, color, false, "[HomingMissile] aligning"); 
		}
		else
		{
			if (bDebug)
				pRenderer->Draw2dLabel(5.0f,  y+=step, 1.5f, color, false, "[HomingMissile] cruising..."); 

			// cruise
			m_isCruising = true;

			if (!m_destination.IsZero())
			{
				float groundDistSq = m_destination.GetSquaredDistance2D(currentPos);
				float distSq = m_destination.GetSquaredDistance(currentPos);
				float descendDistSq = sqr(m_descendDistance);

				if (m_isDescending || groundDistSq <= descendDistSq)
				{
					if (bDebug)
						pRenderer->Draw2dLabel(5.0f,  y+=step, 1.5f, color, false, "[HomingMissile] descending!"); 

					if (distSq != 0)
						goalDir = (m_destination - currentPos).normalized();
					else 
						goalDir.zero();

					m_isDescending = true;
				}              
				else
				{
					Vec3 airPos = m_destination;
					airPos.z = currentPos.z;          
					goalDir = airPos - currentPos;
					if (goalDir.len2() != 0)
						goalDir.Normalize();
				}    
			}
		}
	}  

	float desiredSpeed = currentSpeed;
	if (currentSpeed < m_maxSpeed-0.1f)
	{
		desiredSpeed = min(m_maxSpeed, desiredSpeed + m_accel*frameTime);
	}

	Vec3 currentDir = status.v.GetNormalizedSafe(FORWARD_DIRECTION);
	Vec3 dir = currentDir;

	if (!goalDir.IsZero())
	{ 
		float cosine = max(min(currentDir.Dot(goalDir), 0.999f), -0.999f);
		float goalAngle = RAD2DEG(acos_tpl(cosine));
		float maxAngle = m_turnSpeed * frameTime;

		if (bDebug)
		{ 
			pGeom->DrawCone( currentPos, goalDir, 0.4f, 12.f, ColorB(255,0,0,255) );
			pRenderer->Draw2dLabel(5.0f,  y+=step, 1.5f, color, false, "[HomingMissile] goalAngle: %.2f", goalAngle); 

		}

		if (goalAngle > maxAngle+0.05f)    
			dir = (Vec3::CreateSlerp(currentDir, goalDir, maxAngle/goalAngle)).normalize();
		else //if (goalAngle < 0.005f)
			dir = goalDir;
	}

	pe_action_set_velocity action;
	action.v = dir * desiredSpeed;
	GetEntity()->GetPhysics()->Action(&action);

	if (bDebug)
	{
		pGeom->DrawCone( currentPos, dir, 0.4f, 12.f, ColorB(128,128,0,255) );  
		pRenderer->Draw2dLabel(5.0f,  y+=step, 1.5f, color, false, "[HomingMissile] currentSpeed: %.1f (max: %.1f)", currentSpeed, m_maxSpeed); 
	}
}
//------------------------------------------------------------------------
void CVehicleMovementStdBoat::UpdateRunSound(const float deltaTime)
{
	Vec3 localAccel(ZERO);
	m_measureSpeedTimer+=deltaTime;

	if(m_measureSpeedTimer > 0.25f)
	{
		Vec3 accel = (m_statusDyn.v - m_lastMeasuredVel) * (1.f/m_measureSpeedTimer);
		Matrix33 worldTM(!m_statusPos.q);
		localAccel = worldTM * accel;

		m_lastMeasuredVel = m_statusDyn.v;
		m_measureSpeedTimer = 0.f;
	}

	if(m_pVehicle->IsProbablyDistant())
		return;

	float soundSpeedRatio = ms_engineSoundIdleRatio + (1.f-ms_engineSoundIdleRatio) * m_speedRatio;

	SetSoundParam(eSID_Run, "speed", soundSpeedRatio);
	SetSoundParam(eSID_Ambience, "speed", soundSpeedRatio);
	//SetSoundParam(eSID_Run, "boost", Boosting() ? 1.f : 0.f);

	float acceleration = min(1.f, abs(localAccel.y) / m_accel*max(1.f, m_accelCoeff));

	if(acceleration > 0.5f)
	{
		if(ISound *pSound = GetOrPlaySound(eSID_Acceleration, 2.f))
			SetSoundParam(pSound, "acceleration", acceleration);
	}

	float damage = GetSoundDamage();

	if(damage > 0.1f)
	{
		if(ISound *pSound = GetOrPlaySound(eSID_Damage, 5.f, m_enginePos))
			SetSoundParam(pSound, "damage", damage);
	}

	// rpm dropdown for waves
	if(m_rpmPitchDir != 0)
	{
		float speed = (m_rpmPitchDir > 0) ? 0.1f : -0.8f; // quick down, slow up
		m_waveSoundPitch += deltaTime * speed;

		if(m_waveSoundPitch < -m_waveSoundAmount)  // dropdown amount
		{
			m_waveSoundPitch = -m_waveSoundAmount;
			m_rpmPitchDir = 1;
		}
		else if(m_waveSoundPitch > 0.f)
		{
			m_waveSoundPitch = 0.f;
			m_rpmPitchDir = 0;
		}
	}

	if(m_rpmPitchSpeed>0.f)
	{
		const float maxPedal = (!m_inWater) ? 1.f : Boosting() ? 0.8f : 0.7f;

		// pitch rpm with pedal
		float pedal = GetEnginePedal();
		pedal = sgnnz(pedal)*max(ms_engineSoundIdleRatio, min(maxPedal, abs(pedal))); // clamp "pedal" to [0.2..0.7] range

		float delta = pedal - m_rpmScaleSgn;
		m_rpmScaleSgn = max(-1.f, min(1.f, m_rpmScaleSgn + sgn(delta)*min(abs(delta), m_rpmPitchSpeed*deltaTime)));

		// skip transition around 0 when on pedal (sounds more realistic)
		if(abs(GetEnginePedal()) > 0.001f && abs(delta) > 0.001f && sgn(m_rpmScaleSgn) != sgn(delta) && abs(m_rpmScaleSgn) <= 0.3f)
			m_rpmScaleSgn = sgn(delta)*0.3f;

		// for normal driving, rpm is clamped at max defined by sound dept
		m_rpmScale = abs(m_rpmScaleSgn);
		m_rpmScale = min(1.f, max(ms_engineSoundIdleRatio, m_rpmScale + m_waveSoundPitch));

		SetSoundParam(eSID_Run, "rpm_scale", m_rpmScale);
		SetSoundParam(eSID_Ambience, "rpm_scale", m_rpmScale);
	}
}