Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sphere_display.cpp
Go to the documentation of this file.
1 // -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*-
2 
3 #include "lin_time.h" // GetElapsedTime
4 #include "cmd/unit_generic.h"
5 #include "cmd/unit_util.h"
6 #include "gfxlib.h"
7 #include "viewarea.h"
8 #include "sphere_display.h"
9 
10 namespace
11 {
12 
14 {
15  using namespace Radar;
16 
17  switch (threat)
18  {
20  return 20.0; // Fast pulsation
21 
23  return 7.5; // Slow pulsation
24 
25  default:
26  return 0.0; // No pulsation
27  }
28 }
29 
30 } // anonymous namespace
31 
32 namespace Radar
33 {
34 
36  : innerSphere(0.98),
37  radarTime(0.0)
38 {
39 }
40 
41 void SphereDisplay::Draw(const Sensor& sensor,
42  VSSprite *frontSprite,
43  VSSprite *rearSprite)
44 {
45  assert(frontSprite || rearSprite); // There should be at least one radar display
46 
48 
49  leftRadar.SetSprite(frontSprite);
50  rightRadar.SetSprite(rearSprite);
51 
52  if (frontSprite)
53  frontSprite->Draw();
54  if (rearSprite)
55  rearSprite->Draw();
56 
58 
59  // FIXME: Consider using std::sort instead of the z-buffer
62 
63  DrawBackground(sensor, leftRadar);
64  DrawBackground(sensor, rightRadar);
65 
66  for (Sensor::TrackCollection::const_iterator it = tracks.begin(); it != tracks.end(); ++it)
67  {
68  static bool draw_both =
69  XMLSupport::parse_bool( vs_config->getVariable( "graphics", "hud", "draw_blips_on_both_radar", "false" ));
70  if (it->GetPosition().z < 0 || draw_both)
71  {
72  // Draw tracks behind the ship
73  DrawTrack(sensor, rightRadar, *it,true);
74  }
75  if (it->GetPosition().z >= 0 || draw_both)
76  {
77  // Draw tracks in front of the ship
78  DrawTrack(sensor, leftRadar, *it);
79  }
80  }
81 
82  GFXPointSize(1);
85 }
86 
87 void SphereDisplay::DrawTrack(const Sensor& sensor,
88  const ViewArea& radarView,
89  const Track& track,
90  bool negate_z)
91 {
92  if (!radarView.IsActive())
93  return;
94 
95  GFXColor color = sensor.GetColor(track);
96 
97  Vector position = track.GetPosition();
98  if (negate_z) position.z=-position.z;
99  if (position.z < 0){
100  static bool negate_z =
101  XMLSupport::parse_bool( vs_config->getVariable( "graphics", "hud", "show_negative_blips_as_positive", "true" ));
102  if (negate_z)
103  position.z=-position.z;
104  else
105  position.z = .125;
106  }
107  const float trackSize = 2.0;
108 
109  // FIXME: Jitter only on boundary, not in center
110  if (sensor.InsideNebula())
111  {
112  Jitter(0.02, 0.04, position);
113  }
114  else
115  {
116  const bool isNebula = (track.GetType() == Track::Type::Nebula);
117  const bool isEcmActive = track.HasActiveECM();
118  if (isNebula || isEcmActive)
119  {
120  float error = 0.02 * trackSize;
121  Jitter(error, error, position);
122  }
123  }
124 
125  // The magnitude is used to calculate the unit vector. With subtle scaling
126  // of the magnitude we generate a unit vector whose length will vary from
127  // innerSphere to 1.0, depending on the distance to the object. Combined
128  // with the OpenGL z-buffering, this will ensure that close tracks are drawn
129  // on top of distant tracks.
130  float magnitude = position.Magnitude();
131  float scaleFactor = 0.0; // [0; 1] where 0 = border, 1 = center
132  const float maxRange = sensor.GetMaxRange();
133  if (magnitude <= maxRange)
134  {
135  // [innerSphere; 1]
136  scaleFactor = (1.0 - innerSphere) * (maxRange - magnitude) / maxRange;
137  magnitude /= (1.0 - scaleFactor);
138  }
139  Vector scaledPosition = Vector(-position.x, position.y, position.z) / magnitude;
140 
141  Vector head = radarView.Scale(scaledPosition);
142 
143  GFXColor headColor = color;
144  if (sensor.UseThreatAssessment())
145  {
146  float dangerRate = GetDangerRate(sensor.IdentifyThreat(track));
147  if (dangerRate > 0.0)
148  {
149  // Blinking track
150  headColor.a *= cosf(dangerRate * radarTime);
151  }
152  }
153  // Fade out dying ships
154  if (track.IsExploding())
155  {
156  headColor.a *= (1.0 - track.ExplodingProgress());
157  }
158 
159  GFXColorf(headColor);
160  if (sensor.IsTracking(track))
161  {
162  DrawTargetMarker(head, trackSize);
163  }
164  GFXPointSize(trackSize);
166  GFXVertexf(head);
167  GFXEnd();
168 }
169 
170 void SphereDisplay::DrawTargetMarker(const Vector& position, float trackSize)
171 {
172  // Crosshair
173  const float crossSize = 8.0;
174  const float xcross = crossSize / g_game.x_resolution;
175  const float ycross = crossSize / g_game.y_resolution;
176 
177  // The crosshair wiggles as it moves around. The wiggling is less noticable
178  // when the crosshair is drawn with the smooth option.
179  GFXEnable(SMOOTH);
180  GFXLineWidth(trackSize);
181  GFXBegin(GFXLINE);
182  GFXVertex3f(position.x + xcross, position.y, 0.0f);
183  GFXVertex3f(position.x - xcross, position.y, 0.0f);
184  GFXVertex3f(position.x, position.y - ycross, 0.0f);
185  GFXVertex3f(position.x, position.y + ycross, 0.0f);
186  GFXEnd();
188 }
189 
190 void SphereDisplay::DrawBackground(const Sensor& sensor, const ViewArea& radarView)
191 {
192  // Split crosshair
193 
194  if (!radarView.IsActive())
195  return;
196 
197  GFXColor groundColor = radarView.GetColor();
198 
199  float velocity = sensor.GetPlayer()->GetWarpVelocity().Magnitude();
200  float logvelocity = 3.0; // std::log10(1000.0);
201  if (velocity > 1000.0)
202  {
203  // Max logvelocity is log10(speed_of_light) = 10.46
204  logvelocity = std::log10(velocity);
205  }
206  const float size = 3.0 * logvelocity; // [9; 31]
207  const float xground = size / g_game.x_resolution;
208  const float yground = size / g_game.y_resolution;
209  Vector center = radarView.Scale(Vector(0.0, 0.0, 0.0));
210 
211  GFXEnable(SMOOTH);
212  GFXLineWidth(1);
213  GFXColorf(groundColor);
214  GFXBegin(GFXLINE);
215  GFXVertexf(Vector(center.x - 2.0 * xground, center.y, center.z));
216  GFXVertexf(Vector(center.x - xground, center.y, center.z));
217  GFXVertexf(Vector(center.x + 2.0 * xground, center.y, center.z));
218  GFXVertexf(Vector(center.x + xground, center.y, center.z));
219  GFXVertexf(Vector(center.x, center.y - 2.0 * yground, center.z));
220  GFXVertexf(Vector(center.x, center.y - yground, center.z));
221  GFXVertexf(Vector(center.x, center.y + 2.0 * yground, center.z));
222  GFXVertexf(Vector(center.x, center.y + yground, center.z));
223  GFXEnd();
225 }
226 
227 } // namespace Radar