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 /****************************************************************************/
10 /// @file GUIPerson.cpp
11 /// @author Daniel Krajzewicz
12 /// @author Jakob Erdmann
13 /// @author Michael Behrisch
14 /// @date Sept 2002
15 /// @version $Id$
16 ///
17 // A MSPerson extended by some values for usage within the gui
18 /****************************************************************************/
19
20
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25
26 #include <cmath>
27 #include <vector>
28 #include <string>
29 #include <microsim/MSVehicleControl.h>
30 #include <microsim/MSVehicleType.h>
31 #include <microsim/pedestrians/MSPerson.h>
32 #include <microsim/pedestrians/MSPModel_Striping.h>
33 #include <microsim/logging/CastingFunctionBinding.h>
34 #include <microsim/logging/FunctionBinding.h>
35 #include <microsim/devices/MSDevice_Vehroutes.h>
36 #include <utils/common/StringUtils.h>
37 #include <utils/vehicle/SUMOVehicleParameter.h>
38 #include <utils/geom/GeomHelper.h>
39 #include <utils/gui/images/GUITexturesHelper.h>
40 #include <utils/gui/windows/GUISUMOAbstractView.h>
41 #include <utils/gui/windows/GUIAppEnum.h>
42 #include <utils/gui/div/GUIParameterTableWindow.h>
43 #include <utils/gui/div/GUIGlobalSelection.h>
44 #include <utils/gui/div/GLHelper.h>
45 #include <utils/gui/div/GLObjectValuePassConnector.h>
46 #include <utils/gui/globjects/GLIncludes.h>
47 #include <utils/gui/images/GUIIconSubSys.h>
48 #include <gui/GUIApplicationWindow.h>
49 #include <gui/GUIGlobals.h>
50 #include "GUILane.h"
51 #include "GUINet.h"
52 #include "GUIEdge.h"
53 #include "GUIPerson.h"
54
55 //#define GUIPerson_DEBUG_DRAW_WALKINGAREA_PATHS 1
56
57 // ===========================================================================
58 // FOX callback mapping
59 // ===========================================================================
60 FXDEFMAP(GUIPerson::GUIPersonPopupMenu) GUIPersonPopupMenuMap[] = {
61 FXMAPFUNC(SEL_COMMAND, MID_SHOW_CURRENTROUTE, GUIPerson::GUIPersonPopupMenu::onCmdShowCurrentRoute),
62 FXMAPFUNC(SEL_COMMAND, MID_HIDE_CURRENTROUTE, GUIPerson::GUIPersonPopupMenu::onCmdHideCurrentRoute),
63 FXMAPFUNC(SEL_COMMAND, MID_SHOW_WALKINGAREA_PATH, GUIPerson::GUIPersonPopupMenu::onCmdShowWalkingareaPath),
64 FXMAPFUNC(SEL_COMMAND, MID_HIDE_WALKINGAREA_PATH, GUIPerson::GUIPersonPopupMenu::onCmdHideWalkingareaPath),
65 FXMAPFUNC(SEL_COMMAND, MID_SHOWPLAN, GUIPerson::GUIPersonPopupMenu::onCmdShowPlan),
66 FXMAPFUNC(SEL_COMMAND, MID_START_TRACK, GUIPerson::GUIPersonPopupMenu::onCmdStartTrack),
67 FXMAPFUNC(SEL_COMMAND, MID_STOP_TRACK, GUIPerson::GUIPersonPopupMenu::onCmdStopTrack),
68 };
69
70 // Object implementation
FXIMPLEMENT(GUIPerson::GUIPersonPopupMenu,GUIGLObjectPopupMenu,GUIPersonPopupMenuMap,ARRAYNUMBER (GUIPersonPopupMenuMap))71 FXIMPLEMENT(GUIPerson::GUIPersonPopupMenu, GUIGLObjectPopupMenu, GUIPersonPopupMenuMap, ARRAYNUMBER(GUIPersonPopupMenuMap))
72
73
74
75 // ===========================================================================
76 // method definitions
77 // ===========================================================================
78 /* -------------------------------------------------------------------------
79 * GUIPerson::GUIPersonPopupMenu - methods
80 * ----------------------------------------------------------------------- */
81 GUIPerson::GUIPersonPopupMenu::GUIPersonPopupMenu(
82 GUIMainWindow& app, GUISUMOAbstractView& parent,
83 GUIGlObject& o, std::map<GUISUMOAbstractView*, int>& additionalVisualizations) :
84 GUIGLObjectPopupMenu(app, parent, o),
85 myVehiclesAdditionalVisualizations(additionalVisualizations) {
86 }
87
88
~GUIPersonPopupMenu()89 GUIPerson::GUIPersonPopupMenu::~GUIPersonPopupMenu() {}
90
91 long
onCmdShowCurrentRoute(FXObject *,FXSelector,void *)92 GUIPerson::GUIPersonPopupMenu::onCmdShowCurrentRoute(FXObject*, FXSelector, void*) {
93 assert(myObject->getType() == GLO_PERSON);
94 if (!static_cast<GUIPerson*>(myObject)->hasActiveAddVisualisation(myParent, VO_SHOW_ROUTE)) {
95 static_cast<GUIPerson*>(myObject)->addActiveAddVisualisation(myParent, VO_SHOW_ROUTE);
96 }
97 return 1;
98 }
99
100 long
onCmdHideCurrentRoute(FXObject *,FXSelector,void *)101 GUIPerson::GUIPersonPopupMenu::onCmdHideCurrentRoute(FXObject*, FXSelector, void*) {
102 assert(myObject->getType() == GLO_PERSON);
103 static_cast<GUIPerson*>(myObject)->removeActiveAddVisualisation(myParent, VO_SHOW_ROUTE);
104 return 1;
105 }
106
107
108
109 long
onCmdShowWalkingareaPath(FXObject *,FXSelector,void *)110 GUIPerson::GUIPersonPopupMenu::onCmdShowWalkingareaPath(FXObject*, FXSelector, void*) {
111 assert(myObject->getType() == GLO_PERSON);
112 if (!static_cast<GUIPerson*>(myObject)->hasActiveAddVisualisation(myParent, VO_SHOW_WALKINGAREA_PATH)) {
113 static_cast<GUIPerson*>(myObject)->addActiveAddVisualisation(myParent, VO_SHOW_WALKINGAREA_PATH);
114 }
115 return 1;
116 }
117
118 long
onCmdHideWalkingareaPath(FXObject *,FXSelector,void *)119 GUIPerson::GUIPersonPopupMenu::onCmdHideWalkingareaPath(FXObject*, FXSelector, void*) {
120 assert(myObject->getType() == GLO_PERSON);
121 static_cast<GUIPerson*>(myObject)->removeActiveAddVisualisation(myParent, VO_SHOW_WALKINGAREA_PATH);
122 return 1;
123 }
124
125
126 long
onCmdShowPlan(FXObject *,FXSelector,void *)127 GUIPerson::GUIPersonPopupMenu::onCmdShowPlan(FXObject*, FXSelector, void*) {
128 GUIPerson* p = dynamic_cast<GUIPerson*>(myObject);
129 if (p == nullptr) {
130 return 1;
131 }
132 GUIParameterTableWindow* ret = new GUIParameterTableWindow(*myApplication, *p, p->getNumStages());
133 // add items
134 for (int stage = 1; stage < p->getNumStages(); stage++) {
135 ret->mkItem(toString(stage).c_str(), false, p->getStageSummary(stage));
136 }
137 // close building (use an object that is not Parameterised as argument)
138 Parameterised dummy;
139 ret->closeBuilding(&dummy);
140 return 1;
141 }
142
143
144 long
onCmdStartTrack(FXObject *,FXSelector,void *)145 GUIPerson::GUIPersonPopupMenu::onCmdStartTrack(FXObject*, FXSelector, void*) {
146 assert(myObject->getType() == GLO_PERSON);
147 if (myParent->getTrackedID() != static_cast<GUIPerson*>(myObject)->getGlID()) {
148 myParent->startTrack(static_cast<GUIPerson*>(myObject)->getGlID());
149 }
150 return 1;
151 }
152
153 long
onCmdStopTrack(FXObject *,FXSelector,void *)154 GUIPerson::GUIPersonPopupMenu::onCmdStopTrack(FXObject*, FXSelector, void*) {
155 assert(myObject->getType() == GLO_PERSON);
156 myParent->stopTrack();
157 return 1;
158 }
159
160
161
162
163 /* -------------------------------------------------------------------------
164 * GUIPerson - methods
165 * ----------------------------------------------------------------------- */
GUIPerson(const SUMOVehicleParameter * pars,MSVehicleType * vtype,MSTransportable::MSTransportablePlan * plan,const double speedFactor)166 GUIPerson::GUIPerson(const SUMOVehicleParameter* pars, MSVehicleType* vtype, MSTransportable::MSTransportablePlan* plan, const double speedFactor) :
167 MSPerson(pars, vtype, plan, speedFactor),
168 GUIGlObject(GLO_PERSON, pars->id),
169 myPositionInVehicle(Position::INVALID) {
170 }
171
172
~GUIPerson()173 GUIPerson::~GUIPerson() {
174 myLock.lock();
175 for (std::map<GUISUMOAbstractView*, int>::iterator i = myAdditionalVisualizations.begin(); i != myAdditionalVisualizations.end(); ++i) {
176 if (i->first->getTrackedID() == getGlID()) {
177 i->first->stopTrack();
178 }
179 while (i->first->removeAdditionalGLVisualisation(this));
180 }
181 myLock.unlock();
182 }
183
184
185 GUIGLObjectPopupMenu*
getPopUpMenu(GUIMainWindow & app,GUISUMOAbstractView & parent)186 GUIPerson::getPopUpMenu(GUIMainWindow& app,
187 GUISUMOAbstractView& parent) {
188 GUIGLObjectPopupMenu* ret = new GUIPersonPopupMenu(app, parent, *this, myAdditionalVisualizations);
189 buildPopupHeader(ret, app);
190 buildCenterPopupEntry(ret);
191 buildNameCopyPopupEntry(ret);
192 buildSelectionPopupEntry(ret);
193 if (hasActiveAddVisualisation(&parent, VO_SHOW_ROUTE)) {
194 new FXMenuCommand(ret, "Hide Current Route", nullptr, ret, MID_HIDE_CURRENTROUTE);
195 } else {
196 new FXMenuCommand(ret, "Show Current Route", nullptr, ret, MID_SHOW_CURRENTROUTE);
197 }
198 if (hasActiveAddVisualisation(&parent, VO_SHOW_WALKINGAREA_PATH)) {
199 new FXMenuCommand(ret, "Hide Walkingarea Path", nullptr, ret, MID_HIDE_WALKINGAREA_PATH);
200 } else {
201 new FXMenuCommand(ret, "Show Walkingarea Path", nullptr, ret, MID_SHOW_WALKINGAREA_PATH);
202 }
203 new FXMenuSeparator(ret);
204 if (parent.getTrackedID() != getGlID()) {
205 new FXMenuCommand(ret, "Start Tracking", nullptr, ret, MID_START_TRACK);
206 } else {
207 new FXMenuCommand(ret, "Stop Tracking", nullptr, ret, MID_STOP_TRACK);
208 }
209 new FXMenuSeparator(ret);
210 //
211 buildShowParamsPopupEntry(ret);
212 buildShowTypeParamsPopupEntry(ret);
213 new FXMenuCommand(ret, "Show Plan", GUIIconSubSys::getIcon(ICON_APP_TABLE), ret, MID_SHOWPLAN);
214 new FXMenuSeparator(ret);
215 buildPositionCopyEntry(ret, false);
216 return ret;
217 }
218
219
220 GUIParameterTableWindow*
getParameterWindow(GUIMainWindow & app,GUISUMOAbstractView &)221 GUIPerson::getParameterWindow(GUIMainWindow& app,
222 GUISUMOAbstractView&) {
223 GUIParameterTableWindow* ret =
224 new GUIParameterTableWindow(app, *this, 12 + (int)getParameter().getParametersMap().size());
225 // add items
226 ret->mkItem("stage", false, getCurrentStageDescription());
227 // there is always the "start" stage which we do not count here because it is not strictly part of the plan
228 ret->mkItem("stage index", false, toString(getNumStages() - getNumRemainingStages()) + " of " + toString(getNumStages() - 1));
229 ret->mkItem("start edge [id]", false, getFromEdge()->getID());
230 ret->mkItem("dest edge [id]", false, getDestination()->getID());
231 ret->mkItem("arrivalPos [m]", false, toString(getCurrentStage()->getArrivalPos()));
232 ret->mkItem("edge [id]", false, getEdge()->getID());
233 ret->mkItem("position [m]", true, new FunctionBinding<GUIPerson, double>(this, &GUIPerson::getEdgePos));
234 ret->mkItem("speed [m/s]", true, new FunctionBinding<GUIPerson, double>(this, &GUIPerson::getSpeed));
235 ret->mkItem("speed factor", false, getSpeedFactor());
236 ret->mkItem("angle [degree]", true, new FunctionBinding<GUIPerson, double>(this, &GUIPerson::getNaviDegree));
237 ret->mkItem("waiting time [s]", true, new FunctionBinding<GUIPerson, double>(this, &GUIPerson::getWaitingSeconds));
238 ret->mkItem("desired depart [s]", false, time2string(getParameter().depart));
239 // close building
240 ret->closeBuilding(&getParameter());
241 return ret;
242 }
243
244
245 GUIParameterTableWindow*
getTypeParameterWindow(GUIMainWindow & app,GUISUMOAbstractView &)246 GUIPerson::getTypeParameterWindow(GUIMainWindow& app,
247 GUISUMOAbstractView&) {
248 GUIParameterTableWindow* ret =
249 new GUIParameterTableWindow(app, *this, 8 + (int)myVType->getParameter().getParametersMap().size());
250 // add items
251 ret->mkItem("Type Information:", false, "");
252 ret->mkItem("type [id]", false, myVType->getID());
253 ret->mkItem("length", false, myVType->getLength());
254 ret->mkItem("width", false, myVType->getWidth());
255 ret->mkItem("height", false, myVType->getHeight());
256 ret->mkItem("minGap", false, myVType->getMinGap());
257 ret->mkItem("maximum speed [m/s]", false, myVType->getMaxSpeed());
258 // close building
259 ret->closeBuilding(&(myVType->getParameter()));
260 return ret;
261 }
262
263
264 Boundary
getCenteringBoundary() const265 GUIPerson::getCenteringBoundary() const {
266 Boundary b;
267 // ensure that the vehicle is drawn, otherwise myPositionInVehicle will not be updated
268 b.add(getGUIPosition());
269 b.grow(MAX2(getVehicleType().getWidth(), getVehicleType().getLength()));
270 return b;
271 }
272
273
274 void
drawGL(const GUIVisualizationSettings & s) const275 GUIPerson::drawGL(const GUIVisualizationSettings& s) const {
276 glPushName(getGlID());
277 glPushMatrix();
278 Position p1 = getGUIPosition();
279 glTranslated(p1.x(), p1.y(), getType());
280 glRotated(90, 0, 0, 1);
281 // set person color
282 setColor(s);
283 // scale
284 const double upscale = s.personSize.getExaggeration(s, this, 80);
285 glScaled(upscale, upscale, 1);
286 switch (s.personQuality) {
287 case 0:
288 drawAction_drawAsTriangle(s);
289 break;
290 case 1:
291 drawAction_drawAsCircle(s);
292 break;
293 case 2:
294 drawAction_drawAsPoly(s);
295 break;
296 case 3:
297 default:
298 drawAction_drawAsImage(s);
299 break;
300 }
301 glPopMatrix();
302 #ifdef GUIPerson_DEBUG_DRAW_WALKINGAREA_PATHS
303 drawAction_drawWalkingareaPath(s);
304 #endif
305 drawName(p1, s.scale, s.personName, s.angle);
306 if (s.personValue.show) {
307 Position p2 = p1 + Position(0, 0.6 * s.personName.scaledSize(s.scale));
308 const double value = getColorValue(s.personColorer.getActive());
309 GLHelper::drawTextSettings(s.personValue, toString(value), p2, s.scale, s.angle, GLO_MAX - getType());
310 }
311 glPopName();
312 }
313
314 void
drawAction_drawWalkingareaPath(const GUIVisualizationSettings & s) const315 GUIPerson::drawAction_drawWalkingareaPath(const GUIVisualizationSettings& s) const {
316 MSPersonStage_Walking* stage = dynamic_cast<MSPersonStage_Walking*>(getCurrentStage());
317 if (stage != nullptr) {
318 setColor(s);
319 MSPModel_Striping::PState* stripingState = dynamic_cast<MSPModel_Striping::PState*>(stage->getPedestrianState());
320 if (stripingState != nullptr) {
321 MSPModel_Striping::WalkingAreaPath* waPath = stripingState->myWalkingAreaPath;
322 if (waPath != nullptr) {
323 glPushMatrix();
324 glTranslated(0, 0, getType());
325 GLHelper::drawBoxLines(waPath->shape, 0.05);
326 glPopMatrix();
327 }
328 }
329 }
330 }
331
332 void
drawGLAdditional(GUISUMOAbstractView * const parent,const GUIVisualizationSettings & s) const333 GUIPerson::drawGLAdditional(GUISUMOAbstractView* const parent, const GUIVisualizationSettings& s) const {
334 glPushName(getGlID());
335 glPushMatrix();
336 glTranslated(0, 0, getType() - .1); // don't draw on top of other cars
337 if (hasActiveAddVisualisation(parent, VO_SHOW_WALKINGAREA_PATH)) {
338 drawAction_drawWalkingareaPath(s);
339 }
340 if (hasActiveAddVisualisation(parent, VO_SHOW_ROUTE)) {
341 if (getCurrentStageType() == MOVING_WITHOUT_VEHICLE) {
342 setColor(s);
343 RGBColor current = GLHelper::getColor();
344 RGBColor darker = current.changedBrightness(-51);
345 GLHelper::setColor(darker);
346 MSPersonStage_Walking* stage = dynamic_cast<MSPersonStage_Walking*>(getCurrentStage());
347 assert(stage != 0);
348 const double exaggeration = s.personSize.getExaggeration(s, this);
349 const ConstMSEdgeVector& edges = stage->getRoute();
350 for (ConstMSEdgeVector::const_iterator it = edges.begin(); it != edges.end(); ++it) {
351 GUILane* lane = static_cast<GUILane*>((*it)->getLanes()[0]);
352 GLHelper::drawBoxLines(lane->getShape(), lane->getShapeRotations(), lane->getShapeLengths(), exaggeration);
353 }
354 }
355 }
356 glPopMatrix();
357 glPopName();
358 }
359
360
361
362
363 void
setColor(const GUIVisualizationSettings & s) const364 GUIPerson::setColor(const GUIVisualizationSettings& s) const {
365 const GUIColorer& c = s.personColorer;
366 if (!setFunctionalColor(c.getActive())) {
367 GLHelper::setColor(c.getScheme().getColor(getColorValue(c.getActive())));
368 }
369 }
370
371
372 bool
setFunctionalColor(int activeScheme) const373 GUIPerson::setFunctionalColor(int activeScheme) const {
374 switch (activeScheme) {
375 case 0: {
376 if (getParameter().wasSet(VEHPARS_COLOR_SET)) {
377 GLHelper::setColor(getParameter().color);
378 return true;
379 }
380 if (getVehicleType().wasSet(VTYPEPARS_COLOR_SET)) {
381 GLHelper::setColor(getVehicleType().getColor());
382 return true;
383 }
384 return false;
385 }
386 case 2: {
387 if (getParameter().wasSet(VEHPARS_COLOR_SET)) {
388 GLHelper::setColor(getParameter().color);
389 return true;
390 }
391 return false;
392 }
393 case 3: {
394 if (getVehicleType().wasSet(VTYPEPARS_COLOR_SET)) {
395 GLHelper::setColor(getVehicleType().getColor());
396 return true;
397 }
398 return false;
399 }
400 case 8: { // color by angle
401 double hue = GeomHelper::naviDegree(getAngle());
402 GLHelper::setColor(RGBColor::fromHSV(hue, 1., 1.));
403 return true;
404 }
405 case 9: { // color randomly (by pointer)
406 const double hue = (long)this % 360; // [0-360]
407 const double sat = (((long)this / 360) % 67) / 100.0 + 0.33; // [0.33-1]
408 GLHelper::setColor(RGBColor::fromHSV(hue, sat, 1.));
409 return true;
410 }
411 default:
412 return false;
413 }
414 }
415
416
417 double
getColorValue(int activeScheme) const418 GUIPerson::getColorValue(int activeScheme) const {
419 switch (activeScheme) {
420 case 4:
421 return getSpeed();
422 case 5:
423 if (isWaiting4Vehicle()) {
424 return 5;
425 } else {
426 return (double)getCurrentStageType();
427 }
428 case 6:
429 return getWaitingSeconds();
430 case 7:
431 return gSelected.isSelected(GLO_PERSON, getGlID());
432 }
433 return 0;
434 }
435
436
437 double
getEdgePos() const438 GUIPerson::getEdgePos() const {
439 FXMutexLock locker(myLock);
440 return MSPerson::getEdgePos();
441 }
442
443
444 Position
getPosition() const445 GUIPerson::getPosition() const {
446 FXMutexLock locker(myLock);
447 return MSPerson::getPosition();
448 }
449
450
451 Position
getGUIPosition() const452 GUIPerson::getGUIPosition() const {
453 FXMutexLock locker(myLock);
454 if (getCurrentStageType() == DRIVING && !isWaiting4Vehicle() && myPositionInVehicle != Position::INVALID) {
455 return myPositionInVehicle;
456 } else {
457 return MSPerson::getPosition();
458 }
459 }
460
461
462 double
getNaviDegree() const463 GUIPerson::getNaviDegree() const {
464 FXMutexLock locker(myLock);
465 return GeomHelper::naviDegree(MSPerson::getAngle());
466 }
467
468
469 double
getWaitingSeconds() const470 GUIPerson::getWaitingSeconds() const {
471 FXMutexLock locker(myLock);
472 return MSPerson::getWaitingSeconds();
473 }
474
475
476 double
getSpeed() const477 GUIPerson::getSpeed() const {
478 FXMutexLock locker(myLock);
479 return MSPerson::getSpeed();
480 }
481
482
483 void
drawAction_drawAsTriangle(const GUIVisualizationSettings &) const484 GUIPerson::drawAction_drawAsTriangle(const GUIVisualizationSettings& /* s */) const {
485 // draw triangle pointing forward
486 glRotated(RAD2DEG(getAngle() + M_PI / 2.), 0, 0, 1);
487 glScaled(getVehicleType().getLength(), getVehicleType().getWidth(), 1);
488 glBegin(GL_TRIANGLES);
489 glVertex2d(0., 0.);
490 glVertex2d(1, -0.5);
491 glVertex2d(1, 0.5);
492 glEnd();
493 // draw a smaller triangle to indicate facing
494 GLHelper::setColor(GLHelper::getColor().changedBrightness(-64));
495 glTranslated(0, 0, .045);
496 glBegin(GL_TRIANGLES);
497 glVertex2d(0., 0.);
498 glVertex2d(0.5, -0.25);
499 glVertex2d(0.5, 0.25);
500 glEnd();
501 glTranslated(0, 0, -.045);
502 }
503
504
505 void
drawAction_drawAsCircle(const GUIVisualizationSettings &) const506 GUIPerson::drawAction_drawAsCircle(const GUIVisualizationSettings& /* s */) const {
507 glScaled(getVehicleType().getLength(), getVehicleType().getLength(), 1);
508 GLHelper::drawFilledCircle(0.8);
509 }
510
511
512 void
drawAction_drawAsPoly(const GUIVisualizationSettings &) const513 GUIPerson::drawAction_drawAsPoly(const GUIVisualizationSettings& /* s */) const {
514 // draw pedestrian shape
515 glRotated(GeomHelper::naviDegree(getAngle()) - 180, 0, 0, -1);
516 glScaled(getVehicleType().getLength(), getVehicleType().getWidth(), 1);
517 RGBColor lighter = GLHelper::getColor().changedBrightness(51);
518 glTranslated(0, 0, .045);
519 // head
520 glScaled(1, 0.5, 1.);
521 GLHelper::drawFilledCircle(0.5);
522 // nose
523 glBegin(GL_TRIANGLES);
524 glVertex2d(0.0, -0.2);
525 glVertex2d(0.0, 0.2);
526 glVertex2d(-0.6, 0.0);
527 glEnd();
528 glTranslated(0, 0, -.045);
529 // body
530 glScaled(0.9, 2.0, 1);
531 glTranslated(0, 0, .04);
532 GLHelper::setColor(lighter);
533 GLHelper::drawFilledCircle(0.5);
534 glTranslated(0, 0, -.04);
535 }
536
537
538 void
drawAction_drawAsImage(const GUIVisualizationSettings & s) const539 GUIPerson::drawAction_drawAsImage(const GUIVisualizationSettings& s) const {
540 const std::string& file = getVehicleType().getImgFile();
541 if (file != "") {
542 if (getVehicleType().getGuiShape() == SVS_PEDESTRIAN) {
543 glRotated(RAD2DEG(getAngle() + M_PI / 2.), 0, 0, 1);
544 }
545 int textureID = GUITexturesHelper::getTextureID(file);
546 if (textureID > 0) {
547 const double exaggeration = s.personSize.getExaggeration(s, this);
548 const double halfLength = getVehicleType().getLength() / 2.0 * exaggeration;
549 const double halfWidth = getVehicleType().getWidth() / 2.0 * exaggeration;
550 GUITexturesHelper::drawTexturedBox(textureID, -halfWidth, -halfLength, halfWidth, halfLength);
551 }
552 } else {
553 // fallback if no image is defined
554 drawAction_drawAsPoly(s);
555 }
556 }
557
558
559 // ------------ Additional visualisations
560 bool
hasActiveAddVisualisation(GUISUMOAbstractView * const parent,int which) const561 GUIPerson::hasActiveAddVisualisation(GUISUMOAbstractView* const parent, int which) const {
562 return myAdditionalVisualizations.find(parent) != myAdditionalVisualizations.end() && (myAdditionalVisualizations.find(parent)->second & which) != 0;
563 }
564
565
566 void
addActiveAddVisualisation(GUISUMOAbstractView * const parent,int which)567 GUIPerson::addActiveAddVisualisation(GUISUMOAbstractView* const parent, int which) {
568 if (myAdditionalVisualizations.find(parent) == myAdditionalVisualizations.end()) {
569 myAdditionalVisualizations[parent] = 0;
570 }
571 myAdditionalVisualizations[parent] |= which;
572 parent->addAdditionalGLVisualisation(this);
573 }
574
575
576 void
removeActiveAddVisualisation(GUISUMOAbstractView * const parent,int which)577 GUIPerson::removeActiveAddVisualisation(GUISUMOAbstractView* const parent, int which) {
578 myAdditionalVisualizations[parent] &= ~which;
579 parent->removeAdditionalGLVisualisation(this);
580 }
581
582 bool
isSelected() const583 GUIPerson::isSelected() const {
584 return gSelected.isSelected(GLO_PERSON, getGlID());
585 }
586
587 /****************************************************************************/
588
589