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