コード例 #1
0
ファイル: ai_car_standard.cpp プロジェクト: polyblank2/vdrift
const Bezier * AiCarStandard::GetCurrentPatch(const CarDynamics * c)
{
	const Bezier *curr_patch = c->GetWheelContact(WheelPosition(0)).GetPatch();
	if (!curr_patch)
	{
		// let's try the other wheel
		curr_patch = c->GetWheelContact(WheelPosition(1)).GetPatch();
		if (!curr_patch) return NULL;
	}
	return curr_patch;
}
コード例 #2
0
ファイル: ai_car_standard.cpp プロジェクト: polyblank2/vdrift
void AiCarStandard::CalcMu()
{
	const float tire_load = 0.25 * GRAVITY / car->GetInvMass();
	float long_friction = 0.0;
	float lat_friction = 0.0;
	for (int i = 0; i < 4; i++)
	{
		long_friction += car->GetTire(WheelPosition(i)).getMaxFx(tire_load);
		lat_friction += car->GetTire(WheelPosition(i)).getMaxFy(tire_load, 0.0);
	}
	float long_mu = FRICTION_FACTOR_LONG * long_friction * car->GetInvMass() / GRAVITY;
	float lat_mu = FRICTION_FACTOR_LAT * lat_friction * car->GetInvMass() / GRAVITY;
	if (!std::isnan(long_mu)) longitude_mu = long_mu;
	if (!std::isnan(lat_mu)) lateral_mu = lat_mu;
}
コード例 #3
0
ファイル: carsound.cpp プロジェクト: CheezeCake/vdrift
void CarSound::Update(const CarDynamics & dynamics, float dt)
{
	if (!psound) return;

	Vec3 pos_car = ToMathVector<float>(dynamics.GetPosition());
	Vec3 pos_eng = ToMathVector<float>(dynamics.GetEnginePosition());

	psound->SetSourcePosition(roadnoise, pos_car[0], pos_car[1], pos_car[2]);
	psound->SetSourcePosition(crashsound, pos_car[0], pos_car[1], pos_car[2]);
	psound->SetSourcePosition(gearsound, pos_car[0], pos_car[1], pos_car[2]);
	psound->SetSourcePosition(brakesound, pos_car[0], pos_car[1], pos_car[2]);
	psound->SetSourcePosition(handbrakesound, pos_car[0], pos_car[1], pos_car[2]);

	// update engine sounds
	const float rpm = dynamics.GetTachoRPM();
	const float throttle = dynamics.GetEngine().GetThrottle();
	float total_gain = 0.0;

	std::vector<std::pair<size_t, float> > gainlist;
	gainlist.reserve(enginesounds.size());
	for (auto & info : enginesounds)
	{
		float gain = 1.0;

		if (rpm < info.minrpm)
		{
			gain = 0;
		}
		else if (rpm < info.fullgainrpmstart && info.fullgainrpmstart > info.minrpm)
		{
			gain *= (rpm - info.minrpm) / (info.fullgainrpmstart - info.minrpm);
		}

		if (rpm > info.maxrpm)
		{
			gain = 0;
		}
		else if (rpm > info.fullgainrpmend && info.fullgainrpmend < info.maxrpm)
		{
			gain *= 1.0 - (rpm - info.fullgainrpmend) / (info.maxrpm - info.fullgainrpmend);
		}

		if (info.power == EngineSoundInfo::BOTH)
		{
			gain *= throttle * 0.5 + 0.5;
		}
		else if (info.power == EngineSoundInfo::POWERON)
		{
			gain *= throttle;
		}
		else if (info.power == EngineSoundInfo::POWEROFF)
		{
			gain *= (1.0-throttle);
		}

		total_gain += gain;
		gainlist.push_back(std::make_pair(info.sound_source, gain));

		float pitch = rpm / info.naturalrpm;

		psound->SetSourcePosition(info.sound_source, pos_eng[0], pos_eng[1], pos_eng[2]);
		psound->SetSourcePitch(info.sound_source, pitch);
	}

	// normalize gains
	assert(total_gain >= 0.0);
	for (const auto & sound_gain : gainlist)
	{
		float gain;
		if (total_gain == 0.0)
		{
			gain = 0.0;
		}
		else if (enginesounds.size() == 1 && enginesounds.back().power == EngineSoundInfo::BOTH)
		{
			gain = sound_gain.second;
		}
		else
		{
			gain = sound_gain.second / total_gain;
		}
		psound->SetSourceGain(sound_gain.first, gain);
	}

	// update tire squeal sounds
	for (int i = 0; i < 4; i++)
	{
		// make sure we don't get overlap
		psound->SetSourceGain(gravelsound[i], 0.0);
		psound->SetSourceGain(grasssound[i], 0.0);
		psound->SetSourceGain(tiresqueal[i], 0.0);

		float squeal = dynamics.GetTireSquealAmount(WheelPosition(i));
		float maxgain = 0.3;
		float pitchvariation = 0.4;

		unsigned sound_active = 0;
		const TrackSurface & surface = dynamics.GetWheelContact(WheelPosition(i)).GetSurface();
		if (surface.type == TrackSurface::ASPHALT)
		{
			sound_active = tiresqueal[i];
		}
		else if (surface.type == TrackSurface::GRASS)
		{
			sound_active = grasssound[i];
			maxgain = 0.4; // up the grass sound volume a little
		}
		else if (surface.type == TrackSurface::GRAVEL)
		{
			sound_active = gravelsound[i];
			maxgain = 0.4;
		}
		else if (surface.type == TrackSurface::CONCRETE)
		{
			sound_active = tiresqueal[i];
			maxgain = 0.3;
			pitchvariation = 0.25;
		}
		else if (surface.type == TrackSurface::SAND)
		{
			sound_active = grasssound[i];
			maxgain = 0.25; // quieter for sand
			pitchvariation = 0.25;
		}
		else
		{
			sound_active = tiresqueal[i];
			maxgain = 0.0;
		}

		btVector3 pos_wheel = dynamics.GetWheelPosition(WheelPosition(i));
		btVector3 vel_wheel = dynamics.GetWheelVelocity(WheelPosition(i));
		float pitch = (vel_wheel.length() - 5.0) * 0.1;
		pitch = clamp(pitch, 0.0f, 1.0f);
		pitch = 1.0 - pitch;
		pitch *= pitchvariation;
		pitch = pitch + (1.0 - pitchvariation);
		pitch = clamp(pitch, 0.1f, 4.0f);

		psound->SetSourcePosition(sound_active, pos_wheel[0], pos_wheel[1], pos_wheel[2]);
		psound->SetSourcePitch(sound_active, pitch);
		psound->SetSourceGain(sound_active, squeal * maxgain);
	}

	// update road noise sound
	{
		float gain = dynamics.GetVelocity().length();
		gain *= 0.02;
		gain *= gain;
		if (gain > 1) gain = 1;
		psound->SetSourceGain(roadnoise, gain);
	}
/*	fixme
	// update bump noise sound
	{
		for (int i = 0; i < 4; i++)
		{
			suspensionbumpdetection[i].Update(
				dynamics.GetSuspension(WHEEL_POSITION(i)).GetVelocity(),
				dynamics.GetSuspension(WHEEL_POSITION(i)).GetDisplacementFraction(),
				dt);
			if (suspensionbumpdetection[i].JustSettled())
			{
				float bumpsize = suspensionbumpdetection[i].GetTotalBumpSize();

				const float breakevenms = 5.0;
				float gain = bumpsize * GetSpeed() / breakevenms;
				if (gain > 1)
					gain = 1;
				if (gain < 0)
					gain = 0;

				if (gain > 0 && !tirebump[i].Audible())
				{
					tirebump[i].SetGain(gain);
					tirebump[i].Stop();
					tirebump[i].Play();
				}
			}
		}
	}
*/
	// update crash sound
	crashdetection.Update(dynamics.GetSpeed(), dt);
	float crashdecel = crashdetection.GetMaxDecel();
	if (crashdecel > 0)
	{
		const float mingainat = 200;
		const float maxgainat = 2000;
		float gain = (crashdecel - mingainat) / (maxgainat - mingainat);
		gain = clamp(gain, 0.1f, 1.0f);

		if (!psound->GetSourcePlaying(crashsound))
		{
			psound->ResetSource(crashsound);
			psound->SetSourceGain(crashsound, gain);
		}
	}

	// update interior sounds
	if (!interior) return;

	// update gear sound
	if (gearsound_check != dynamics.GetTransmission().GetGear())
	{
		float gain = 0.0;
		if (rpm > 0.0)
			gain = dynamics.GetEngine().GetRPMLimit() / rpm;
		gain = clamp(gain, 0.25f, 0.50f);

		if (!psound->GetSourcePlaying(gearsound))
		{
			psound->ResetSource(gearsound);
			psound->SetSourceGain(gearsound, gain);
		}
		gearsound_check = dynamics.GetTransmission().GetGear();
	}
/*	fixme
	// brake sound
	if (inputs[CarInput::BRAKE] > 0 && !brakesound_check)
	{
		// disable brake sound, sounds wierd
		if (false)//!psound->GetSourcePlaying(brakesound))
		{
			psound->ResetSource(brakesound);
			psound->SetSourceGain(brakesound, 0.5);
		}
		brakesound_check = true;
	}
	if (inputs[CarInput::BRAKE] <= 0)
		brakesound_check = false;

	// handbrake sound
	if (inputs[CarInput::HANDBRAKE] > 0 && !handbrakesound_check)
	{
		if (!psound->GetSourcePlaying(handbrakesound))
		{
			psound->ResetSource(handbrakesound);
			psound->SetSourceGain(handbrakesound, 0.5);
		}
		handbrakesound_check = true;
	}
	if (inputs[CarInput::HANDBRAKE] <= 0)
		handbrakesound_check = false;
*/
}
コード例 #4
0
void PerformanceTesting::TestStoppingDistance(bool abs, std::ostream & info_output, std::ostream & error_output)
{
	info_output << "Testing stopping distance" << std::endl;

	float maxtime = 300.0;
	float t = 0.;
	float dt = 1/90.0;
	int i = 0;

	float stopthreshold = 0.1; //if the speed (in m/s) is less than this value, discontinue the testing
	btVector3 stopstart; //where the stopping starts
	float brakestartspeed = 26.82; //speed at which to start braking, in m/s (26.82 m/s is 60 mph)

	bool accelerating = true; //switches to false once 60 mph is reached

	ResetCar();

	car.SetABS(abs);

	while (t < maxtime)
	{
		if (accelerating)
		{
			carinput[CarInput::THROTTLE] = 1.0f;
			carinput[CarInput::BRAKE] = 0.0f;
		}
		else
		{
			carinput[CarInput::THROTTLE] = 0.0f;
			carinput[CarInput::BRAKE] = 1.0f;
		}

		car.Update(carinput);

		world.update(dt);

		float car_speed = car.GetSpeed();

		if (car_speed >= brakestartspeed && accelerating) //stop accelerating and hit the brakes
		{
			accelerating = false;
			stopstart = car.GetWheelPosition(WheelPosition(0));
			//std::cout << "hitting the brakes at " << t << ", " << car_speed << std::endl;
		}

		if (!accelerating && car_speed < stopthreshold)
		{
			break;
		}

		if (!car.GetEngine().GetCombustion())
		{
			error_output << "Car stalled during launch, t=" << t << std::endl;
			break;
		}

		if (i % (int)(1.0/dt) == 0) //every second
		{
			//std::cout << t << ", " << car.dynamics.GetSpeed() << ", " << car.GetGear() << ", " << car.GetEngineRPM() << std::endl;
		}

		t += dt;
		i++;
	}

	btVector3 stopend = car.GetWheelPosition(WheelPosition(0));

	info_output << "60-0 stopping distance ";
	if (abs)
		info_output << "(ABS)";
	else
		info_output << "(no ABS)";
	info_output << ": " << ConvertToFeet((stopend-stopstart).length()) << " ft" << std::endl;
}
コード例 #5
0
ファイル: performance_testing.cpp プロジェクト: Timo6/vdrift
void PerformanceTesting::TestStoppingDistance(bool abs, std::ostream & info_output, std::ostream & error_output)
{
	info_output << "Testing stopping distance" << std::endl;

	float maxtime = 300;
	float t = 0.;
	float dt = 1/90.0;
	int i = 0;

	float stopthreshold = 0.1; //if the speed (in m/s) is less than this value, discontinue the testing
	btVector3 stopstart; //where the stopping starts
	float brakestartspeed = 26.82; //speed at which to start braking, in m/s (26.82 m/s is 60 mph)

	// wheel lockup speeds during braking
	float front_lockup_speed = 0.0f;
	float rear_lockup_speed = 0.0f;

	bool accelerating = true; //switches to false once 60 mph is reached

	ResetCar();

	car.SetABS(abs);

	while (t < maxtime)
	{
		if (accelerating && car.GetTransmission().GetGear() == 1 &&
			car.GetEngine().GetRPM() > 0.8f * car.GetEngine().GetRedline())
		{
			carinput[CarInput::BRAKE] = 0;
			carinput[CarInput::CLUTCH] = 0;
		}

		car.Update(carinput);

		world.update(dt);

		float car_speed = car.GetSpeed();

		if (car_speed >= brakestartspeed && accelerating) //stop accelerating and hit the brakes
		{
			stopstart = car.GetWheelPosition(WheelPosition(0));

			carinput[CarInput::THROTTLE] = 0;
			carinput[CarInput::BRAKE] = 1;
			accelerating = false;

			//info_output << "hitting the brakes at " << t << ", " << car_speed << std::endl;
		}

		if (!accelerating && car_speed < stopthreshold)
		{
			break;
		}

		if (!accelerating)
		{
			if (!(front_lockup_speed > 0) && car.GetWheel(WheelPosition(0)).GetRPM() < 0.001f)
			{
				front_lockup_speed = car_speed;
			}
			if (!(rear_lockup_speed > 0) && car.GetWheel(WheelPosition(3)).GetRPM() < 0.001f)
			{
				rear_lockup_speed = car_speed;
			}
		}

		if (t > 0 && !car.GetEngine().GetCombustion())
		{
			error_output << "Car stalled during launch, t=" << t << std::endl;
		}

		if (i % (int)(1/dt) == 0) //every second
		{
			//info_output << t
			//	<< ", " << car_speed
			//	<< ", " << car.GetWheel(WheelPosition(0)).GetAngularVelocity()
			//	<< ", " << car.GetBrake(WheelPosition(0)).GetBrakeFactor()
			//	<< std::endl;
		}

		t += dt;
		i++;
	}

	btVector3 stopend = car.GetWheelPosition(WheelPosition(0));

	info_output << "60-0 stopping distance ";
	if (abs)
		info_output << "(ABS)";
	else
		info_output << "(no ABS)";
	info_output << ": " << ConvertToFeet((stopend-stopstart).length()) << " ft\n"
		<< "Wheel lockup speed " << ConvertToMPH(front_lockup_speed)
		<< ", " << ConvertToMPH(rear_lockup_speed) << std::endl;
}