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  cullMask ^= (-int(myVisualizationSettings->show3DTLSDomes) ^ cullMask) & (1UL << NODESET_TLSDOMES);
274  cullMask ^= (-int(myVisualizationSettings->show3DTLSLinkMarkers) ^ cullMask) & (1UL << NODESET_TLSLINKMARKERS);
275  cullMask ^= (-int(myVisualizationSettings->generate3DTLSModels) ^ cullMask) & (1UL << NODESET_TLSMODELS);
276  myViewer->getCamera()->setCullMask(cullMask);
277  unsigned int hudCullMask = (myVisualizationSettings->show3DHeadUpDisplay) ? 0xFFFFFFFF : 0;
278  myHUD->setCullMask(hudCullMask);
279 }
280 
281 
282 Position
283 GUIOSGView::getPositionInformation() const {
284  Position pos;
285  getPositionAtCursor(myOSGNormalizedCursorX, myOSGNormalizedCursorY, pos);
286  return pos;
287 }
288 
289 
290 bool
291 GUIOSGView::is3DView() const {
292  return true;
293 }
294 
295 
296 void
297 GUIOSGView::buildViewToolBars(GUIGlChildWindow* v) {
298  // build coloring tools
299  {
300  const std::vector<std::string>& names = gSchemeStorage.getNames();
301  for (std::vector<std::string>::const_iterator i = names.begin(); i != names.end(); ++i) {
302  v->getColoringSchemesCombo()->appendIconItem(i->c_str());
303  if ((*i) == myVisualizationSettings->name) {
305  }
306  }
307  }
308  // for junctions
310  "Locate Junction", "Locate a junction within the network.", "",
313  // for edges
315  "Locate Street", "Locate a street within the network.", "",
318  // for vehicles
320  "Locate Vehicle", "Locate a vehicle within the network.", "",
323  // for persons
325  "Locate Person", "Locate a person within the network.", "",
328  // for containers
330  "Locate Container", "Locate a container within the network.", "",
333  // for tls
335  "Locate TLS", "Locate a tls within the network.", "",
338  // for additional stuff
340  "Locate Additional", "Locate an additional structure within the network.", "",
343  // for pois
345  "Locate POI", "Locate a POI within the network.", "",
348  // for polygons
350  "Locate Polygon", "Locate a Polygon within the network.", "",
353 }
354 
355 
356 void
357 GUIOSGView::resize(int w, int h) {
358  GUISUMOAbstractView::resize(w, h);
359  updateHUDPosition(w, h);
360 }
361 
362 
363 void
364 GUIOSGView::position(int x, int y, int w, int h) {
365  GUISUMOAbstractView::position(x, y, w, h);
366  updateHUDPosition(w, h);
367 }
368 
369 
370 void
371 GUIOSGView::updateHUDPosition(int w, int h) {
372  // keep the HUD text in the left top corner
373  myHUD->setProjectionMatrixAsOrtho2D(0, w, 0, h);
374  myText->setPosition(osg::Vec3d(0., static_cast<double>(height), 0.));
375 }
376 
377 
378 void
379 GUIOSGView::updateHUDText(const std::string text) {
380  myText->setText(text, osgText::String::ENCODING_UTF8);
381 }
382 
383 
384 void
385 GUIOSGView::recenterView() {
386  stopTrack();
387  Position center = myGrid->getCenter();
388  double radius = std::max(myGrid->xmax() - myGrid->xmin(), myGrid->ymax() - myGrid->ymin());
389  myChanger->centerTo(center, radius);
390 }
391 
392 
393 bool
394 GUIOSGView::setColorScheme(const std::string& name) {
395  if (!gSchemeStorage.contains(name)) {
396  return false;
397  }
398  if (myGUIDialogViewSettings != 0) {
399  if (myGUIDialogViewSettings->getCurrentScheme() != name) {
400  myGUIDialogViewSettings->setCurrentScheme(name);
401  }
402  }
403  myVisualizationSettings = &gSchemeStorage.get(name.c_str());
404  myVisualizationSettings->gaming = myApp->isGaming();
405  adoptViewSettings();
406  update();
407  return true;
408 }
409 
410 
411 long
412 GUIOSGView::onPaint(FXObject*, FXSelector, void*) {
413  if (!isEnabled()) {
414  return 1;
415  }
416  myDecalsLockMutex.lock();
417  for (GUISUMOAbstractView::Decal& d : myDecals) {
418  if (!d.initialised && d.filename.length() > 0) {
419  if (d.filename.length() == 6 && d.filename.substr(0, 5) == "light") {
420  GUIOSGBuilder::buildLight(d, *myRoot);
421  } else if (d.filename.length() > 3 && d.filename.substr(0, 3) == "tl:") {
422  const int linkStringIdx = (int)d.filename.find(':', 3);
423  GUINet* net = (GUINet*) MSNet::getInstance();
424  try {
425  const std::string tlLogic = d.filename.substr(3, linkStringIdx - 3);
426  MSTLLogicControl::TLSLogicVariants& vars = net->getTLSControl().get(tlLogic);
427  const int linkIdx = StringUtils::toInt(d.filename.substr(linkStringIdx + 1));
428  if (linkIdx < 0 || linkIdx >= static_cast<int>(vars.getActive()->getLinks().size())) {
429  throw NumberFormatException("");
430  }
431  const MSLink* const link = vars.getActive()->getLinksAt(linkIdx)[0];
432  osg::Group* tlNode = GUIOSGBuilder::getTrafficLight(d, vars, link, myGreenLight, myYellowLight, myRedLight, myRedYellowLight, myPoleBase, true, 0.5);
433  tlNode->setName("tlLogic:" + tlLogic);
434  myRoot->addChild(tlNode);
435  } catch (NumberFormatException&) {
436  WRITE_ERRORF(TL("Invalid link index in '%'."), d.filename);
437  } catch (InvalidArgument&) {
438  WRITE_ERRORF(TL("Unknown traffic light in '%'."), d.filename);
439  }
440  } else {
441  GUIOSGBuilder::buildDecal(d, *myRoot);
442  }
443  d.initialised = true;
444  }
445  }
446  myDecalsLockMutex.unlock();
447 
448  // reset active flag
449  for (auto& item : myVehicles) {
450  item.second.active = false;
451  }
452 
453  GUINet* net = static_cast<GUINet*>(MSNet::getInstance());
454  // build edges
455  for (const MSEdge* e : net->getEdgeControl().getEdges()) {
456  for (const MSLane* l : e->getLanes()) {
457  const MSLane::VehCont& vehicles = l->getVehiclesSecure();
458  for (MSVehicle* msVeh : vehicles) {
459  GUIVehicle* veh = static_cast<GUIVehicle*>(msVeh);
460  if (!(veh->isOnRoad() || veh->isParking() || veh->wasRemoteControlled())) {
461  continue;
462  }
463  auto itVeh = myVehicles.find(veh);
464  if (itVeh == myVehicles.end()) {
465  myVehicles[veh] = GUIOSGBuilder::buildMovable(veh->getVehicleType());
466  myRoot->addChild(myVehicles[veh].pos);
467  myVehicles[veh].pos->setName("vehicle:" + veh->getID());
468  veh->setNode(myVehicles[veh].pos);
469  } else {
470  itVeh->second.active = true;
471  }
472  osg::PositionAttitudeTransform* n = myVehicles[veh].pos;
473  n->setPosition(osg::Vec3d(veh->getPosition().x(), veh->getPosition().y(), veh->getPosition().z()));
474  const double dir = veh->getAngle() + M_PI / 2.;
475  const double slope = -veh->getSlope();
476  n->setAttitude(osg::Quat(osg::DegreesToRadians(slope), osg::Vec3(1, 0, 0),
477  0, osg::Vec3(0, 1, 0),
478  dir, osg::Vec3(0, 0, 1)));
479  /*
480  osg::ref_ptr<osg::AnimationPath> path = new osg::AnimationPath;
481  // path->setLoopMode( osg::AnimationPath::NO_LOOPING );
482  osg::AnimationPath::ControlPoint pointA(n->getPosition(), n->getAttitude());
483  osg::AnimationPath::ControlPoint pointB(osg::Vec3(veh->getPosition().x(), veh->getPosition().y(), veh->getPosition().z()),
484  osg::Quat(dir, osg::Vec3(0, 0, 1)) *
485  osg::Quat(osg::DegreesToRadians(slope), osg::Vec3(0, 1, 0)));
486  path->insert(0.0f, pointA);
487  path->insert(0.5f, pointB);
488  n->setUpdateCallback(new osg::AnimationPathCallback(path));
489  */
490  RGBColor col;
491 
492  if (!GUIBaseVehicle::setFunctionalColor(myVisualizationSettings->vehicleColorer.getActive(), veh, col)) {
493  col = myVisualizationSettings->vehicleColorer.getScheme().getColor(veh->getColorValue(*myVisualizationSettings, myVisualizationSettings->vehicleColorer.getActive()));
494  }
495  myVehicles[veh].mat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4d(col.red() / 255., col.green() / 255., col.blue() / 255., col.alpha() / 255.));
497  myVehicles[veh].lights->setValue(1, veh->signalSet(MSVehicle::VEH_SIGNAL_BLINKER_LEFT | MSVehicle::VEH_SIGNAL_BLINKER_EMERGENCY));
498  myVehicles[veh].lights->setValue(2, veh->signalSet(MSVehicle::VEH_SIGNAL_BRAKELIGHT));
499  }
500  l->releaseVehicles();
501  }
502  }
503  // remove inactive
504  for (auto veh = myVehicles.begin(); veh != myVehicles.end();) {
505  if (!veh->second.active) {
506  removeVeh((veh++)->first);
507  } else {
508  ++veh;
509  }
510  }
511 
513  if (now != myLastUpdate || (myGUIDialogViewSettings != 0 && myGUIDialogViewSettings->shown())) {
514  GUINet::getGUIInstance()->updateColor(*myVisualizationSettings);
515  }
516  if (now != myLastUpdate && myTracked != 0) {
517  osg::Vec3d lookFrom, lookAt, up;
518  lookAt[0] = myTracked->getPosition().x();
519  lookAt[1] = myTracked->getPosition().y();
520  lookAt[2] = myTracked->getPosition().z();
521  const double angle = myTracked->getAngle();
522  lookFrom[0] = lookAt[0] + 50. * cos(angle);
523  lookFrom[1] = lookAt[1] + 50. * sin(angle);
524  lookFrom[2] = lookAt[2] + 10.;
525  osg::Matrix m;
526  m.makeLookAt(lookFrom, lookAt, osg::Z_AXIS);
527  myViewer->getCameraManipulator()->setByInverseMatrix(m);
528  }
529 
530  // reset active flag
531  for (auto& item : myPersons) {
532  item.second.active = false;
533  }
534 
535  for (const MSEdge* e : net->getEdgeControl().getEdges()) {
536  const GUIEdge* ge = static_cast<const GUIEdge*>(e);
537  const std::set<MSTransportable*, ComparatorNumericalIdLess>& persons = ge->getPersonsSecure();
538  for (auto person : persons) {
539  if (person->hasArrived() || !person->hasDeparted()) {
540  //std::cout << SIMTIME << " person " << person->getID() << " is loaded but arrived\n";
541  continue;
542  }
543  auto itPers = myPersons.find(person);
544  if (itPers == myPersons.end()) {
545  myPersons[person] = GUIOSGBuilder::buildMovable(person->getVehicleType());
546  myRoot->addChild(myPersons[person].pos);
547  } else {
548  itPers->second.active = true;
549  }
550  osg::PositionAttitudeTransform* n = myPersons[person].pos;
551  const Position pos = person->getPosition();
552  n->setPosition(osg::Vec3d(pos.x(), pos.y(), pos.z()));
553  const double dir = person->getAngle() + M_PI / 2.;
554  n->setAttitude(osg::Quat(dir, osg::Vec3d(0, 0, 1)));
555 
556  RGBColor col;
557  GUIPerson* actualPerson = dynamic_cast<GUIPerson*>(person);
558  if (!GUIPerson::setFunctionalColor(myVisualizationSettings->personColorer.getActive(), actualPerson, col)) {
559  col = myVisualizationSettings->personColorer.getScheme().getColor(actualPerson->getColorValue(*myVisualizationSettings, myVisualizationSettings->vehicleColorer.getActive()));
560  }
561  myPersons[person].mat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4d(col.red() / 255., col.green() / 255., col.blue() / 255., col.alpha() / 255.));
562  }
563  ge->releasePersons();
564  }
565 
566  // remove inactive
567  for (auto person = myPersons.begin(); person != myPersons.end();) {
568  if (!person->second.active) {
569  removeTransportable((person++)->first);
570  } else {
571  ++person;
572  }
573  }
574 
575  if (myAdapter->makeCurrent()) {
576  myViewer->frame();
577  makeNonCurrent();
578  }
579  myLastUpdate = now;
580  return 1;
581 }
582 
583 
584 void
585 GUIOSGView::removeVeh(MSVehicle* veh) {
586  if (myTracked == veh) {
587  stopTrack();
588  }
589  std::map<MSVehicle*, OSGMovable>::iterator i = myVehicles.find(veh);
590  if (i != myVehicles.end()) {
591  myRoot->removeChild(i->second.pos);
592  myVehicles.erase(i);
593  }
594 }
595 
596 
597 void
598 GUIOSGView::removeTransportable(MSTransportable* t) {
599  std::map<MSTransportable*, OSGMovable>::iterator i = myPersons.find(t);
600  if (i != myPersons.end()) {
601  myRoot->removeChild(i->second.pos);
602  myPersons.erase(i);
603  }
604 }
605 
606 
607 void GUIOSGView::updateViewportValues() {
608  osg::Vec3d lookFrom, lookAt, up;
609  myViewer->getCameraManipulator()->getInverseMatrix().getLookAt(lookFrom, lookAt, up);
610  myGUIDialogEditViewport->setValues(Position(lookFrom[0], lookFrom[1], lookFrom[2]),
611  Position(lookAt[0], lookAt[1], lookAt[2]), calculateRotation(lookFrom, lookAt, up));
612 }
613 
614 
615 void
616 GUIOSGView::showViewportEditor() {
617  getViewportEditor(); // make sure it exists;
618  osg::Vec3d lookFrom, lookAt, up;
619  myViewer->getCameraManipulator()->getInverseMatrix().getLookAt(lookFrom, lookAt, up);
620  Position from(lookFrom[0], lookFrom[1], lookFrom[2]), at(lookAt[0], lookAt[1], lookAt[2]);
621  myGUIDialogEditViewport->setOldValues(from, at, calculateRotation(lookFrom, lookAt, up));
622  myGUIDialogEditViewport->setZoomValue(100);
623  myGUIDialogEditViewport->show();
624 }
625 
626 
627 void
628 GUIOSGView::setViewportFromToRot(const Position& lookFrom, const Position& lookAt, double rotation) {
629  osg::Vec3d lookFromOSG, lookAtOSG, up;
630  lookFromOSG[0] = lookFrom.x();
631  lookFromOSG[1] = lookFrom.y();
632  lookFromOSG[2] = lookFrom.z();
633  lookAtOSG[0] = lookAt.x();
634  lookAtOSG[1] = lookAt.y();
635  lookAtOSG[2] = lookAt.z();
636 
637  osg::Vec3d viewAxis, viewUp, orthogonal, normal;
638  viewAxis = lookFromOSG - lookAtOSG;
639  viewAxis.normalize();
640  viewUp = (viewAxis[0] + viewAxis[1] == 0.) ? osg::Vec3d(0., 1., 0.) : osg::Vec3d(0., 0., 1.); // check for parallel vectors
641  orthogonal = viewUp ^ viewAxis;
642  orthogonal.normalize();
643  normal = viewAxis ^ orthogonal;
644 
645  rotation = std::fmod(rotation, 360.);
646  if (rotation < 0) {
647  rotation += 360.;
648  }
649  myChanger->setRotation(rotation);
650  double angle = DEG2RAD(rotation);
651  up = normal * cos(angle) - orthogonal * sin(angle);
652  up.normalize();
653 
654  double zoom = (myGUIDialogEditViewport != nullptr) ? myGUIDialogEditViewport->getZoomValue() : 100.;
655  lookFromOSG = lookFromOSG + viewAxis * (100. - zoom);
656  lookAtOSG = lookFromOSG - viewAxis;
657  myViewer->getCameraManipulator()->setHomePosition(lookFromOSG, lookAtOSG, up);
658  myViewer->home();
659 }
660 
661 
662 void
663 GUIOSGView::copyViewportTo(GUISUMOAbstractView* view) {
664  osg::Vec3d lookFrom, lookAt, up;
665  myViewer->getCameraManipulator()->getHomePosition(lookFrom, lookAt, up);
666  view->setViewportFromToRot(Position(lookFrom[0], lookFrom[1], lookFrom[2]),
667  Position(lookAt[0], lookAt[1], lookAt[2]), 0);
668 }
669 
670 
671 void
672 GUIOSGView::startTrack(int id) {
673  if (myTracked == 0 || (int)myTracked->getGlID() != id) {
674  myTracked = 0;
676  for (; it != MSNet::getInstance()->getVehicleControl().loadedVehEnd(); it++) {
677  GUIVehicle* veh = (GUIVehicle*)(*it).second;
678  if ((int)veh->getGlID() == id) {
679  if (!veh->isOnRoad() || myVehicles.find(veh) == myVehicles.end()) {
680  return;
681  }
682  myTracked = veh;
683  break;
684  }
685  }
686  if (myTracked != 0) {
687  osg::Vec3d lookFrom, lookAt, up;
688  lookAt[0] = myTracked->getPosition().x();
689  lookAt[1] = myTracked->getPosition().y();
690  lookAt[2] = myTracked->getPosition().z();
691  lookFrom[0] = lookAt[0] + 50.;
692  lookFrom[1] = lookAt[1] + 50.;
693  lookFrom[2] = lookAt[2] + 10.;
694  osg::Matrix m;
695  m.makeLookAt(lookFrom, lookAt, osg::Z_AXIS);
696  myViewer->getCameraManipulator()->setByInverseMatrix(m);
697  }
698  }
699 }
700 
701 
702 void
703 GUIOSGView::stopTrack() {
704  myTracked = 0;
705 }
706 
707 
708 GUIGlID
709 GUIOSGView::getTrackedID() const {
710  return myTracked == 0 ? GUIGlObject::INVALID_ID : myTracked->getGlID();
711 }
712 
713 
714 void
715 GUIOSGView::onGamingClick(Position pos) {
717  const MSTrafficLightLogic* minTll = nullptr;
718  double minDist = std::numeric_limits<double>::infinity();
719  for (const MSTrafficLightLogic* const tll : tlsControl.getAllLogics()) {
720  if (tlsControl.isActive(tll)) {
721  // get the links
722  const MSTrafficLightLogic::LaneVector& lanes = tll->getLanesAt(0);
723  if (lanes.size() > 0) {
724  const Position& endPos = lanes[0]->getShape().back();
725  if (endPos.distanceTo(pos) < minDist) {
726  minDist = endPos.distanceTo(pos);
727  minTll = tll;
728  }
729  }
730  }
731  }
732  if (minTll != 0) {
733  const MSTLLogicControl::TLSLogicVariants& vars = tlsControl.get(minTll->getID());
734  const std::vector<MSTrafficLightLogic*> logics = vars.getAllLogics();
735  if (logics.size() > 1) {
737  for (int i = 0; i < (int)logics.size() - 1; i++) {
738  if (minTll->getProgramID() == logics[i]->getProgramID()) {
739  l = (MSSimpleTrafficLightLogic*) logics[i + 1];
740  tlsControl.switchTo(minTll->getID(), l->getProgramID());
741  }
742  }
743  if (l == logics[0]) {
744  tlsControl.switchTo(minTll->getID(), l->getProgramID());
745  }
747  update();
748  }
749  }
750 }
751 
752 
753 SUMOTime
754 GUIOSGView::getCurrentTimeStep() const {
756 }
757 
758 
759 long GUIOSGView::onConfigure(FXObject* sender, FXSelector sel, void* ptr) {
760  // update the window dimensions, in case the window has been resized.
761  const int w = getWidth();
762  const int h = getHeight();
763  if (w > 0 && h > 0) {
764  myAdapter->getEventQueue()->windowResize(0, 0, w, h);
765  myAdapter->resized(0, 0, w, h);
766  updateHUDPosition(w, h);
767  }
768  return FXGLCanvas::onConfigure(sender, sel, ptr);
769 }
770 
771 
772 long GUIOSGView::onKeyPress(FXObject* sender, FXSelector sel, void* ptr) {
773  int key = ((FXEvent*)ptr)->code;
774  myAdapter->getEventQueue()->keyPress(key);
775  // leave key handling for some cases to OSG
776  if (key == FX::KEY_f || key == FX::KEY_Left || key == FX::KEY_Right || key == FX::KEY_Up || key == FX::KEY_Down) {
777  return 1;
778  }
779  return FXGLCanvas::onKeyPress(sender, sel, ptr);
780 }
781 
782 
783 long GUIOSGView::onKeyRelease(FXObject* sender, FXSelector sel, void* ptr) {
784  int key = ((FXEvent*)ptr)->code;
785  myAdapter->getEventQueue()->keyRelease(key);
786  // leave key handling for some cases to OSG
787  if (key == FX::KEY_f || key == FX::KEY_Left || key == FX::KEY_Right || key == FX::KEY_Up || key == FX::KEY_Down) {
788  return 1;
789  }
790  return FXGLCanvas::onKeyRelease(sender, sel, ptr);
791 }
792 
793 
794 long GUIOSGView::onLeftBtnPress(FXObject* sender, FXSelector sel, void* ptr) {
795  handle(this, FXSEL(SEL_FOCUS_SELF, 0), ptr);
796 
797  FXEvent* event = (FXEvent*)ptr;
798  myAdapter->getEventQueue()->mouseButtonPress((float)event->click_x, (float)event->click_y, 1);
799  if (myApp->isGaming()) {
800  onGamingClick(getPositionInformation());
801  }
802 
803  return FXGLCanvas::onLeftBtnPress(sender, sel, ptr);
804 }
805 
806 
807 long GUIOSGView::onLeftBtnRelease(FXObject* sender, FXSelector sel, void* ptr) {
808  FXEvent* event = (FXEvent*)ptr;
809  myAdapter->getEventQueue()->mouseButtonRelease((float)event->click_x, (float)event->click_y, 1);
810  myChanger->onLeftBtnRelease(ptr);
811  return FXGLCanvas::onLeftBtnRelease(sender, sel, ptr);
812 }
813 
814 
815 long GUIOSGView::onMiddleBtnPress(FXObject* sender, FXSelector sel, void* ptr) {
816  handle(this, FXSEL(SEL_FOCUS_SELF, 0), ptr);
817 
818  FXEvent* event = (FXEvent*)ptr;
819  myAdapter->getEventQueue()->mouseButtonPress((float)event->click_x, (float)event->click_y, 2);
820 
821  return FXGLCanvas::onMiddleBtnPress(sender, sel, ptr);
822 }
823 
824 
825 long GUIOSGView::onMiddleBtnRelease(FXObject* sender, FXSelector sel, void* ptr) {
826  FXEvent* event = (FXEvent*)ptr;
827  myAdapter->getEventQueue()->mouseButtonRelease((float)event->click_x, (float)event->click_y, 2);
828  myChanger->onMiddleBtnRelease(ptr);
829  return FXGLCanvas::onMiddleBtnRelease(sender, sel, ptr);
830 }
831 
832 
833 long GUIOSGView::onRightBtnPress(FXObject* sender, FXSelector sel, void* ptr) {
834  handle(this, FXSEL(SEL_FOCUS_SELF, 0), ptr);
835 
836  FXEvent* event = (FXEvent*)ptr;
837  myAdapter->getEventQueue()->mouseButtonPress((float)event->click_x, (float)event->click_y, 3);
838 
839  return FXGLCanvas::onRightBtnPress(sender, sel, ptr);
840 }
841 
842 
843 long GUIOSGView::onRightBtnRelease(FXObject* sender, FXSelector sel, void* ptr) {
844  FXEvent* event = (FXEvent*)ptr;
845  myAdapter->getEventQueue()->mouseButtonRelease((float)event->click_x, (float)event->click_y, 3);
846  myChanger->onRightBtnRelease(ptr);
847  return FXGLCanvas::onRightBtnRelease(sender, sel, ptr);
848 }
849 
850 
851 long
852 GUIOSGView::onMouseMove(FXObject* sender, FXSelector sel, void* ptr) {
853  // if popup exist but isn't shown, destroy it first
854  if (myPopup && !myPopup->shown()) {
855  destroyPopup();
856  }
857 
858  FXEvent* event = (FXEvent*)ptr;
859  osgGA::GUIEventAdapter* ea = myAdapter->getEventQueue()->mouseMotion((float)event->win_x, (float)event->win_y);
860  setWindowCursorPosition(ea->getXnormalized(), ea->getYnormalized());
861  if (myGUIDialogEditViewport != nullptr && myGUIDialogEditViewport->shown()) {
862  updateViewportValues();
863  }
864  updatePositionInformation();
865  return FXGLCanvas::onMotion(sender, sel, ptr);
866 }
867 
868 
869 long
870 GUIOSGView::onIdle(FXObject* /* sender */, FXSelector /* sel */, void*) {
871  forceRefresh();
872  update();
873  getApp()->addChore(this, MID_CHORE);
874  return 1;
875 }
876 
877 
878 long
879 GUIOSGView::onCmdCloseLane(FXObject*, FXSelector, void*) {
880  GUILane* lane = getLaneUnderCursor();
881  if (lane != nullptr) {
882  lane->closeTraffic();
884  GUINet::getGUIInstance()->updateColor(*myVisualizationSettings);
885  update();
886  }
887  return 1;
888 }
889 
890 
891 long
892 GUIOSGView::onCmdCloseEdge(FXObject*, FXSelector, void*) {
893  GUILane* lane = getLaneUnderCursor();
894  if (lane != nullptr) {
895  dynamic_cast<GUIEdge*>(&lane->getEdge())->closeTraffic(lane);
897  GUINet::getGUIInstance()->updateColor(*myVisualizationSettings);
898  update();
899  }
900  return 1;
901 }
902 
903 
904 long
905 GUIOSGView::onCmdAddRerouter(FXObject*, FXSelector, void*) {
906  GUILane* lane = getLaneUnderCursor();
907  if (lane != nullptr) {
908  dynamic_cast<GUIEdge*>(&lane->getEdge())->addRerouter();
910  update();
911  }
912  return 1;
913 }
914 
915 
916 long
917 GUIOSGView::onCmdShowReachability(FXObject* menu, FXSelector selector, void*) {
918  GUILane* lane = getLaneUnderCursor();
919  if (lane != nullptr) {
920  // reset
921  GUIViewTraffic::showLaneReachability(lane, menu, selector);
922  // switch to 'color by selection' unless coloring 'by reachability'
923  if (myVisualizationSettings->laneColorer.getActive() != 36) {
924  myVisualizationSettings->laneColorer.setActive(1);
925  GUINet::getGUIInstance()->updateColor(*myVisualizationSettings);
926  }
927  update();
928  }
929  return 1;
930 }
931 
932 
933 long
934 GUIOSGView::onVisualizationChange(FXObject*, FXSelector, void*) {
935  adoptViewSettings();
936  return 1;
937 }
938 
939 
940 void
941 GUIOSGView::setWindowCursorPosition(float x, float y) {
942  myOSGNormalizedCursorX = x;
943  myOSGNormalizedCursorY = y;
944 }
945 
946 
947 double
948 GUIOSGView::calculateRotation(const osg::Vec3d& lookFrom, const osg::Vec3d& lookAt, const osg::Vec3d& up) {
949  osg::Vec3d viewAxis, viewUp, orthogonal, normal;
950  viewAxis = lookFrom - lookAt;
951  viewAxis.normalize();
952  viewUp = (abs(viewAxis[0]) + abs(viewAxis[1]) == 0.) ? osg::Y_AXIS : osg::Z_AXIS; // check for parallel vectors
953  orthogonal = viewUp ^ viewAxis;
954  orthogonal.normalize();
955  normal = viewAxis ^ orthogonal;
956  double angle = atan2((normal ^ up).length() / (normal.length() * up.length()), (normal * up) / (normal.length() * up.length()));
957  if (angle < 0) {
958  angle += M_PI;
959  }
960  return RAD2DEG(angle);
961 }
962 
963 
964 void
965 GUIOSGView::updatePositionInformation() const {
966  Position pos;
967  if (getPositionAtCursor(myOSGNormalizedCursorX, myOSGNormalizedCursorY, pos)) {
968  myApp->getCartesianLabel()->setText(("x:" + toString(pos.x()) + ", y:" + toString(pos.y())).c_str());
969  // set geo position
971  if (GeoConvHelper::getFinal().usingGeoProjection()) {
972  myApp->getGeoLabel()->setText(("lat:" + toString(pos.y(), gPrecisionGeo) + ", lon:" + toString(pos.x(), gPrecisionGeo)).c_str());
973  } else {
974  myApp->getGeoLabel()->setText(TL("(No projection defined)"));
975  }
976  } else {
977  // set placeholder
978  myApp->getCartesianLabel()->setText(TL("N/A"));
979  myApp->getGeoLabel()->setText(TL("N/A"));
980  }
981 }
982 
983 
984 bool
985 GUIOSGView::getPositionAtCursor(float xNorm, float yNorm, Position& pos) const {
986  // only reasonable if view axis points to the ground (not parallel to the ground or in the sky)
987  osg::Vec3d lookFrom, lookAt, up, viewAxis;
988  myViewer->getCameraManipulator()->getInverseMatrix().getLookAt(lookFrom, lookAt, up);
989  if ((lookAt - lookFrom).z() >= 0.) {
990  // looking to the sky makes position at ground pointless
991  return false;
992  }
993  // solve linear equation of ray crossing the ground plane
994  osg::Matrixd iVP = osg::Matrixd::inverse(myViewer->getCamera()->getViewMatrix() * myViewer->getCamera()->getProjectionMatrix());
995  osg::Vec3 nearPoint = osg::Vec3(xNorm, yNorm, 0.0f) * iVP;
996  osg::Vec3 farPoint = osg::Vec3(xNorm, yNorm, 1.0f) * iVP;
997  osg::Vec3 ray = farPoint - nearPoint;
998  osg::Vec3 groundPos = nearPoint - ray * nearPoint.z() / ray.z();
999  pos.setx(groundPos.x());
1000  pos.sety(groundPos.y());
1001  pos.setz(0.);
1002  return true;
1003 }
1004 
1005 
1006 std::vector<GUIGlObject*>
1007 GUIOSGView::getGUIGlObjectsUnderCursor() {
1008  std::vector<GUIGlObject*> result;
1009  osgUtil::LineSegmentIntersector::Intersections intersections;
1010  if (myViewer->computeIntersections(myViewer->getCamera(), osgUtil::Intersector::CoordinateFrame::PROJECTION, myOSGNormalizedCursorX, myOSGNormalizedCursorY, intersections)) {
1011  for (auto intersection : intersections) {
1012  if (!intersection.nodePath.empty()) {
1013  // the object is identified by the ID stored in OSG
1014  for (osg::Node* currentNode : intersection.nodePath) {
1015  if (currentNode->getName().length() > 0 && currentNode->getName().find(":") != std::string::npos) {
1016  const std::string objID = currentNode->getName();
1018  // check that GUIGlObject exist
1019  if (o == nullptr) {
1020  continue;
1021  }
1022  // check that GUIGlObject isn't the network
1023  if (o->getGlID() == 0) {
1024  continue;
1025  }
1026  result.push_back(o);
1027  // unblock object
1029  }
1030  }
1031  }
1032  }
1033  }
1034  return result;
1035 }
1036 
1037 
1038 GUILane*
1039 GUIOSGView::getLaneUnderCursor() {
1040  std::vector<GUIGlObject*> objects = getGUIGlObjectsUnderCursor();
1041  if (objects.size() > 0) {
1042  return dynamic_cast<GUILane*>(objects[0]);
1043  }
1044  return nullptr;
1045 }
1046 
1047 
1048 void
1049 GUIOSGView::zoom2Pos(Position& camera, Position& lookAt, double zoom) {
1050  osg::Vec3d lookFromOSG, lookAtOSG, viewAxis, up;
1051  myViewer->getCameraManipulator()->getInverseMatrix().getLookAt(lookFromOSG, lookAtOSG, up);
1052  lookFromOSG[0] = camera.x();
1053  lookFromOSG[1] = camera.y();
1054  lookFromOSG[2] = camera.z();
1055  lookAtOSG[0] = lookAt.x();
1056  lookAtOSG[1] = lookAt.y();
1057  lookAtOSG[2] = lookAt.z();
1058  viewAxis = lookAtOSG - lookFromOSG;
1059  viewAxis.normalize();
1060 
1061  // compute new camera and lookAt pos
1062  osg::Vec3d cameraUpdate = lookFromOSG + viewAxis * (zoom - 100.);
1063  osg::Vec3d lookAtUpdate = cameraUpdate + viewAxis;
1064 
1065  myViewer->getCameraManipulator()->setHomePosition(cameraUpdate, lookAtUpdate, up);
1066  myViewer->home();
1067 }
1068 
1069 
1070 osg::Vec4d
1071 GUIOSGView::toOSGColorVector(RGBColor c, bool useAlpha) {
1072  return osg::Vec4d(c.red() / 255., c.green() / 255., c.blue() / 255., (useAlpha) ? c.alpha() / 255. : 1.);
1073 }
1074 
1075 
1076 GUIOSGView::FXOSGAdapter::FXOSGAdapter(GUISUMOAbstractView* parent, FXCursor* cursor)
1077  : myParent(parent), myOldCursor(cursor) {
1078  _traits = new GraphicsContext::Traits();
1079  _traits->x = 0;
1080  _traits->y = 0;
1081  _traits->width = parent->getWidth();
1082  _traits->height = parent->getHeight();
1083  _traits->windowDecoration = false;
1084  _traits->doubleBuffer = true;
1085  _traits->sharedContext = 0;
1086  if (valid()) {
1087  setState(new osg::State());
1088  getState()->setGraphicsContext(this);
1089 #ifdef DEBUG_GLERRORS
1090  getState()->setCheckForGLErrors(osg::State::ONCE_PER_ATTRIBUTE);
1091  std::cout << "OSG getCheckForGLErrors " << getState()->getCheckForGLErrors() << std::endl;
1092 #endif
1093  if (_traits.valid() && _traits->sharedContext != 0) {
1094  getState()->setContextID(_traits->sharedContext->getState()->getContextID());
1095  incrementContextIDUsageCount(getState()->getContextID());
1096  } else {
1097  getState()->setContextID(createNewContextID());
1098  }
1099  }
1100 }
1101 
1102 
1103 GUIOSGView::FXOSGAdapter::~FXOSGAdapter() {
1104  delete myOldCursor;
1105 }
1106 
1107 
1108 void
1109 GUIOSGView::FXOSGAdapter::grabFocus() {
1110  // focus this window
1111  myParent->setFocus();
1112 }
1113 
1114 
1115 void
1116 GUIOSGView::FXOSGAdapter::useCursor(bool cursorOn) {
1117  if (cursorOn) {
1118  myParent->setDefaultCursor(myOldCursor);
1119  } else {
1120  myParent->setDefaultCursor(NULL);
1121  }
1122 }
1123 
1124 
1125 bool
1126 GUIOSGView::FXOSGAdapter::makeCurrentImplementation() {
1127  myParent->makeCurrent();
1128  return true;
1129 }
1130 
1131 
1132 bool
1133 GUIOSGView::FXOSGAdapter::releaseContext() {
1134  myParent->makeNonCurrent();
1135  return true;
1136 }
1137 
1138 
1139 void
1140 GUIOSGView::FXOSGAdapter::swapBuffersImplementation() {
1141  myParent->swapBuffers();
1142 }
1143 
1144 
1145 bool
1146 GUIOSGView::PickHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& /* aa */) {
1147  if (ea.getEventType() == osgGA::GUIEventAdapter::DRAG) {
1148  myDrag = true;
1149  } else if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE && ea.getButton() == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) {
1150  if (!myDrag) {
1151  if (myParent->makeCurrent()) {
1152  std::vector<GUIGlObject*> objects = myParent->getGUIGlObjectsUnderCursor();
1153  if (objects.size() > 0) {
1154  myParent->openObjectDialog(objects);
1155  }
1156  myParent->makeNonCurrent();
1157  }
1158  }
1159  myDrag = false;
1160  }
1161  return false;
1162 }
1163 
1164 
1165 #endif
1166 
1167 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
@ MID_CHORE
chore
Definition: GUIAppEnum.h:411
@ 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:1557
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:534
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:182
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:7254
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:1215
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 dimension
Definition: Position.h:261
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.