void CustomVehicleControllerComponentEngine::dGearBox::Update(dFloat timestep) { if (m_automatic) { m_shiftTimer -= timestep; if (m_shiftTimer < 0.0f) { int oldGear = GetGear(); m_currentGear = m_currentGear->Update(m_controller); if (oldGear != GetGear()) { m_shiftTimer = 0.5f; } } } }
CCar::Direction CCar::GetDirection() const { if (m_speed == 0) { return STAY; } if (GetGear() == -1) { return MOVE_BACK; } return MOVE_FRONT; }
bool CCar::SetSpeed(int speed) { if (!IsEngineOn()) { std::cout << "Couldn't change speed(Engine is off)." << std::endl; return false; } if (GetGear() == 0 && speed > GetSpeed()) { std::cout << "Couldn't change speed(can't increase speed on 0-gear)." << std::endl; return false; } std::array<int, 2> speedRange = GetSpeedRange(GetGear()); if (speed >= speedRange[0] && speed <= speedRange[1]) { m_speed = speed; return true; } std::cout << "Couldn't change speed(Your gear does not support this speed)." << std::endl; return false; }
bool CCar::SetGear(int gear) { int currentGear = GetGear(); if (gear == currentGear) { return true; } if (!IsEngineOn()) { std::cout << "Couldn't change gear(Engine is off)." << std::endl; return false; } if (currentGear == -1) { if (gear == 1 && GetSpeed() != 0) { std::cout << "Couldn't change gear(from -1 to 1 on speed)." << std::endl; return false; } else if (gear > 1) { std::cout << "Couldn't change gear(from -1 to > 1)." << std::endl; return false; } } if (gear == -1 && ((currentGear == 0 || currentGear == 1) && GetSpeed() != 0)) { std::cout << "Couldn't change gear(from -1 to 1 on speed)." << std::endl; return false; } int currentSpeed = GetSpeed(); std::array<int,2> speedRange = GetSpeedRange(gear); if (currentSpeed >= speedRange[0] && currentSpeed <= speedRange[1]) { m_gear = gear; return true; } std::cout << "Couldn't change gear(Incorrect speed interval)." << std::endl; return false; }
void CAR::UpdateGraphics() { if (!bodynode.valid()) return; assert(dynamics.GetNumBodies() == topnode.Nodes()); unsigned int i = 0; keyed_container<SCENENODE> & childlist = topnode.GetNodelist(); for (keyed_container<SCENENODE>::iterator ni = childlist.begin(); ni != childlist.end(); ++ni, ++i) { MATHVECTOR<float, 3> pos = ToMathVector<float>(dynamics.GetPosition(i)); QUATERNION<float> rot = ToMathQuaternion<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 = GetDrawlist(node, OMNI).get(i->draw); draw.SetDrawEnable(applied_brakes > 0); } if (brakelights.valid()) { GetDrawlist(bodynoderef, EMISSIVE).get(brakelights).SetDrawEnable(applied_brakes > 0); } if (reverselights.valid()) { GetDrawlist(bodynoderef, EMISSIVE).get(reverselights).SetDrawEnable(GetGear() < 0); } // steering if (steernode.valid()) { SCENENODE & steernoderef = bodynoderef.GetNode(steernode); steernoderef.GetTransform().SetRotation(steer_rotation); } }
void CAR::UpdateSounds(float dt) { if (!psound) return; MATHVECTOR <float, 3> pos_car = GetPosition(); MATHVECTOR <float, 3> 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 float rpm = GetEngineRPM(); float throttle = dynamics.GetEngine().GetThrottle(); float total_gain = 0.0; std::vector<std::pair<size_t, float> > gainlist; gainlist.reserve(enginesounds.size()); for (std::vector<ENGINESOUNDINFO>::iterator i = enginesounds.begin(); i != enginesounds.end(); ++i) { ENGINESOUNDINFO & info = *i; 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 (std::vector<std::pair<size_t, float> >::iterator i = gainlist.begin(); i != gainlist.end(); ++i) { float gain; if (total_gain == 0.0) { gain = 0.0; } else if (enginesounds.size() == 1 && enginesounds.back().power == ENGINESOUNDINFO::BOTH) { gain = i->second; } else { gain = i->second / total_gain; } psound->SetSourceGain(i->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 = GetTireSquealAmount(WHEEL_POSITION(i)); float maxgain = 0.3; float pitchvariation = 0.4; size_t * sound_active; const TRACKSURFACE & surface = dynamics.GetWheelContact(WHEEL_POSITION(i)).GetSurface(); if (surface.type == TRACKSURFACE::ASPHALT) { sound_active = tiresqueal; } else if (surface.type == TRACKSURFACE::GRASS) { sound_active = grasssound; maxgain = 0.4; // up the grass sound volume a little } else if (surface.type == TRACKSURFACE::GRAVEL) { sound_active = gravelsound; maxgain = 0.4; } else if (surface.type == TRACKSURFACE::CONCRETE) { sound_active = tiresqueal; maxgain = 0.3; pitchvariation = 0.25; } else if (surface.type == TRACKSURFACE::SAND) { sound_active = grasssound; maxgain = 0.25; // quieter for sand pitchvariation = 0.25; } else { sound_active = tiresqueal; maxgain = 0.0; } btVector3 pos_wheel = dynamics.GetWheelPosition(WHEEL_POSITION(i)); btVector3 vel_wheel = dynamics.GetWheelVelocity(WHEEL_POSITION(i)); float pitch = (vel_wheel.length() - 5.0) * 0.1; if (pitch < 0) pitch = 0; if (pitch > 1) pitch = 1; pitch = 1.0 - pitch; pitch *= pitchvariation; pitch = pitch + (1.0 - pitchvariation); if (pitch < 0.1) pitch = 0.1; if (pitch > 4.0) pitch = 4.0; psound->SetSourcePosition(sound_active[i], pos_wheel[0], pos_wheel[1], pos_wheel[2]); psound->SetSourcePitch(sound_active[i], pitch); psound->SetSourceGain(sound_active[i], squeal * maxgain); } //update road noise sound { float gain = dynamics.GetVelocity().length(); if (gain < 0) gain = -gain; gain *= 0.02; gain *= gain; if (gain > 1.0) gain = 1.0; psound->SetSourceGain(roadnoise, gain); } /* //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(GetSpeed(), dt); float crashdecel = crashdetection.GetMaxDecel(); if (crashdecel > 0) { const float mingainat = 500; const float maxgainat = 3000; const float mingain = 0.1; float gain = (crashdecel-mingainat)/(maxgainat-mingainat); if (gain > 1) gain = 1; if (gain < mingain) gain = mingain; if (!crashsound.Audible()) { crashsound.SetGain(gain); crashsound.Stop(); crashsound.Play(); } } } */ // update gear sound if (driver_view && gearsound_check != GetGear()) { float gain = 0.0; if (GetEngineRPM() != 0.0) gain = GetEngineRPMLimit() / GetEngineRPM(); if (gain > 0.5) gain = 0.5; if (gain < 0.25) gain = 0.25; if (!psound->GetSourcePlaying(gearsound)) { psound->ResetSource(gearsound); psound->SetSourceGain(gearsound, gain); } gearsound_check = GetGear(); } }