HOG2
MapOverlay.cpp
Go to the documentation of this file.
1 /*
2  * MapOverlay.cpp
3  * hog
4  *
5  * Created by Nathan Sturtevant on 3/21/06.
6  * Copyright 2006 Nathan Sturtevant. All rights reserved.
7  *
8  */
9 
10 #include "MapOverlay.h"
11 #include "FPUtil.h"
12 #include "GLUtil.h"
13 #include "SVGUtil.h"
14 #include "Colors.h"
15 
16 const double stripResolution = 20;
17 
19 :m(_m), maxVal(0), minVal(0.0)
20 {
21  values.resize(m->GetMapWidth()*m->GetMapHeight());
22  colorMap = 4;
23  displayList = 0;
24  drawBorders = false;
25 }
26 
28 {
29  if (displayList)
30  {
31  glDeleteLists(displayList, 1);
32  displayList = 0;
33  }
34 
35  for (unsigned int x = 0; x < values.size(); x++)
36  values[x] = ignoreVal;
37 
38  maxVal = DBL_MIN;
39  minVal = DBL_MAX;
40 }
41 
43 {
44  if (displayList)
45  {
46  glDeleteLists(displayList, 1);
47  displayList = 0;
48  }
49  maxVal = DBL_MIN;
50  minVal = DBL_MAX;
51  for (unsigned int t = 0; t < values.size(); t++)
52  {
53  if (!fequal(values[t], ignoreVal))
54  {
55  if (fgreater(values[t], maxVal))
56  maxVal = values[t];
57  if (fless(values[t], minVal))
58  minVal = values[t];
59  }
60  }
61 }
62 
63 void MapOverlay::SetOverlayValue(int x, int y, double value)
64 {
65  if ((x < 0) || (x >= m->GetMapWidth()) || (y < 0) || (y >= m->GetMapHeight()))
66  return;
67  if (displayList)
68  {
69  glDeleteLists(displayList, 1);
70  displayList = 0;
71  }
72 
73  values[y*m->GetMapWidth()+x] = value;
74  if (value > maxVal)
75  maxVal = value;
76  if (value < minVal)
77  minVal = value;
78 // printf("Min: %f; max: %f\n", minVal, maxVal);
79  //resetValues();
80 }
81 
82 double MapOverlay::GetOverlayValue(int x, int y)
83 {
84  if ((x < 0) || (x >= m->GetMapWidth()) || (y < 0) || (y >= m->GetMapHeight()))
85  return 0;
86  return values[y*m->GetMapWidth()+x];
87 }
88 
90 {
91  int v = (int)value;
92  auto loc = colors.find(v);
93  if (loc == colors.end() || colorMap != -1)
94  return Colors::GetColor(value, minVal, maxVal, 0);
95  return loc->second;
96 }
97 
99 {
100  if (displayList)
101  {
102  glCallList(displayList);
103  }
104  else if (!fequal(minVal, maxVal)) // we get unddefined behavior when they are equal`
105  {
106 
107  displayList = glGenLists(1);
108  glNewList(displayList, GL_COMPILE_AND_EXECUTE);
109 
110  glBegin(GL_QUADS);
111  glNormal3f(0, 0, -1);
112  for (unsigned int t = 0; t < values.size(); t++)
113  {
114  //printf("Drawing: (%ld, %ld): %f\n", t%m->GetMapWidth(), t/m->GetMapWidth(), values[t]);
115  if (fequal(values[t], ignoreVal))
116  {
117  //glColor4f(0.5, 0.5, 0.5, 0.5);
118  continue;
119  }
120  else {
121  rgbColor r;
122  if (colorMap == customColorMap)
123  r = GetValueColor(values[t]);
124  else
126  glColor3f(r.r, r.g, r.b);
127  }
128  unsigned int last;
129  for (last = t+1;
130  last < values.size() && (last%(m->GetMapWidth()) != 0) &&
131  fequal(values[t], values[last]); last++)
132  {}
133  last -= 1;
134  GLdouble coverage = 1.0;
135  GLdouble a, b, c, radius;
136  m->GetOpenGLCoord((int)(t%(m->GetMapWidth())), (int)(t/m->GetMapWidth()), a, b, c, radius);
137  glVertex3f(a-coverage*radius, b+coverage*radius, c-0.0001);//+1.01*radius);
138  glVertex3f(a-coverage*radius, b-coverage*radius, c-0.0001);//+1.01*radius);
139  m->GetOpenGLCoord((int)(last%(m->GetMapWidth())), (int)(last/m->GetMapWidth()), a, b, c, radius);
140  glVertex3f(a+coverage*radius, b-coverage*radius, c-0.0001);//+1.01*radius);
141  glVertex3f(a+coverage*radius, b+coverage*radius, c-0.0001);//+1.01*radius);
142  t = last;
143  }
144  glEnd();
145 
146  // borders between regions
147  if (drawBorders)
148  {
149  glLineWidth(2.0);
150  glColor3f(0.0, 0.0, 0.0);
151  glBegin(GL_LINES);
152  for (int y = 0; y < m->GetMapHeight()-1; y++)
153  {
154  for (int x = 0; x < m->GetMapWidth()-1; x++)
155  {
156  int index = x+y*m->GetMapWidth();
157  if (values[index] != values[index+1])
158  {
159  GLdouble a, b, c, r;
160  m->GetOpenGLCoord(x, y, a, b, c, r);
161  glVertex3f(a+r, b+r, c-1.12*r);
162  glVertex3f(a+r, b-r, c-1.12*r);
163  }
164  if (values[index] != values[index+m->GetMapWidth()])
165  {
166  GLdouble a, b, c, r;
167  m->GetOpenGLCoord(x, y, a, b, c, r);
168  glVertex3f(a-r, b+r, c-1.12*r);
169  glVertex3f(a+r, b+r, c-1.12*r);
170  }
171  }
172  }
173  glEnd();
174  }
175 
176 
177  if (1)// drawColorBar
178  {
179  // black background
180  glBegin(GL_QUADS);
181  glNormal3f(0, 0, -1);
182  GLdouble a, b, c, radius;
183  m->GetOpenGLCoord(0, 0, a, b, c, radius);
184  double wide = radius*2.0*m->GetMapWidth()/100.0;
185  glColor3f(0.2, 0.2, 0.2);
186  glVertex3f(a-wide, b+2*m->GetMapHeight()*radius+wide, c-4*radius);
187  glVertex3f(a-4*wide, b+2*m->GetMapHeight()*radius+wide, c-4*radius);
188  glVertex3f(a-4*wide, b-wide, c-4*radius);
189  glVertex3f(a-wide, b-wide, c-4*radius);
190  glEnd();
191 
192  char text[255];
193  sprintf(text, "%1.2f", minVal);
194  glColor3f(1.0, 1.0, 1.0);
195  DrawText(a-wide, b+2*m->GetMapHeight()*radius+wide, c-3*radius, 0.1, text);
196  sprintf(text, "%1.2f", maxVal);
197  DrawText(a-wide, b-wide+0.05, c-3*radius, 0.1, text);
198 
199  // white border
200  glBegin(GL_LINE_LOOP);
201  glColor3f(1.0, 1.0, 1.0);
202  glVertex3f(a-wide, b+2*m->GetMapHeight()*radius+wide, c-4*radius-radius/10.0);
203  glVertex3f(a-4*wide, b+2*m->GetMapHeight()*radius+wide, c-4*radius-radius/10.0);
204  glVertex3f(a-4*wide, b-wide, c-4*radius);
205  glVertex3f(a-wide, b-wide, c-4*radius);
206  glEnd();
207 
208  // color bar on the side
209  glBegin(GL_QUAD_STRIP);
210  glNormal3f(0, 0, -1);
211  m->GetOpenGLCoord(0, 0, a, b, c, radius);
212  for (int x = 0; x <= stripResolution; x++)
213  {
216  glColor3f(r.r, r.g, r.b);
217  glVertex3f(a-2*wide, b+2*m->GetMapHeight()*radius*(1.0-(double)x/stripResolution), c-4*radius-radius/8.0);
218  glVertex3f(a-3*wide, b+2*m->GetMapHeight()*radius*(1.0-(double)x/stripResolution), c-4*radius-radius/8.0);
219  }
220  glEnd();
221 
222  if (maxVal-minVal != 0)
223  {
224  double mult = 1.0;
225  double range = 1.0;
226  while (1)
227  {
228  if (!(fless((maxVal-minVal)*mult, 10.0)))
229  mult /= 10;
230  else if (fless((maxVal-minVal)*mult, 1.0))
231  mult *= 10;
232  else {
233  if ((maxVal-minVal)*mult >= 5)
234  range = 1.0;
235  else if ((maxVal-minVal)*mult >= 3)
236  range = 0.5;
237  else
238  range = 0.1;
239  break;
240  }
241  }
242  glBegin(GL_LINES);
243  glColor3f(1.0, 1.0, 1.0);
244  //double top = (double)((int)(maxVal*mult))/mult;
245  double bottom = (double)((int)(minVal*mult))/mult;
246  // printf("min/max %f, %f, stepped min/max %f, %f\n",
247  // minVal, maxVal, bottom, top);
248  // printf("Range: %f, mult %f\n", range, mult);
249  for (double x = bottom; !fgreater(x, maxVal); x+=range/mult)
250  {
251  if (fequal(x, 0))
252  glColor3f(1.0, 0, 0);
253  glVertex3f(a-1*wide, b+2*m->GetMapHeight()*radius*(1.0-(x-minVal)/(maxVal-minVal)), c-4*radius-radius/9.0);
254  glVertex3f(a-4*wide, b+2*m->GetMapHeight()*radius*(1.0-(x-minVal)/(maxVal-minVal)), c-4*radius-radius/9.0);
255  if (fequal(x, 0))
256  glColor3f(1.0, 1.0, 1.0);
257  }
258  for (double x = bottom-range/mult; !fless(x, minVal); x-=range/mult)
259  {
260  if (fequal(x, 0))
261  glColor3f(1.0, 0, 0);
262  glVertex3f(a-1*wide, b+2*m->GetMapHeight()*radius*(1.0-(x-minVal)/(maxVal-minVal)), c-4*radius-radius/9.0);
263  glVertex3f(a-4*wide, b+2*m->GetMapHeight()*radius*(1.0-(x-minVal)/(maxVal-minVal)), c-4*radius-radius/9.0);
264  if (fequal(x, 0))
265  glColor3f(1.0, 1.0, 1.0);
266  }
267  glEnd();
268  }
269  }
270 
271  glEndList();
272  }
273 }
274 
276 {
277  for (unsigned int t = 0; t < values.size(); t++)
278  {
279  if (fequal(values[t], ignoreVal))
280  {
281  continue;
282  }
283  else {
285  GLdouble x, y, z, rad;
286  m->GetOpenGLCoord(static_cast<int>(t%m->GetMapWidth()), static_cast<int>(t/m->GetMapWidth()), x, y, z, rad);
287  display.FillRect({static_cast<float>(x-rad), static_cast<float>(y-rad), static_cast<float>(x+rad), static_cast<float>(y+rad)}, r);
288  //s += SVGDrawRect(t%m->GetMapWidth()+1, t/m->GetMapWidth()+1, 1, 1, r);
289  }
290  }
291 
292 }
293 
294 std::string MapOverlay::SVGDraw() const
295 {
296  std::string s;
297  char s1[255];
298  char s2[255];
299  sprintf(s1, "%1.2f", maxVal);
300  sprintf(s2, "%1.2f", minVal);
301  s += "\n";
302  int margin = std::max(1.0, m->GetMapWidth()/40.0);
303  s += SVGDefineGradient(true, true,
305  Colors::GetColor(minVal, minVal, maxVal, colorMap), "sideBar");
306  s += "\n";
307  s += SVGDrawRect(-margin, 1, margin, m->GetMapHeight(), "sideBar");
308  s += SVGFrameRect(-margin, 1, margin, m->GetMapHeight(), 1, Colors::darkgray);
309  s += "\n";
310  s += SVGDrawText(0, 1+margin, s1, Colors::black, margin);
311  s += "\n";
312  s += SVGDrawText(0, m->GetMapHeight()+1, s2, Colors::black, margin);
313  s += "\n";
314  for (unsigned int t = 0; t < values.size(); t++)
315  {
316  if (fequal(values[t], ignoreVal))
317  {
318  continue;
319  }
320  else {
322  s += SVGDrawRect(t%m->GetMapWidth()+1, t/m->GetMapWidth()+1, 1, 1, r);
323  }
324  }
325 
326  rgbColor black = {0, 0, 0};
327 
328 // // terrain borders
329 // for (int y = 0; y < m->GetMapHeight()-1; y++)
330 // {
331 // for (int x = 0; x < m->GetMapWidth()-1; x++)
332 // {
333 // if ((m->GetTerrainType(x, y)>>terrainBits) != (m->GetTerrainType(x+1, y)>>terrainBits))
334 // {
335 // s += SVGDrawLine(x+1, y, x+1, y+1, 2, black, false);
336 // }
337 // if ((m->GetTerrainType(x, y)>>terrainBits) != (m->GetTerrainType(x, y+1)>>terrainBits))
338 // {
339 // s += SVGDrawLine(x, y+1, x+1, y+1, 2, black, false);
340 // }
341 // }
342 // }
343 
344  return s;
345 
346  // value borders
347  for (int x = 0; x < m->GetMapWidth()-1; x++)
348  {
349  for (int y = 0; y < m->GetMapHeight()-1; y++)
350  {
351  int index = x+y*m->GetMapWidth();
352  if (values[index] != values[index+1])
353  {
354  s += SVGDrawLine(x+1, y, x+1, y+1, 2, black, false);
355  }
356  if (values[index] != values[index+m->GetMapWidth()])
357  {
358  s += SVGDrawLine(x, y+1, x+1, y+1, 2, black, false);
359  }
360  }
361  }
362 
363  return s;
364 }
Colors::GetColor
rgbColor GetColor(float v, float vmin, float vmax, int type)
Given min/max values, get a color from a color schema.
Definition: Colors.cpp:24
SVGDefineGradient
std::string SVGDefineGradient(bool horizontal, bool vertical, rgbColor c1, rgbColor c2, const char *name)
Definition: SVGUtil.cpp:34
rgbColor::b
float b
Definition: Colors.h:71
rgbColor
A color; r/g/b are between 0...1.
Definition: Colors.h:17
MapOverlay::resetValues
void resetValues()
Definition: MapOverlay.cpp:42
MapOverlay::minVal
double minVal
Definition: MapOverlay.h:48
MapOverlay::ignoreVal
double ignoreVal
Definition: MapOverlay.h:49
MapOverlay::colors
std::unordered_map< int, rgbColor > colors
Definition: MapOverlay.h:47
MapOverlay::GetOverlayValue
double GetOverlayValue(int x, int y)
Definition: MapOverlay.cpp:82
SVGDrawText
std::string SVGDrawText(float x1, float y1, const char *txt, rgbColor c, double size, const char *typeface, SVG::svgAlignment align, SVG::svgBaseline base)
Definition: SVGUtil.cpp:227
SVGDrawRect
std::string SVGDrawRect(float x, float y, float width, float height, const char *gradient)
Definition: SVGUtil.cpp:74
MapOverlay::drawBorders
bool drawBorders
Definition: MapOverlay.h:51
FPUtil.h
MapOverlay::SVGDraw
std::string SVGDraw() const
Definition: MapOverlay.cpp:294
rgbColor::g
float g
Definition: Colors.h:71
stripResolution
const double stripResolution
Definition: MapOverlay.cpp:16
MapOverlay::SetOverlayValue
void SetOverlayValue(int x, int y, double value)
Definition: MapOverlay.cpp:63
MapOverlay.h
loc
Definition: MapGenerators.cpp:296
MapOverlay::maxVal
double maxVal
Definition: MapOverlay.h:48
Colors.h
Colors::black
const rgbColor black
Definition: Colors.h:119
MapOverlay::GetValueColor
rgbColor GetValueColor(double value) const
Definition: MapOverlay.cpp:89
SVGUtil.h
Graphics::Display
Definition: Graphics.h:146
MapOverlay::MapOverlay
MapOverlay(Map *m)
Definition: MapOverlay.cpp:18
fless
bool fless(double a, double b)
Definition: FPUtil.h:28
Colors::darkgray
const rgbColor darkgray
Definition: Colors.h:123
DrawText
void DrawText(double x, double y, double z, double scale, const char *str)
Definition: GLUtil.cpp:526
Map::GetMapWidth
long GetMapWidth() const
return the width of the map
Definition: Map.h:163
fgreater
bool fgreater(double a, double b)
Definition: FPUtil.h:29
max
#define max(a, b)
Definition: MinimalSectorAbstraction.cpp:40
GLUtil.h
rgbColor::r
float r
Definition: Colors.h:71
SVGDrawLine
std::string SVGDrawLine(float x1, float y1, float x2, float y2, float width, rgbColor c)
Definition: SVGUtil.cpp:192
MapOverlay::OpenGLDraw
void OpenGLDraw() const
Definition: MapOverlay.cpp:98
MapOverlay::Draw
void Draw(Graphics::Display &display) const
Definition: MapOverlay.cpp:275
Map::GetMapHeight
long GetMapHeight() const
return the height of the map
Definition: Map.h:165
MapOverlay::colorMap
int colorMap
Definition: MapOverlay.h:50
MapOverlay::displayList
GLuint displayList
Definition: MapOverlay.h:52
Map::GetOpenGLCoord
bool GetOpenGLCoord(int _x, int _y, GLdouble &x, GLdouble &y, GLdouble &z, GLdouble &radius) const
Get the openGL coordinates of a given tile.
Definition: Map.cpp:1826
MapOverlay::customColorMap
static const int customColorMap
Definition: MapOverlay.h:42
fequal
bool fequal(double a, double b, double tolerance=TOLERANCE)
Definition: FPUtil.h:32
Graphics::Display::FillRect
void FillRect(rect r, rgbColor c)
Definition: Graphics.cpp:101
MapOverlay::m
Map * m
Definition: MapOverlay.h:45
MapOverlay::values
std::vector< double > values
Definition: MapOverlay.h:46
MapOverlay::Clear
void Clear()
Definition: MapOverlay.cpp:27
Map
A tile-based representation of the world.
Definition: Map.h:142
SVGFrameRect
std::string SVGFrameRect(float x, float y, float width, float height, float border, rgbColor c)
Definition: SVGUtil.cpp:99