#pragma once
#include <config.h>
#ifdef HAVE_OSG
#include "GUIOSGHeader.h"
#include "GUIOSGManipulator.h"
#include <string>
#include <microsim/traffic_lights/MSTLLogicControl.h>
#include <utils/geom/Boundary.h>
#include <utils/geom/Position.h>
#include <utils/common/RGBColor.h>
#include <utils/geom/PositionVector.h>
#include <gui/GUISUMOViewParent.h>
#include <utils/gui/windows/GUISUMOAbstractView.h>
class GUINet;
class GUISUMOViewParent;
class GUIVehicle;
class GUILaneWrapper;
class MSRoute;
class MSTransportable;
class MSVehicle;
namespace osgGA {
class CameraManipulator;
}
class GUIOSGView : public GUISUMOAbstractView {
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winconsistent-missing-override"
#endif
FXDECLARE(GUIOSGView)
#ifdef __clang__
#pragma clang diagnostic pop
#endif
public:
friend class GUIOSGPerspectiveChanger;
enum NodeSetGroup {
NODESET_TLSDOMES = 1,
NODESET_TLSLINKMARKERS = 2,
NODESET_TLSMODELS = 4,
};
class Command_TLSChange : public MSTLLogicControl::OnSwitchAction {
public:
Command_TLSChange(const MSLink* const link, osg::Switch* switchNode);
virtual ~Command_TLSChange();
void execute();
private:
const MSLink* const myLink;
osg::ref_ptr<osg::Switch> mySwitch;
LinkState myLastState;
private:
Command_TLSChange(const Command_TLSChange&) = delete;
Command_TLSChange& operator=(const Command_TLSChange&) = delete;
};
struct OSGMovable {
osg::ref_ptr<osg::PositionAttitudeTransform> pos;
osg::ref_ptr<osg::PositionAttitudeTransform> body;
osg::ref_ptr<osg::Material> mat;
osg::ref_ptr<osg::Switch> lights;
bool active;
void activateMaterial(bool state = true) {
osg::ref_ptr<osg::StateSet> ss = body->getOrCreateStateSet();
if (state) {
ss->setAttribute(mat, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
} else {
ss->setAttribute(mat, osg::StateAttribute::OFF);
}
}
};
GUIOSGView(FXComposite* p, GUIMainWindow& app,
GUISUMOViewParent* parent, GUINet& net, FXGLVisual* glVis,
FXGLCanvas* share);
virtual ~GUIOSGView();
Position getPositionInformation() const override;
bool is3DView() const override;
virtual void buildViewToolBars(GUIGlChildWindow*) override;
void recenterView() override;
void updateViewportValues() override;
void showViewportEditor() override;
void setViewportFromToRot(const Position& lookFrom, const Position& lookAt, double rotation) override;
void copyViewportTo(GUISUMOAbstractView* view) override;
void startTrack(int id) override;
void stopTrack() override;
GUIGlID getTrackedID() const override;
bool setColorScheme(const std::string& name) override;
void onGamingClick(Position pos) override;
SUMOTime getCurrentTimeStep() const override;
void removeVeh(MSVehicle* veh);
void removeTransportable(MSTransportable* t);
void position(int x, int y, int w, int h) override;
void resize(int w, int h) override;
long onConfigure(FXObject*, FXSelector, void*) override;
long onKeyPress(FXObject*, FXSelector, void*) override;
long onKeyRelease(FXObject*, FXSelector, void*) override;
long onLeftBtnPress(FXObject*, FXSelector, void*) override;
long onLeftBtnRelease(FXObject*, FXSelector, void*) override;
long onMiddleBtnPress(FXObject*, FXSelector, void*) override;
long onMiddleBtnRelease(FXObject*, FXSelector, void*) override;
long onRightBtnPress(FXObject*, FXSelector, void*) override;
long onRightBtnRelease(FXObject*, FXSelector, void*) override;
long onMouseMove(FXObject*, FXSelector, void*) override;
long onPaint(FXObject*, FXSelector, void*) override;
long onIdle(FXObject* sender, FXSelector sel, void* ptr);
long onCmdCloseLane(FXObject*, FXSelector, void*) override;
long onCmdCloseEdge(FXObject*, FXSelector, void*) override;
long onCmdAddRerouter(FXObject*, FXSelector, void*) override;
long onCmdShowReachability(FXObject*, FXSelector, void*) override;
long onVisualizationChange(FXObject*, FXSelector, void*) override;
void zoom2Pos(Position& camera, Position& lookAt, double zoom) override;
static osg::Vec4d toOSGColorVector(RGBColor c, bool useAlpha = false);
void updateHUDText(const std::string text);
protected:
void setWindowCursorPosition(float x, float y);
void updatePositionInformation() const;
bool getPositionAtCursor(float xNorm, float yNorm, Position& pos) const;
std::vector<GUIGlObject*> getGUIGlObjectsUnderCursor();
GUILane* getLaneUnderCursor() override;
void adoptViewSettings();
private:
double calculateRotation(const osg::Vec3d& lookFrom, const osg::Vec3d& lookAt, const osg::Vec3d& up);
void updateHUDPosition(int width, int height);
class FXOSGAdapter : public osgViewer::GraphicsWindow {
public:
FXOSGAdapter(GUISUMOAbstractView* parent, FXCursor* cursor);
void grabFocus();
void grabFocusIfPointerInWindow() {}
void useCursor(bool cursorOn);
bool makeCurrentImplementation();
bool releaseContext();
void swapBuffersImplementation();
bool valid() const {
return true;
}
bool realizeImplementation() {
return true;
}
bool isRealizedImplementation() const {
return true;
}
void closeImplementation() {}
bool releaseContextImplementation() {
return true;
}
void requestWarpPointer(float x, float y) {
int xRound = std::lround(x);
int yRound = std::lround(y);
int xPrev, yPrev;
unsigned int buttons;
myParent->getCursorPosition(xPrev, yPrev, buttons);
if (xRound - xPrev != 0 || yRound - yPrev != 0) {
myParent->setCursorPosition(xRound, yRound);
getEventQueue()->mouseWarped(x, y);
}
}
protected:
~FXOSGAdapter();
private:
GUISUMOAbstractView* const myParent;
FXCursor* const myOldCursor;
};
class PlaneMoverCallback : public osg::Callback {
public:
PlaneMoverCallback(osg::Camera* camera) : myCamera(camera) {};
virtual bool run(osg::Object* object, osg::Object* ) override {
osg::MatrixTransform* mt = dynamic_cast<osg::MatrixTransform*>(object);
osg::Vec3d lookFrom, lookAt, up;
myCamera->getViewMatrixAsLookAt(lookFrom, lookAt, up);
osg::Vec3d direction = lookAt - lookFrom;
direction.normalize();
osg::Vec3d lookAtGround = lookFrom - direction * (lookFrom.z() / direction.z());
osg::Matrixd translateMatrix;
translateMatrix.makeTranslate(lookAtGround.x(), lookAtGround.y(), 0.);
double angle = atan2(direction.y(), direction.x());
osg::Matrixd rotMatrix = osg::Matrixd::rotate(angle, osg::Z_AXIS);
mt->setMatrix(rotMatrix * translateMatrix);
return true;
}
protected:
~PlaneMoverCallback() {};
private:
osg::Camera* myCamera;
};
class PickHandler : public osgGA::GUIEventHandler {
public:
PickHandler(GUIOSGView* parent) : myParent(parent), myDrag(false) {};
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);
using osgGA::GUIEventHandler::handle;
protected:
~PickHandler() {};
private:
GUIOSGView* const myParent;
bool myDrag;
};
class ExcludeFromNearFarComputationCallback : public osg::NodeCallback {
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) {
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
osg::CullSettings::ComputeNearFarMode oldMode = osg::CullSettings::COMPUTE_NEAR_FAR_USING_BOUNDING_VOLUMES;
if (cv) {
oldMode = cv->getComputeNearFarMode();
cv->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
}
traverse(node, nv);
if (cv) {
cv->setComputeNearFarMode(oldMode);
}
}
};
protected:
GUIOSGView() {}
osg::ref_ptr<FXOSGAdapter> myAdapter;
osg::ref_ptr<osgViewer::Viewer> myViewer;
osg::ref_ptr<osg::Group> myRoot;
osg::ref_ptr<osg::MatrixTransform> myPlane;
osg::ref_ptr<osg::Camera> myHUD;
osg::ref_ptr<osg::Geode> myTextNode;
osg::ref_ptr<osgText::Text> myText;
private:
GUIVehicle* myTracked;
osg::ref_ptr<GUIOSGManipulator> myCameraManipulator;
SUMOTime myLastUpdate;
float myOSGNormalizedCursorX, myOSGNormalizedCursorY;
std::map<MSVehicle*, OSGMovable > myVehicles;
std::map<MSTransportable*, OSGMovable > myPersons;
osg::ref_ptr<osg::Node> myGreenLight;
osg::ref_ptr<osg::Node> myYellowLight;
osg::ref_ptr<osg::Node> myRedLight;
osg::ref_ptr<osg::Node> myRedYellowLight;
osg::ref_ptr<osg::Node> myPoleBase;
osg::ref_ptr<osg::Node> myPlaneTransform;
};
#endif