SUMO - Simulation of Urban MObility
GLHelper.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
17 // Some methods which help to draw certain geometrical objects in openGL
18 /****************************************************************************/
19 
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25 
26 #include <cassert>
27 #include <utils/geom/GeomHelper.h>
28 #include <utils/common/StdDefs.h>
30 #include <utils/common/ToString.h>
31 #define FONTSTASH_IMPLEMENTATION // Expands implementation
32 #ifdef _MSC_VER
33 #pragma warning(disable: 4505) // do not warn about unused functions
34 #endif
35 #if __GNUC__ > 3
36 #pragma GCC diagnostic push
37 #pragma GCC diagnostic ignored "-Wunused-function"
38 #endif
42 #define GLFONTSTASH_IMPLEMENTATION // Expands implementation
44 #include "Roboto.h"
45 #include "GLHelper.h"
46 
47 #define CIRCLE_RESOLUTION (double)10 // inverse in degrees
48 
49 // ===========================================================================
50 // static member definitions
51 // ===========================================================================
52 std::vector<std::pair<double, double> > GLHelper::myCircleCoords;
53 std::vector<RGBColor> GLHelper::myDottedcontourColors;
54 FONScontext* GLHelper::myFont = nullptr;
55 double GLHelper::myFontSize = 50.0;
56 
57 void APIENTRY combCallback(GLdouble coords[3],
58  GLdouble* vertex_data[4],
59  GLfloat weight[4], GLdouble** dataOut) {
60  UNUSED_PARAMETER(weight);
61  UNUSED_PARAMETER(*vertex_data);
62  GLdouble* vertex;
63 
64  vertex = (GLdouble*)malloc(7 * sizeof(GLdouble));
65 
66  vertex[0] = coords[0];
67  vertex[1] = coords[1];
68  vertex[2] = coords[2];
69  *dataOut = vertex;
70 }
71 
72 // ===========================================================================
73 // method definitions
74 // ===========================================================================
75 
76 
77 void
79  if (v.size() == 0) {
80  return;
81  }
82  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
83  glBegin(GL_POLYGON);
84  for (PositionVector::const_iterator i = v.begin(); i != v.end(); i++) {
85  const Position& p = *i;
86  glVertex2d(p.x(), p.y());
87  }
88  if (close) {
89  const Position& p = *(v.begin());
90  glVertex2d(p.x(), p.y());
91  }
92  glEnd();
93 }
94 
95 
96 void
98  if (v.size() == 0) {
99  return;
100  }
101  GLUtesselator* tobj = gluNewTess();
102  gluTessCallback(tobj, GLU_TESS_VERTEX, (GLvoid(APIENTRY*)()) &glVertex3dv);
103  gluTessCallback(tobj, GLU_TESS_BEGIN, (GLvoid(APIENTRY*)()) &glBegin);
104  gluTessCallback(tobj, GLU_TESS_END, (GLvoid(APIENTRY*)()) &glEnd);
105  gluTessCallback(tobj, GLU_TESS_COMBINE, (GLvoid(APIENTRY*)()) &combCallback);
106  gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
107  gluTessBeginPolygon(tobj, nullptr);
108  gluTessBeginContour(tobj);
109  double* points = new double[(v.size() + int(close)) * 3];
110 
111  for (int i = 0; i != (int)v.size(); ++i) {
112  points[3 * i] = v[i].x();
113  points[3 * i + 1] = v[i].y();
114  points[3 * i + 2] = 0;
115  gluTessVertex(tobj, points + 3 * i, points + 3 * i);
116  }
117  if (close) {
118  const int i = (int)v.size();
119  points[3 * i] = v[0].x();
120  points[3 * i + 1] = v[0].y();
121  points[3 * i + 2] = 0;
122  gluTessVertex(tobj, points + 3 * i, points + 3 * i);
123  }
124  gluTessEndContour(tobj);
125  gluTessEndPolygon(tobj);
126  gluDeleteTess(tobj);
127  delete[] points;
128 }
129 
130 
131 void
132 GLHelper::drawBoxLine(const Position& beg, double rot, double visLength,
133  double width, double offset) {
134  glPushMatrix();
135  glTranslated(beg.x(), beg.y(), 0);
136  glRotated(rot, 0, 0, 1);
137  glBegin(GL_QUADS);
138  glVertex2d(-width - offset, 0);
139  glVertex2d(-width - offset, -visLength);
140  glVertex2d(width - offset, -visLength);
141  glVertex2d(width - offset, 0);
142  glEnd();
143  glPopMatrix();
144 }
145 
146 
147 void
148 GLHelper::drawBoxLine(const Position& beg1, const Position& beg2,
149  double rot, double visLength,
150  double width) {
151  glPushMatrix();
152  glTranslated((beg2.x() + beg1.x())*.5, (beg2.y() + beg1.y())*.5, 0);
153  glRotated(rot, 0, 0, 1);
154  glBegin(GL_QUADS);
155  glVertex2d(-width, 0);
156  glVertex2d(-width, -visLength);
157  glVertex2d(width, -visLength);
158  glVertex2d(width, 0);
159  glEnd();
160  glPopMatrix();
161 }
162 
163 
164 bool
165 GLHelper::rightTurn(double angle1, double angle2) {
166  double delta = angle2 - angle1;
167  while (delta > 180) {
168  delta -= 360;
169  }
170  while (delta < -180) {
171  delta += 360;
172  }
173  return delta <= 0;
174 }
175 
176 
177 void
179  const std::vector<double>& rots,
180  const std::vector<double>& lengths,
181  double width, int cornerDetail, double offset) {
182  // draw the lane
183  int e = (int) geom.size() - 1;
184  for (int i = 0; i < e; i++) {
185  drawBoxLine(geom[i], rots[i], lengths[i], width, offset);
186  }
187  // draw the corner details
188  if (cornerDetail > 0) {
189  for (int i = 1; i < e; i++) {
190  glPushMatrix();
191  glTranslated(geom[i].x(), geom[i].y(), 0.1);
192  double angleBeg = -rots[i - 1];
193  double angleEnd = 180 - rots[i];
194  if (rightTurn(rots[i - 1], rots[i])) {
195  std::swap(angleBeg, angleEnd);
196  }
197  // only draw the missing piece
198  angleBeg -= 90;
199  angleEnd += 90;
200  // avoid drawing more than 360 degrees
201  if (angleEnd - angleBeg > 360) {
202  angleBeg += 360;
203  }
204  if (angleEnd - angleBeg < -360) {
205  angleEnd += 360;
206  }
207  // draw the right way around
208  if (angleEnd > angleBeg) {
209  angleEnd -= 360;
210  }
211  drawFilledCircle(width + offset, cornerDetail, angleBeg, angleEnd);
212  glPopMatrix();
213  }
214  }
215 }
216 
217 
218 void
220  const std::vector<double>& rots,
221  const std::vector<double>& lengths,
222  const std::vector<RGBColor>& cols,
223  double width, int cornerDetail, double offset) {
224  int e = (int) geom.size() - 1;
225  for (int i = 0; i < e; i++) {
226  setColor(cols[i]);
227  drawBoxLine(geom[i], rots[i], lengths[i], width, offset);
228  }
229  if (cornerDetail > 0) {
230  for (int i = 1; i < e; i++) {
231  glPushMatrix();
232  setColor(cols[i]);
233  glTranslated(geom[i].x(), geom[i].y(), 0);
234  drawFilledCircle(width, cornerDetail);
235  glEnd();
236  glPopMatrix();
237  }
238  }
239 }
240 
241 
242 void
244  const PositionVector& geom2,
245  const std::vector<double>& rots,
246  const std::vector<double>& lengths,
247  double width) {
248  int minS = (int) MIN4(rots.size(), lengths.size(), geom1.size(), geom2.size());
249  for (int i = 0; i < minS; i++) {
250  GLHelper::drawBoxLine(geom1[i], geom2[i], rots[i], lengths[i], width);
251  }
252 }
253 
254 
255 void
256 GLHelper::drawBoxLines(const PositionVector& geom, double width) {
257  int e = (int) geom.size() - 1;
258  for (int i = 0; i < e; i++) {
259  const Position& f = geom[i];
260  const Position& s = geom[i + 1];
261  drawBoxLine(f,
262  RAD2DEG(atan2((s.x() - f.x()), (f.y() - s.y()))),
263  f.distanceTo(s),
264  width);
265  }
266 }
267 
268 
269 void
270 GLHelper::drawLine(const Position& beg, double rot, double visLength) {
271  glPushMatrix();
272  glTranslated(beg.x(), beg.y(), 0);
273  glRotated(rot, 0, 0, 1);
274  glBegin(GL_LINES);
275  glVertex2d(0, 0);
276  glVertex2d(0, -visLength);
277  glEnd();
278  glPopMatrix();
279 }
280 
281 
282 void
283 GLHelper::drawLine(const Position& beg1, const Position& beg2,
284  double rot, double visLength) {
285  glPushMatrix();
286  glTranslated((beg2.x() + beg1.x())*.5, (beg2.y() + beg1.y())*.5, 0);
287  glRotated(rot, 0, 0, 1);
288  glBegin(GL_LINES);
289  glVertex2d(0, 0);
290  glVertex2d(0, -visLength);
291  glEnd();
292  glPopMatrix();
293 }
294 
295 
296 
297 void
299  glBegin(GL_LINES);
300  int e = (int) v.size() - 1;
301  for (int i = 0; i < e; ++i) {
302  glVertex2d(v[i].x(), v[i].y());
303  glVertex2d(v[i + 1].x(), v[i + 1].y());
304  }
305  glEnd();
306 }
307 
308 
309 void
310 GLHelper::drawLine(const PositionVector& v, const std::vector<RGBColor>& cols) {
311  glBegin(GL_LINES);
312  int e = (int) v.size() - 1;
313  for (int i = 0; i < e; ++i) {
314  setColor(cols[i]);
315  glVertex2d(v[i].x(), v[i].y());
316  glVertex2d(v[i + 1].x(), v[i + 1].y());
317  }
318  glEnd();
319 }
320 
321 
322 void
323 GLHelper::drawLine(const Position& beg, const Position& end) {
324  glBegin(GL_LINES);
325  glVertex2d(beg.x(), beg.y());
326  glVertex2d(end.x(), end.y());
327  glEnd();
328 }
329 
330 
331 int
332 GLHelper::angleLookup(double angleDeg) {
333  const int numCoords = (int)myCircleCoords.size() - 1;
334  int index = ((int)(floor(angleDeg * CIRCLE_RESOLUTION + 0.5))) % numCoords;
335  if (index < 0) {
336  index += numCoords;
337  }
338  assert(index >= 0);
339  return (int)index;
340 }
341 
342 
343 void
344 GLHelper::drawFilledCircle(double width, int steps) {
345  drawFilledCircle(width, steps, 0, 360);
346 }
347 
348 
349 std::vector<Position>
351  drawFilledCircle(width, steps, 0, 360);
352  std::vector<Position> result;
353  const double inc = 360 / (double)steps;
354  // obtain all vertices
355  for (int i = 0; i <= steps; ++i) {
356  const std::pair<double, double>& vertex = myCircleCoords[angleLookup(i * inc)];
357  result.push_back(Position(vertex.first * width, vertex.second * width));
358  }
359  return result;
360 }
361 
362 
363 void
364 GLHelper::drawFilledCircle(double width, int steps, double beg, double end) {
365  if (myCircleCoords.size() == 0) {
366  for (int i = 0; i <= (int)(360 * CIRCLE_RESOLUTION); ++i) {
367  const double x = (double) sin(DEG2RAD(i / CIRCLE_RESOLUTION));
368  const double y = (double) cos(DEG2RAD(i / CIRCLE_RESOLUTION));
369  myCircleCoords.push_back(std::pair<double, double>(x, y));
370  }
371  }
372  const double inc = (end - beg) / (double)steps;
373  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
374  std::pair<double, double> p1 = myCircleCoords[angleLookup(beg)];
375 
376  for (int i = 0; i <= steps; ++i) {
377  const std::pair<double, double>& p2 = myCircleCoords[angleLookup(beg + i * inc)];
378  glBegin(GL_TRIANGLES);
379  glVertex2d(p1.first * width, p1.second * width);
380  glVertex2d(p2.first * width, p2.second * width);
381  glVertex2d(0, 0);
382  glEnd();
383  p1 = p2;
384  }
385 }
386 
387 
388 void
389 GLHelper::drawOutlineCircle(double width, double iwidth, int steps) {
390  drawOutlineCircle(width, iwidth, steps, 0, 360);
391 }
392 
393 
394 void
395 GLHelper::drawOutlineCircle(double width, double iwidth, int steps,
396  double beg, double end) {
397  if (myCircleCoords.size() == 0) {
398  for (int i = 0; i < 360; i += 10) {
399  double x = (double) sin(DEG2RAD(i));
400  double y = (double) cos(DEG2RAD(i));
401  myCircleCoords.push_back(std::pair<double, double>(x, y));
402  }
403  }
404  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
405  std::pair<double, double> p1 =
406  beg == 0 ? myCircleCoords[0] : myCircleCoords[((int) beg / 10) % 36];
407  for (int i = (int)(beg / 10); i < steps && (36.0 / (double) steps * (double) i) * 10 < end; i++) {
408  const std::pair<double, double>& p2 =
409  myCircleCoords[(int)(36.0 / (double) steps * (double) i)];
410  glBegin(GL_TRIANGLES);
411  glVertex2d(p1.first * width, p1.second * width);
412  glVertex2d(p2.first * width, p2.second * width);
413  glVertex2d(p2.first * iwidth, p2.second * iwidth);
414 
415  glVertex2d(p2.first * iwidth, p2.second * iwidth);
416  glVertex2d(p1.first * iwidth, p1.second * iwidth);
417  glVertex2d(p1.first * width, p1.second * width);
418  glEnd();
419  p1 = p2;
420  }
421  const std::pair<double, double>& p2 =
422  end == 360 ? myCircleCoords[0] : myCircleCoords[((int) end / 10) % 36];
423  glBegin(GL_TRIANGLES);
424  glVertex2d(p1.first * width, p1.second * width);
425  glVertex2d(p2.first * width, p2.second * width);
426  glVertex2d(p2.first * iwidth, p2.second * iwidth);
427 
428  glVertex2d(p2.first * iwidth, p2.second * iwidth);
429  glVertex2d(p1.first * iwidth, p1.second * iwidth);
430  glVertex2d(p1.first * width, p1.second * width);
431  glEnd();
432 }
433 
434 
435 void
437  double tLength, double tWidth) {
438  const double length = p1.distanceTo(p2);
439  if (length < tLength) {
440  tWidth *= length / tLength;
441  tLength = length;
442  }
443  Position rl(PositionVector::positionAtOffset(p1, p2, length - tLength));
444  glPushMatrix();
445  glTranslated(rl.x(), rl.y(), 0);
446  glRotated(-GeomHelper::naviDegree(p1.angleTo2D(p2)), 0, 0, 1);
447  glBegin(GL_TRIANGLES);
448  glVertex2d(0, tLength);
449  glVertex2d(-tWidth, 0);
450  glVertex2d(+tWidth, 0);
451  glEnd();
452  glPopMatrix();
453 }
454 
455 
456 const std::vector<RGBColor>&
458  // check if more colors has to be added
459  while ((int)myDottedcontourColors.size() < size) {
462  } else {
464  }
465  }
466  return myDottedcontourColors;
467 }
468 
469 
470 void
471 GLHelper::drawShapeDottedContour(const int type, const PositionVector& shape, const double width) {
472  glPushMatrix();
473  // build contour using shapes of first and last lane shapes
474  PositionVector contourFront = shape;
475  // only add an contourback if width is greather of 0
476  if (width > 0) {
477  PositionVector contourback = contourFront;
478  contourFront.move2side(width);
479  contourback.move2side(-width);
480  contourback = contourback.reverse();
481  for (auto i : contourback) {
482  contourFront.push_back(i);
483  }
484  contourFront.push_back(shape.front());
485  }
486  // resample shape
487  PositionVector resampledShape = contourFront.resample(1);
488  // draw contour over shape
489  glTranslated(0, 0, type + 2);
490  // set custom line width
491  glLineWidth(3);
492  // draw contour
493  drawLine(resampledShape, getDottedcontourColors((int)resampledShape.size()));
494  //restore line width
495  glLineWidth(1);
496  glPopMatrix();
497 }
498 
499 
500 void
501 GLHelper::drawShapeDottedContour(const int type, const PositionVector& shape) {
502  glPushMatrix();
503  // resample junction shape
504  PositionVector resampledShape = shape.resample(1);
505  // draw contour over shape
506  glTranslated(0, 0, type + 0.1);
507  // set custom line width
508  glLineWidth(3);
509  // draw contour
510  GLHelper::drawLine(resampledShape, GLHelper::getDottedcontourColors((int)resampledShape.size()));
511  //restore line width
512  glLineWidth(1);
513  glPopMatrix();
514 }
515 
516 
517 void
518 GLHelper::drawShapeDottedContour(const int type, const PositionVector& frontShape, const double offsetFrontShape, const PositionVector& backShape, const double offsetBackShape) {
519  glPushMatrix();
520  // build contour using shapes of first and last lane shapes
521  PositionVector contourFront = frontShape;
522  PositionVector contourback = backShape;
523  contourFront.move2side(offsetFrontShape);
524  contourback.move2side(offsetBackShape);
525  contourback = contourback.reverse();
526  for (auto i : contourback) {
527  contourFront.push_back(i);
528  }
529  contourFront.push_back(frontShape.front());
530  // resample shape
531  PositionVector resampledShape = contourFront.resample(1);
532  // draw contour over shape
533  glTranslated(0, 0, type + 2);
534  // set custom line width
535  glLineWidth(3);
536  // draw contour
537  GLHelper::drawLine(resampledShape, getDottedcontourColors((int)resampledShape.size()));
538  //restore line width
539  glLineWidth(1);
540  glPopMatrix();
541 }
542 
543 
544 void
545 GLHelper::drawShapeDottedContour(const int type, const Position& center, const double width, const double height, const double rotation, const double offsetX, const double offsetY) {
546  glPushMatrix();
547  // create shape around center
548  PositionVector shape;
549  shape.push_back(Position(width / 2, height / 2));
550  shape.push_back(Position(width / -2, height / 2));
551  shape.push_back(Position(width / -2, height / -2));
552  shape.push_back(Position(width / 2, height / -2));
553  shape.push_back(Position(width / 2, height / 2));
554  // resample shape
555  shape = shape.resample(1);
556  // draw contour over shape
557  glTranslated(center.x(), center.y(), type + 2);
558  // set custom line width
559  glLineWidth(3);
560  // rotate
561  glRotated(rotation, 0, 0, 1);
562  // translate offset
563  glTranslated(offsetX, offsetY, 0);
564  // draw contour
565  GLHelper::drawLine(shape, getDottedcontourColors((int)shape.size()));
566  //restore line width
567  glLineWidth(1);
568  glPopMatrix();
569 }
570 
571 
572 void
574  glColor4ub(c.red(), c.green(), c.blue(), c.alpha());
575 }
576 
577 
578 RGBColor
580  GLdouble current[4];
581  glGetDoublev(GL_CURRENT_COLOR, current);
582  return RGBColor(static_cast<unsigned char>(current[0] * 255. + 0.5),
583  static_cast<unsigned char>(current[1] * 255. + 0.5),
584  static_cast<unsigned char>(current[2] * 255. + 0.5),
585  static_cast<unsigned char>(current[3] * 255. + 0.5));
586 }
587 
588 
589 void
592  myFont = nullptr;
593 }
594 
595 
596 bool
598  if (myFont == nullptr) {
600  if (myFont != nullptr) {
602  fonsSetFont(myFont, fontNormal);
603  fonsSetSize(myFont, (float)myFontSize);
604  }
605  }
606  return myFont != nullptr;
607 }
608 
609 
610 void
611 GLHelper::drawText(const std::string& text, const Position& pos,
612  const double layer, const double size,
613  const RGBColor& col, const double angle, const int align,
614  double width) {
615  if (width <= 0) {
616  width = size;
617  }
618  if (!initFont()) {
619  return;
620  };
621  glPushMatrix();
622  glAlphaFunc(GL_GREATER, 0.5);
623  glEnable(GL_ALPHA_TEST);
624  glTranslated(pos.x(), pos.y(), layer);
625  glScaled(width / myFontSize, size / myFontSize, 1.);
626  glRotated(-angle, 0, 0, 1);
627  fonsSetAlign(myFont, align == 0 ? FONS_ALIGN_CENTER | FONS_ALIGN_MIDDLE : align);
628  fonsSetColor(myFont, glfonsRGBA(col.red(), col.green(), col.blue(), col.alpha()));
629  fonsDrawText(myFont, 0., 0., text.c_str(), nullptr);
630  glPopMatrix();
631 }
632 
633 
634 void
636  const GUIVisualizationTextSettings& settings,
637  const std::string& text, const Position& pos,
638  const double scale,
639  const double angle,
640  const double layer) {
641  drawTextBox(text, pos, layer,
642  settings.scaledSize(scale),
643  settings.color,
644  settings.bgColor,
646  angle, 0, 0.2);
647 }
648 
649 
650 void
651 GLHelper::drawTextBox(const std::string& text, const Position& pos,
652  const double layer, const double size,
653  const RGBColor& txtColor, const RGBColor& bgColor, const RGBColor& borderColor,
654  const double angle,
655  const double relBorder,
656  const double relMargin)
657 {
658  if (!initFont()) {
659  return;
660  };
661  const double boxAngle = 90;
662  const double stringWidth = size / myFontSize * fonsTextBounds(myFont, 0, 0, text.c_str(), nullptr, nullptr);
663  const double borderWidth = size * relBorder;
664  const double boxHeight = size * (0.32 + 0.6 * relMargin);
665  const double boxWidth = stringWidth + size * relMargin;
666  glPushMatrix();
667  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
668  glTranslated(pos.x(), pos.y(), layer);
669  glRotated(-angle, 0, 0, 1);
670  Position left(-boxWidth * 0.5, 0);
671  setColor(borderColor);
672  drawBoxLine(left, boxAngle, boxWidth, boxHeight);
673  left.add(borderWidth * 1.5, 0);
674  setColor(bgColor);
675  glTranslated(0, 0, 0.01);
676  drawBoxLine(left, boxAngle, boxWidth - 3 * borderWidth, boxHeight - 2 * borderWidth);
677  glPopMatrix();
678  drawText(text, pos, layer + 0.02, size, txtColor, angle);
679 }
680 
681 
682 void
683 GLHelper::drawTextAtEnd(const std::string& text, const PositionVector& shape, double x, double size, RGBColor color) {
684  glPushMatrix();
685  const Position& end = shape.back();
686  const Position& f = shape[-2];
687  const double rot = RAD2DEG(atan2((end.x() - f.x()), (f.y() - end.y())));
688  glTranslated(end.x(), end.y(), 0);
689  glRotated(rot, 0, 0, 1);
690  GLHelper::drawText(text, Position(x, 0.26), 0, .6 * size / 50, color, 180);
691  glPopMatrix();
692 }
693 
694 
695 void
697  const std::vector<double>& rots,
698  const std::vector<double>& lengths,
699  double length, double spacing,
700  double halfWidth, bool drawForSelecting) {
701  glPushMatrix();
702  // draw on top of of the white area between the rails
703  glTranslated(0, 0, 0.1);
704  int e = (int) geom.size() - 1;
705  for (int i = 0; i < e; ++i) {
706  glPushMatrix();
707  glTranslated(geom[i].x(), geom[i].y(), 0.0);
708  glRotated(rots[i], 0, 0, 1);
709  // draw crossing depending if isn't being drawn for selecting
710  if (!drawForSelecting) {
711  for (double t = 0; t < lengths[i]; t += spacing) {
712  glBegin(GL_QUADS);
713  glVertex2d(-halfWidth, -t);
714  glVertex2d(-halfWidth, -t - length);
715  glVertex2d(halfWidth, -t - length);
716  glVertex2d(halfWidth, -t);
717  glEnd();
718  }
719  } else {
720  // only draw a single rectangle if it's being drawn only for selecting
721  glBegin(GL_QUADS);
722  glVertex2d(-halfWidth, 0);
723  glVertex2d(-halfWidth, -lengths.back());
724  glVertex2d(halfWidth, -lengths.back());
725  glVertex2d(halfWidth, 0);
726  glEnd();
727  }
728  // pop three draw matrix
729  glPopMatrix();
730  }
731  glPopMatrix();
732 }
733 
734 
735 void
736 GLHelper::debugVertices(const PositionVector& shape, double size, double layer) {
737  RGBColor color = RGBColor::randomHue();
738  for (int i = 0; i < (int)shape.size(); ++i) {
739  GLHelper::drawText(toString(i), shape[i], layer, size, color, 0);
740  }
741 }
742 
743 
744 /****************************************************************************/
745 
FONS_DEF void fonsSetAlign(FONScontext *s, int align)
static std::vector< std::pair< double, double > > myCircleCoords
Storage for precomputed sin/cos-values describing a circle.
Definition: GLHelper.h:359
static RGBColor randomHue(double s=1, double v=1)
Return color with random hue.
Definition: RGBColor.cpp:334
static void resetFont()
to be called when the font context is invalidated
Definition: GLHelper.cpp:590
FONS_DEF float fonsDrawText(FONScontext *s, float x, float y, const char *string, const char *end)
static void drawBoxLines(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double width, int cornerDetail=0, double offset=0)
Draws thick lines.
Definition: GLHelper.cpp:178
static void drawTextBox(const std::string &text, const Position &pos, const double layer, const double size, const RGBColor &txtColor=RGBColor::BLACK, const RGBColor &bgColor=RGBColor::WHITE, const RGBColor &borderColor=RGBColor::BLACK, const double angle=0, const double relBorder=0.05, const double relMargin=0.5)
draw Text box with given parameters
Definition: GLHelper.cpp:651
void add(const Position &pos)
Adds the given position to this one.
Definition: Position.h:127
static void drawTextAtEnd(const std::string &text, const PositionVector &shape, double x, double size, RGBColor color)
draw text and the end of shape
Definition: GLHelper.cpp:683
static const RGBColor WHITE
Definition: RGBColor.h:191
static bool initFont()
init myFont
Definition: GLHelper.cpp:597
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition: RGBColor.h:84
T MIN4(T a, T b, T c, T d)
Definition: StdDefs.h:97
PositionVector resample(double maxLength) const
resample shape with the given number of points (equal spacing)
static void debugVertices(const PositionVector &shape, double size, double layer=256)
draw vertex numbers for the given shape (in a random color)
Definition: GLHelper.cpp:736
double y() const
Returns the y-position.
Definition: Position.h:62
static void drawTextSettings(const GUIVisualizationTextSettings &settings, const std::string &text, const Position &pos, const double scale, const double angle=0, const double layer=2048)
Definition: GLHelper.cpp:635
double x() const
Returns the x-position.
Definition: Position.h:57
static void drawText(const std::string &text, const Position &pos, const double layer, const double size, const RGBColor &col=RGBColor::BLACK, const double angle=0, int align=0, double width=-1)
Definition: GLHelper.cpp:611
void glfonsDelete(FONScontext *ctx)
FONS_DEF void fonsSetFont(FONScontext *s, int font)
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position ...
Definition: Position.h:254
unsigned int glfonsRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
static void drawFilledPoly(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
Definition: GLHelper.cpp:78
PositionVector reverse() const
reverse position vector
unsigned char blue() const
Returns the blue-amount of the color.
Definition: RGBColor.h:77
#define RAD2DEG(x)
Definition: GeomHelper.h:39
static const RGBColor BLACK
Definition: RGBColor.h:192
static void drawFilledCircle(double width, int steps=8)
Draws a filled circle around (0,0)
Definition: GLHelper.cpp:344
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:33
static void drawFilledPolyTesselated(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
Definition: GLHelper.cpp:97
static double naviDegree(const double angle)
Definition: GeomHelper.cpp:180
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:49
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:573
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
A list of positions.
double scaledSize(double scale, double constFactor=0.1) const
static std::vector< Position > drawFilledCircleReturnVertices(double width, int steps=8)
Draws a filled circle around (0,0) returning circle vertex.
Definition: GLHelper.cpp:350
static double myFontSize
Definition: GLHelper.h:363
static int angleLookup(double angleDeg)
normalize angle for lookup in myCircleCoords
Definition: GLHelper.cpp:332
static void drawOutlineCircle(double width, double iwidth, int steps=8)
Draws an unfilled circle around (0,0)
Definition: GLHelper.cpp:389
static void drawLine(const Position &beg, double rot, double visLength)
Draws a thin line.
Definition: GLHelper.cpp:270
#define DEG2RAD(x)
Definition: GeomHelper.h:38
void move2side(double amount)
move position vector to side using certain ammount
static struct FONScontext * myFont
Font context.
Definition: GLHelper.h:362
FONS_DEF void fonsSetColor(FONScontext *s, unsigned int color)
void APIENTRY combCallback(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **dataOut)
Definition: GLHelper.cpp:57
FONS_DEF void fonsSetSize(FONScontext *s, float size)
static void drawShapeDottedContour(const int type, const PositionVector &shape, const double width)
draw a dotted contour around the given Non closed shape with certain width
Definition: GLHelper.cpp:471
unsigned char green() const
Returns the green-amount of the color.
Definition: RGBColor.h:70
unsigned char data_font_Roboto_Medium_ttf[]
Definition: Roboto.h:18
static void drawCrossTies(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double length, double spacing, double halfWidth, bool drawForSelecting)
draw crossties for railroads or pedestrian crossings
Definition: GLHelper.cpp:696
static bool rightTurn(double angle1, double angle2)
whether the road makes a right turn (or goes straight)
Definition: GLHelper.cpp:165
static std::vector< RGBColor > myDottedcontourColors
static vector with a list of alternated black/white colors (used for contourns)
Definition: GLHelper.h:366
#define CIRCLE_RESOLUTION
Definition: GLHelper.cpp:47
unsigned int data_font_Roboto_Medium_ttf_len
Definition: Roboto.h:14359
unsigned char red() const
Returns the red-amount of the color.
Definition: RGBColor.h:63
FONScontext * glfonsCreate(int width, int height, int flags)
static void drawTriangleAtEnd(const Position &p1, const Position &p2, double tLength, double tWidth)
Draws a triangle at the end of the given line.
Definition: GLHelper.cpp:436
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
Definition: Position.h:234
FONS_DEF int fonsAddFontMem(FONScontext *s, const char *name, unsigned char *data, int ndata, int freeData)
struct FONScontext FONScontext
Definition: fontstash.h:95
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition: GLHelper.cpp:132
static const RGBColor INVISIBLE
Definition: RGBColor.h:194
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
FONS_DEF float fonsTextBounds(FONScontext *s, float x, float y, const char *string, const char *end, float *bounds)
static const std::vector< RGBColor > & getDottedcontourColors(const int size)
get dotted contour colors (black and white). Vector will be automatically increased if current size i...
Definition: GLHelper.cpp:457
static RGBColor getColor()
gets the gl-color
Definition: GLHelper.cpp:579