LCOV - code coverage report
Current view: top level - src/osgview - GUIOSGView.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 27 40 67.5 %
Date: 2024-05-08 15:29:52 Functions: 10 16 62.5 %

          Line data    Source code
       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             : /****************************************************************************/
      14             : /// @file    GUIOSGView.h
      15             : /// @author  Daniel Krajzewicz
      16             : /// @author  Mirko Barthauer
      17             : /// @date    19.01.2012
      18             : ///
      19             : // An OSG-based 3D view on the simulation
      20             : /****************************************************************************/
      21             : #pragma once
      22             : #include <config.h>
      23             : 
      24             : #ifdef HAVE_OSG
      25             : 
      26             : #include "GUIOSGHeader.h"
      27             : #include "GUIOSGManipulator.h"
      28             : 
      29             : #include <string>
      30             : #include <microsim/traffic_lights/MSTLLogicControl.h>
      31             : #include <utils/geom/Boundary.h>
      32             : #include <utils/geom/Position.h>
      33             : #include <utils/common/RGBColor.h>
      34             : #include <utils/geom/PositionVector.h>
      35             : #include <gui/GUISUMOViewParent.h>
      36             : #include <utils/gui/windows/GUISUMOAbstractView.h>
      37             : 
      38             : 
      39             : // ===========================================================================
      40             : // class declarations
      41             : // ===========================================================================
      42             : 
      43             : class GUINet;
      44             : class GUISUMOViewParent;
      45             : class GUIVehicle;
      46             : class GUILaneWrapper;
      47             : class MSRoute;
      48             : class MSTransportable;
      49             : class MSVehicle;
      50             : 
      51             : namespace osgGA {
      52             : class CameraManipulator;
      53             : }
      54             : 
      55             : // ===========================================================================
      56             : // class definitions
      57             : // ===========================================================================
      58             : /**
      59             :  * @class GUIOSGView
      60             :  * @brief An OSG-based 3D view on the simulation
      61             :  */
      62             : class GUIOSGView : public GUISUMOAbstractView {
      63             : #ifdef __clang__
      64             : #pragma clang diagnostic push
      65             : #pragma clang diagnostic ignored "-Winconsistent-missing-override"
      66             : #endif
      67           0 :     FXDECLARE(GUIOSGView)
      68             : #ifdef __clang__
      69             : #pragma clang diagnostic pop
      70             : #endif
      71             : 
      72             : public:
      73             :     friend class GUIOSGPerspectiveChanger;
      74             : 
      75             :     /// @brief Used osg::NodeSet groups
      76             :     enum NodeSetGroup {
      77             :         /// @brief semi-transparent domes around user-placed TLS models
      78             :         NODESET_TLSDOMES,
      79             :         /// @brief markers above lanes showing the signal state of the corresponding tlIndex
      80             :         NODESET_TLSLINKMARKERS,
      81             :         /// @brief auto-generated TLS models
      82             :         NODESET_TLSMODELS,
      83             :     };
      84             : 
      85             :     /**
      86             :      * @class Command_TLSChange
      87             :      * @brief Updates scene on each tls switch
      88             :      */
      89             :     class Command_TLSChange : public MSTLLogicControl::OnSwitchAction {
      90             :     public:
      91             :         /** @brief Constructor
      92             :          *
      93             :          * @param[in] link   The link to observe
      94             :          * @param[in] root   the root of the scene
      95             :          * @param[in] green  the green light
      96             :          * @param[in] yellow the yellow light
      97             :          * @param[in] red    the red light
      98             :          */
      99             :         Command_TLSChange(const MSLink* const link, osg::Switch* switchNode);
     100             : 
     101             :         /// @brief Destructor
     102             :         virtual ~Command_TLSChange();
     103             : 
     104             :         /** @brief Executes the command
     105             :          *
     106             :          * Called when an active tls program switches.
     107             :          *  If the state of the observed linkchanged, this method removes
     108             :          *  the old traffic light and adds a new one.
     109             :          */
     110             :         void execute();
     111             : 
     112             :     private:
     113             :         /// @brief The link to observe
     114             :         const MSLink* const myLink;
     115             : 
     116             :         /// @brief The switch for the traffic light models
     117             :         osg::ref_ptr<osg::Switch> mySwitch;
     118             : 
     119             :         /// @brief The previous link state
     120             :         LinkState myLastState;
     121             : 
     122             :     private:
     123             :         /// @brief Invalidated copy constructor.
     124             :         Command_TLSChange(const Command_TLSChange&) = delete;
     125             : 
     126             :         /// @brief Invalidated assignment operator.
     127             :         Command_TLSChange& operator=(const Command_TLSChange&) = delete;
     128             :     };
     129             : 
     130             :     /// @brief struct for OSG movable elements
     131             :     struct OSGMovable {
     132             :         osg::ref_ptr<osg::PositionAttitudeTransform> pos;
     133             :         osg::ref_ptr<osg::ShapeDrawable> geom;
     134             :         osg::ref_ptr<osg::Material> mat;
     135             :         osg::ref_ptr<osg::Switch> lights;
     136             :         bool active;
     137             :     };
     138             : 
     139             :     /// @brief constructor
     140             :     GUIOSGView(FXComposite* p, GUIMainWindow& app,
     141             :                GUISUMOViewParent* parent, GUINet& net, FXGLVisual* glVis,
     142             :                FXGLCanvas* share);
     143             : 
     144             :     /// @brief destructor
     145             :     virtual ~GUIOSGView();
     146             : 
     147             :     /// @brief Returns the cursor's x/y position within the network
     148             :     Position getPositionInformation() const override;
     149             : 
     150             :     /// @brief confirm 3D view to viewport editor
     151             :     bool is3DView() const override;
     152             : 
     153             :     /// @brief builds the view toolbars
     154             :     virtual void buildViewToolBars(GUIGlChildWindow*) override;
     155             : 
     156             :     /// @brief recenters the view
     157             :     void recenterView() override;
     158             : 
     159             :     /** @brief centers to the chosen artifact
     160             :      * @param[in] id The id of the artifact to center to
     161             :      * @param[in] applyZoom Whether to zoom in
     162             :      * @param[in] zoomDist The distance in m to use for the zoom, values < 0 means: use the centeringBoundary
     163             :      * @note caller is responsible for calling update
     164             :      */
     165             :     //void centerTo(GUIGlID id, bool applyZoom, double zoomDist = 20);
     166             : 
     167             :     /// @brief update the viewport chooser with the current view values
     168             :     void updateViewportValues() override;
     169             : 
     170             :     /// @brief show viewport editor
     171             :     void showViewportEditor() override;
     172             : 
     173             :     /// @brief applies the given viewport settings
     174             :     void setViewportFromToRot(const Position& lookFrom, const Position& lookAt, double rotation) override;
     175             : 
     176             :     /// @brief copy the viewport to the given view
     177             :     void copyViewportTo(GUISUMOAbstractView* view) override;
     178             : 
     179             :     /** @brief Starts vehicle tracking
     180             :      * @param[in] id The glID of the vehicle to track
     181             :      */
     182             :     void startTrack(int id) override;
     183             : 
     184             :     /** @brief Stops vehicle tracking
     185             :      */
     186             :     void stopTrack() override;
     187             : 
     188             :     /** @brief Returns the id of the tracked vehicle (-1 if none)
     189             :      * @return The glID of the vehicle to track
     190             :      */
     191             :     GUIGlID getTrackedID() const override;
     192             : 
     193             :     bool setColorScheme(const std::string& name) override;
     194             : 
     195             :     /// @brief handle mouse click in gaming mode
     196             :     void onGamingClick(Position pos) override;
     197             : 
     198             :     /// @brief get the current simulation time
     199             :     SUMOTime getCurrentTimeStep() const override;
     200             : 
     201             :     void removeVeh(MSVehicle* veh);
     202             :     void removeTransportable(MSTransportable* t);
     203             : 
     204             :     /// @brief added some callback to OSG to resize
     205             :     void position(int x, int y, int w, int h) override;
     206             :     void resize(int w, int h) override;
     207             : 
     208             :     // callback
     209             :     long onConfigure(FXObject*, FXSelector, void*) override;
     210             :     long onKeyPress(FXObject*, FXSelector, void*) override;
     211             :     long onKeyRelease(FXObject*, FXSelector, void*) override;
     212             :     long onLeftBtnPress(FXObject*, FXSelector, void*) override;
     213             :     long onLeftBtnRelease(FXObject*, FXSelector, void*) override;
     214             :     long onMiddleBtnPress(FXObject*, FXSelector, void*) override;
     215             :     long onMiddleBtnRelease(FXObject*, FXSelector, void*) override;
     216             :     long onRightBtnPress(FXObject*, FXSelector, void*) override;
     217             :     long onRightBtnRelease(FXObject*, FXSelector, void*) override;
     218             :     //long onMotion(FXObject*, FXSelector, void*);
     219             :     long onMouseMove(FXObject*, FXSelector, void*) override;
     220             :     long onPaint(FXObject*, FXSelector, void*) override;
     221             :     long onIdle(FXObject* sender, FXSelector sel, void* ptr);
     222             : 
     223             :     /// @brief interaction with the simulation
     224             :     long onCmdCloseLane(FXObject*, FXSelector, void*) override;
     225             :     long onCmdCloseEdge(FXObject*, FXSelector, void*) override;
     226             :     long onCmdAddRerouter(FXObject*, FXSelector, void*) override;
     227             : 
     228             :     /// @brief highlight edges according to reachability
     229             :     long onCmdShowReachability(FXObject*, FXSelector, void*) override;
     230             : 
     231             :     /// @brief reset graphical settings when forced to refresh the view (triggered by ViewSettings)
     232             :     long onVisualizationChange(FXObject*, FXSelector, void*) override;
     233             : 
     234             :     // @brief get the new camera position given a zoom value
     235             :     void zoom2Pos(Position& camera, Position& lookAt, double zoom) override;
     236             : 
     237             :     // @brief convert RGBColor 0..255 RGBA values to osg::Vec4 0..1 vector
     238             :     static osg::Vec4d toOSGColorVector(RGBColor c, bool useAlpha = false);
     239             : 
     240             :     // @brief Overwrite the HUD text
     241             :     void updateHUDText(const std::string text);
     242             : 
     243             : protected:
     244             :     /// @brief Store the normalized OSG window cursor coordinates
     245             :     void setWindowCursorPosition(float x, float y);
     246             : 
     247             :     void updatePositionInformation() const;
     248             : 
     249             :     /// @brief Compute the world coordinate on the ground plane given the normalized cursor position inside the OSG view (range X, Y [-1;1])
     250             :     bool getPositionAtCursor(float xNorm, float yNorm, Position& pos) const;
     251             : 
     252             :     /// @brief returns the GUIGlObject under the cursor using OSG ray intersecting
     253             :     std::vector<GUIGlObject*> getGUIGlObjectsUnderCursor();
     254             : 
     255             :     /* @brief Find GUILane which intersects with a ray from the camera to the stored cursor position
     256             :      * @return The first found GUILane found or nullptr
     257             :      */
     258             :     GUILane* getLaneUnderCursor() override;
     259             : 
     260             :     /// @brief implement the current view settings in OSG
     261             :     void adoptViewSettings();
     262             : 
     263             : private:
     264             :     double calculateRotation(const osg::Vec3d& lookFrom, const osg::Vec3d& lookAt, const osg::Vec3d& up);
     265             : 
     266             :     /// @brief inform HUD about the current window size to let it reposition
     267             :     void updateHUDPosition(int width, int height);
     268             : 
     269             :     class FXOSGAdapter : public osgViewer::GraphicsWindow {
     270             :     public:
     271             :         FXOSGAdapter(GUISUMOAbstractView* parent, FXCursor* cursor);
     272             :         void grabFocus();
     273           0 :         void grabFocusIfPointerInWindow() {}
     274             :         void useCursor(bool cursorOn);
     275             : 
     276             :         bool makeCurrentImplementation();
     277             :         bool releaseContext();
     278             :         void swapBuffersImplementation();
     279             : 
     280             :         // not implemented yet...just use dummy implementation to get working.
     281      215928 :         bool valid() const {
     282      215928 :             return true;
     283             :         }
     284           0 :         bool realizeImplementation() {
     285           0 :             return true;
     286             :         }
     287        1194 :         bool isRealizedImplementation() const  {
     288        1194 :             return true;
     289             :         }
     290         400 :         void closeImplementation() {}
     291       21474 :         bool releaseContextImplementation() {
     292       21474 :             return true;
     293             :         }
     294           0 :         void requestWarpPointer(float x, float y) {
     295           0 :             int xRound = std::lround(x);
     296           0 :             int yRound = std::lround(y);
     297             :             int xPrev, yPrev;
     298             :             unsigned int buttons;
     299           0 :             myParent->getCursorPosition(xPrev, yPrev, buttons);
     300           0 :             if (xRound - xPrev != 0 || yRound - yPrev != 0) {
     301           0 :                 myParent->setCursorPosition(xRound, yRound);
     302           0 :                 getEventQueue()->mouseWarped(x, y);
     303             :             }
     304           0 :         }
     305             : 
     306             :     protected:
     307             :         ~FXOSGAdapter();
     308             :     private:
     309             :         GUISUMOAbstractView* const myParent;
     310             :         FXCursor* const myOldCursor;
     311             :     };
     312             : 
     313             :     class PlaneMoverCallback : public osg::Callback {
     314             :     public:
     315         400 :         PlaneMoverCallback(osg::Camera* camera) : myCamera(camera) {};
     316       21074 :         virtual bool run(osg::Object* object, osg::Object* /* data */) override {
     317       21074 :             osg::MatrixTransform* mt = dynamic_cast<osg::MatrixTransform*>(object);
     318             :             osg::Vec3d lookFrom, lookAt, up;
     319       21074 :             myCamera->getViewMatrixAsLookAt(lookFrom, lookAt, up);
     320             :             osg::Vec3d direction = lookAt - lookFrom;
     321       21074 :             direction.normalize();
     322       21074 :             osg::Vec3d lookAtGround = lookFrom - direction * (lookFrom.z() / direction.z());
     323             :             osg::Matrixd translateMatrix;
     324       21074 :             translateMatrix.makeTranslate(lookAtGround.x(), lookAtGround.y(), 0.);
     325       21074 :             double angle = atan2(direction.y(), direction.x());
     326             :             osg::Matrixd rotMatrix = osg::Matrixd::rotate(angle, osg::Z_AXIS);
     327       21074 :             mt->setMatrix(rotMatrix * translateMatrix);
     328       21074 :             return true;
     329             :         }
     330             :     protected:
     331         400 :         ~PlaneMoverCallback() {};
     332             :     private:
     333             :         osg::Camera* myCamera;
     334             :     };
     335             : 
     336             :     class PickHandler : public osgGA::GUIEventHandler {
     337             :     public:
     338         400 :         PickHandler(GUIOSGView* parent) : myParent(parent), myDrag(false) {};
     339             :         bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);
     340             :     protected:
     341         800 :         ~PickHandler() {};
     342             :     private:
     343             :         GUIOSGView* const myParent;
     344             :         bool myDrag;
     345             :     };
     346             : 
     347         400 :     class ExcludeFromNearFarComputationCallback : public osg::NodeCallback {
     348       20847 :         virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) {
     349       20847 :             osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
     350             :             // Default value
     351             :             osg::CullSettings::ComputeNearFarMode oldMode = osg::CullSettings::COMPUTE_NEAR_FAR_USING_BOUNDING_VOLUMES;
     352       20847 :             if (cv) {
     353             :                 oldMode = cv->getComputeNearFarMode();
     354             :                 cv->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
     355             :             }
     356       20847 :             traverse(node, nv);
     357       20847 :             if (cv) {
     358             :                 cv->setComputeNearFarMode(oldMode);
     359             :             }
     360       20847 :         }
     361             :     };
     362             : 
     363             : 
     364             : 
     365             : protected:
     366           0 :     GUIOSGView() {}
     367             : 
     368             :     osg::ref_ptr<FXOSGAdapter> myAdapter;
     369             :     osg::ref_ptr<osgViewer::Viewer> myViewer;
     370             :     osg::ref_ptr<osg::Group> myRoot;
     371             :     osg::ref_ptr<osg::MatrixTransform> myPlane;
     372             :     osg::ref_ptr<osg::Camera> myHUD;
     373             :     osg::ref_ptr<osg::Geode> myTextNode;
     374             :     osg::ref_ptr<osgText::Text> myText;
     375             : 
     376             : private:
     377             :     GUIVehicle* myTracked;
     378             :     osg::ref_ptr<GUIOSGManipulator> myCameraManipulator;
     379             :     SUMOTime myLastUpdate;
     380             : 
     381             :     float myOSGNormalizedCursorX, myOSGNormalizedCursorY;
     382             : 
     383             :     std::map<MSVehicle*, OSGMovable > myVehicles;
     384             :     std::map<MSTransportable*, OSGMovable > myPersons;
     385             : 
     386             :     osg::ref_ptr<osg::Node> myGreenLight;
     387             :     osg::ref_ptr<osg::Node> myYellowLight;
     388             :     osg::ref_ptr<osg::Node> myRedLight;
     389             :     osg::ref_ptr<osg::Node> myRedYellowLight;
     390             :     osg::ref_ptr<osg::Node> myPoleBase;
     391             :     osg::ref_ptr<osg::Node> myPlaneTransform;
     392             : };
     393             : 
     394             : #endif

Generated by: LCOV version 1.14