void SphereDisplay::DrawTrack(const Sensor& sensor, const ViewArea& radarView, const Track& track, bool negate_z) { if (!radarView.IsActive()) return; GFXColor color = sensor.GetColor(track); Vector position = track.GetPosition(); if (negate_z) position.z=-position.z; if (position.z < 0){ static bool negate_z = XMLSupport::parse_bool( vs_config->getVariable( "graphics", "hud", "show_negative_blips_as_positive", "true" )); if (negate_z) position.z=-position.z; else position.z = .125; } const float trackSize = 2.0; // FIXME: Jitter only on boundary, not in center if (sensor.InsideNebula()) { Jitter(0.02, 0.04, position); } else { const bool isNebula = (track.GetType() == Track::Type::Nebula); const bool isEcmActive = track.HasActiveECM(); if (isNebula || isEcmActive) { float error = 0.02 * trackSize; Jitter(error, error, position); } } // The magnitude is used to calculate the unit vector. With subtle scaling // of the magnitude we generate a unit vector whose length will vary from // innerSphere to 1.0, depending on the distance to the object. Combined // with the OpenGL z-buffering, this will ensure that close tracks are drawn // on top of distant tracks. float magnitude = position.Magnitude(); float scaleFactor = 0.0; // [0; 1] where 0 = border, 1 = center const float maxRange = sensor.GetMaxRange(); if (magnitude <= maxRange) { // [innerSphere; 1] scaleFactor = (1.0 - innerSphere) * (maxRange - magnitude) / maxRange; magnitude /= (1.0 - scaleFactor); } Vector scaledPosition = Vector(-position.x, position.y, position.z) / magnitude; Vector head = radarView.Scale(scaledPosition); GFXColor headColor = color; if (sensor.UseThreatAssessment()) { float dangerRate = GetDangerRate(sensor.IdentifyThreat(track)); if (dangerRate > 0.0) { // Blinking track headColor.a *= cosf(dangerRate * radarTime); } } // Fade out dying ships if (track.IsExploding()) { headColor.a *= (1.0 - track.ExplodingProgress()); } GFXColorf(headColor); if (sensor.IsTracking(track)) { DrawTargetMarker(head, trackSize); } GFXPointSize(trackSize); GFXBegin(GFXPOINT); GFXVertexf(head); GFXEnd(); }
void BubbleDisplay::DrawTrack(const Sensor& sensor, const ViewArea& radarView, const Track& track) { if (!radarView.IsActive()) return; GFXColor color = sensor.GetColor(track); Vector position = track.GetPosition(); if (position.z < 0) position.z = -position.z; float magnitude = position.Magnitude(); float scaleFactor = 0.0; // [0; 1] where 0 = border, 1 = center float maxRange = sensor.GetMaxRange(); if (magnitude <= maxRange) { // [innerSphere; outerSphere] scaleFactor = (outerSphere - innerSphere) * ((maxRange - magnitude) / maxRange); magnitude /= (1.0 - scaleFactor); } if (sensor.InsideNebula()) { magnitude /= (1.0 - 0.04 * Jitter(0.0, 1.0)); } Vector scaledPosition = sphereZoom * Vector(-position.x, position.y, position.z) / magnitude; Vector head = radarView.Scale(scaledPosition); GFXColor headColor = color; headColor.a *= 0.2 + scaleFactor * (1.0 - 0.2); // [0;1] => [0.1;1] if (sensor.UseThreatAssessment()) { float dangerRate = GetDangerRate(sensor.IdentifyThreat(track)); if (dangerRate > 0.0) { // Blinking blip headColor.a *= cosf(dangerRate * radarTime); } } // Fade out dying ships if (track.IsExploding()) { headColor.a *= (1.0 - track.ExplodingProgress()); } float trackSize = std::max(1.0f, std::log10(track.GetSize())); if (track.GetType() != Track::Type::Cargo) trackSize += 1.0; if (sensor.IsTracking(track)) { currentTargetMarkerSize = trackSize; DrawTargetMarker(head, headColor, trackSize); } const bool isNebula = (track.GetType() == Track::Type::Nebula); const bool isEcmActive = track.HasActiveECM(); if (isNebula || isEcmActive) { // Vary size between 50% and 150% trackSize *= Jitter(0.5, 1.0); } impl->getPointBuffer(trackSize).insert(GFXColorVertex(head, headColor)); }