Eclipse SUMO - Simulation of Urban MObility
GUIOSGView.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2001-2024 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 // An OSG-based 3D view on the simulation
21 /****************************************************************************/
22 #include <config.h>
23 
24 #ifdef HAVE_OSG
25 
26 #include <cmath>
27 #include <fxkeys.h>
28 #include <iostream>
29 #include <limits>
30 #include <utility>
33 #include <gui/GUISUMOViewParent.h>
34 #include <gui/GUIViewTraffic.h>
35 #include <guisim/GUIEdge.h>
37 #include <guisim/GUILane.h>
38 #include <guisim/GUINet.h>
39 #include <guisim/GUIPerson.h>
40 #include <guisim/GUIVehicle.h>
41 #include <microsim/MSEdge.h>
42 #include <microsim/MSEdgeControl.h>
43 #include <microsim/MSLane.h>
44 #include <microsim/MSNet.h>
51 #include <utils/common/RGBColor.h>
57 #include <utils/gui/div/GLHelper.h>
70 
71 #include "GUIOSGBuilder.h"
73 #include "GUIOSGView.h"
74 
75 //#define DEBUG_GLERRORS
76 
77 FXDEFMAP(GUIOSGView) GUIOSGView_Map[] = {
78  //________Message_Type_________ ___ID___ ________Message_Handler________
79  FXMAPFUNC(SEL_CHORE, MID_CHORE, GUIOSGView::onIdle),
80 };
81 FXIMPLEMENT(GUIOSGView, GUISUMOAbstractView, GUIOSGView_Map, ARRAYNUMBER(GUIOSGView_Map))
82 
83 
84 std::ostream&
85 operator<<(std::ostream& os, const osg::Vec3d& v) {
86  return os << v.x() << "," << v.y() << "," << v.z();
87 }
88 
89 // ===========================================================================
90 // GUIOSGView::Command_TLSChange member method definitions
91 // ===========================================================================
92 
93 GUIOSGView::Command_TLSChange::Command_TLSChange(const MSLink* const link, osg::Switch* switchNode)
94  : myLink(link), mySwitch(switchNode), myLastState(LINKSTATE_TL_OFF_NOSIGNAL) {
95  execute();
96 }
97 
98 
99 GUIOSGView::Command_TLSChange::~Command_TLSChange() {}
100 
101 
102 void
103 GUIOSGView::Command_TLSChange::execute() {
104  switch (myLink->getState()) {
107  mySwitch->setSingleChildOn(0);
108  break;
111  mySwitch->setSingleChildOn(1);
112  break;
113  case LINKSTATE_TL_RED:
114  case LINKSTATE_STOP:
115  mySwitch->setSingleChildOn(2);
116  break;
118  mySwitch->setSingleChildOn(3);
119  break;
122  mySwitch->setSingleChildOn(3);
123  break;
124  default:
125  mySwitch->setAllChildrenOff();
126  }
127  myLastState = myLink->getState();
128 }
129 
130 // ===========================================================================
131 // GUIOSGView member method definitions
132 // ===========================================================================
133 
134 GUIOSGView::GUIOSGView(
135  FXComposite* p,
136  GUIMainWindow& app,
137  GUISUMOViewParent* parent,
138  GUINet& net, FXGLVisual* glVis,
139  FXGLCanvas* share) :
140  GUISUMOAbstractView(p, app, parent, net.getVisualisationSpeedUp(), glVis, share),
141  myTracked(0), myCameraManipulator(new GUIOSGManipulator(this)), myLastUpdate(-1),
142  myOSGNormalizedCursorX(0.), myOSGNormalizedCursorY(0.) {
143  if (myChanger != nullptr) {
144  delete (myChanger);
145  }
146  int w = getWidth();
147  int h = getHeight();
148  myAdapter = new FXOSGAdapter(this, new FXCursor(parent->getApp(), CURSOR_CROSS));
149  myViewer = new osgViewer::Viewer();
150  myChanger = new GUIOSGPerspectiveChanger(*this, *myGrid);
151  const char* sumoPath = getenv("SUMO_HOME");
152  if (sumoPath != 0) {
153  std::string newPath = std::string(sumoPath) + "/data/3D";
154  if (FileHelpers::isReadable(newPath)) {
155  osgDB::FilePathList path = osgDB::Registry::instance()->getDataFilePathList();
156  path.push_back(newPath);
157  osgDB::Registry::instance()->setDataFilePathList(path);
158  }
159  }
160 
161  myGreenLight = osgDB::readNodeFile("tlg.obj");
162  myYellowLight = osgDB::readNodeFile("tly.obj");
163  myRedLight = osgDB::readNodeFile("tlr.obj");
164  myRedYellowLight = osgDB::readNodeFile("tlu.obj");
165  myPoleBase = osgDB::readNodeFile("poleBase.obj");
166  if (myGreenLight == 0 || myYellowLight == 0 || myRedLight == 0 || myRedYellowLight == 0 || myPoleBase == 0) {
167  WRITE_ERROR(TL("Could not load traffic light files."));
168  }
169  // calculate camera frustum to scale the ground plane all across
170  double left, right, bottom, top, zNear, zFar;
171  myViewer->getCamera()->getProjectionMatrixAsFrustum(left, right, bottom, top, zNear, zFar);
172  myRoot = GUIOSGBuilder::buildOSGScene(myGreenLight, myYellowLight, myRedLight, myRedYellowLight, myPoleBase);
173  myPlane = new osg::MatrixTransform();
174  myPlane->setCullCallback(new ExcludeFromNearFarComputationCallback());
175  myPlane->addChild(GUIOSGBuilder::buildPlane((float)(zFar - zNear)));
176  myPlane->addUpdateCallback(new PlaneMoverCallback(myViewer->getCamera()));
177  myRoot->addChild(myPlane);
178  // add the stats handler
179  osgViewer::StatsHandler* statsHandler = new osgViewer::StatsHandler();
180  statsHandler->setKeyEventTogglesOnScreenStats(osgGA::GUIEventAdapter::KEY_I);
181  myViewer->addEventHandler(statsHandler);
182  myViewer->setSceneData(myRoot);
183  myViewer->setCameraManipulator(myCameraManipulator);
184 
185  myViewer->setKeyEventSetsDone(0);
186  myViewer->getCamera()->setGraphicsContext(myAdapter);
187  myViewer->getCamera()->setViewport(0, 0, w, h);
188  myViewer->getCamera()->setNearFarRatio(0.005); // does not work together with setUpDepthPartitionForCamera
189  myViewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
190  myViewer->addEventHandler(new PickHandler(this));
191  osg::Vec3d lookFrom, lookAt, up;
192  myCameraManipulator->getHomePosition(lookFrom, lookAt, up);
193  lookFrom = lookAt + osg::Z_AXIS;
194  up = osg::Y_AXIS;
195  myCameraManipulator->setHomePosition(lookFrom, lookAt, up);
196  myViewer->home();
197  recenterView();
198  myViewer->home();
199  getApp()->addChore(this, MID_CHORE);
200  myTextNode = new osg::Geode();
201  myText = new osgText::Text;
202  myText->setCharacterSizeMode(osgText::Text::SCREEN_COORDS);
203  myText->setShaderTechnique(osgText::NO_TEXT_SHADER);
204  osgText::Font* font = osgText::readFontFile("arial.ttf");
205  if (font != nullptr) {
206  myText->setFont(font);
207  }
208  myText->setCharacterSize(16.f);
209  myTextNode->addDrawable(myText);
210  myText->setAlignment(osgText::TextBase::AlignmentType::LEFT_TOP);
211  myText->setDrawMode(osgText::TextBase::DrawModeMask::FILLEDBOUNDINGBOX | osgText::TextBase::DrawModeMask::TEXT);
212  myText->setBoundingBoxColor(osg::Vec4(0.0f, 0.0f, 0.2f, 0.5f));
213  myText->setBoundingBoxMargin(2.0f);
214 
215  myHUD = new osg::Camera;
216  myHUD->setProjectionMatrixAsOrtho2D(0, 800, 0, 800); // default size will be overwritten
217  myHUD->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
218  myHUD->setViewMatrix(osg::Matrix::identity());
219  myHUD->setClearMask(GL_DEPTH_BUFFER_BIT);
220  myHUD->setRenderOrder(osg::Camera::POST_RENDER);
221  myHUD->setAllowEventFocus(false);
222  myHUD->setGraphicsContext(myAdapter);
223  myHUD->addChild(myTextNode);
224  myHUD->setViewport(0, 0, w, h);
225  myViewer->addSlave(myHUD, false);
226  myCameraManipulator->updateHUDText();
227 
228  // adjust the main light
229  adoptViewSettings();
230  osgUtil::Optimizer optimizer;
231  optimizer.optimize(myRoot);
232 }
233 
234 
235 GUIOSGView::~GUIOSGView() {
236  getApp()->removeChore(this, MID_CHORE);
237  myViewer->setDone(true);
238  myViewer = 0;
239  myRoot = 0;
240  myAdapter = 0;
241  myCameraManipulator = 0;
242  myHUD = 0;
243  myText = 0;
244  myTextNode = 0;
245  myGreenLight = 0;
246  myYellowLight = 0;
247  myRedLight = 0;
248  myRedYellowLight = 0;
249  myPoleBase = 0;
250 }
251 
252 
253 void
254 GUIOSGView::adoptViewSettings() {
255  // lighting
256  osg::Light* globalLight = myViewer->getLight();
257  globalLight->setAmbient(toOSGColorVector(myVisualizationSettings->ambient3DLight));
258  globalLight->setDiffuse(toOSGColorVector(myVisualizationSettings->diffuse3DLight));
259  myViewer->getCamera()->setClearColor(toOSGColorVector(myVisualizationSettings->skyColor));
260 
261  // ground color
262  osg::Geode* planeGeode = dynamic_cast<osg::Geode*>(myPlane->getChild(0));
263  osg::Geometry* planeGeom = dynamic_cast<osg::Geometry*>(planeGeode->getChild(0));
264  osg::Vec4ubArray* colors = dynamic_cast<osg::Vec4ubArray*>(planeGeom->getColorArray());
265  (*colors)[0].set(myVisualizationSettings->backgroundColor.red(),
266  myVisualizationSettings->backgroundColor.green(),
267  myVisualizationSettings->backgroundColor.blue(),
268  myVisualizationSettings->backgroundColor.alpha());
269  planeGeom->setColorArray(colors);
270 
271  // show/hide OSG nodes
272  unsigned int cullMask = 0xFFFFFFFF;
273  if (!myVisualizationSettings->show3DTLSDomes) {
274  cullMask &= ~(unsigned int)NODESET_TLSDOMES;
275  }
276  if (!myVisualizationSettings->show3DTLSLinkMarkers) {
277  cullMask &= ~(unsigned int)NODESET_TLSLINKMARKERS;
278  }
279  if (!myVisualizationSettings->generate3DTLSModels) {
280  cullMask &= ~(unsigned int)NODESET_TLSMODELS;
281  }
282  myViewer->getCamera()->setCullMask(cullMask);
283  unsigned int hudCullMask = (myVisualizationSettings->show3DHeadUpDisplay) ? 0xFFFFFFFF : 0;
284  myHUD->setCullMask(hudCullMask);
285 }
286 
287 
288 Position
289 GUIOSGView::getPositionInformation() const {
290  Position pos;
291  getPositionAtCursor(myOSGNormalizedCursorX, myOSGNormalizedCursorY, pos);
292  return pos;
293 }
294 
295 
296 bool
297 GUIOSGView::is3DView() const {
298  return true;
299 }
300 
301 
302 void
303 GUIOSGView::buildViewToolBars(GUIGlChildWindow* v) {
304  // build coloring tools
305  {
306  const std::vector<std::string>& names = gSchemeStorage.getNames();
307  for (std::vector<std::string>::const_iterator i = names.begin(); i != names.end(); ++i) {
308  v->getColoringSchemesCombo()->appendIconItem(i->c_str());
309  if ((*i) == myVisualizationSettings->name) {
311  }
312  }
313  }
314  // for junctions
316  "Locate Junction", "Locate a junction within the network.", "",
319  // for edges
321  "Locate Street", "Locate a street within the network.", "",
324  // for vehicles
326  "Locate Vehicle", "Locate a vehicle within the network.", "",
329  // for persons
331  "Locate Person", "Locate a person within the network.", "",
334  // for containers
336  "Locate Container", "Locate a container within the network.", "",
339  // for tls
341  "Locate TLS", "Locate a tls within the network.", "",
344  // for additional stuff
346  "Locate Additional", "Locate an additional structure within the network.", "",
349  // for pois
351  "Locate POI", "Locate a POI within the network.", "",
354  // for polygons
356  "Locate Polygon", "Locate a Polygon within the network.", "",
359 }
360 
361 
362 void
363 GUIOSGView::resize(int w, int h) {
364  GUISUMOAbstractView::resize(w, h);
365  updateHUDPosition(w, h);
366 }
367 
368 
369 void
370 GUIOSGView::position(int x, int y, int w, int h) {
371  GUISUMOAbstractView::position(x, y, w, h);
372  updateHUDPosition(w, h);
373 }
374 
375 
376 void
377 GUIOSGView::updateHUDPosition(int w, int h) {
378  // keep the HUD text in the left top corner
379  myHUD->setProjectionMatrixAsOrtho2D(0, w, 0, h);
380  myText->setPosition(osg::Vec3d(0., static_cast<double>(height), 0.));
381 }
382 
383 
384 void
385 GUIOSGView::updateHUDText(const std::string text) {
386  myText->setText(text, osgText::String::ENCODING_UTF8);
387 }
388 
389 
390 void
391 GUIOSGView::recenterView() {
392  stopTrack();
393  Position center = myGrid->getCenter();
394  double radius = std::max(myGrid->xmax() - myGrid->xmin(), myGrid->ymax() - myGrid->ymin());
395  myChanger->centerTo(center, radius);
396 }
397 
398 
399 bool
400 GUIOSGView::setColorScheme(const std::string& name) {
401  if (!gSchemeStorage.contains(name)) {
402  return false;
403  }
404  if (myGUIDialogViewSettings != 0) {
405  if (myGUIDialogViewSettings->getCurrentScheme() != name) {
406  myGUIDialogViewSettings->setCurrentScheme(name);
407  }
408  }
409  myVisualizationSettings = &gSchemeStorage.get(name.c_str());
410  myVisualizationSettings->gaming = myApp->isGaming();
411  adoptViewSettings();
412  update();
413  return true;
414 }
415 
416 
417 long
418 GUIOSGView::onPaint(FXObject*, FXSelector, void*) {
419  if (!isEnabled()) {
420  return 1;
421  }
422  myDecalsLockMutex.lock();
423  for (GUISUMOAbstractView::Decal& d : myDecals) {
424  if (!d.initialised && d.filename.length() > 0) {
425  if (d.filename.length() == 6 && d.filename.substr(0, 5) == "light") {
426  GUIOSGBuilder::buildLight(d, *myRoot);
427  } else if (d.filename.length() > 3 && d.filename.substr(0, 3) == "tl:") {
428  const int linkStringIdx = (int)d.filename.find(':', 3);
429  GUINet* net = (GUINet*) MSNet::getInstance();
430  try {
431  const std::string tlLogic = d.filename.substr(3, linkStringIdx - 3);
432  MSTLLogicControl::TLSLogicVariants& vars = net->getTLSControl().get(tlLogic);
433  const int linkIdx = StringUtils::toInt(d.filename.substr(linkStringIdx + 1));
434  if (linkIdx < 0 || linkIdx >= static_cast<int>(vars.getActive()->getLinks().size())) {
435  throw NumberFormatException("");
436  }
437  const MSLink* const link = vars.getActive()->getLinksAt(linkIdx)[0];
438  osg::Group* tlNode = GUIOSGBuilder::getTrafficLight(d, vars, link, myGreenLight, myYellowLight, myRedLight, myRedYellowLight, myPoleBase, true, 0.5);
439  tlNode->setName("tlLogic:" + tlLogic);
440  myRoot->addChild(tlNode);
441  } catch (NumberFormatException&) {
442  WRITE_ERRORF(TL("Invalid link index in '%'."), d.filename);
443  } catch (InvalidArgument&) {
444  WRITE_ERRORF(TL("Unknown traffic light in '%'."), d.filename);
445  }
446  } else {
447  GUIOSGBuilder::buildDecal(d, *myRoot);
448  }
449  d.initialised = true;
450  }
451  }
452  myDecalsLockMutex.unlock();
453 
454  // reset active flag
455  for (auto& item : myVehicles) {
456  item.second.active = false;
457  }
458 
459  GUINet* net = static_cast<GUINet*>(MSNet::getInstance());
460  // build edges
461  for (const MSEdge* e : net->getEdgeControl().getEdges()) {
462  for (const MSLane* l : e->getLanes()) {
463  const MSLane::VehCont& vehicles = l->getVehiclesSecure();
464  for (MSVehicle* msVeh : vehicles) {
465  GUIVehicle* veh = static_cast<GUIVehicle*>(msVeh);
466  if (!(veh->isOnRoad() || veh->isParking() || veh->wasRemoteControlled())) {
467  continue;
468  }
469  auto itVeh = myVehicles.find(veh);
470  if (itVeh == myVehicles.end()) {
471  myVehicles[veh] = GUIOSGBuilder::buildMovable(veh->getVehicleType());
472  myRoot->addChild(myVehicles[veh].pos);
473  myVehicles[veh].pos->setName("vehicle:" + veh->getID());
474  veh->setNode(myVehicles[veh].pos);
475  } else {
476  itVeh->second.active = true;
477  }
478  osg::PositionAttitudeTransform* n = myVehicles[veh].pos;
479  n->setPosition(osg::Vec3d(veh->getPosition().x(), veh->getPosition().y(), veh->getPosition().z()));
480  const double dir = veh->getAngle() + M_PI / 2.;
481  const double slope = -veh->getSlope();
482  n->setAttitude(osg::Quat(osg::DegreesToRadians(slope), osg::Vec3(1, 0, 0),
483  0, osg::Vec3(0, 1, 0),
484  dir, osg::Vec3(0, 0, 1)));
485  /*
486  osg::ref_ptr<osg::AnimationPath> path = new osg::AnimationPath;
487  // path->setLoopMode( osg::AnimationPath::NO_LOOPING );
488  osg::AnimationPath::ControlPoint pointA(n->getPosition(), n->getAttitude());
489  osg::AnimationPath::ControlPoint pointB(osg::Vec3(veh->getPosition().x(), veh->getPosition().y(), veh->getPosition().z()),
490  osg::Quat(dir, osg::Vec3(0, 0, 1)) *
491  osg::Quat(osg::DegreesToRadians(slope), osg::Vec3(0, 1, 0)));
492  path->insert(0.0f, pointA);
493  path->insert(0.5f, pointB);
494  n->setUpdateCallback(new osg::AnimationPathCallback(path));
495  */
496  RGBColor col;
497 
498  if (!GUIBaseVehicle::setFunctionalColor(myVisualizationSettings->vehicleColorer.getActive(), veh, col)) {
499  col = myVisualizationSettings->vehicleColorer.getScheme().getColor(veh->getColorValue(*myVisualizationSettings, myVisualizationSettings->vehicleColorer.getActive()));
500  }
501  myVehicles[veh].mat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4d(col.red() / 255., col.green() / 255., col.blue() / 255., col.alpha() / 255.));
503  myVehicles[veh].lights->setValue(1, veh->signalSet(MSVehicle::VEH_SIGNAL_BLINKER_LEFT | MSVehicle::VEH_SIGNAL_BLINKER_EMERGENCY));
504  myVehicles[veh].lights->setValue(2, veh->signalSet(MSVehicle::VEH_SIGNAL_BRAKELIGHT));
505  }
506  l->releaseVehicles();
507  }
508  }
509  // remove inactive
510  for (auto veh = myVehicles.begin(); veh != myVehicles.end();) {
511  if (!veh->second.active) {
512  removeVeh((veh++)->first);
513  } else {
514  ++veh;
515  }
516  }
517 
519  if (now != myLastUpdate || (myGUIDialogViewSettings != 0 && myGUIDialogViewSettings->shown())) {
520  GUINet::getGUIInstance()->updateColor(*myVisualizationSettings);
521  }
522  if (now != myLastUpdate && myTracked != 0) {
523  osg::Vec3d lookFrom, lookAt, up;
524  lookAt[0] = myTracked->getPosition().x();
525  lookAt[1] = myTracked->getPosition().y();
526  lookAt[2] = myTracked->getPosition().z();
527  const double angle = myTracked->getAngle();
528  lookFrom[0] = lookAt[0] + 50. * cos(angle);
529  lookFrom[1] = lookAt[1] + 50. * sin(angle);
530  lookFrom[2] = lookAt[2] + 10.;
531  osg::Matrix m;
532  m.makeLookAt(lookFrom, lookAt, osg::Z_AXIS);
533  myViewer->getCameraManipulator()->setByInverseMatrix(m);
534  }
535 
536  // reset active flag
537  for (auto& item : myPersons) {
538  item.second.active = false;
539  }
540 
541  for (const MSEdge* e : net->getEdgeControl().getEdges()) {
542  const GUIEdge* ge = static_cast<const GUIEdge*>(e);
543  const std::set<MSTransportable*, ComparatorNumericalIdLess>& persons = ge->getPersonsSecure();
544  for (auto person : persons) {
545  if (person->hasArrived() || !person->hasDeparted()) {
546  //std::cout << SIMTIME << " person " << person->getID() << " is loaded but arrived\n";
547  continue;
548  }
549  auto itPers = myPersons.find(person);
550  if (itPers == myPersons.end()) {
551  myPersons[person] = GUIOSGBuilder::buildMovable(person->getVehicleType());
552  myRoot->addChild(myPersons[person].pos);
553  } else {
554  itPers->second.active = true;
555  }
556  osg::PositionAttitudeTransform* n = myPersons[person].pos;
557  const Position pos = person->getPosition();
558  n->setPosition(osg::Vec3d(pos.x(), pos.y(), pos.z()));
559  const double dir = person->getAngle() + M_PI / 2.;
560  n->setAttitude(osg::Quat(dir, osg::Vec3d(0, 0, 1)));
561 
562  RGBColor col;
563  GUIPerson* actualPerson = dynamic_cast<GUIPerson*>(person);
564  if (!GUIPerson::setFunctionalColor(myVisualizationSettings->personColorer.getActive(), actualPerson, col)) {
565  col = myVisualizationSettings->personColorer.getScheme().getColor(actualPerson->getColorValue(*myVisualizationSettings, myVisualizationSettings->vehicleColorer.getActive()));
566  }
567  myPersons[person].mat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4d(col.red() / 255., col.green() / 255., col.blue() / 255., col.alpha() / 255.));
568  }
569  ge->releasePersons();
570  }
571 
572  // remove inactive
573  for (auto person = myPersons.begin(); person != myPersons.end();) {
574  if (!person->second.active) {
575  removeTransportable((person++)->first);
576  } else {
577  ++person;
578  }
579  }
580 
581  if (myAdapter->makeCurrent()) {
582  myViewer->frame();
583  makeNonCurrent();
584  }
585  myLastUpdate = now;
586  return 1;
587 }
588 
589 
590 void
591 GUIOSGView::removeVeh(MSVehicle* veh) {
592  if (myTracked == veh) {
593  stopTrack();
594  }
595  std::map<MSVehicle*, OSGMovable>::iterator i = myVehicles.find(veh);
596  if (i != myVehicles.end()) {
597  myRoot->removeChild(i->second.pos);
598  myVehicles.erase(i);
599  }
600 }
601 
602 
603 void
604 GUIOSGView::removeTransportable(MSTransportable* t) {
605  std::map<MSTransportable*, OSGMovable>::iterator i = myPersons.find(t);
606  if (i != myPersons.end()) {
607  myRoot->removeChild(i->second.pos);
608  myPersons.erase(i);
609  }
610 }
611 
612 
613 void GUIOSGView::updateViewportValues() {
614  osg::Vec3d lookFrom, lookAt, up;
615  myViewer->getCameraManipulator()->getInverseMatrix().getLookAt(lookFrom, lookAt, up);
616  myGUIDialogEditViewport->setValues(Position(lookFrom[0], lookFrom[1], lookFrom[2]),
617  Position(lookAt[0], lookAt[1], lookAt[2]), calculateRotation(lookFrom, lookAt, up));
618 }
619 
620 
621 void
622 GUIOSGView::showViewportEditor() {
623  getViewportEditor(); // make sure it exists;
624  osg::Vec3d lookFrom, lookAt, up;
625  myViewer->getCameraManipulator()->getInverseMatrix().getLookAt(lookFrom, lookAt, up);
626  Position from(lookFrom[0], lookFrom[1], lookFrom[2]), at(lookAt[0], lookAt[1], lookAt[2]);
627  myGUIDialogEditViewport->setOldValues(from, at, calculateRotation(lookFrom, lookAt, up));
628  myGUIDialogEditViewport->setZoomValue(100);
629  myGUIDialogEditViewport->show();
630 }
631 
632 
633 void
634 GUIOSGView::setViewportFromToRot(const Position& lookFrom, const Position& lookAt, double rotation) {
635  osg::Vec3d lookFromOSG, lookAtOSG, up;
636  lookFromOSG[0] = lookFrom.x();
637  lookFromOSG[1] = lookFrom.y();
638  lookFromOSG[2] = lookFrom.z();
639  lookAtOSG[0] = lookAt.x();
640  lookAtOSG[1] = lookAt.y();
641  lookAtOSG[2] = lookAt.z();
642 
643  osg::Vec3d viewAxis, viewUp, orthogonal, normal;
644  viewAxis = lookFromOSG - lookAtOSG;
645  viewAxis.normalize();
646  viewUp = (viewAxis[0] + viewAxis[1] == 0.) ? osg::Vec3d(0., 1., 0.) : osg::Vec3d(0., 0., 1.); // check for parallel vectors
647  orthogonal = viewUp ^ viewAxis;
648  orthogonal.normalize();
649  normal = viewAxis ^ orthogonal;
650 
651  rotation = std::fmod(rotation, 360.);
652  if (rotation < 0) {
653  rotation += 360.;
654  }
655  myChanger->setRotation(rotation);
656  double angle = DEG2RAD(rotation);
657  up = normal * cos(angle) - orthogonal * sin(angle);
658  up.normalize();
659 
660  double zoom = (myGUIDialogEditViewport != nullptr) ? myGUIDialogEditViewport->getZoomValue() : 100.;
661  lookFromOSG = lookFromOSG + viewAxis * (100. - zoom);
662  lookAtOSG = lookFromOSG - viewAxis;
663  myViewer->getCameraManipulator()->setHomePosition(lookFromOSG, lookAtOSG, up);
664  myViewer->home();
665 }
666 
667 
668 void
669 GUIOSGView::copyViewportTo(GUISUMOAbstractView* view) {
670  osg::Vec3d lookFrom, lookAt, up;
671  myViewer->getCameraManipulator()->getHomePosition(lookFrom, lookAt, up);
672  view->setViewportFromToRot(Position(lookFrom[0], lookFrom[1], lookFrom[2]),
673  Position(lookAt[0], lookAt[1], lookAt[2]), 0);
674 }
675 
676 
677 void
678 GUIOSGView::startTrack(int id) {
679  if (myTracked == 0 || (int)myTracked->getGlID() != id) {
680  myTracked = 0;
682  for (; it != MSNet::getInstance()->getVehicleControl().loadedVehEnd(); it++) {
683  GUIVehicle* veh = (GUIVehicle*)(*it).second;
684  if ((int)veh->getGlID() == id) {
685  if (!veh->isOnRoad() || myVehicles.find(veh) == myVehicles.end()) {
686  return;
687  }
688  myTracked = veh;
689  break;
690  }
691  }
692  if (myTracked != 0) {
693  osg::Vec3d lookFrom, lookAt, up;
694  lookAt[0] = myTracked->getPosition().x();
695  lookAt[1] = myTracked->getPosition().y();
696  lookAt[2] = myTracked->getPosition().z();
697  lookFrom[0] = lookAt[0] + 50.;
698  lookFrom[1] = lookAt[1] + 50.;
699  lookFrom[2] = lookAt[2] + 10.;
700  osg::Matrix m;
701  m.makeLookAt(lookFrom, lookAt, osg::Z_AXIS);
702  myViewer->getCameraManipulator()->setByInverseMatrix(m);
703  }
704  }
705 }
706 
707 
708 void
709 GUIOSGView::stopTrack() {
710  myTracked = 0;
711 }
712 
713 
714 GUIGlID
715 GUIOSGView::getTrackedID() const {
716  return myTracked == 0 ? GUIGlObject::INVALID_ID : myTracked->getGlID();
717 }
718 
719 
720 void
721 GUIOSGView::onGamingClick(Position pos) {
723  const MSTrafficLightLogic* minTll = nullptr;
724  double minDist = std::numeric_limits<double>::infinity();
725  for (const MSTrafficLightLogic* const tll : tlsControl.getAllLogics()) {
726  if (tlsControl.isActive(tll)) {
727  // get the links
728  const MSTrafficLightLogic::LaneVector& lanes = tll->getLanesAt(0);
729  if (lanes.size() > 0) {
730  const Position& endPos = lanes[0]->getShape().back();
731  if (endPos.distanceTo(pos) < minDist) {
732  minDist = endPos.distanceTo(pos);
733  minTll = tll;
734  }
735  }
736  }
737  }
738  if (minTll != 0) {
739  const MSTLLogicControl::TLSLogicVariants& vars = tlsControl.get(minTll->getID());
740  const std::vector<MSTrafficLightLogic*> logics = vars.getAllLogics();
741  if (logics.size() > 1) {
743  for (int i = 0; i < (int)logics.size() - 1; i++) {
744  if (minTll->getProgramID() == logics[i]->getProgramID()) {
745  l = (MSSimpleTrafficLightLogic*) logics[i + 1];
746  tlsControl.switchTo(minTll->getID(), l->getProgramID());
747  }
748  }
749  if (l == logics[0]) {
750  tlsControl.switchTo(minTll->getID(), l->getProgramID());
751  }
753  update();
754  }
755  }
756 }
757 
758 
759 SUMOTime
760 GUIOSGView::getCurrentTimeStep() const {
762 }
763 
764 
765 long GUIOSGView::onConfigure(FXObject* sender, FXSelector sel, void* ptr) {
766  // update the window dimensions, in case the window has been resized.
767  const int w = getWidth();
768  const int h = getHeight();
769  if (w > 0 && h > 0) {
770  myAdapter->getEventQueue()->windowResize(0, 0, w, h);
771  myAdapter->resized(0, 0, w, h);
772  updateHUDPosition(w, h);
773  }
774  return FXGLCanvas::onConfigure(sender, sel, ptr);
775 }
776 
777 
778 long GUIOSGView::onKeyPress(FXObject* sender, FXSelector sel, void* ptr) {
779  int key = ((FXEvent*)ptr)->code;
780  myAdapter->getEventQueue()->keyPress(key);
781  // leave key handling for some cases to OSG
782  if (key == FX::KEY_f || key == FX::KEY_Left || key == FX::KEY_Right || key == FX::KEY_Up || key == FX::KEY_Down) {
783  return 1;
784  }
785  return FXGLCanvas::onKeyPress(sender, sel, ptr);
786 }
787 
788 
789 long GUIOSGView::onKeyRelease(FXObject* sender, FXSelector sel, void* ptr) {
790  int key = ((FXEvent*)ptr)->code;
791  myAdapter->getEventQueue()->keyRelease(key);
792  // leave key handling for some cases to OSG
793  if (key == FX::KEY_f || key == FX::KEY_Left || key == FX::KEY_Right || key == FX::KEY_Up || key == FX::KEY_Down) {
794  return 1;
795  }
796  return FXGLCanvas::onKeyRelease(sender, sel, ptr);
797 }
798 
799 
800 long GUIOSGView::onLeftBtnPress(FXObject* sender, FXSelector sel, void* ptr) {
801  handle(this, FXSEL(SEL_FOCUS_SELF, 0), ptr);
802 
803  FXEvent* event = (FXEvent*)ptr;
804  myAdapter->getEventQueue()->mouseButtonPress((float)event->click_x, (float)event->click_y, 1);
805  if (myApp->isGaming()) {
806  onGamingClick(getPositionInformation());
807  }
808 
809  return FXGLCanvas::onLeftBtnPress(sender, sel, ptr);
810 }
811 
812 
813 long GUIOSGView::onLeftBtnRelease(FXObject* sender, FXSelector sel, void* ptr) {
814  FXEvent* event = (FXEvent*)ptr;
815  myAdapter->getEventQueue()->mouseButtonRelease((float)event->click_x, (float)event->click_y, 1);
816  myChanger->onLeftBtnRelease(ptr);
817  return FXGLCanvas::onLeftBtnRelease(sender, sel, ptr);
818 }
819 
820 
821 long GUIOSGView::onMiddleBtnPress(FXObject* sender, FXSelector sel, void* ptr) {
822  handle(this, FXSEL(SEL_FOCUS_SELF, 0), ptr);
823 
824  FXEvent* event = (FXEvent*)ptr;
825  myAdapter->getEventQueue()->mouseButtonPress((float)event->click_x, (float)event->click_y, 2);
826 
827  return FXGLCanvas::onMiddleBtnPress(sender, sel, ptr);
828 }
829 
830 
831 long GUIOSGView::onMiddleBtnRelease(FXObject* sender, FXSelector sel, void* ptr) {
832  FXEvent* event = (FXEvent*)ptr;
833  myAdapter->getEventQueue()->mouseButtonRelease((float)event->click_x, (float)event->click_y, 2);
834  myChanger->onMiddleBtnRelease(ptr);
835  return FXGLCanvas::onMiddleBtnRelease(sender, sel, ptr);
836 }
837 
838 
839 long GUIOSGView::onRightBtnPress(FXObject* sender, FXSelector sel, void* ptr) {
840  handle(this, FXSEL(SEL_FOCUS_SELF, 0), ptr);
841 
842  FXEvent* event = (FXEvent*)ptr;
843  myAdapter->getEventQueue()->mouseButtonPress((float)event->click_x, (float)event->click_y, 3);
844 
845  return FXGLCanvas::onRightBtnPress(sender, sel, ptr);
846 }
847 
848 
849 long GUIOSGView::onRightBtnRelease(FXObject* sender, FXSelector sel, void* ptr) {
850  FXEvent* event = (FXEvent*)ptr;
851  myAdapter->getEventQueue()->mouseButtonRelease((float)event->click_x, (float)event->click_y, 3);
852  myChanger->onRightBtnRelease(ptr);
853  return FXGLCanvas::onRightBtnRelease(sender, sel, ptr);
854 }
855 
856 
857 long
858 GUIOSGView::onMouseMove(FXObject* sender, FXSelector sel, void* ptr) {
859  // if popup exist but isn't shown, destroy it first
860  if (myPopup && !myPopup->shown()) {
861  destroyPopup();
862  }
863 
864  FXEvent* event = (FXEvent*)ptr;
865  osgGA::GUIEventAdapter* ea = myAdapter->getEventQueue()->mouseMotion((float)event->win_x, (float)event->win_y);
866  setWindowCursorPosition(ea->getXnormalized(), ea->getYnormalized());
867  if (myGUIDialogEditViewport != nullptr && myGUIDialogEditViewport->shown()) {
868  updateViewportValues();
869  }
870  updatePositionInformation();
871  return FXGLCanvas::onMotion(sender, sel, ptr);
872 }
873 
874 
875 long
876 GUIOSGView::onIdle(FXObject* /* sender */, FXSelector /* sel */, void*) {
877  forceRefresh();
878  update();
879  getApp()->addChore(this, MID_CHORE);
880  return 1;
881 }
882 
883 
884 long
885 GUIOSGView::onCmdCloseLane(FXObject*, FXSelector, void*) {
886  GUILane* lane = getLaneUnderCursor();
887  if (lane != nullptr) {
888  lane->closeTraffic();
890  GUINet::getGUIInstance()->updateColor(*myVisualizationSettings);
891  update();
892  }
893  return 1;
894 }
895 
896 
897 long
898 GUIOSGView::onCmdCloseEdge(FXObject*, FXSelector, void*) {
899  GUILane* lane = getLaneUnderCursor();
900  if (lane != nullptr) {
901  dynamic_cast<GUIEdge*>(&lane->getEdge())->closeTraffic(lane);
903  GUINet::getGUIInstance()->updateColor(*myVisualizationSettings);
904  update();
905  }
906  return 1;
907 }
908 
909 
910 long
911 GUIOSGView::onCmdAddRerouter(FXObject*, FXSelector, void*) {
912  GUILane* lane = getLaneUnderCursor();
913  if (lane != nullptr) {
914  dynamic_cast<GUIEdge*>(&lane->getEdge())->addRerouter();
916  update();
917  }
918  return 1;
919 }
920 
921 
922 long
923 GUIOSGView::onCmdShowReachability(FXObject* menu, FXSelector selector, void*) {
924  GUILane* lane = getLaneUnderCursor();
925  if (lane != nullptr) {
926  // reset
927  GUIViewTraffic::showLaneReachability(lane, menu, selector);
928  // switch to 'color by selection' unless coloring 'by reachability'
929  if (myVisualizationSettings->laneColorer.getActive() != 36) {
930  myVisualizationSettings->laneColorer.setActive(1);
931  GUINet::getGUIInstance()->updateColor(*myVisualizationSettings);
932  }
933  update();
934  }
935  return 1;
936 }
937 
938 
939 long
940 GUIOSGView::onVisualizationChange(FXObject*, FXSelector, void*) {
941  adoptViewSettings();
942  return 1;
943 }
944 
945 
946 void
947 GUIOSGView::setWindowCursorPosition(float x, float y) {
948  myOSGNormalizedCursorX = x;
949  myOSGNormalizedCursorY = y;
950 }
951 
952 
953 double
954 GUIOSGView::calculateRotation(const osg::Vec3d& lookFrom, const osg::Vec3d& lookAt, const osg::Vec3d& up) {
955  osg::Vec3d viewAxis, viewUp, orthogonal, normal;
956  viewAxis = lookFrom - lookAt;
957  viewAxis.normalize();
958  viewUp = (abs(viewAxis[0]) + abs(viewAxis[1]) == 0.) ? osg::Y_AXIS : osg::Z_AXIS; // check for parallel vectors
959  orthogonal = viewUp ^ viewAxis;
960  orthogonal.normalize();
961  normal = viewAxis ^ orthogonal;
962  double angle = atan2((normal ^ up).length() / (normal.length() * up.length()), (normal * up) / (normal.length() * up.length()));
963  if (angle < 0) {
964  angle += M_PI;
965  }
966  return RAD2DEG(angle);
967 }
968 
969 
970 void
971 GUIOSGView::updatePositionInformation() const {
972  Position pos;
973  if (getPositionAtCursor(myOSGNormalizedCursorX, myOSGNormalizedCursorY, pos)) {
974  myApp->getCartesianLabel()->setText(("x:" + toString(pos.x()) + ", y:" + toString(pos.y())).c_str());
975  // set geo position
977  if (GeoConvHelper::getFinal().usingGeoProjection()) {
978  myApp->getGeoLabel()->setText(("lat:" + toString(pos.y(), gPrecisionGeo) + ", lon:" + toString(pos.x(), gPrecisionGeo)).c_str());
979  } else {
980  myApp->getGeoLabel()->setText(TL("(No projection defined)"));
981  }
982  } else {
983  // set placeholder
984  myApp->getCartesianLabel()->setText(TL("N/A"));
985  myApp->getGeoLabel()->setText(TL("N/A"));
986  }
987 }
988 
989 
990 bool
991 GUIOSGView::getPositionAtCursor(float xNorm, float yNorm, Position& pos) const {
992  // only reasonable if view axis points to the ground (not parallel to the ground or in the sky)
993  osg::Vec3d lookFrom, lookAt, up, viewAxis;
994  myViewer->getCameraManipulator()->getInverseMatrix().getLookAt(lookFrom, lookAt, up);
995  if ((lookAt - lookFrom).z() >= 0.) {
996  // looking to the sky makes position at ground pointless
997  return false;
998  }
999  // solve linear equation of ray crossing the ground plane
1000  osg::Matrixd iVP = osg::Matrixd::inverse(myViewer->getCamera()->getViewMatrix() * myViewer->getCamera()->getProjectionMatrix());
1001  osg::Vec3 nearPoint = osg::Vec3(xNorm, yNorm, 0.0f) * iVP;
1002  osg::Vec3 farPoint = osg::Vec3(xNorm, yNorm, 1.0f) * iVP;
1003  osg::Vec3 ray = farPoint - nearPoint;
1004  osg::Vec3 groundPos = nearPoint - ray * nearPoint.z() / ray.z();
1005  pos.setx(groundPos.x());
1006  pos.sety(groundPos.y());
1007  pos.setz(0.);
1008  return true;
1009 }
1010 
1011 
1012 std::vector<GUIGlObject*>
1013 GUIOSGView::getGUIGlObjectsUnderCursor() {
1014  std::vector<GUIGlObject*> result;
1015  osgUtil::LineSegmentIntersector::Intersections intersections;
1016  if (myViewer->computeIntersections(myViewer->getCamera(), osgUtil::Intersector::CoordinateFrame::PROJECTION, myOSGNormalizedCursorX, myOSGNormalizedCursorY, intersections)) {
1017  for (auto intersection : intersections) {
1018  if (!intersection.nodePath.empty()) {
1019  // the object is identified by the ID stored in OSG
1020  for (osg::Node* currentNode : intersection.nodePath) {
1021  if (currentNode->getName().length() > 0 && currentNode->getName().find(":") != std::string::npos) {
1022  const std::string objID = currentNode->getName();
1024  // check that GUIGlObject exist
1025  if (o == nullptr) {
1026  continue;
1027  }
1028  // check that GUIGlObject isn't the network
1029  if (o->getGlID() == 0) {
1030  continue;
1031  }
1032  result.push_back(o);
1033  // unblock object
1035  }
1036  }
1037  }
1038  }
1039  }
1040  return result;
1041 }
1042 
1043 
1044 GUILane*
1045 GUIOSGView::getLaneUnderCursor() {
1046  std::vector<GUIGlObject*> objects = getGUIGlObjectsUnderCursor();
1047  if (objects.size() > 0) {
1048  return dynamic_cast<GUILane*>(objects[0]);
1049  }
1050  return nullptr;
1051 }
1052 
1053 
1054 void
1055 GUIOSGView::zoom2Pos(Position& camera, Position& lookAt, double zoom) {
1056  osg::Vec3d lookFromOSG, lookAtOSG, viewAxis, up;
1057  myViewer->getCameraManipulator()->getInverseMatrix().getLookAt(lookFromOSG, lookAtOSG, up);
1058  lookFromOSG[0] = camera.x();
1059  lookFromOSG[1] = camera.y();
1060  lookFromOSG[2] = camera.z();
1061  lookAtOSG[0] = lookAt.x();
1062  lookAtOSG[1] = lookAt.y();
1063  lookAtOSG[2] = lookAt.z();
1064  viewAxis = lookAtOSG - lookFromOSG;
1065  viewAxis.normalize();
1066 
1067  // compute new camera and lookAt pos
1068  osg::Vec3d cameraUpdate = lookFromOSG + viewAxis * (zoom - 100.);
1069  osg::Vec3d lookAtUpdate = cameraUpdate + viewAxis;
1070 
1071  myViewer->getCameraManipulator()->setHomePosition(cameraUpdate, lookAtUpdate, up);
1072  myViewer->home();
1073 }
1074 
1075 
1076 osg::Vec4d
1077 GUIOSGView::toOSGColorVector(RGBColor c, bool useAlpha) {
1078  return osg::Vec4d(c.red() / 255., c.green() / 255., c.blue() / 255., (useAlpha) ? c.alpha() / 255. : 1.);
1079 }
1080 
1081 
1082 GUIOSGView::FXOSGAdapter::FXOSGAdapter(GUISUMOAbstractView* parent, FXCursor* cursor)
1083  : myParent(parent), myOldCursor(cursor) {
1084  _traits = new GraphicsContext::Traits();
1085  _traits->x = 0;
1086  _traits->y = 0;
1087  _traits->width = parent->getWidth();
1088  _traits->height = parent->getHeight();
1089  _traits->windowDecoration = false;
1090  _traits->doubleBuffer = true;
1091  _traits->sharedContext = 0;
1092  if (valid()) {
1093  setState(new osg::State());
1094  getState()->setGraphicsContext(this);
1095 #ifdef DEBUG_GLERRORS
1096  getState()->setCheckForGLErrors(osg::State::ONCE_PER_ATTRIBUTE);
1097  std::cout << "OSG getCheckForGLErrors " << getState()->getCheckForGLErrors() << std::endl;
1098 #endif
1099  if (_traits.valid() && _traits->sharedContext != 0) {
1100  getState()->setContextID(_traits->sharedContext->getState()->getContextID());
1101  incrementContextIDUsageCount(getState()->getContextID());
1102  } else {
1103  getState()->setContextID(createNewContextID());
1104  }
1105  }
1106 }
1107 
1108 
1109 GUIOSGView::FXOSGAdapter::~FXOSGAdapter() {
1110  delete myOldCursor;
1111 }
1112 
1113 
1114 void
1115 GUIOSGView::FXOSGAdapter::grabFocus() {
1116  // focus this window
1117  myParent->setFocus();
1118 }
1119 
1120 
1121 void
1122 GUIOSGView::FXOSGAdapter::useCursor(bool cursorOn) {
1123  if (cursorOn) {
1124  myParent->setDefaultCursor(myOldCursor);
1125  } else {
1126  myParent->setDefaultCursor(NULL);
1127  }
1128 }
1129 
1130 
1131 bool
1132 GUIOSGView::FXOSGAdapter::makeCurrentImplementation() {
1133  myParent->makeCurrent();
1134  return true;
1135 }
1136 
1137 
1138 bool
1139 GUIOSGView::FXOSGAdapter::releaseContext() {
1140  myParent->makeNonCurrent();
1141  return true;
1142 }
1143 
1144 
1145 void
1146 GUIOSGView::FXOSGAdapter::swapBuffersImplementation() {
1147  myParent->swapBuffers();
1148 }
1149 
1150 
1151 bool
1152 GUIOSGView::PickHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& /* aa */) {
1153  if (ea.getEventType() == osgGA::GUIEventAdapter::DRAG) {
1154  myDrag = true;
1155  } else if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE && ea.getButton() == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) {
1156  if (!myDrag) {
1157  if (myParent->makeCurrent()) {
1158  std::vector<GUIGlObject*> objects = myParent->getGUIGlObjectsUnderCursor();
1159  if (objects.size() > 0) {
1160  myParent->openObjectDialog(objects);
1161  }
1162  myParent->makeNonCurrent();
1163  }
1164  }
1165  myDrag = false;
1166  }
1167  return false;
1168 }
1169 
1170 
1171 #endif
1172 
1173 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
@ MID_CHORE
chore
Definition: GUIAppEnum.h:413
@ MID_HOTKEY_SHIFT_O_LOCATEPOI
Locate poi - button.
Definition: GUIAppEnum.h:182
@ MID_HOTKEY_SHIFT_A_LOCATEADDITIONAL
Locate additional structure - button.
Definition: GUIAppEnum.h:172
@ MID_HOTKEY_SHIFT_C_LOCATECONTAINER
Locate container - button.
Definition: GUIAppEnum.h:174
@ MID_HOTKEY_SHIFT_V_LOCATEVEHICLE
Locate vehicle - button.
Definition: GUIAppEnum.h:192
@ MID_HOTKEY_SHIFT_L_LOCATEPOLY
Locate polygons - button.
Definition: GUIAppEnum.h:180
@ MID_HOTKEY_SHIFT_E_LOCATEEDGE
Locate edge - button.
Definition: GUIAppEnum.h:176
@ MID_HOTKEY_SHIFT_P_LOCATEPERSON
Locate person - button.
Definition: GUIAppEnum.h:184
@ MID_HOTKEY_SHIFT_J_LOCATEJUNCTION
Locate junction - button.
Definition: GUIAppEnum.h:178
@ MID_HOTKEY_SHIFT_T_LOCATETLS
Locate TLS - button.
Definition: GUIAppEnum.h:190
GUICompleteSchemeStorage gSchemeStorage
#define GUIDesignButtonPopup
checkable button placed in popup (for example, locate buttons)
Definition: GUIDesigns.h:118
FXDEFMAP(GUIDialog_AppSettings) GUIDialog_AppSettingsMap[]
unsigned int GUIGlID
Definition: GUIGlObject.h:43
@ LOCATEVEHICLE
@ LOCATEPERSON
@ LOCATECONTAINER
@ LOCATEJUNCTION
@ KEY_I
Definition: GUIShortcuts.h:78
@ KEY_f
Definition: GUIShortcuts.h:48
#define DEG2RAD(x)
Definition: GeomHelper.h:35
#define RAD2DEG(x)
Definition: GeomHelper.h:36
std::ostream & operator<<(std::ostream &out, MSDevice_SSM::EncounterType type)
Nicer output for EncounterType enum.
#define WRITE_ERRORF(...)
Definition: MsgHandler.h:305
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:304
#define TL(string)
Definition: MsgHandler.h:315
@ LINKSTATE_TL_REDYELLOW
The link has red light (must brake) but indicates upcoming green.
@ LINKSTATE_STOP
This is an uncontrolled, minor link, has to stop.
@ LINKSTATE_TL_YELLOW_MAJOR
The link has yellow light, may pass.
@ LINKSTATE_TL_GREEN_MAJOR
The link has green light, may pass.
@ LINKSTATE_TL_OFF_BLINKING
The link is controlled by a tls which is off and blinks, has to brake.
@ LINKSTATE_TL_YELLOW_MINOR
The link has yellow light, has to brake anyway.
@ LINKSTATE_TL_RED
The link has red light (must brake)
@ LINKSTATE_TL_GREEN_MINOR
The link has green light, has to brake.
@ LINKSTATE_TL_OFF_NOSIGNAL
The link is controlled by a tls which is off, not blinking, may pass.
int gPrecisionGeo
Definition: StdDefs.cpp:27
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
static bool isReadable(std::string path)
Checks whether the given file is readable.
Definition: FileHelpers.cpp:51
static bool setFunctionalColor(int activeScheme, const MSBaseVehicle *veh, RGBColor &col)
sets the color according to the current scheme index and some vehicle function
bool contains(const std::string &name) const
Returns the information whether a setting with the given name is stored.
GUIVisualizationSettings & get(const std::string &name)
Returns the named scheme.
const std::vector< std::string > & getNames() const
Returns a list of stored settings names.
static FXButton * buildFXButton(FXComposite *p, const std::string &text, const std::string &tip, const std::string &help, FXIcon *ic, FXObject *tgt, FXSelector sel, FXuint opts=BUTTON_NORMAL, FXint x=0, FXint y=0, FXint w=0, FXint h=0, FXint pl=DEFAULT_PAD, FXint pr=DEFAULT_PAD, FXint pt=DEFAULT_PAD, FXint pb=DEFAULT_PAD)
build button
Definition: GUIDesigns.cpp:128
A road/street connecting two junctions (gui-version)
Definition: GUIEdge.h:51
const std::set< MSTransportable *, ComparatorNumericalIdLess > & getPersonsSecure() const
Returns this edge's persons set; locks it for microsimulation.
Definition: GUIEdge.h:164
void releasePersons() const
Allows to use the container for microsimulation again.
Definition: GUIEdge.h:173
MFXComboBoxIcon * getColoringSchemesCombo()
return combobox with the current coloring schemes (standard, fastest standard, real world....
FXPopup * getLocatorPopup()
@ brief return a pointer to locator popup
static const GUIGlID INVALID_ID
Definition: GUIGlObject.h:72
GUIGlID getGlID() const
Returns the numerical id of the object.
Definition: GUIGlObject.h:104
void unblockObject(GUIGlID id)
Marks an object as unblocked.
GUIGlObject * getObjectBlocking(GUIGlID id) const
Returns the object from the container locking it.
static GUIGlObjectStorage gIDStorage
A single static instance of this class.
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
Representation of a lane in the micro simulation (gui-version)
Definition: GUILane.h:60
void closeTraffic(bool rebuildAllowed=true)
close this lane for traffic
Definition: GUILane.cpp:1560
A MSNet extended by some values for usage within the gui.
Definition: GUINet.h:82
static GUINet * getGUIInstance()
Returns the pointer to the unique instance of GUINet (singleton).
Definition: GUINet.cpp:572
double getColorValue(const GUIVisualizationSettings &s, int activeScheme) const override
gets the color value according to the current scheme index
Definition: GUIPerson.cpp:435
static bool setFunctionalColor(int activeScheme, const MSPerson *person, RGBColor &col)
sets the color according to the current scheme index and some vehicle function
Definition: GUIPerson.cpp:390
virtual void setViewportFromToRot(const Position &lookFrom, const Position &lookAt, double rotation)
applies the given viewport settings
A single child window which contains a view of the simulation area.
A MSVehicle extended by some values for usage within the gui.
Definition: GUIVehicle.h:51
double getAngle() const
Return current angle.
Definition: GUIVehicle.h:81
Position getPosition(const double offset=0) const
Return current position (x/y, cartesian)
Definition: GUIVehicle.h:71
double getColorValue(const GUIVisualizationSettings &s, int activeScheme) const
gets the color value according to the current scheme index
Definition: GUIVehicle.cpp:544
static long showLaneReachability(GUILane *lane, FXObject *, FXSelector)
bool gaming
whether the application is in gaming mode or not
void cartesian2geo(Position &cartesian) const
Converts the given cartesian (shifted) position to its geo (lat/long) representation.
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
long setCurrentItem(const FXint index, FXbool notify=FALSE)
Set the current item (index is zero-based)
FXint getNumItems() const
Return the number of items in the list.
FXint appendIconItem(const FXString &text, FXIcon *icon=nullptr, FXColor bgColor=FXRGB(255, 255, 255), void *ptr=nullptr)
append icon item in the last position
bool isParking() const
Returns whether the vehicle is parking.
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
const MSEdgeVector & getEdges() const
Returns loaded edges.
A road/street connecting two junctions.
Definition: MSEdge.h:77
Representation of a lane in the micro simulation.
Definition: MSLane.h:84
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:119
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:756
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:184
MSTLLogicControl & getTLSControl()
Returns the tls logics control.
Definition: MSNet.h:451
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:378
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:320
MSEdgeControl & getEdgeControl()
Returns the edge control.
Definition: MSNet.h:421
SUMOTime duration
The duration of the phase.
A fixed traffic light logic.
virtual void changeStepAndDuration(MSTLLogicControl &tlcontrol, SUMOTime simStep, int step, SUMOTime stepDuration) override
Changes the current phase and her duration.
const MSPhaseDefinition & getPhase(int givenstep) const override
Returns the definition of the phase from the given position within the plan.
Storage for all programs of a single tls.
std::vector< MSTrafficLightLogic * > getAllLogics() const
MSTrafficLightLogic * getActive() const
A class that stores and controls tls and switching of their programs.
std::vector< MSTrafficLightLogic * > getAllLogics() const
Returns a vector which contains all logics.
void switchTo(const std::string &id, const std::string &programID)
Switches the named (id) tls to the named (programID) program.
TLSLogicVariants & get(const std::string &id) const
Returns the variants of a named tls.
bool isActive(const MSTrafficLightLogic *tl) const
Returns whether the given tls program is the currently active for his tls.
The parent class for traffic light logics.
const LinkVector & getLinksAt(int i) const
Returns the list of links that are controlled by the signals at the given position.
std::vector< MSLane * > LaneVector
Definition of the list of arrival lanes subjected to this tls.
const LinkVectorVector & getLinks() const
Returns the list of lists of all affected links.
const std::string & getProgramID() const
Returns this tl-logic's id.
std::map< std::string, SUMOVehicle * >::const_iterator constVehIt
Definition of the internal vehicles map iterator.
constVehIt loadedVehBegin() const
Returns the begin of the internal vehicle map.
constVehIt loadedVehEnd() const
Returns the end of the internal vehicle map.
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:77
bool wasRemoteControlled(SUMOTime lookBack=DELTA_T) const
Returns the information whether the vehicle is fully controlled via TraCI within the lookBack time.
Definition: MSVehicle.cpp:7311
bool isOnRoad() const
Returns the information whether the vehicle is on a road (is simulated)
Definition: MSVehicle.h:608
bool signalSet(int which) const
Returns whether the given signal is on.
Definition: MSVehicle.h:1194
@ VEH_SIGNAL_BLINKER_RIGHT
Right blinker lights are switched on.
Definition: MSVehicle.h:1116
@ VEH_SIGNAL_BRAKELIGHT
The brake lights are on.
Definition: MSVehicle.h:1122
@ VEH_SIGNAL_BLINKER_LEFT
Left blinker lights are switched on.
Definition: MSVehicle.h:1118
@ VEH_SIGNAL_BLINKER_EMERGENCY
Blinker lights on both sides are switched on.
Definition: MSVehicle.h:1120
double getSlope() const
Returns the slope of the road at vehicle's position in degrees.
Definition: MSVehicle.cpp:1217
const std::string & getID() const
Returns the id.
Definition: Named.h:74
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
void setx(double x)
set position x
Definition: Position.h:70
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimensions
Definition: Position.h:266
double x() const
Returns the x-position.
Definition: Position.h:55
void setz(double z)
set position z
Definition: Position.h:80
double z() const
Returns the z-position.
Definition: Position.h:65
void sety(double y)
set position y
Definition: Position.h:75
double y() const
Returns the y-position.
Definition: Position.h:60
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
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 int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...
@ key
the parser read a key of a value in an object
#define M_PI
Definition: odrSpiral.cpp:45
A decal (an image) that can be shown.