SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GUIVehicle.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // A MSVehicle extended by some values for usage within the gui
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
12 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #include <cmath>
34 #include <vector>
35 #include <string>
45 #include <utils/gui/div/GLHelper.h>
47 #include <microsim/MSVehicle.h>
55 #include <gui/GUIGlobals.h>
56 #include "GUIVehicle.h"
57 #include "GUIPerson.h"
58 #include "GUINet.h"
59 #include "GUIEdge.h"
60 #include "GUILaneWrapper.h"
61 
62 #ifdef CHECK_MEMORY_LEAKS
63 #include <foreign/nvwa/debug_new.h>
64 #endif // CHECK_MEMORY_LEAKS
65 
66 
67 // ===========================================================================
68 // FOX callback mapping
69 // ===========================================================================
70 FXDEFMAP(GUIVehicle::GUIVehiclePopupMenu) GUIVehiclePopupMenuMap[] = {
81 };
82 
83 // Object implementation
84 FXIMPLEMENT(GUIVehicle::GUIVehiclePopupMenu, GUIGLObjectPopupMenu, GUIVehiclePopupMenuMap, ARRAYNUMBER(GUIVehiclePopupMenuMap))
85 
86 
87 
88 // ===========================================================================
89 // data definitions
90 // ===========================================================================
91 /* -------------------------------------------------------------------------
92  * drawed shapes
93  * ----------------------------------------------------------------------- */
94 double vehiclePoly_PassengerCarBody[] = { .5, 0, 0, 0, 0, .3, 0.08, .44, 0.25, .5, 0.95, .5, 1., .4, 1., -.4, 0.95, -.5, 0.25, -.5, 0.08, -.44, 0, -.3, 0, 0, -10000 };
95 double vehiclePoly_PassengerCarBodyFront[] = { 0.1, 0, 0.025, 0, 0.025, 0.25, 0.27, 0.4, 0.27, -.4, 0.025, -0.25, 0.025, 0, -10000 };
96 double vehiclePoly_PassengerFrontGlass[] = { 0.35, 0, 0.3, 0, 0.3, 0.4, 0.43, 0.3, 0.43, -0.3, 0.3, -0.4, 0.3, 0, -10000 };
97 double vehiclePoly_PassengerSedanRightGlass[] = { 0.36, -.43, 0.34, -.47, 0.77, -.47, 0.67, -.37, 0.45, -.37, 0.34, -.47, -10000 };
98 double vehiclePoly_PassengerSedanLeftGlass[] = { 0.36, .43, 0.34, .47, 0.77, .47, 0.67, .37, 0.45, .37, 0.34, .47, -10000 };
99 double vehiclePoly_PassengerSedanBackGlass[] = { 0.80, 0, 0.70, 0, 0.70, 0.3, 0.83, 0.4, 0.83, -.4, 0.70, -.3, 0.70, 0, -10000 };
100 double vehiclePoly_PassengerHatchbackRightGlass[] = { 0.36, -.43, 0.34, -.47, 0.94, -.47, 0.80, -.37, 0.45, -.37, 0.34, -.47, -10000 };
101 double vehiclePoly_PassengerHatchbackLeftGlass[] = { 0.36, .43, 0.34, .47, 0.94, .47, 0.80, .37, 0.45, .37, 0.34, .47, -10000 };
102 double vehiclePoly_PassengerHatchbackBackGlass[] = { 0.92, 0, 0.80, 0, 0.80, 0.3, 0.95, 0.4, 0.95, -.4, 0.80, -.3, 0.80, 0, -10000 };
103 double vehiclePoly_PassengerWagonRightGlass[] = { 0.36, -.43, 0.34, -.47, 0.94, -.47, 0.87, -.37, 0.45, -.37, 0.34, -.47, -10000 };
104 double vehiclePoly_PassengerWagonLeftGlass[] = { 0.36, .43, 0.34, .47, 0.94, .47, 0.87, .37, 0.45, .37, 0.34, .47, -10000 };
105 double vehiclePoly_PassengerWagonBackGlass[] = { 0.92, 0, 0.90, 0, 0.90, 0.3, 0.95, 0.4, 0.95, -.4, 0.90, -.3, 0.90, 0, -10000 };
106 
107 double vehiclePoly_PassengerVanBody[] = { .5, 0, 0, 0, 0, .4, 0.1, .5, 0.97, .5, 1., .47, 1., -.47, 0.97, -.5, 0.1, -.5, 0, -.4, 0, 0, -10000 };
108 double vehiclePoly_PassengerVanBodyFront[] = { 0.1, 0, 0.025, 0, 0.025, 0.25, 0.13, 0.4, 0.13, -.4, 0.025, -0.25, 0.025, 0, -10000 };
109 double vehiclePoly_PassengerVanFrontGlass[] = { 0.21, 0, 0.16, 0, 0.16, 0.4, 0.29, 0.3, 0.29, -0.3, 0.16, -0.4, 0.16, 0, -10000 };
110 double vehiclePoly_PassengerVanRightGlass[] = { 0.36, -.43, 0.20, -.47, 0.98, -.47, 0.91, -.37, 0.31, -.37, 0.20, -.47, -10000 };
111 double vehiclePoly_PassengerVanLeftGlass[] = { 0.36, .43, 0.20, .47, 0.98, .47, 0.91, .37, 0.31, .37, 0.20, .47, -10000 };
112 double vehiclePoly_PassengerVanBackGlass[] = { 0.95, 0, 0.94, 0, 0.94, 0.3, 0.98, 0.4, 0.98, -.4, 0.94, -.3, 0.94, 0, -10000 };
113 
114 double vehiclePoly_DeliveryMediumRightGlass[] = { 0.21, -.43, 0.20, -.47, 0.38, -.47, 0.38, -.37, 0.31, -.37, 0.20, -.47, -10000 };
115 double vehiclePoly_DeliveryMediumLeftGlass[] = { 0.21, .43, 0.20, .47, 0.38, .47, 0.38, .37, 0.31, .37, 0.20, .47, -10000 };
116 
117 double vehiclePoly_TransportBody[] = { .5, 0, 0, 0, 0, .45, 0.05, .5, 2.25, .5, 2.25, -.5, 0.05, -.5, 0, -.45, 0, 0, -10000 };
118 double vehiclePoly_TransportFrontGlass[] = { 0.1, 0, 0.05, 0, 0.05, 0.45, 0.25, 0.4, 0.25, -.4, 0.05, -0.45, 0.05, 0, -10000 };
119 double vehiclePoly_TransportRightGlass[] = { 0.36, -.47, 0.10, -.48, 1.25, -.48, 1.25, -.4, 0.3, -.4, 0.10, -.48, -10000 };
120 double vehiclePoly_TransportLeftGlass[] = { 0.36, .47, 0.10, .48, 1.25, .48, 1.25, .4, 0.3, .4, 0.10, .48, -10000 };
121 
122 double vehiclePoly_EVehicleBody[] = { .5, 0, 0, 0, 0, .3, 0.08, .44, 0.25, .5, 0.75, .5, .92, .44, 1, .3, 1, -.3, .92, -.44, .75, -.5, .25, -.5, 0.08, -.44, 0, -.3, 0, 0, -1000 };
123 double vehiclePoly_EVehicleFrontGlass[] = { .5, 0, 0.05, .05, 0.05, .25, 0.13, .39, 0.3, .45, 0.70, .45, .87, .39, .95, .25, .95, -.25, .87, -.39, .70, -.45, .3, -.45, 0.13, -.39, 0.05, -.25, 0.05, 0.05, -1000 };
124 //double vehiclePoly_EVehicleFrontGlass[] = { 0.35,0, 0.1,0, 0.1,0.4, 0.43,0.3, 0.43,-0.3, 0.1,-0.4, 0.1,0, -10000 };
125 double vehiclePoly_EVehicleBackGlass[] = { 0.65, 0, 0.9, 0, 0.9, 0.4, 0.57, 0.3, 0.57, -0.3, 0.9, -0.4, 0.9, 0, -10000 };
126 
127 
128 // ===========================================================================
129 // method definitions
130 // ===========================================================================
131 /* -------------------------------------------------------------------------
132  * GUIVehicle::GUIVehiclePopupMenu - methods
133  * ----------------------------------------------------------------------- */
135  GUIMainWindow& app, GUISUMOAbstractView& parent,
136  GUIGlObject& o, std::map<GUISUMOAbstractView*, int>& additionalVisualizations)
137  : GUIGLObjectPopupMenu(app, parent, o), myVehiclesAdditionalVisualizations(additionalVisualizations) {
138 }
139 
140 
142 
143 
144 long
146  assert(myObject->getType() == GLO_VEHICLE);
147  if (!static_cast<GUIVehicle*>(myObject)->hasActiveAddVisualisation(myParent, VO_SHOW_ALL_ROUTES)) {
148  static_cast<GUIVehicle*>(myObject)->addActiveAddVisualisation(myParent, VO_SHOW_ALL_ROUTES);
149  }
150  return 1;
151 }
152 
153 long
155  assert(myObject->getType() == GLO_VEHICLE);
156  static_cast<GUIVehicle*>(myObject)->removeActiveAddVisualisation(myParent, VO_SHOW_ALL_ROUTES);
157  return 1;
158 }
159 
160 
161 long
163  assert(myObject->getType() == GLO_VEHICLE);
164  if (!static_cast<GUIVehicle*>(myObject)->hasActiveAddVisualisation(myParent, VO_SHOW_ROUTE)) {
165  static_cast<GUIVehicle*>(myObject)->addActiveAddVisualisation(myParent, VO_SHOW_ROUTE);
166  }
167  return 1;
168 }
169 
170 long
172  assert(myObject->getType() == GLO_VEHICLE);
173  static_cast<GUIVehicle*>(myObject)->removeActiveAddVisualisation(myParent, VO_SHOW_ROUTE);
174  return 1;
175 }
176 
177 
178 long
180  assert(myObject->getType() == GLO_VEHICLE);
181  if (!static_cast<GUIVehicle*>(myObject)->hasActiveAddVisualisation(myParent, VO_SHOW_BEST_LANES)) {
182  static_cast<GUIVehicle*>(myObject)->addActiveAddVisualisation(myParent, VO_SHOW_BEST_LANES);
183  }
184  return 1;
185 }
186 
187 long
189  assert(myObject->getType() == GLO_VEHICLE);
190  static_cast<GUIVehicle*>(myObject)->removeActiveAddVisualisation(myParent, VO_SHOW_BEST_LANES);
191  return 1;
192 }
193 
194 
195 long
197  assert(myObject->getType() == GLO_VEHICLE);
198  if (!static_cast<GUIVehicle*>(myObject)->hasActiveAddVisualisation(myParent, VO_TRACKED)) {
199  myParent->startTrack(static_cast<GUIVehicle*>(myObject)->getGlID());
200  static_cast<GUIVehicle*>(myObject)->addActiveAddVisualisation(myParent, VO_TRACKED);
201  }
202  return 1;
203 }
204 
205 long
207  assert(myObject->getType() == GLO_VEHICLE);
208  static_cast<GUIVehicle*>(myObject)->removeActiveAddVisualisation(myParent, VO_TRACKED);
209  myParent->stopTrack();
210  return 1;
211 }
212 
213 
214 long
216  assert(myObject->getType() == GLO_VEHICLE);
217  if (!static_cast<GUIVehicle*>(myObject)->hasActiveAddVisualisation(myParent, VO_SHOW_LFLINKITEMS)) {
218  static_cast<GUIVehicle*>(myObject)->addActiveAddVisualisation(myParent, VO_SHOW_LFLINKITEMS);
219  }
220  return 1;
221 }
222 
223 long
225  assert(myObject->getType() == GLO_VEHICLE);
226  static_cast<GUIVehicle*>(myObject)->removeActiveAddVisualisation(myParent, VO_SHOW_LFLINKITEMS);
227  return 1;
228 }
229 
230 
231 /* -------------------------------------------------------------------------
232  * GUIVehicle - methods
233  * ----------------------------------------------------------------------- */
235  const MSVehicleType* type,
236  SUMOReal speedFactor, int vehicleIndex) :
237  MSVehicle(pars, route, type, speedFactor, vehicleIndex),
238  GUIGlObject(GLO_VEHICLE, pars->id) {
239  // as it is possible to show all vehicle routes, we have to store them... (bug [ 2519761 ])
241  myMoveReminders.push_back(std::make_pair(myRoutes, 0.));
242  mySeatPositions.push_back(Position(0, 0)); // ensure length 1
243 }
244 
245 
247  myLock.lock();
248  for (std::map<GUISUMOAbstractView*, int>::iterator i = myAdditionalVisualizations.begin(); i != myAdditionalVisualizations.end(); ++i) {
249  while (i->first->removeAdditionalGLVisualisation(this));
250  }
251  myLock.unlock();
253  delete myRoutes;
254 }
255 
256 
259  GUISUMOAbstractView& parent) {
261  buildPopupHeader(ret, app);
265  //
267  new FXMenuCommand(ret, "Hide Current Route", 0, ret, MID_HIDE_CURRENTROUTE);
268  } else {
269  new FXMenuCommand(ret, "Show Current Route", 0, ret, MID_SHOW_CURRENTROUTE);
270  }
272  new FXMenuCommand(ret, "Hide All Routes", 0, ret, MID_HIDE_ALLROUTES);
273  } else {
274  new FXMenuCommand(ret, "Show All Routes", 0, ret, MID_SHOW_ALLROUTES);
275  }
277  new FXMenuCommand(ret, "Hide Best Lanes", 0, ret, MID_HIDE_BEST_LANES);
278  } else {
279  new FXMenuCommand(ret, "Show Best Lanes", 0, ret, MID_SHOW_BEST_LANES);
280  }
282  new FXMenuCommand(ret, "Hide Link Items", 0, ret, MID_HIDE_LFLINKITEMS);
283  } else {
284  new FXMenuCommand(ret, "Show Link Items", 0, ret, MID_SHOW_LFLINKITEMS);
285  }
286  new FXMenuSeparator(ret);
287  int trackedID = parent.getTrackedID();
288  if (trackedID < 0 || (size_t)trackedID != getGlID()) {
289  new FXMenuCommand(ret, "Start Tracking", 0, ret, MID_START_TRACK);
290  } else {
291  new FXMenuCommand(ret, "Stop Tracking", 0, ret, MID_STOP_TRACK);
292  }
293  new FXMenuSeparator(ret);
294  //
296  buildPositionCopyEntry(ret, false);
297  return ret;
298 }
299 
300 
305  new GUIParameterTableWindow(app, *this, 20);
306  // add items
307  ret->mkItem("type [NAME]", false, myType->getID());
308  if (getParameter().repetitionNumber > 0) {
309  ret->mkItem("left same route [#]", false, (unsigned int) getParameter().repetitionNumber);
310  }
311  if (getParameter().repetitionOffset > 0) {
312  ret->mkItem("insertion period [s]", false, time2string(getParameter().repetitionOffset));
313  }
314  if (getChosenSpeedFactor() != 1) {
315  ret->mkItem("speed factor", false, getChosenSpeedFactor());
316  }
317  ret->mkItem("insertion period [s]", false, time2string(getParameter().repetitionOffset));
318  ret->mkItem("waiting time [s]", true,
320  ret->mkItem("last lane change [s]", true,
322  ret->mkItem("desired depart [s]", false, time2string(getParameter().depart));
323  ret->mkItem("position [m]", true,
325  ret->mkItem("speed [m/s]", true,
327  ret->mkItem("angle", true,
329  ret->mkItem("CO2 (HBEFA) [mg/s]", true,
331  ret->mkItem("CO (HBEFA) [mg/s]", true,
333  ret->mkItem("HC (HBEFA) [mg/s]", true,
335  ret->mkItem("NOx (HBEFA) [mg/s]", true,
337  ret->mkItem("PMx (HBEFA) [mg/s]", true,
339  ret->mkItem("fuel (HBEFA) [ml/s]", true,
341  ret->mkItem("noise (Harmonoise) [dB]", true,
343  // close building
344  ret->closeBuilding();
345  return ret;
346 }
347 
348 
349 Boundary
351  Boundary b;
352  b.add(getPosition());
353  b.grow(20);
354  return b;
355 }
356 
357 
358 void
360  glPushMatrix();
361  glScaled(getVehicleType().getWidth(), getVehicleType().getLength(), 1.);
362  glBegin(GL_TRIANGLE_STRIP);
363  glVertex2d(0., 0.);
364  glVertex2d(-.5, .15);
365  glVertex2d(.5, .15);
366  glVertex2d(-.5, 1.);
367  glVertex2d(.5, 1.);
368  glEnd();
369  glPopMatrix();
370 }
371 
372 
373 void
375  const SUMOReal length = getVehicleType().getLength();
376  if (length >= 8.) {
378  return;
379  }
380  glPushMatrix();
381  glScaled(getVehicleType().getWidth(), length, 1.);
382  glBegin(GL_TRIANGLES);
383  glVertex2d(0., 0.);
384  glVertex2d(-.5, 1.);
385  glVertex2d(.5, 1.);
386  glEnd();
387  glPopMatrix();
388 }
389 
390 
391 void
392 GUIVehicle::drawPoly(double* poses, SUMOReal offset) {
393  glPushMatrix();
394  glTranslated(0, 0, offset * .1);
395  glPolygonOffset(0, offset * -1);
396  glBegin(GL_TRIANGLE_FAN);
397  int i = 0;
398  while (poses[i] > -999) {
399  glVertex2d(poses[i], poses[i + 1]);
400  i = i + 2;
401  }
402  glEnd();
403  glPopMatrix();
404 }
405 
406 
407 void
409  RGBColor current = GLHelper::getColor();
410  RGBColor lighter = current.changedBrightness(.2);
411  RGBColor darker = current.changedBrightness(-.2);
412 
413  const SUMOReal length = getVehicleType().getLength();
414  const SUMOReal width = getVehicleType().getWidth();
415  glPushMatrix();
416  glRotated(90, 0, 0, 1);
417  glScaled(length, width, 1.);
419 
420  // draw main body
421  switch (shape) {
422  case SVS_UNKNOWN:
424  GLHelper::setColor(lighter);
425  drawPoly(vehiclePoly_PassengerCarBodyFront, 4.5);
426  glColor3d(0, 0, 0);
427  drawPoly(vehiclePoly_PassengerFrontGlass, 4.5);
428  break;
429  case SVS_PEDESTRIAN:
430  //glScaled(1./(lenght)), 1, 1.);
431  glTranslated(0, 0, .045);
433  glTranslated(0, 0, -.045);
434  glScaled(.7, 2, 1);
435  glTranslated(0, 0, .04);
436  GLHelper::setColor(lighter);
438  glTranslated(0, 0, -.04);
439  break;
440  case SVS_BICYCLE:
441  case SVS_MOTORCYCLE: {
442  glPushMatrix();
443  glTranslated(.5, 0, 0);
444  glScaled(.25 / (length), 1, 1.);
445  glTranslated(0, 0, .045);
447  glScaled(.7, 2, 1);
448  glTranslated(0, 0, -.045);
449  glTranslated(0, 0, .04);
450  GLHelper::setColor(lighter);
452  glTranslated(0, 0, -.04);
453  glPopMatrix();
454  }
455  break;
456  case SVS_PASSENGER:
457  case SVS_PASSENGER_SEDAN:
459  case SVS_PASSENGER_WAGON:
461  GLHelper::setColor(lighter);
462  drawPoly(vehiclePoly_PassengerCarBodyFront, 4.5);
463  glColor3d(0, 0, 0);
464  drawPoly(vehiclePoly_PassengerFrontGlass, 4.5);
465  break;
466  case SVS_PASSENGER_VAN:
467  drawPoly(vehiclePoly_PassengerVanBody, 4);
468  GLHelper::setColor(lighter);
469  drawPoly(vehiclePoly_PassengerVanBodyFront, 4.5);
470  glColor3d(0, 0, 0);
471  drawPoly(vehiclePoly_PassengerVanFrontGlass, 4.5);
472  drawPoly(vehiclePoly_PassengerVanRightGlass, 4.5);
473  drawPoly(vehiclePoly_PassengerVanLeftGlass, 4.5);
474  drawPoly(vehiclePoly_PassengerVanBackGlass, 4.5);
475  break;
476  case SVS_DELIVERY:
477  drawPoly(vehiclePoly_PassengerVanBody, 4);
478  GLHelper::setColor(lighter);
479  drawPoly(vehiclePoly_PassengerVanBodyFront, 4.5);
480  glColor3d(0, 0, 0);
481  drawPoly(vehiclePoly_PassengerVanFrontGlass, 4.5);
482  drawPoly(vehiclePoly_DeliveryMediumRightGlass, 4.5);
483  drawPoly(vehiclePoly_DeliveryMediumLeftGlass, 4.5);
484  break;
485  case SVS_TRANSPORT:
488  glScaled(1. / (length), 1, 1.);
489  drawPoly(vehiclePoly_TransportBody, 4);
490  glColor3d(0, 0, 0);
491  drawPoly(vehiclePoly_TransportFrontGlass, 4.5);
492  drawPoly(vehiclePoly_TransportRightGlass, 4.5);
493  drawPoly(vehiclePoly_TransportLeftGlass, 4.5);
494  break;
495  case SVS_BUS:
496  case SVS_BUS_TROLLEY:
498  case SVS_BUS_CITY: {
499  SUMOReal ml = length;
500  glScaled(1. / (length), 1, 1.);
501  glTranslated(0, 0, .04);
502  glBegin(GL_TRIANGLE_FAN);
503  glVertex2d(ml / 2., 0);
504  glVertex2d(0, 0);
505  glVertex2d(0, -.45);
506  glVertex2d(0 + .05, -.5);
507  glVertex2d(ml - .05, -.5);
508  glVertex2d(ml, -.45);
509  glVertex2d(ml, .45);
510  glVertex2d(ml - .05, .5);
511  glVertex2d(0 + .05, .5);
512  glVertex2d(0, .45);
513  glVertex2d(0, 0);
514  glEnd();
515  glTranslated(0, 0, -.04);
516 
517  glTranslated(0, 0, .045);
518  glColor3d(0, 0, 0);
519  glBegin(GL_QUADS);
520  glVertex2d(0 + .05, .48);
521  glVertex2d(0 + .05, -.48);
522  glVertex2d(0 + .15, -.48);
523  glVertex2d(0 + .15, .48);
524 
525  glVertex2d(ml - .1, .45);
526  glVertex2d(ml - .1, -.45);
527  glVertex2d(ml - .05, -.45);
528  glVertex2d(ml - .05, .45);
529 
530  glVertex2d(0 + .20, .49);
531  glVertex2d(0 + .20, .45);
532  glVertex2d(ml - .20, .45);
533  glVertex2d(ml - .20, .49);
534 
535  glVertex2d(0 + .20, -.49);
536  glVertex2d(0 + .20, -.45);
537  glVertex2d(ml - .20, -.45);
538  glVertex2d(ml - .20, -.49);
539 
540  glEnd();
541  glTranslated(0, 0, -.045);
542  }
543  break;
544  case SVS_BUS_OVERLAND:
545  case SVS_RAIL:
546  drawAction_drawRailCarriages(s, 25.0, 1);
547  break;
548  case SVS_RAIL_LIGHT:
550  break;
551  case SVS_RAIL_CITY:
553  break;
554  case SVS_RAIL_SLOW:
555  drawAction_drawRailCarriages(s, 15.0, 1);
556  break;
557  case SVS_RAIL_FAST:
558  drawAction_drawRailCarriages(s, 40.0, 1);
559  break;
560  case SVS_RAIL_CARGO:
562  break;
563  case SVS_E_VEHICLE:
564  drawPoly(vehiclePoly_EVehicleBody, 4);
565  glColor3d(0, 0, 0);
566  drawPoly(vehiclePoly_EVehicleFrontGlass, 4.5);
567  glTranslated(0, 0, .048);
568  GLHelper::setColor(current);
569  glBegin(GL_QUADS);
570  glVertex2d(.3, .5);
571  glVertex2d(.35, .5);
572  glVertex2d(.35, -.5);
573  glVertex2d(.3, -.5);
574 
575  glVertex2d(.3, -.05);
576  glVertex2d(.7, -.05);
577  glVertex2d(.7, .05);
578  glVertex2d(.3, .05);
579 
580  glVertex2d(.7, .5);
581  glVertex2d(.65, .5);
582  glVertex2d(.65, -.5);
583  glVertex2d(.7, -.5);
584  glEnd();
585  glTranslated(0, 0, -.048);
586  //drawPoly(vehiclePoly_EVehicleBackGlass, 4.5);
587  break;
588  case SVS_ANT:
589  glPushMatrix();
590  // ant is stretched via vehicle length
591  GLHelper::setColor(darker);
592  // draw left side
593  GLHelper::drawBoxLine(Position(-0.2, -.10), 350, 0.5, .02);
594  GLHelper::drawBoxLine(Position(-0.3, -.50), 240, 0.4, .03);
595  GLHelper::drawBoxLine(Position(0.3, -.10), 340, 0.8, .03);
596  GLHelper::drawBoxLine(Position(0.05, -.80), 290, 0.6, .04);
597  GLHelper::drawBoxLine(Position(0.4, -.10), 20, 0.8, .03);
598  GLHelper::drawBoxLine(Position(0.65, -.80), 75, 0.6, .04);
599  GLHelper::drawBoxLine(Position(0.5, -.10), 55, 0.8, .04);
600  GLHelper::drawBoxLine(Position(1.1, -.55), 90, 0.6, .04);
601  // draw right side
602  GLHelper::drawBoxLine(Position(-0.2, .10), 190, 0.5, .02);
603  GLHelper::drawBoxLine(Position(-0.3, .50), 300, 0.4, .03);
604  GLHelper::drawBoxLine(Position(0.3, .10), 200, 0.8, .03);
605  GLHelper::drawBoxLine(Position(0.05, .80), 250, 0.6, .04);
606  GLHelper::drawBoxLine(Position(0.4, .10), 160, 0.8, .03);
607  GLHelper::drawBoxLine(Position(0.65, .80), 105, 0.6, .04);
608  GLHelper::drawBoxLine(Position(0.5, .10), 125, 0.8, .04);
609  GLHelper::drawBoxLine(Position(1.1, .55), 90, 0.6, .04);
610  // draw body
611  GLHelper::setColor(current);
612  glTranslated(0, 0, 0.1);
614  glTranslated(.4, 0, 0);
616  glTranslated(.4, 0, 0);
618  glPopMatrix();
619  break;
620  default: // same as passenger
622  glColor3d(1, 1, 1);
623  drawPoly(vehiclePoly_PassengerCarBodyFront, 4.5);
624  glColor3d(0, 0, 0);
625  drawPoly(vehiclePoly_PassengerFrontGlass, 4.5);
626  break;
627  }
628 
629  // draw decorations
630  switch (shape) {
631  case SVS_PEDESTRIAN:
632  break;
633  case SVS_BICYCLE:
634  //glScaled(length, 1, 1.);
635  glBegin(GL_TRIANGLE_FAN);
636  glVertex2d(1 / 2., 0);
637  glVertex2d(0, 0);
638  glVertex2d(0, -.03);
639  glVertex2d(0 + .05, -.05);
640  glVertex2d(1 - .05, -.05);
641  glVertex2d(1, -.03);
642  glVertex2d(1, .03);
643  glVertex2d(1 - .05, .05);
644  glVertex2d(0 + .05, .05);
645  glVertex2d(0, .03);
646  glVertex2d(0, 0);
647  glEnd();
648  break;
649  case SVS_MOTORCYCLE:
650  //glScaled(length, 1, 1.);
651  glBegin(GL_TRIANGLE_FAN);
652  glVertex2d(1 / 2., 0);
653  glVertex2d(0, 0);
654  glVertex2d(0, -.03);
655  glVertex2d(0 + .05, -.2);
656  glVertex2d(1 - .05, -.2);
657  glVertex2d(1, -.03);
658  glVertex2d(1, .03);
659  glVertex2d(1 - .05, .2);
660  glVertex2d(0 + .05, .2);
661  glVertex2d(0, .03);
662  glVertex2d(0, 0);
663  glEnd();
664  break;
665  case SVS_PASSENGER:
666  case SVS_PASSENGER_SEDAN:
667  drawPoly(vehiclePoly_PassengerSedanRightGlass, 4.5);
668  drawPoly(vehiclePoly_PassengerSedanLeftGlass, 4.5);
669  drawPoly(vehiclePoly_PassengerSedanBackGlass, 4.5);
670  break;
672  drawPoly(vehiclePoly_PassengerHatchbackRightGlass, 4.5);
673  drawPoly(vehiclePoly_PassengerHatchbackLeftGlass, 4.5);
674  drawPoly(vehiclePoly_PassengerHatchbackBackGlass, 4.5);
675  break;
676  case SVS_PASSENGER_WAGON:
677  drawPoly(vehiclePoly_PassengerWagonRightGlass, 4.5);
678  drawPoly(vehiclePoly_PassengerWagonLeftGlass, 4.5);
679  drawPoly(vehiclePoly_PassengerWagonBackGlass, 4.5);
680  break;
681  case SVS_PASSENGER_VAN:
682  case SVS_DELIVERY:
683  break;
684  case SVS_TRANSPORT:
685  GLHelper::setColor(current);
686  GLHelper::drawBoxLine(Position(2.3, 0), 90., length - 2.3, .5);
687  break;
689  GLHelper::setColor(current);
690  GLHelper::drawBoxLine(Position(2.8, 0), 90., length - 2.8, .5);
691  break;
692  case SVS_TRANSPORT_1TRAILER: {
693  GLHelper::setColor(current);
694  SUMOReal l = length - 2.3;
695  l = l / 2.;
696  GLHelper::drawBoxLine(Position(2.3, 0), 90., l, .5);
697  GLHelper::drawBoxLine(Position(2.3 + l + .5, 0), 90., l - .5, .5);
698  break;
699  }
700  case SVS_BUS_TROLLEY:
701  glPushMatrix();
702  glTranslated(0, 0, .1);
703  GLHelper::setColor(darker);
704  GLHelper::drawBoxLine(Position(3.8, 0), 90., 1, .3);
705  glTranslated(0, 0, .1);
706  glColor3d(0, 0, 0);
707  GLHelper::drawBoxLine(Position(4.3, .2), 90., 1, .06);
708  GLHelper::drawBoxLine(Position(4.3, -.2), 90., 1, .06);
709  GLHelper::drawBoxLine(Position(5.3, .2), 90., 3, .03);
710  GLHelper::drawBoxLine(Position(5.3, -.2), 90., 3, .03);
711  glPopMatrix();
712  break;
713  case SVS_BUS:
714  case SVS_BUS_CITY:
716  case SVS_BUS_OVERLAND:
717  case SVS_RAIL:
718  case SVS_RAIL_LIGHT:
719  case SVS_RAIL_CITY:
720  case SVS_RAIL_SLOW:
721  case SVS_RAIL_FAST:
722  case SVS_RAIL_CARGO:
723  case SVS_E_VEHICLE:
724  case SVS_ANT:
725  break;
726  default: // same as passenger/sedan
727  drawPoly(vehiclePoly_PassengerSedanRightGlass, 4.5);
728  drawPoly(vehiclePoly_PassengerSedanLeftGlass, 4.5);
729  drawPoly(vehiclePoly_PassengerSedanBackGlass, 4.5);
730  break;
731  }
732  /*
733  glBegin(GL_TRIANGLE_FAN);
734  glVertex2d(.5,.5); // center - strip begin
735  glVertex2d(0, .5); // center, front
736  glVertex2d(0, .8); // ... clockwise ... (vehicle right side)
737  glVertex2d(0.08, .94);
738  glVertex2d(0.25, 1.);
739  glVertex2d(0.95, 1.);
740  glVertex2d(1., .9);
741  glVertex2d(1., .1); // (vehicle left side)
742  glVertex2d(0.95, 0.);
743  glVertex2d(0.25, 0.);
744  glVertex2d(0.08, .06);
745  glVertex2d(0, .2); //
746  glVertex2d(0, .5); // center, front (close)
747  glEnd();
748 
749  glPolygonOffset(0, -4.5);
750  glColor3d(1, 1, 1); // front
751  glBegin(GL_TRIANGLE_FAN);
752  glVertex2d(0.1,0.5);
753  glVertex2d(0.025,0.5);
754  glVertex2d(0.025,0.75);
755  glVertex2d(0.27,0.9);
756  glVertex2d(0.27,0.1);
757  glVertex2d(0.025,0.25);
758  glVertex2d(0.025,0.5);
759  glEnd();
760 
761  glColor3d(0, 0, 0); // front glass
762  glBegin(GL_TRIANGLE_FAN);
763  glVertex2d(0.35,0.5);
764  glVertex2d(0.3,0.5);
765  glVertex2d(0.3,0.9);
766  glVertex2d(0.43,0.8);
767  glVertex2d(0.43,0.2);
768  glVertex2d(0.3,0.1);
769  glVertex2d(0.3,0.5);
770  glEnd();
771 
772  glBegin(GL_TRIANGLE_FAN); // back glass
773  glVertex2d(0.92,0.5);
774  glVertex2d(0.90,0.5);
775  glVertex2d(0.90,0.8);
776  glVertex2d(0.95,0.9);
777  glVertex2d(0.95,0.1);
778  glVertex2d(0.90,0.2);
779  glVertex2d(0.90,0.5);
780  glEnd();
781 
782  glBegin(GL_TRIANGLE_FAN); // right glass
783  glVertex2d(0.36,0.07);
784  glVertex2d(0.34,0.03);
785  glVertex2d(0.94,0.03);
786  glVertex2d(0.87,0.13);
787  glVertex2d(0.45,0.13);
788  glVertex2d(0.34,0.03);
789  glEnd();
790 
791  glBegin(GL_TRIANGLE_FAN); // left glass
792  glVertex2d(0.36,1.-0.07);
793  glVertex2d(0.34,1.-0.03);
794  glVertex2d(0.94,1.-0.03);
795  glVertex2d(0.87,1.-0.13);
796  glVertex2d(0.45,1.-0.13);
797  glVertex2d(0.34,1.-0.03);
798  glEnd();
799  */
800 
801  glPopMatrix();
802 }
803 
804 
805 bool
807  const std::string& file = getVehicleType().getImgFile();
808  if (file != "") {
809  int textureID = GUITexturesHelper::getTextureID(file);
810  if (textureID > 0) {
811  if (length < 0) {
813  }
814  const SUMOReal halfWidth = getVehicleType().getWidth() / 2.0 * s.vehicleExaggeration;
815  GUITexturesHelper::drawTexturedBox(textureID, -halfWidth, 0, halfWidth, length);
816  return true;
817  }
818  }
819  return false;
820 }
821 
822 
823 #define BLINKER_POS_FRONT .5
824 #define BLINKER_POS_BACK .5
825 
826 inline void
827 drawAction_drawBlinker(const GUIVehicle& veh, double dir) {
828  glColor3d(1.f, .8f, 0);
829  glPushMatrix();
830  glTranslated(dir, BLINKER_POS_FRONT, -0.1);
832  glPopMatrix();
833  glPushMatrix();
834  glTranslated(dir, veh.getVehicleType().getLength() - BLINKER_POS_BACK, -0.1);
836  glPopMatrix();
837 }
838 
839 
840 inline void
843  return;
844  }
845  const double offset = MAX2(.5 * veh.getVehicleType().getWidth(), .4);
847  drawAction_drawBlinker(veh, -offset);
848  }
850  drawAction_drawBlinker(veh, offset);;
851  }
853  drawAction_drawBlinker(veh, -offset);
854  drawAction_drawBlinker(veh, offset);
855  }
856 }
857 
858 
859 inline void
862  return;
863  }
864  glColor3f(1.f, .2f, 0);
865  glPushMatrix();
866  glTranslated(-veh.getVehicleType().getWidth() * 0.5, veh.getVehicleType().getLength(), -0.1);
868  glPopMatrix();
869  glPushMatrix();
870  glTranslated(veh.getVehicleType().getWidth() * 0.5, veh.getVehicleType().getLength(), -0.1);
872  glPopMatrix();
873 }
874 
875 
876 void
878  glPushName(getGlID());
879  glPushMatrix();
882  // one seat in the center of the vehicle by default
885  myState.pos() - getVehicleType().getLength() / 2));
886  glTranslated(p1.x(), p1.y(), getType());
887  glRotated(getAngle(), 0, 0, 1);
888  // set lane color
889  setColor(s);
890  // scale
891  SUMOReal upscale = s.vehicleExaggeration;
892  glScaled(upscale, upscale, 1);
893  /*
894  MSLCM_DK2004 &m2 = static_cast<MSLCM_DK2004&>(veh->getLaneChangeModel());
895  if((m2.getState()&LCA_URGENT)!=0) {
896  glColor3d(1, .4, .4);
897  } else if((m2.getState()&LCA_SPEEDGAIN)!=0) {
898  glColor3d(.4, .4, 1);
899  } else {
900  glColor3d(.4, 1, .4);
901  }
902  */
903  // draw the vehicle
904  switch (s.vehicleQuality) {
905  case 0:
907  break;
908  case 1:
910  break;
911  case 2:
913  break;
914  case 3:
915  default:
916  // draw as image but take special care for drawing trains
917  // XXX handle default carriage lenghts someplace else
918  switch (getVehicleType().getGuiShape()) {
919  case SVS_RAIL:
920  drawAction_drawRailCarriages(s, 25.0, 1, true);
921  break;
922  case SVS_RAIL_LIGHT:
923  drawAction_drawRailCarriages(s, 38.0, true);
924  break;
925  case SVS_RAIL_CITY:
926  drawAction_drawRailCarriages(s, 25.0, true);
927  break;
928  case SVS_RAIL_SLOW:
929  drawAction_drawRailCarriages(s, 15.0, 1, true);
930  break;
931  case SVS_RAIL_FAST:
932  drawAction_drawRailCarriages(s, 40.0, 1, true);
933  break;
934  case SVS_RAIL_CARGO:
935  drawAction_drawRailCarriages(s, 20.0, true);
936  break;
937  default:
938  // draw normal vehicle
941  };
942  };
943  break;
944  }
945  if (s.drawMinGap) {
946  SUMOReal minGap = -getVehicleType().getMinGap();
947  glColor3d(0., 1., 0.);
948  glBegin(GL_LINES);
949  glVertex2d(0., 0);
950  glVertex2d(0., minGap);
951  glVertex2d(-.5, minGap);
952  glVertex2d(.5, minGap);
953  glEnd();
954  }
955  // draw the blinker and brakelights if wished
956  if (s.showBlinker) {
957  glTranslated(0, 0, .1);
958  switch (getVehicleType().getGuiShape()) {
959  case SVS_PEDESTRIAN:
960  case SVS_BICYCLE:
961  case SVS_ANT:
962  case SVS_RAIL:
963  case SVS_RAIL_LIGHT:
964  case SVS_RAIL_SLOW:
965  case SVS_RAIL_FAST:
966  case SVS_RAIL_CARGO:
967  // only SVS_RAIL_CITY has blinkers and brake lights
968  break;
969  default:
972  break;
973  }
974  }
975  // draw the wish to change the lane
976  if (s.drawLaneChangePreference) {
977  /*
978  if(gSelected.isSelected(GLO_VEHICLE, veh->getGlID())) {
979  MSLCM_DK2004 &m = static_cast<MSLCM_DK2004&>(veh->getLaneChangeModel());
980  glColor3d(.5, .5, 1);
981  glBegin(GL_LINES);
982  glVertex2f(0, 0);
983  glVertex2f(m.getChangeProbability(), .5);
984  glEnd();
985 
986  glColor3d(1, 0, 0);
987  glBegin(GL_LINES);
988  glVertex2f(0.1, 0);
989  glVertex2f(0.1, m.myMaxJam1);
990  glEnd();
991 
992  glColor3d(0, 1, 0);
993  glBegin(GL_LINES);
994  glVertex2f(-0.1, 0);
995  glVertex2f(-0.1, m.myTDist);
996  glEnd();
997  }
998  */
999  }
1000  // draw best lanes
1001  /*
1002  if (true) {
1003  const MSLane &l = veh->getLane();
1004  SUMOReal r1 = veh->allowedContinuationsLength(&l, 0);
1005  SUMOReal r2 = l.getLeftLane()!=0 ? veh->allowedContinuationsLength(l.getLeftLane(), 0) : 0;
1006  SUMOReal r3 = l.getRightLane()!=0 ? veh->allowedContinuationsLength(l.getRightLane(), 0) : 0;
1007  SUMOReal mmax = MAX3(r1, r2, r3);
1008  glBegin(GL_LINES);
1009  glVertex2f(0, 0);
1010  glVertex2f(0, r1/mmax/2.);
1011  glEnd();
1012  glBegin(GL_LINES);
1013  glVertex2f(.4, 0);
1014  glVertex2f(.4, r2/mmax/2.);
1015  glEnd();
1016  glBegin(GL_LINES);
1017  glVertex2f(-.4, 0);
1018  glVertex2f(-.4, r3/mmax/2.);
1019  glEnd();
1020  }
1021  */
1022  glPopMatrix();
1025  myState.pos() - MIN2(getVehicleType().getLength() / 2, SUMOReal(5)))),
1026  s.scale, s.vehicleName);
1027  glPopName();
1028  if (myPersonDevice != 0) {
1029  const std::vector<MSPerson*>& ps = myPersonDevice->getPersons();
1030  size_t personIndex = 0;
1031  for (std::vector<MSPerson*>::const_iterator i = ps.begin(); i != ps.end(); ++i) {
1032  GUIPerson* person = dynamic_cast<GUIPerson*>(*i);
1033  assert(person != 0);
1034  person->setPositionInVehicle(getSeatPosition(personIndex++));
1035  person->drawGL(s);
1036  }
1037  }
1038 }
1039 
1040 
1041 void
1043  glPushName(getGlID());
1044  glPushMatrix();
1045  glTranslated(0, 0, getType() - .1); // don't draw on top of other cars
1047  drawBestLanes();
1048  }
1050  drawRoute(s, 0, 0.25);
1051  }
1053  if (getNumberReroutes() > 0) {
1054  const int noReroutePlus1 = getNumberReroutes() + 1;
1055  for (int i = noReroutePlus1 - 1; i >= 0; i--) {
1056  SUMOReal darken = SUMOReal(0.4) / SUMOReal(noReroutePlus1) * SUMOReal(i);
1057  drawRoute(s, i, darken);
1058  }
1059  } else {
1060  drawRoute(s, 0, 0.25);
1061  }
1062  }
1064  for (DriveItemVector::const_iterator i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
1065  if ((*i).myLink == 0) {
1066  continue;
1067  }
1068  MSLink* link = (*i).myLink;
1069  MSLane* via = link->getViaLaneOrLane();
1070  if (via != 0) {
1071  Position p = via->getShape()[0];
1072  if ((*i).mySetRequest) {
1073  glColor3d(0, .8, 0);
1074  } else {
1075  glColor3d(.8, 0, 0);
1076  }
1077  glTranslated(p.x(), p.y(), -.1);
1079 
1080  const SUMOTime leaveTime = (*i).myArrivalTime + TIME2STEPS(((*i).myLink->getLength() + getVehicleType().getLength()) / (*i).myArrivalSpeed);
1081  std::string times = toString(STEPS2TIME((*i).myArrivalTime)) + "/" + toString(STEPS2TIME(leaveTime));
1082  GLHelper::drawText(times.c_str(), Position(), .1, 1.6 * s.addExaggeration, RGBColor(0, 1, 0), 0);
1083 
1084  glTranslated(-p.x(), -p.y(), .1);
1085  }
1086  }
1087  }
1088  glPopMatrix();
1089  glPopName();
1090 }
1091 
1092 
1093 const std::vector<MSVehicle::LaneQ>&
1095  myLock.lock();
1096  const std::vector<MSVehicle::LaneQ>& ret = MSVehicle::getBestLanes();
1097  myLock.unlock();
1098  return ret;
1099 }
1100 
1101 
1102 void
1104  const GUIColorer& c = s.vehicleColorer;
1105  if (!setFunctionalColor(c.getActive())) {
1107  }
1108 }
1109 
1110 
1111 bool
1112 GUIVehicle::setFunctionalColor(size_t activeScheme) const {
1113  switch (activeScheme) {
1114  case 0: {
1115  if (getParameter().wasSet(VEHPARS_COLOR_SET)) {
1117  return true;
1118  }
1119  if (getVehicleType().wasSet(VTYPEPARS_COLOR_SET)) {
1120  GLHelper::setColor(getVehicleType().getColor());
1121  return true;
1122  }
1123  if (&getRoute().getColor() != &RGBColor::DEFAULT_COLOR) {
1124  GLHelper::setColor(getRoute().getColor());
1125  return true;
1126  }
1127  return false;
1128  }
1129  case 2: {
1130  if (getParameter().wasSet(VEHPARS_COLOR_SET)) {
1132  return true;
1133  }
1134  return false;
1135  }
1136  case 3: {
1137  if (getVehicleType().wasSet(VTYPEPARS_COLOR_SET)) {
1138  GLHelper::setColor(getVehicleType().getColor());
1139  return true;
1140  }
1141  return false;
1142  }
1143  case 4: {
1144  if (&getRoute().getColor() != &RGBColor::DEFAULT_COLOR) {
1145  GLHelper::setColor(getRoute().getColor());
1146  return true;
1147  }
1148  return false;
1149  }
1150  case 5: {
1151  Position p = getRoute().getEdges()[0]->getLanes()[0]->getShape()[0];
1152  const Boundary& b = ((GUINet*) MSNet::getInstance())->getBoundary();
1153  Position center = b.getCenter();
1154  SUMOReal hue = 180. + atan2(center.x() - p.x(), center.y() - p.y()) * 180. / PI;
1155  SUMOReal sat = p.distanceTo(center) / center.distanceTo(Position(b.xmin(), b.ymin()));
1156  GLHelper::setColor(RGBColor::fromHSV(hue, sat, 1.));
1157  return true;
1158  }
1159  case 6: {
1160  Position p = getRoute().getEdges().back()->getLanes()[0]->getShape()[-1];
1161  const Boundary& b = ((GUINet*) MSNet::getInstance())->getBoundary();
1162  Position center = b.getCenter();
1163  SUMOReal hue = 180. + atan2(center.x() - p.x(), center.y() - p.y()) * 180. / PI;
1164  SUMOReal sat = p.distanceTo(center) / center.distanceTo(Position(b.xmin(), b.ymin()));
1165  GLHelper::setColor(RGBColor::fromHSV(hue, sat, 1.));
1166  return true;
1167  }
1168  case 7: {
1169  Position pb = getRoute().getEdges()[0]->getLanes()[0]->getShape()[0];
1170  Position pe = getRoute().getEdges().back()->getLanes()[0]->getShape()[-1];
1171  const Boundary& b = ((GUINet*) MSNet::getInstance())->getBoundary();
1172  SUMOReal hue = 180. + atan2(pb.x() - pe.x(), pb.y() - pe.y()) * 180. / PI;
1173  Position minp(b.xmin(), b.ymin());
1174  Position maxp(b.xmax(), b.ymax());
1175  SUMOReal sat = pb.distanceTo(pe) / minp.distanceTo(maxp);
1176  GLHelper::setColor(RGBColor::fromHSV(hue, sat, 1.));
1177  return true;
1178  }
1179  }
1180  return false;
1181 }
1182 
1183 
1184 SUMOReal
1185 GUIVehicle::getColorValue(size_t activeScheme) const {
1186  switch (activeScheme) {
1187  case 8:
1188  return getSpeed();
1189  case 9:
1190  return getWaitingSeconds();
1191  case 10:
1192  return getLastLaneChangeOffset();
1193  case 11:
1194  return getMaxSpeed();
1195  case 12:
1196  return getHBEFA_CO2Emissions();
1197  case 13:
1198  return getHBEFA_COEmissions();
1199  case 14:
1200  return getHBEFA_PMxEmissions();
1201  case 15:
1202  return getHBEFA_NOxEmissions();
1203  case 16:
1204  return getHBEFA_HCEmissions();
1205  case 17:
1206  return getHBEFA_FuelConsumption();
1207  case 18:
1209  case 19:
1210  if (getNumberReroutes() == 0) {
1211  return -1;
1212  }
1213  return getNumberReroutes();
1214  }
1215  return 0;
1216 }
1217 
1218 
1219 // ------------ Additional visualisations
1220 bool
1222  return myAdditionalVisualizations.find(parent) != myAdditionalVisualizations.end() && (myAdditionalVisualizations.find(parent)->second & which) != 0;
1223 }
1224 
1225 
1226 bool
1228  if (myAdditionalVisualizations.find(parent) == myAdditionalVisualizations.end()) {
1229  myAdditionalVisualizations[parent] = 0;
1230  }
1231  myAdditionalVisualizations[parent] |= which;
1232  return parent->addAdditionalGLVisualisation(this);
1233 }
1234 
1235 
1236 bool
1238  myAdditionalVisualizations[parent] &= ~which;
1239  return parent->removeAdditionalGLVisualisation(this);
1240 }
1241 
1242 
1243 void
1244 GUIVehicle::drawRoute(const GUIVisualizationSettings& s, int routeNo, SUMOReal darken) const {
1245  setColor(s);
1246  GLdouble colors[4];
1247  glGetDoublev(GL_CURRENT_COLOR, colors);
1248  colors[0] -= darken;
1249  if (colors[0] < 0) {
1250  colors[0] = 0;
1251  }
1252  colors[1] -= darken;
1253  if (colors[1] < 0) {
1254  colors[1] = 0;
1255  }
1256  colors[2] -= darken;
1257  if (colors[2] < 0) {
1258  colors[2] = 0;
1259  }
1260  colors[3] -= darken;
1261  if (colors[3] < 0) {
1262  colors[3] = 0;
1263  }
1264  glColor3dv(colors);
1265  if (routeNo == 0) {
1266  draw(*myRoute);
1267  return;
1268  }
1269  --routeNo; // only prior routes are stored
1270  draw(*myRoutes->getRoute(routeNo));
1271 }
1272 
1273 
1274 void
1276  myLock.lock();
1277  std::vector<std::vector<MSVehicle::LaneQ> > bestLanes = myBestLanes;
1278  myLock.unlock();
1279  SUMOReal width = 0.5;
1280  for (std::vector<std::vector<MSVehicle::LaneQ> >::iterator j = bestLanes.begin(); j != bestLanes.end(); ++j) {
1281  std::vector<MSVehicle::LaneQ>& lanes = *j;
1282  SUMOReal gmax = -1;
1283  SUMOReal rmax = -1;
1284  for (std::vector<MSVehicle::LaneQ>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
1285  gmax = MAX2((*i).length, gmax);
1286  rmax = MAX2((*i).occupation, rmax);
1287  }
1288  for (std::vector<MSVehicle::LaneQ>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
1289  const PositionVector& shape = (*i).lane->getShape();
1290  SUMOReal g = (*i).length / gmax;
1291  SUMOReal r = (*i).occupation / rmax;
1292  glColor3d(r, g, 0);
1293  GLHelper::drawBoxLines(shape, width);
1294 
1295  PositionVector s1 = shape;
1296  s1.move2side((SUMOReal) .1);
1297  glColor3d(r, 0, 0);
1298  GLHelper::drawLine(s1);
1299  s1.move2side((SUMOReal) - .2);
1300  glColor3d(0, g, 0);
1301  GLHelper::drawLine(s1);
1302 
1303  glColor3d(r, g, 0);
1304  Position lastPos = shape[-1];
1305  }
1306  width = .2;
1307  }
1308 }
1309 
1310 
1311 void
1312 GUIVehicle::draw(const MSRoute& r) const {
1313  MSRouteIterator i = r.begin();
1314  for (; i != r.end(); ++i) {
1315  const MSEdge* e = *i;
1316  const GUIEdge* ge = static_cast<const GUIEdge*>(e);
1317  const GUILaneWrapper& lane = ge->getLaneGeometry((size_t) 0);
1319  }
1320 }
1321 
1322 
1325  GUIEdge* edge = dynamic_cast<GUIEdge*>(&(myLane->getEdge()));
1326  assert(edge != 0);
1327  return edge->getLaneGeometry(myLane);
1328 }
1329 
1330 
1331 MSLane*
1332 GUIVehicle::getPreviousLane(MSLane* current, int& routeIndex) const {
1333  const bool isInternal = current->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL;
1334  if (isInternal) {
1335  // route pointer still points to the previous lane
1336  return myRoute->getEdges()[routeIndex]->getLanes()[0];
1337  } else if (routeIndex == 0) {
1338  // there is no previous lane because the route has just begun
1339  return current;
1340  } else {
1341  // retrieve the previous internal edge
1342  routeIndex -= 1;
1343  const MSEdge* previous = myRoute->getEdges()[routeIndex];
1344 #ifdef HAVE_INTERNAL_LANES
1345  const MSEdge* previousInternal = previous->getInternalFollowingEdge(&current->getEdge());
1346 #else
1347  const MSEdge* previousInternal = 0;
1348 #endif
1349  if (previousInternal != 0) {
1350  return previousInternal->getLanes()[0];
1351  } else {
1352  // network without internal links, use previous edge instead
1353  return previous->getLanes()[0];
1354  }
1355  }
1356 }
1357 
1358 
1359 void
1360 GUIVehicle::drawAction_drawRailCarriages(const GUIVisualizationSettings& s, SUMOReal defaultLength, int firstPassengerCarriage, bool asImage) const {
1361  RGBColor current = GLHelper::getColor();
1362  RGBColor darker = current.changedBrightness(-.2);
1363  const SUMOReal length = getVehicleType().getLength() * s.vehicleExaggeration;
1364  const SUMOReal halfWidth = getVehicleType().getWidth() / 2.0 * s.vehicleExaggeration;
1365  glPopMatrix(); // undo scaling and 90 degree rotation
1366  glPopMatrix(); // undo initial translation and rotation
1367  glPushMatrix();
1368  glPushMatrix();
1369  GLHelper::setColor(darker);
1370  const SUMOReal carriageGap = 1;
1371  const SUMOReal xCornerCut = 0.3;
1372  const SUMOReal yCornerCut = 0.4;
1373  // round to closest integer
1374  const int numCarriages = floor(length / (defaultLength + carriageGap) + 0.5);
1375  assert(numCarriages > 0);
1376  const SUMOReal carriageLengthWithGap = length / numCarriages;
1377  const SUMOReal carriageLength = carriageLengthWithGap - carriageGap;
1378  // lane on which the carriage front is situated
1379  MSLane* lane = myLane;
1380  int routeIndex = myCurrEdge - myRoute->begin();
1381  // lane on which the carriage back is situated
1382  MSLane* backLane = myLane;
1383  int backRouteIndex = routeIndex;
1384  // offsets of front and back
1385  SUMOReal carriageOffset = myState.pos();
1386  SUMOReal carriageBackOffset = myState.pos() - carriageLength;
1387  // handle seats
1388  int requiredSeats = getNumPassengers();
1389  if (requiredSeats > 0) {
1391  }
1392  // draw individual carriages
1393  for (int i = 0; i < numCarriages; ++i) {
1394  while (carriageOffset < 0) {
1395  lane = getPreviousLane(lane, routeIndex);
1396  carriageOffset += lane->getLength();
1397  }
1398  while (carriageBackOffset < 0) {
1399  backLane = getPreviousLane(backLane, backRouteIndex);
1400  carriageBackOffset += backLane->getLength();
1401  }
1402  const Position front = lane->getShape().positionAtLengthPosition2D(carriageOffset);
1403  const Position back = backLane->getShape().positionAtLengthPosition2D(carriageBackOffset);
1404  const SUMOReal angle = atan2((front.x() - back.x()), (back.y() - front.y())) * (SUMOReal) 180.0 / (SUMOReal) PI;
1405  if (i >= firstPassengerCarriage) {
1406  computeSeats(front, back, requiredSeats);
1407  }
1408  glPushMatrix();
1409  glTranslated(front.x(), front.y(), getType());
1410  glRotated(angle, 0, 0, 1);
1411  if (!asImage || !drawAction_drawVehicleAsImage(s, carriageLength)) {
1412  glBegin(GL_TRIANGLE_FAN);
1413  glVertex2d(-halfWidth + xCornerCut, 0);
1414  glVertex2d(-halfWidth, yCornerCut);
1415  glVertex2d(-halfWidth, carriageLength - yCornerCut);
1416  glVertex2d(-halfWidth + xCornerCut, carriageLength);
1417  glVertex2d(halfWidth - xCornerCut, carriageLength);
1418  glVertex2d(halfWidth, carriageLength - yCornerCut);
1419  glVertex2d(halfWidth, yCornerCut);
1420  glVertex2d(halfWidth - xCornerCut, 0);
1421  glEnd();
1422  }
1423  glPopMatrix();
1424  carriageOffset -= carriageLengthWithGap;
1425  carriageBackOffset -= carriageLengthWithGap;
1426  GLHelper::setColor(current);
1427  }
1428 }
1429 
1430 
1431 const Position&
1432 GUIVehicle::getSeatPosition(size_t personIndex) const {
1434  return mySeatPositions[(int)MIN2(personIndex, mySeatPositions.size() - 1)];
1435 }
1436 
1437 
1438 int
1440  if (myPersonDevice != 0) {
1441  return (int)myPersonDevice->getPersons().size();
1442  }
1443  return 0;
1444 }
1445 
1446 
1447 void
1448 GUIVehicle::computeSeats(const Position& front, const Position& back, int& requiredSeats) const {
1449  if (requiredSeats <= 0) {
1450  return; // save some work
1451  }
1452  const Line l(front, back);
1453  const SUMOReal length = l.length2D();
1454  if (length < 4) {
1455  // small vehicle, sit at the center
1457  requiredSeats--;
1458  } else {
1459  for (SUMOReal p = 2; p <= length - 1; p += 1) {
1461  requiredSeats--;
1462  }
1463  }
1464 }
1465 
1466 /****************************************************************************/
1467