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-2022 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
20 // Some methods which help to draw certain geometrical objects in openGL
21 /****************************************************************************/
22 #include <config.h>
23 
24 #include <cassert>
25 #include <utils/geom/GeomHelper.h>
26 #include <utils/common/StdDefs.h>
28 #include <utils/common/ToString.h>
30 #define FONTSTASH_IMPLEMENTATION // Expands implementation
31 #ifdef _MSC_VER
32 #pragma warning(disable: 4505) // do not warn about unused functions
33 #endif
34 #if __GNUC__ > 3
35 #pragma GCC diagnostic push
36 #pragma GCC diagnostic ignored "-Wunused-function"
37 #endif
40 #define GLFONTSTASH_IMPLEMENTATION // Expands implementation
42 #include <utils/geom/Boundary.h>
43 #ifdef HAVE_GL2PS
44 #include <gl2ps.h>
45 #endif
46 #include "Roboto.h"
47 #include "GLHelper.h"
48 
49 #define CIRCLE_RESOLUTION (double)10 // inverse in degrees
50 //#define CHECK_PUSHPOP // enable or disable check push and pop matrix/names
51 
52 #ifndef CALLBACK
53 #define CALLBACK
54 #endif
55 
56 // ===========================================================================
57 // static member definitions
58 // ===========================================================================
59 
62 std::vector<std::pair<double, double> > GLHelper::myCircleCoords;
63 std::vector<RGBColor> GLHelper::myDottedcontourColors;
64 FONScontext* GLHelper::myFont = nullptr;
65 double GLHelper::myFontSize = 50.0;
66 bool GLHelper::myGL2PSActive = false;
67 
68 void CALLBACK combCallback(GLdouble coords[3],
69  GLdouble* vertex_data[4],
70  GLfloat weight[4], GLdouble** dataOut) {
71  UNUSED_PARAMETER(weight);
72  UNUSED_PARAMETER(*vertex_data);
73  GLdouble* vertex;
74 
75  vertex = (GLdouble*)malloc(7 * sizeof(GLdouble));
76 
77  vertex[0] = coords[0];
78  vertex[1] = coords[1];
79  vertex[2] = coords[2];
80  *dataOut = vertex;
81 }
82 
83 // ===========================================================================
84 // method definitions
85 // ===========================================================================
86 
87 const std::vector<std::pair<double, double> >&
89  // fill in first call
90  if (myCircleCoords.size() == 0) {
91  for (int i = 0; i <= (int)(360 * CIRCLE_RESOLUTION); ++i) {
92  const double x = (double) sin(DEG2RAD(i / CIRCLE_RESOLUTION));
93  const double y = (double) cos(DEG2RAD(i / CIRCLE_RESOLUTION));
94  myCircleCoords.push_back(std::pair<double, double>(x, y));
95  }
96  }
97  return myCircleCoords;
98 }
99 
100 
101 int
102 GLHelper::angleLookup(double angleDeg) {
103  const int numCoords = (int)getCircleCoords().size() - 1;
104  int index = ((int)(floor(angleDeg * CIRCLE_RESOLUTION + 0.5))) % numCoords;
105  if (index < 0) {
106  index += numCoords;
107  }
108  assert(index >= 0);
109  return (int)index;
110 }
111 
112 
113 void
115  glPushMatrix();
116 #ifdef CHECK_PUSHPOP
117  myMatrixCounter++;
118 #endif
119 }
120 
121 
122 void
124  glPopMatrix();
125 #ifdef CHECK_PUSHPOP
126  myMatrixCounter--;
127 #endif
128 }
129 
130 
131 void
132 GLHelper::pushName(unsigned int name) {
133  glPushName(name);
134 #ifdef CHECK_PUSHPOP
135  myNameCounter++;
136 #endif
137 }
138 
139 
140 void
142  glPopName();
143 #ifdef CHECK_PUSHPOP
144  myNameCounter--;
145 #endif
146 }
147 
148 
149 void
151 #ifdef CHECK_PUSHPOP
152  if (myMatrixCounter != 0) {
153  WRITE_WARNING("invalid matrix counter. Check that number of pushMatrix and popMatrix functions calls are the same");
154  }
155 #endif
156 }
157 
158 
159 void
161 #ifdef CHECK_PUSHPOP
162  if (myNameCounter != 0) {
163  WRITE_WARNING("invalid Name counter. Check that number of pushName and popName functions calls are the same");
164  }
165 #endif
166 }
167 
168 
169 void
171  if (v.size() == 0) {
172  return;
173  }
174  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
175  glBegin(GL_POLYGON);
176  for (PositionVector::const_iterator i = v.begin(); i != v.end(); i++) {
177  const Position& p = *i;
178  glVertex2d(p.x(), p.y());
179  }
180  if (close) {
181  const Position& p = *(v.begin());
182  glVertex2d(p.x(), p.y());
183  }
184  glEnd();
185 }
186 
187 
188 void
190  if (v.size() == 0) {
191  return;
192  }
193  GLUtesselator* tobj = gluNewTess();
194 #if defined(__GNUC__) && __GNUC__ >= 8
195 #pragma GCC diagnostic push
196 #pragma GCC diagnostic ignored "-Wcast-function-type"
197 #endif
198  gluTessCallback(tobj, GLU_TESS_VERTEX, (GLvoid(CALLBACK*)()) &glVertex3dv);
199  gluTessCallback(tobj, GLU_TESS_BEGIN, (GLvoid(CALLBACK*)()) &glBegin);
200  gluTessCallback(tobj, GLU_TESS_END, (GLvoid(CALLBACK*)()) &glEnd);
201  gluTessCallback(tobj, GLU_TESS_COMBINE, (GLvoid(CALLBACK*)()) &combCallback);
202 #if defined(__GNUC__) && __GNUC__ >= 8
203 #pragma GCC diagnostic pop
204 #endif
205  gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
206  gluTessBeginPolygon(tobj, nullptr);
207  gluTessBeginContour(tobj);
208  double* points = new double[(v.size() + int(close)) * 3];
209 
210  for (int i = 0; i != (int)v.size(); ++i) {
211  points[3 * i] = v[i].x();
212  points[3 * i + 1] = v[i].y();
213  points[3 * i + 2] = 0;
214  gluTessVertex(tobj, points + 3 * i, points + 3 * i);
215  }
216  if (close) {
217  const int i = (int)v.size();
218  points[3 * i] = v[0].x();
219  points[3 * i + 1] = v[0].y();
220  points[3 * i + 2] = 0;
221  gluTessVertex(tobj, points + 3 * i, points + 3 * i);
222  }
223  gluTessEndContour(tobj);
224  gluTessEndPolygon(tobj);
225  gluDeleteTess(tobj);
226  delete[] points;
227 }
228 
229 
230 void
231 GLHelper::drawBoxLine(const Position& beg, double rot, double visLength,
232  double width, double offset) {
234  glTranslated(beg.x(), beg.y(), 0);
235  glRotated(rot, 0, 0, 1);
236  glBegin(GL_QUADS);
237  glVertex2d(-width - offset, 0);
238  glVertex2d(-width - offset, -visLength);
239  glVertex2d(width - offset, -visLength);
240  glVertex2d(width - offset, 0);
241  glEnd();
243 }
244 
245 
246 void
247 GLHelper::drawBoxLine(const Position& beg1, const Position& beg2,
248  double rot, double visLength,
249  double width) {
251  glTranslated((beg2.x() + beg1.x())*.5, (beg2.y() + beg1.y())*.5, 0);
252  glRotated(rot, 0, 0, 1);
253  glBegin(GL_QUADS);
254  glVertex2d(-width, 0);
255  glVertex2d(-width, -visLength);
256  glVertex2d(width, -visLength);
257  glVertex2d(width, 0);
258  glEnd();
260 }
261 
262 
263 bool
264 GLHelper::rightTurn(double angle1, double angle2) {
265  double delta = angle2 - angle1;
266  while (delta > 180) {
267  delta -= 360;
268  }
269  while (delta < -180) {
270  delta += 360;
271  }
272  return delta <= 0;
273 }
274 
275 
276 void
278  const std::vector<double>& rots,
279  const std::vector<double>& lengths,
280  double width, int cornerDetail, double offset) {
281  // draw the lane
282  int e = (int) geom.size() - 1;
283  for (int i = 0; i < e; i++) {
284  drawBoxLine(geom[i], rots[i], lengths[i], width, offset);
285  }
286  // draw the corner details
287  if (cornerDetail > 0) {
288  for (int i = 1; i < e; i++) {
290  glTranslated(geom[i].x(), geom[i].y(), 0.1);
291  double angleBeg = -rots[i - 1];
292  double angleEnd = 180 - rots[i];
293  if (rightTurn(rots[i - 1], rots[i])) {
294  std::swap(angleBeg, angleEnd);
295  }
296  // only draw the missing piece
297  angleBeg -= 90;
298  angleEnd += 90;
299  // avoid drawing more than 360 degrees
300  if (angleEnd - angleBeg > 360) {
301  angleBeg += 360;
302  }
303  if (angleEnd - angleBeg < -360) {
304  angleEnd += 360;
305  }
306  // draw the right way around
307  if (angleEnd > angleBeg) {
308  angleEnd -= 360;
309  }
310  drawFilledCircle(width + offset, cornerDetail, angleBeg, angleEnd);
312  }
313  }
314 }
315 
316 
317 void
319  const std::vector<double>& rots,
320  const std::vector<double>& lengths,
321  const std::vector<RGBColor>& cols,
322  double width, int cornerDetail, double offset) {
323  int e = (int) geom.size() - 1;
324  for (int i = 0; i < e; i++) {
325  setColor(cols[i]);
326  drawBoxLine(geom[i], rots[i], lengths[i], width, offset);
327  }
328  if (cornerDetail > 0) {
329  for (int i = 1; i < e; i++) {
331  setColor(cols[i]);
332  glTranslated(geom[i].x(), geom[i].y(), 0);
333  drawFilledCircle(width, cornerDetail);
334  glEnd();
336  }
337  }
338 }
339 
340 
341 void
343  const PositionVector& geom2,
344  const std::vector<double>& rots,
345  const std::vector<double>& lengths,
346  double width) {
347  int minS = (int) MIN4(rots.size(), lengths.size(), geom1.size(), geom2.size());
348  for (int i = 0; i < minS; i++) {
349  GLHelper::drawBoxLine(geom1[i], geom2[i], rots[i], lengths[i], width);
350  }
351 }
352 
353 
354 void
355 GLHelper::drawBoxLines(const PositionVector& geom, double width) {
356  int e = (int) geom.size() - 1;
357  for (int i = 0; i < e; i++) {
358  const Position& f = geom[i];
359  const Position& s = geom[i + 1];
360  drawBoxLine(f,
361  RAD2DEG(atan2((s.x() - f.x()), (f.y() - s.y()))),
362  f.distanceTo(s),
363  width);
364  }
365 }
366 
367 
368 void
369 GLHelper::drawLine(const Position& beg, double rot, double visLength) {
371  glTranslated(beg.x(), beg.y(), 0);
372  glRotated(rot, 0, 0, 1);
373  glBegin(GL_LINES);
374  glVertex2d(0, 0);
375  glVertex2d(0, -visLength);
376  glEnd();
378 }
379 
380 
381 void
382 GLHelper::drawLine(const Position& beg1, const Position& beg2,
383  double rot, double visLength) {
385  glTranslated((beg2.x() + beg1.x())*.5, (beg2.y() + beg1.y())*.5, 0);
386  glRotated(rot, 0, 0, 1);
387  glBegin(GL_LINES);
388  glVertex2d(0, 0);
389  glVertex2d(0, -visLength);
390  glEnd();
392 }
393 
394 
395 
396 void
398  glBegin(GL_LINES);
399  int e = (int) v.size() - 1;
400  for (int i = 0; i < e; ++i) {
401  glVertex2d(v[i].x(), v[i].y());
402  glVertex2d(v[i + 1].x(), v[i + 1].y());
403  }
404  glEnd();
405 }
406 
407 
408 void
409 GLHelper::drawLine(const PositionVector& v, const std::vector<RGBColor>& cols) {
410  glBegin(GL_LINES);
411  int e = (int) v.size() - 1;
412  for (int i = 0; i < e; ++i) {
413  setColor(cols[i]);
414  glVertex2d(v[i].x(), v[i].y());
415  glVertex2d(v[i + 1].x(), v[i + 1].y());
416  }
417  glEnd();
418 }
419 
420 
421 void
422 GLHelper::drawLine(const Position& beg, const Position& end) {
423  glBegin(GL_LINES);
424  glVertex2d(beg.x(), beg.y());
425  glVertex2d(end.x(), end.y());
426  glEnd();
427 }
428 
429 
430 void
431 GLHelper::drawFilledCircle(double width, int steps) {
432  drawFilledCircle(width, steps, 0, 360);
433 }
434 
435 
436 void
437 GLHelper::drawFilledCircle(double width, int steps, double beg, double end) {
438  const double inc = (end - beg) / (double)steps;
439  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
440  std::pair<double, double> p1 = getCircleCoords().at(angleLookup(beg));
441 
442  for (int i = 0; i <= steps; ++i) {
443  const std::pair<double, double>& p2 = getCircleCoords().at(angleLookup(beg + i * inc));
444  glBegin(GL_TRIANGLES);
445  glVertex2d(p1.first * width, p1.second * width);
446  glVertex2d(p2.first * width, p2.second * width);
447  glVertex2d(0, 0);
448  glEnd();
449  p1 = p2;
450  }
451 }
452 
453 
454 void
455 GLHelper::drawOutlineCircle(double width, double iwidth, int steps) {
456  drawOutlineCircle(width, iwidth, steps, 0, 360);
457 }
458 
459 
460 void
461 GLHelper::drawOutlineCircle(double width, double iwidth, int steps,
462  double beg, double end) {
463  const double inc = (end - beg) / (double)steps;
464  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
465  std::pair<double, double> p1 = getCircleCoords().at(angleLookup(beg));
466 
467  for (int i = 0; i <= steps; ++i) {
468  const std::pair<double, double>& p2 = getCircleCoords().at(angleLookup(beg + i * inc));
469  glBegin(GL_TRIANGLES);
470  glVertex2d(p1.first * width, p1.second * width);
471  glVertex2d(p2.first * width, p2.second * width);
472  glVertex2d(p2.first * iwidth, p2.second * iwidth);
473 
474  glVertex2d(p2.first * iwidth, p2.second * iwidth);
475  glVertex2d(p1.first * iwidth, p1.second * iwidth);
476  glVertex2d(p1.first * width, p1.second * width);
477 
478  glEnd();
479  p1 = p2;
480  }
481 }
482 
483 
484 void
485 GLHelper::drawTriangleAtEnd(const Position& p1, const Position& p2, double tLength,
486  double tWidth, const double extraOffset) {
487  const double length = p1.distanceTo(p2);
488  if (length < tLength) {
489  tWidth *= length / tLength;
490  tLength = length;
491  }
492  Position rl(PositionVector::positionAtOffset(p1, p2, length - tLength));
494  glTranslated(rl.x(), rl.y(), 0);
495  glRotated(-GeomHelper::naviDegree(p1.angleTo2D(p2)), 0, 0, 1);
496  glTranslated(0, extraOffset, 0);
497  glBegin(GL_TRIANGLES);
498  glVertex2d(0, tLength);
499  glVertex2d(-tWidth, 0);
500  glVertex2d(+tWidth, 0);
501  glEnd();
503 }
504 
505 
506 void
508  glColor4ub(c.red(), c.green(), c.blue(), c.alpha());
509 }
510 
511 
512 RGBColor
514  GLdouble current[4];
515  glGetDoublev(GL_CURRENT_COLOR, current);
516  return RGBColor(static_cast<unsigned char>(current[0] * 255. + 0.5),
517  static_cast<unsigned char>(current[1] * 255. + 0.5),
518  static_cast<unsigned char>(current[2] * 255. + 0.5),
519  static_cast<unsigned char>(current[3] * 255. + 0.5));
520 }
521 
522 
523 void
526  myFont = nullptr;
527 }
528 
529 
530 void
531 GLHelper::setGL2PS(bool active) {
532  myGL2PSActive = active;
533 }
534 
535 
536 void
537 GLHelper::drawSpaceOccupancies(const double exaggeration, const Position& pos, const double rotation,
538  const double width, const double length, const bool vehicle) {
539  // declare colors
540  const RGBColor red(255, 0, 0, 255);
541  const RGBColor green(0, 255, 0, 255);
542  // declare geometry
543  PositionVector geom;
544  const double w = width / 2. - 0.1 * exaggeration;
545  const double h = length;
546  // set geometry
547  geom.push_back(Position(-w, +0, 0.));
548  geom.push_back(Position(+w, +0, 0.));
549  geom.push_back(Position(+w, +h, 0.));
550  geom.push_back(Position(-w, +h, 0.));
551  geom.push_back(Position(-w, +0, 0.));
552  /*
553  geom.push_back(Position(pos.x(), pos.y(), pos.z()));
554  geom.push_back(Position(pos.x() + (*l).second.myWidth, pos.y(), pos.z()));
555  geom.push_back(Position(pos.x() + (*l).second.myWidth, pos.y() - (*l).second.myLength, pos.z()));
556  geom.push_back(Position(pos.x(), pos.y() - (*l).second.myLength, pos.z()));
557  geom.push_back(Position(pos.x(), pos.y(), pos.z()));
558  */
559  // push matrix
561  // translate
562  glTranslated(pos.x(), pos.y(), pos.z());
563  // rotate
564  glRotated(rotation, 0, 0, 1);
565  // set color
566  GLHelper::setColor(vehicle ? green : red);
567  // draw box lines
568  GLHelper::drawBoxLines(geom, 0.1 * exaggeration);
569  // pop matrix
571 }
572 
573 
574 bool
576  if (myFont == nullptr) {
578  if (myFont != nullptr) {
580  fonsSetFont(myFont, fontNormal);
581  fonsSetSize(myFont, (float)myFontSize);
582  }
583  }
584  return myFont != nullptr;
585 }
586 
587 
588 const std::vector<RGBColor>&
590  // check if more colors has to be added
591  while ((int)myDottedcontourColors.size() < size) {
594  } else {
596  }
597  }
598  return myDottedcontourColors;
599 }
600 
601 
602 double
603 GLHelper::getTextWidth(const std::string& text, double size) {
604  return size / myFontSize * fonsTextBounds(myFont, 0, 0, text.c_str(), nullptr, nullptr);
605 }
606 
607 
608 void
609 GLHelper::drawText(const std::string& text, const Position& pos, const double layer, const double size,
610  const RGBColor& col, const double angle, const int align, double width) {
611  if (width <= 0) {
612  width = size;
613  }
614  if (!initFont()) {
615  return;
616  }
618  glAlphaFunc(GL_GREATER, 0.5);
619  glEnable(GL_ALPHA_TEST);
620 #ifdef HAVE_GL2PS
621  if (myGL2PSActive) {
622  glRasterPos3d(pos.x(), pos.y(), layer);
623  GLfloat color[] = {col.red() / 255.f, col.green() / 255.f, col.blue() / 255.f, col.alpha() / 255.f};
624  gl2psTextOptColor(text.c_str(), "Roboto", 10, align == 0 ? GL2PS_TEXT_C : align, (GLfloat) - angle, color);
626  return;
627  }
628 #endif
629  glTranslated(pos.x(), pos.y(), layer);
630  glScaled(width / myFontSize, size / myFontSize, 1.);
631  glRotated(-angle, 0, 0, 1);
632  fonsSetAlign(myFont, align == 0 ? FONS_ALIGN_CENTER | FONS_ALIGN_MIDDLE : align);
633  fonsSetColor(myFont, glfonsRGBA(col.red(), col.green(), col.blue(), col.alpha()));
634  fonsDrawText(myFont, 0., 0., text.c_str(), nullptr);
636 }
637 
638 
639 void
641  const GUIVisualizationTextSettings& settings,
642  const std::string& text, const Position& pos,
643  const double scale,
644  const double angle,
645  const double layer,
646  const int align) {
647  drawTextBox(text, pos, layer,
648  settings.scaledSize(scale),
649  settings.color,
650  settings.bgColor,
652  angle, 0, 0.2, align);
653 }
654 
655 
656 void
657 GLHelper::drawTextBox(const std::string& text, const Position& pos,
658  const double layer, const double size,
659  const RGBColor& txtColor, const RGBColor& bgColor, const RGBColor& borderColor,
660  const double angle,
661  const double relBorder,
662  const double relMargin,
663  const int align) {
664  if (!initFont()) {
665  return;
666  };
667  if (bgColor.alpha() != 0) {
668  const double boxAngle = 90;
669  const double stringWidth = size / myFontSize * fonsTextBounds(myFont, 0, 0, text.c_str(), nullptr, nullptr);
670  const double borderWidth = size * relBorder;
671  const double boxHeight = size * (0.32 + 0.6 * relMargin);
672  const double boxWidth = stringWidth + size * relMargin;
674  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
675  glTranslated(pos.x(), pos.y(), layer);
676  glRotated(-angle, 0, 0, 1);
677  Position left(-boxWidth * 0.5, 0);
678  setColor(borderColor);
679  drawBoxLine(left, boxAngle, boxWidth, boxHeight);
680  left.add(borderWidth * 1.5, 0);
681  setColor(bgColor);
682  glTranslated(0, 0, 0.01);
683  drawBoxLine(left, boxAngle, boxWidth - 3 * borderWidth, boxHeight - 2 * borderWidth);
685  }
686  drawText(text, pos, layer + 0.02, size, txtColor, angle, align);
687 }
688 
689 
690 void
691 GLHelper::drawTextAtEnd(const std::string& text, const PositionVector& shape, double x,
692  const GUIVisualizationTextSettings& settings, const double scale) {
694  const Position& end = shape.back();
695  const Position& f = shape[-2];
696  const double rot = RAD2DEG(atan2((end.x() - f.x()), (f.y() - end.y())));
697  glTranslated(end.x(), end.y(), 0);
698  glRotated(rot, 0, 0, 1);
699  drawTextBox(text, Position(x, 0.26), 0,
700  settings.scaledSize(scale, 0.01),
701  settings.color,
702  settings.bgColor,
704  180, 0, 0.2);
706 }
707 
708 void
710  const std::vector<double>& rots,
711  const std::vector<double>& lengths,
712  double length, double spacing,
713  double halfWidth, bool drawForSelection) {
715  // draw on top of of the white area between the rails
716  glTranslated(0, 0, 0.1);
717  int e = (int) geom.size() - 1;
718  for (int i = 0; i < e; ++i) {
720  glTranslated(geom[i].x(), geom[i].y(), 0.0);
721  glRotated(rots[i], 0, 0, 1);
722  // draw crossing depending if isn't being drawn for selecting
723  if (!drawForSelection) {
724  for (double t = 0; t < lengths[i]; t += spacing) {
725  glBegin(GL_QUADS);
726  glVertex2d(-halfWidth, -t);
727  glVertex2d(-halfWidth, -t - length);
728  glVertex2d(halfWidth, -t - length);
729  glVertex2d(halfWidth, -t);
730  glEnd();
731  }
732  } else {
733  // only draw a single rectangle if it's being drawn only for selecting
734  glBegin(GL_QUADS);
735  glVertex2d(-halfWidth, 0);
736  glVertex2d(-halfWidth, -lengths.back());
737  glVertex2d(halfWidth, -lengths.back());
738  glVertex2d(halfWidth, 0);
739  glEnd();
740  }
741  // pop three draw matrix
743  }
745 }
746 
747 void
749  const std::vector<double>& rots,
750  const std::vector<double>& lengths,
751  double maxLength, double spacing,
752  double halfWidth, bool cl, bool cr, bool lefthand, double scale) {
753 
754  double mw = (halfWidth + SUMO_const_laneMarkWidth * (cl ? 0.6 : 0.2)) * scale;
755  double mw2 = (halfWidth - SUMO_const_laneMarkWidth * (cr ? 0.6 : 0.2)) * scale;
756  if (cl || cr) {
757  if (lefthand) {
758  mw *= -1;
759  mw2 *= -1;
760  }
761  int e = (int) geom.size() - 1;
762  for (int i = 0; i < e; ++i) {
764  glTranslated(geom[i].x(), geom[i].y(), 2.1);
765  glRotated(rots[i], 0, 0, 1);
766  for (double t = 0; t < lengths[i]; t += spacing) {
767  const double length = MIN2((double)maxLength, lengths[i] - t);
768  glBegin(GL_QUADS);
769  glVertex2d(-mw, -t);
770  glVertex2d(-mw, -t - length);
771  glVertex2d(-mw2, -t - length);
772  glVertex2d(-mw2, -t);
773  glEnd();
774  if (!cl || !cr) {
775  // draw inverse marking between asymmetrical lane markings
776  const double length2 = MIN2((double)6, lengths[i] - t);
777  glBegin(GL_QUADS);
778  glVertex2d(-halfWidth + 0.02, -t - length2);
779  glVertex2d(-halfWidth + 0.02, -t - length);
780  glVertex2d(-halfWidth - 0.02, -t - length);
781  glVertex2d(-halfWidth - 0.02, -t - length2);
782  glEnd();
783  }
784  }
786  }
787  }
788 }
789 
790 
791 void
792 GLHelper::debugVertices(const PositionVector& shape, double size, double layer) {
793  RGBColor color = RGBColor::randomHue();
794  for (int i = 0; i < (int)shape.size(); ++i) {
795  GLHelper::drawText(toString(i), shape[i], layer, size, color, 0);
796  }
797 }
798 
799 
800 void
804  // draw on top
805  glTranslated(0, 0, 1024);
806  drawLine(Position(b.xmin(), b.ymax()), Position(b.xmax(), b.ymax()));
807  drawLine(Position(b.xmax(), b.ymax()), Position(b.xmax(), b.ymin()));
808  drawLine(Position(b.xmax(), b.ymin()), Position(b.xmin(), b.ymin()));
809  drawLine(Position(b.xmin(), b.ymin()), Position(b.xmin(), b.ymax()));
811 }
812 
813 
814 /****************************************************************************/
void CALLBACK combCallback(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **dataOut)
Definition: GLHelper.cpp:68
#define CIRCLE_RESOLUTION
Definition: GLHelper.cpp:49
#define CALLBACK
Definition: GLHelper.cpp:53
#define DEG2RAD(x)
Definition: GeomHelper.h:35
#define RAD2DEG(x)
Definition: GeomHelper.h:36
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:280
static unsigned int data_font_Roboto_Medium_ttf_len
Definition: Roboto.h:22
static unsigned char data_font_Roboto_Medium_ttf[]
Definition: Roboto.h:24
T MIN4(T a, T b, T c, T d)
Definition: StdDefs.h:101
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:30
T MIN2(T a, T b)
Definition: StdDefs.h:74
const double SUMO_const_laneMarkWidth
Definition: StdDefs.h:54
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:39
double ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:129
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:117
double ymax() const
Returns maximum y-coordinate.
Definition: Boundary.cpp:135
double xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:123
static void drawFilledPoly(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
Definition: GLHelper.cpp:170
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:792
static void drawBoundary(const Boundary &b)
Draw a boundary (used for debugging)
Definition: GLHelper.cpp:801
static void drawFilledPolyTesselated(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
Definition: GLHelper.cpp:189
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, const int align=0)
draw Text box with given parameters
Definition: GLHelper.cpp:657
static std::vector< std::pair< double, double > > myCircleCoords
Storage for precomputed sin/cos-values describing a circle.
Definition: GLHelper.h:391
static void drawLine(const Position &beg, double rot, double visLength)
Draws a thin line.
Definition: GLHelper.cpp:369
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:507
static void drawFilledCircle(double width, int steps=8)
Draws a filled circle around (0,0)
Definition: GLHelper.cpp:431
static struct FONScontext * myFont
Font context.
Definition: GLHelper.h:394
static void drawTriangleAtEnd(const Position &p1, const Position &p2, double tLength, double tWidth, const double extraOffset=0)
Draws a triangle at the end of the given line.
Definition: GLHelper.cpp:485
static void drawTextAtEnd(const std::string &text, const PositionVector &shape, double x, const GUIVisualizationTextSettings &settings, const double scale)
draw text and the end of shape
Definition: GLHelper.cpp:691
static void resetFont()
to be called when the font context is invalidated
Definition: GLHelper.cpp:524
static void pushName(unsigned int name)
push Name
Definition: GLHelper.cpp:132
static void checkCounterMatrix()
check counter matrix
Definition: GLHelper.cpp:150
static void drawOutlineCircle(double width, double iwidth, int steps=8)
Draws an unfilled circle around (0,0)
Definition: GLHelper.cpp:455
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:589
static std::vector< RGBColor > myDottedcontourColors
static vector with a list of alternated black/white colors (used for contourns)
Definition: GLHelper.h:401
static int angleLookup(double angleDeg)
normalize angle for lookup in myCircleCoords
Definition: GLHelper.cpp:102
static double getTextWidth(const std::string &text, double size)
get required width of text
Definition: GLHelper.cpp:603
static int myMatrixCounter
matrix counter
Definition: GLHelper.h:385
static void popMatrix()
pop matrix
Definition: GLHelper.cpp:123
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:277
static RGBColor getColor()
gets the gl-color
Definition: GLHelper.cpp:513
static void drawCrossTies(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double length, double spacing, double halfWidth, bool drawForSelection)
draw crossties for railroads or pedestrian crossings
Definition: GLHelper.cpp:709
static const std::vector< std::pair< double, double > > & getCircleCoords()
Storage for precomputed sin/cos-values describing a circle.
Definition: GLHelper.cpp:88
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition: GLHelper.cpp:231
static void checkCounterName()
check counter name
Definition: GLHelper.cpp:160
static void popName()
pop Name
Definition: GLHelper.cpp:141
static bool rightTurn(double angle1, double angle2)
whether the road makes a right turn (or goes straight)
Definition: GLHelper.cpp:264
static int myNameCounter
name counter
Definition: GLHelper.h:388
static void pushMatrix()
push matrix
Definition: GLHelper.cpp:114
static void setGL2PS(bool active=true)
set GL2PS
Definition: GLHelper.cpp:531
static void drawInverseMarkings(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double maxLength, double spacing, double halfWidth, bool cl, bool cr, bool lefthand, double scale)
@bried draw the space between markings (in road color)
Definition: GLHelper.cpp:748
static bool myGL2PSActive
whether we are currently rendering for gl2ps
Definition: GLHelper.h:398
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, const int align=0, double width=-1)
Definition: GLHelper.cpp:609
static void drawSpaceOccupancies(const double exaggeration, const Position &pos, const double rotation, const double width, const double length, const bool vehicle)
darw
Definition: GLHelper.cpp:537
static bool initFont()
init myFont
Definition: GLHelper.cpp:575
static double myFontSize
Definition: GLHelper.h:395
static void drawTextSettings(const GUIVisualizationTextSettings &settings, const std::string &text, const Position &pos, const double scale, const double angle=0, const double layer=2048, const int align=0)
Definition: GLHelper.cpp:640
static double naviDegree(const double angle)
Definition: GeomHelper.cpp:192
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
Definition: Position.h:242
double x() const
Returns the x-position.
Definition: Position.h:55
void add(const Position &pos)
Adds the given position to this one.
Definition: Position.h:125
double z() const
Returns the z-position.
Definition: Position.h:65
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:262
double y() const
Returns the y-position.
Definition: Position.h:60
A list of positions.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
static const RGBColor WHITE
Definition: RGBColor.h:192
unsigned char red() const
Returns the red-amount of the color.
Definition: RGBColor.cpp:74
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition: RGBColor.cpp:92
static const RGBColor INVISIBLE
Definition: RGBColor.h:195
unsigned char green() const
Returns the green-amount of the color.
Definition: RGBColor.cpp:80
unsigned char blue() const
Returns the blue-amount of the color.
Definition: RGBColor.cpp:86
static const RGBColor BLACK
Definition: RGBColor.h:193
static const RGBColor MAGENTA
Definition: RGBColor.h:190
static RGBColor randomHue(double s=1, double v=1)
Return color with random hue.
Definition: RGBColor.cpp:397
@ FONS_ZERO_BOTTOMLEFT
Definition: fontstash.h:37
FONS_DEF void fonsSetSize(FONScontext *s, float size)
FONS_DEF float fonsDrawText(FONScontext *s, float x, float y, const char *string, const char *end)
FONS_DEF float fonsTextBounds(FONScontext *s, float x, float y, const char *string, const char *end, float *bounds)
@ FONS_ALIGN_MIDDLE
Definition: fontstash.h:47
@ FONS_ALIGN_CENTER
Definition: fontstash.h:43
FONS_DEF void fonsSetColor(FONScontext *s, unsigned int color)
FONS_DEF void fonsSetAlign(FONScontext *s, int align)
FONS_DEF int fonsAddFontMem(FONScontext *s, const char *name, unsigned char *data, int ndata, int freeData)
FONS_DEF void fonsSetFont(FONScontext *s, int font)
struct FONScontext FONScontext
Definition: fontstash.h:95
unsigned int glfonsRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
void glfonsDelete(FONScontext *ctx)
FONScontext * glfonsCreate(int width, int height, int flags)
RGBColor bgColor
background text color
double scaledSize(double scale, double constFactor=0.1) const
get scale size