35 #pragma warning(disable: 4127) // do not warn about constant conditional expression
37 #include <osgViewer/Viewer>
38 #include <osgViewer/ViewerEventHandlers>
39 #include <osgGA/NodeTrackerManipulator>
40 #include <osgDB/ReadFile>
41 #include <osg/PositionAttitudeTransform>
43 #include <osg/ShapeDrawable>
85 FXDEFMAP(GUIOSGView) GUIOSGView_Map[] = {
87 FXMAPFUNC(SEL_CHORE,
MID_CHORE, GUIOSGView::OnIdle)
93 operator<<(std::ostream& os,
const osg::Vec3d& v) {
94 return os << v.x() <<
"," << v.y() <<
"," << v.z();
101 GUIOSGView::Command_TLSChange::Command_TLSChange(
const MSLink*
const link, osg::Switch* switchNode)
107 GUIOSGView::Command_TLSChange::~Command_TLSChange() {}
111 GUIOSGView::Command_TLSChange::execute() {
112 switch (myLink->getState()) {
115 mySwitch->setSingleChildOn(0);
119 mySwitch->setSingleChildOn(1);
122 mySwitch->setSingleChildOn(2);
125 mySwitch->setSingleChildOn(3);
128 mySwitch->setAllChildrenOff();
130 myLastState = myLink->getState();
138 GUIOSGView::GUIOSGView(
142 GUINet& net, FXGLVisual* glVis,
145 myTracked(0), myCameraManipulator(new SUMOTerrainManipulator()), myLastUpdate(-1) {
153 myAdapter =
new FXOSGAdapter(
this,
new FXCursor(parent->getApp(), CURSOR_CROSS));
155 myViewer =
new osgViewer::Viewer();
156 myViewer->getCamera()->setGraphicsContext(myAdapter);
157 myViewer->getCamera()->setViewport(0, 0, w, h);
158 myViewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
160 const char* sumoPath = getenv(
"SUMO_HOME");
162 std::string newPath = std::string(sumoPath) +
"/data/3D";
164 osgDB::FilePathList path = osgDB::Registry::instance()->getDataFilePathList();
165 path.push_back(newPath);
166 osgDB::Registry::instance()->setDataFilePathList(path);
170 myGreenLight = osgDB::readNodeFile(
"tlg.obj");
171 myYellowLight = osgDB::readNodeFile(
"tly.obj");
172 myRedLight = osgDB::readNodeFile(
"tlr.obj");
173 myRedYellowLight = osgDB::readNodeFile(
"tlu.obj");
174 if (myGreenLight == 0 || myYellowLight == 0 || myRedLight == 0 || myRedYellowLight == 0) {
175 WRITE_ERROR(
"Could not load traffic light files.");
177 myRoot = GUIOSGBuilder::buildOSGScene(myGreenLight, myYellowLight, myRedLight, myRedYellowLight);
179 myViewer->addEventHandler(
new osgViewer::StatsHandler());
180 myViewer->setSceneData(myRoot);
181 myViewer->setCameraManipulator(myCameraManipulator);
182 osg::Vec3d lookFrom, lookAt, up;
183 myCameraManipulator->getHomePosition(lookFrom, lookAt, up);
184 double z = lookFrom[2];
185 lookFrom[2] = -lookFrom.y();
187 myCameraManipulator->setHomePosition(lookFrom, lookAt, up);
193 GUIOSGView::~GUIOSGView() {
195 myViewer->setDone(
true);
207 for (std::vector<std::string>::const_iterator i = names.begin(); i != names.end(); ++i) {
209 if ((*i) == myVisualizationSettings->name) {
217 "\tLocate Junction\tLocate a junction within the network.",
219 ICON_ABOVE_TEXT | FRAME_THICK | FRAME_RAISED);
222 "\tLocate Street\tLocate a street within the network.",
224 ICON_ABOVE_TEXT | FRAME_THICK | FRAME_RAISED);
227 "\tLocate Vehicle\tLocate a vehicle within the network.",
229 ICON_ABOVE_TEXT | FRAME_THICK | FRAME_RAISED);
232 "\tLocate Vehicle\tLocate a person within the network.",
234 ICON_ABOVE_TEXT | FRAME_THICK | FRAME_RAISED);
237 "\tLocate TLS\tLocate a tls within the network.",
239 ICON_ABOVE_TEXT | FRAME_THICK | FRAME_RAISED);
242 "\tLocate Additional\tLocate an additional structure within the network.",
244 ICON_ABOVE_TEXT | FRAME_THICK | FRAME_RAISED);
247 "\tLocate POI\tLocate a POI within the network.",
249 ICON_ABOVE_TEXT | FRAME_THICK | FRAME_RAISED);
252 "\tLocate Polygon\tLocate a Polygon within the network.",
254 ICON_ABOVE_TEXT | FRAME_THICK | FRAME_RAISED);
259 GUIOSGView::recenterView() {
261 Position center = myGrid->getCenter();
262 osg::Vec3d lookFromOSG, lookAtOSG, up;
263 myViewer->getCameraManipulator()->getHomePosition(lookFromOSG, lookAtOSG, up);
264 lookFromOSG[0] = center.
x();
265 lookFromOSG[1] = center.
y();
266 lookFromOSG[2] = myChanger->zoom2ZPos(100);
267 lookAtOSG[0] = center.
x();
268 lookAtOSG[1] = center.
y();
270 myViewer->getCameraManipulator()->setHomePosition(lookFromOSG, lookAtOSG, up);
276 GUIOSGView::centerTo(
GUIGlID id,
bool ,
double ) {
282 GUIOSGView::setColorScheme(
const std::string& name) {
286 if (myVisualizationChanger != 0) {
287 if (myVisualizationChanger->getCurrentScheme() != name) {
288 myVisualizationChanger->setCurrentScheme(name);
292 myVisualizationSettings->
gaming = myApp->isGaming();
299 GUIOSGView::onPaint(FXObject*, FXSelector,
void*) {
304 for (std::vector<GUISUMOAbstractView::Decal>::iterator l = myDecals.begin(); l != myDecals.end(); ++l) {
308 GUIOSGBuilder::buildLight(d, *myRoot);
310 const int linkStringIdx = (int)d.
filename.find(
':', 3);
315 if (linkIdx < 0 || linkIdx >= static_cast<int>(vars.
getActive()->
getLinks().size())) {
319 osg::Switch* switchNode =
new osg::Switch();
320 switchNode->addChild(GUIOSGBuilder::getTrafficLight(d, d.
layer < 0 ? 0 : myGreenLight, osg::Vec4d(0., 1., 0., .3)),
false);
321 switchNode->addChild(GUIOSGBuilder::getTrafficLight(d, d.
layer < 0 ? 0 : myYellowLight, osg::Vec4d(1., 1., 0., .3)),
false);
322 switchNode->addChild(GUIOSGBuilder::getTrafficLight(d, d.
layer < 0 ? 0 : myRedLight, osg::Vec4d(1., 0., 0., .3)),
false);
323 switchNode->addChild(GUIOSGBuilder::getTrafficLight(d, d.
layer < 0 ? 0 : myRedYellowLight, osg::Vec4d(1., .5, 0., .3)),
false);
324 myRoot->addChild(switchNode);
332 GUIOSGBuilder::buildDecal(d, *myRoot);
337 myDecalsLock.unlock();
340 for (
auto& item : myVehicles) {
341 item.second.active =
false;
344 GUIVehicle* veh = static_cast<GUIVehicle*>(it->second);
348 auto itVeh = myVehicles.find(veh);
349 if (itVeh == myVehicles.end()) {
350 myVehicles[veh] = GUIOSGBuilder::buildMovable(veh->
getVehicleType());
351 myRoot->addChild(myVehicles[veh].pos);
353 itVeh->second.active =
true;
355 osg::PositionAttitudeTransform* n = myVehicles[veh].pos;
358 const double slope = veh->
getSlope();
359 n->setAttitude(osg::Quat(dir, osg::Vec3d(0, 0, 1)) *
360 osg::Quat(osg::DegreesToRadians(slope), osg::Vec3d(0, 1, 0)));
372 const RGBColor& col = myVisualizationSettings->vehicleColorer.getScheme().getColor(veh->
getColorValue(*myVisualizationSettings, myVisualizationSettings->vehicleColorer.getActive()));
373 myVehicles[veh].geom->setColor(osg::Vec4d(col.
red() / 255., col.
green() / 255., col.
blue() / 255., col.
alpha() / 255.));
379 for (
auto it = myVehicles.begin(); it != myVehicles.end();) {
380 if (!it->second.active) {
381 removeVeh((it++)->first);
388 if (now != myLastUpdate || (myVisualizationChanger != 0 && myVisualizationChanger->shown())) {
391 if (now != myLastUpdate && myTracked != 0) {
392 osg::Vec3d lookFrom, lookAt, up;
393 lookAt[0] = myTracked->getPosition().x();
394 lookAt[1] = myTracked->getPosition().y();
395 lookAt[2] = myTracked->getPosition().z();
396 const double angle = myTracked->getAngle();
397 lookFrom[0] = lookAt[0] + 50. * cos(angle);
398 lookFrom[1] = lookAt[1] + 50. * sin(angle);
399 lookFrom[2] = lookAt[2] + 10.;
401 m.makeLookAt(lookFrom, lookAt, osg::Z_AXIS);
402 myCameraManipulator->setByInverseMatrix(m);
406 for (
auto& item : myPersons) {
407 item.second.active =
false;
416 auto itPers = myPersons.find(person);
417 if (itPers == myPersons.end()) {
418 myPersons[person] = GUIOSGBuilder::buildMovable(person->
getVehicleType());
419 myRoot->addChild(myPersons[person].pos);
421 itPers->second.active =
true;
423 osg::PositionAttitudeTransform* n = myPersons[person].pos;
425 n->setPosition(osg::Vec3d(pos.
x(), pos.
y(), pos.
z()));
427 n->setAttitude(osg::Quat(dir, osg::Vec3d(0, 0, 1)));
430 for (
auto it = myPersons.begin(); it != myPersons.end();) {
431 if (!it->second.active) {
432 removeTransportable((it++)->first);
439 if (myAdapter->makeCurrent()) {
450 if (myTracked == veh) {
453 std::map<MSVehicle*, OSGMovable>::iterator i = myVehicles.find(veh);
454 if (i != myVehicles.end()) {
455 myRoot->removeChild(i->second.pos);
463 std::map<MSTransportable*, OSGMovable>::iterator i = myPersons.find(t);
464 if (i != myPersons.end()) {
465 myRoot->removeChild(i->second.pos);
472 GUIOSGView::showViewportEditor() {
474 osg::Vec3d lookFromOSG, lookAtOSG, up;
475 myViewer->getCameraManipulator()->getInverseMatrix().getLookAt(lookFromOSG, lookAtOSG, up);
476 Position from(lookFromOSG[0], lookFromOSG[1], lookFromOSG[2]), at(lookAtOSG[0], lookAtOSG[1], lookAtOSG[2]);
477 myViewportChooser->setOldValues(from, at, 0);
478 myViewportChooser->show();
483 GUIOSGView::setViewportFromToRot(
const Position& lookFrom,
const Position& lookAt,
double ) {
484 osg::Vec3d lookFromOSG, lookAtOSG, up;
485 myViewer->getCameraManipulator()->getHomePosition(lookFromOSG, lookAtOSG, up);
486 lookFromOSG[0] = lookFrom.
x();
487 lookFromOSG[1] = lookFrom.
y();
488 lookFromOSG[2] = lookFrom.
z();
489 lookAtOSG[0] = lookAt.
x();
490 lookAtOSG[1] = lookAt.
y();
491 lookAtOSG[2] = lookAt.
z();
492 myViewer->getCameraManipulator()->setHomePosition(lookFromOSG, lookAtOSG, up);
500 osg::Vec3d lookFrom, lookAt, up;
501 myCameraManipulator->getHomePosition(lookFrom, lookAt, up);
503 Position(lookAt[0], lookAt[1], lookAt[2]), 0);
509 GUIOSGView::startTrack(
int id) {
510 if (myTracked == 0 || (
int)myTracked->getGlID() != id) {
515 if ((
int)veh->
getGlID() == id) {
516 if (!veh->
isOnRoad() || myVehicles.find(veh) == myVehicles.end()) {
523 if (myTracked != 0) {
524 osg::Vec3d lookFrom, lookAt, up;
526 lookAt[1] = myTracked->getPosition().y();
527 lookAt[2] = myTracked->getPosition().z();
528 lookFrom[0] = lookAt[0] + 50.;
529 lookFrom[1] = lookAt[1] + 50.;
530 lookFrom[2] = lookAt[2] + 10.;
532 m.makeLookAt(lookFrom, lookAt, osg::Z_AXIS);
533 myCameraManipulator->setByInverseMatrix(m);
540 GUIOSGView::stopTrack() {
546 GUIOSGView::getTrackedID()
const {
552 GUIOSGView::onGamingClick(
Position pos) {
554 const std::vector<MSTrafficLightLogic*>& logics = tlsControl.
getAllLogics();
556 double minDist = std::numeric_limits<double>::infinity();
557 for (std::vector<MSTrafficLightLogic*>::const_iterator i = logics.begin(); i != logics.end(); ++i) {
563 if (lanes.size() > 0) {
564 const Position& endPos = lanes[0]->getShape().back();
574 const std::vector<MSTrafficLightLogic*> logics = vars.
getAllLogics();
575 if (logics.size() > 1) {
577 for (
int i = 0; i < (int)logics.size() - 1; i++) {
578 if (minTll->
getProgramID() == logics[i]->getProgramID()) {
583 if (l == logics[0]) {
594 GUIOSGView::getCurrentTimeStep()
const {
599 long GUIOSGView::onConfigure(FXObject* sender, FXSelector sel,
void* ptr) {
601 myAdapter->getEventQueue()->windowResize(0, 0, getWidth(), getHeight());
602 myAdapter->resized(0, 0, getWidth(), getHeight());
604 return FXGLCanvas::onConfigure(sender, sel, ptr);
607 long GUIOSGView::onKeyPress(FXObject* sender, FXSelector sel,
void* ptr) {
608 int key = ((FXEvent*)ptr)->code;
609 myAdapter->getEventQueue()->keyPress(key);
611 return FXGLCanvas::onKeyPress(sender, sel, ptr);
614 long GUIOSGView::onKeyRelease(FXObject* sender, FXSelector sel,
void* ptr) {
615 int key = ((FXEvent*)ptr)->code;
616 myAdapter->getEventQueue()->keyRelease(key);
618 return FXGLCanvas::onKeyRelease(sender, sel, ptr);
621 long GUIOSGView::onLeftBtnPress(FXObject* sender, FXSelector sel,
void* ptr) {
622 handle(
this, FXSEL(SEL_FOCUS_SELF, 0), ptr);
624 FXEvent*
event = (FXEvent*)ptr;
625 myAdapter->getEventQueue()->mouseButtonPress((
float)event->click_x, (
float)event->click_y, 1);
626 if (myApp->isGaming()) {
627 onGamingClick(getPositionInformation());
630 return FXGLCanvas::onLeftBtnPress(sender, sel, ptr);
633 long GUIOSGView::onLeftBtnRelease(FXObject* sender, FXSelector sel,
void* ptr) {
634 FXEvent*
event = (FXEvent*)ptr;
635 myAdapter->getEventQueue()->mouseButtonRelease((
float)event->click_x, (
float)event->click_y, 1);
637 return FXGLCanvas::onLeftBtnRelease(sender, sel, ptr);
640 long GUIOSGView::onMiddleBtnPress(FXObject* sender, FXSelector sel,
void* ptr) {
641 handle(
this, FXSEL(SEL_FOCUS_SELF, 0), ptr);
643 FXEvent*
event = (FXEvent*)ptr;
644 myAdapter->getEventQueue()->mouseButtonPress((
float)event->click_x, (
float)event->click_y, 2);
646 return FXGLCanvas::onMiddleBtnPress(sender, sel, ptr);
649 long GUIOSGView::onMiddleBtnRelease(FXObject* sender, FXSelector sel,
void* ptr) {
650 FXEvent*
event = (FXEvent*)ptr;
651 myAdapter->getEventQueue()->mouseButtonRelease((
float)event->click_x, (
float)event->click_y, 2);
653 return FXGLCanvas::onMiddleBtnRelease(sender, sel, ptr);
656 long GUIOSGView::onRightBtnPress(FXObject* sender, FXSelector sel,
void* ptr) {
657 handle(
this, FXSEL(SEL_FOCUS_SELF, 0), ptr);
659 FXEvent*
event = (FXEvent*)ptr;
660 myAdapter->getEventQueue()->mouseButtonPress((
float)event->click_x, (
float)event->click_y, 3);
662 return FXGLCanvas::onRightBtnPress(sender, sel, ptr);
665 long GUIOSGView::onRightBtnRelease(FXObject* sender, FXSelector sel,
void* ptr) {
666 FXEvent*
event = (FXEvent*)ptr;
667 myAdapter->getEventQueue()->mouseButtonRelease((
float)event->click_x, (
float)event->click_y, 3);
669 return FXGLCanvas::onRightBtnRelease(sender, sel, ptr);
673 GUIOSGView::onMouseMove(FXObject* sender, FXSelector sel,
void* ptr) {
674 FXEvent*
event = (FXEvent*)ptr;
675 myAdapter->getEventQueue()->mouseMotion((
float)event->win_x, (
float)event->win_y);
677 return FXGLCanvas::onMotion(sender, sel, ptr);
681 GUIOSGView::OnIdle(FXObject* , FXSelector ,
void*) {
691 : myParent(parent), myOldCursor(cursor) {
692 _traits =
new GraphicsContext::Traits();
695 _traits->width = parent->getWidth();
696 _traits->height = parent->getHeight();
697 _traits->windowDecoration =
false;
698 _traits->doubleBuffer =
true;
699 _traits->sharedContext = 0;
701 setState(
new osg::State());
702 getState()->setGraphicsContext(
this);
703 if (_traits.valid() && _traits->sharedContext != 0) {
704 getState()->setContextID(_traits->sharedContext->getState()->getContextID());
705 incrementContextIDUsageCount(getState()->getContextID());
707 getState()->setContextID(createNewContextID());
713 GUIOSGView::FXOSGAdapter::~FXOSGAdapter() {
718 void GUIOSGView::FXOSGAdapter::grabFocus() {
720 myParent->setFocus();
723 void GUIOSGView::FXOSGAdapter::useCursor(
bool cursorOn) {
725 myParent->setDefaultCursor(myOldCursor);
727 myParent->setDefaultCursor(NULL);
731 bool GUIOSGView::FXOSGAdapter::makeCurrentImplementation() {
732 myParent->makeCurrent();
736 bool GUIOSGView::FXOSGAdapter::releaseContext() {
737 myParent->makeNonCurrent();
741 void GUIOSGView::FXOSGAdapter::swapBuffersImplementation() {
742 myParent->swapBuffers();