Exemple #1
0
void Replay::CarState::RecordFrame(const std::vector <float> & inputs, CarDynamics & car)
{
	assert(inputbuffer.size() == CarInput::INVALID);

	// record inputs, delta encoding
	InputFrame newinputframe(frame);
	for (unsigned i = 0; i < CarInput::INVALID; i++)
	{
		if (inputs[i] != inputbuffer[i])
		{
			inputbuffer[i] = inputs[i];
			newinputframe.AddInput(i, inputs[i]);
		}
	}
	if (newinputframe.GetNumInputs() > 0)
		inputframes.push_back(newinputframe);

	// record every 30th state, input frame
	if (frame % 30 == 0)
	{
		std::ostringstream statestream;
		joeserialize::BinaryOutputSerializer serialize_output(statestream);
		car.Serialize(serialize_output);
		stateframes.push_back(StateFrame(frame));
		stateframes.back().SetBinaryStateData(statestream.str());
		stateframes.back().SetInputSnapshot(inputs);
	}

	frame++;
}
void CarGraphics::Update(const CarDynamics & dynamics)
{
	if (!bodynode.valid()) return;
	assert(dynamics.GetNumBodies() == topnode.GetNodeList().size());

	unsigned i = 0;
	SceneNode::List & childlist = topnode.GetNodeList();
	for (SceneNode::List::iterator ni = childlist.begin(); ni != childlist.end(); ++ni, ++i)
	{
		Vec3 pos = ToMathVector<float>(dynamics.GetPosition(i));
		Quat rot = ToQuaternion<float>(dynamics.GetOrientation(i));
		ni->GetTransform().SetTranslation(pos);
		ni->GetTransform().SetRotation(rot);
	}

	// brake/reverse lights
	SceneNode & bodynoderef = topnode.GetNode(bodynode);
	for (std::list<Light>::iterator i = lights.begin(); i != lights.end(); i++)
	{
		SceneNode & node = bodynoderef.GetNode(i->node);
		Drawable & draw = node.GetDrawList().lights_omni.get(i->draw);
		draw.SetDrawEnable(applied_brakes > 0);
	}
	if (brakelights.valid())
	{
		Drawable & draw = bodynoderef.GetDrawList().lights_emissive.get(brakelights);
		draw.SetDrawEnable(applied_brakes > 0);
	}
	if (reverselights.valid())
	{
		Drawable & draw = bodynoderef.GetDrawList().lights_emissive.get(reverselights);
		draw.SetDrawEnable(dynamics.GetTransmission().GetGear() < 0);
	}

	// steering
	if (steernode.valid())
	{
		SceneNode & steernoderef = bodynoderef.GetNode(steernode);
		steernoderef.GetTransform().SetRotation(steer_rotation);
	}
}
Exemple #3
0
void Replay::CarState::ProcessPlayStateFrame(const StateFrame & frame, CarDynamics & car)
{
	// process input snapshot
	for (unsigned i = 0; i < inputbuffer.size() && i < frame.GetInputSnapshot().size(); i++)
	{
		inputbuffer[i] = frame.GetInputSnapshot()[i];
	}

	// process binary car state
	std::istringstream statestream(frame.GetBinaryStateData());
	joeserialize::BinaryInputSerializer serialize_input(statestream);
	car.Serialize(serialize_input);
}
Exemple #4
0
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;
*/
}