Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/osgview/GUIOSGView.h
169665 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2025 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
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 = 1,
79
/// @brief markers above lanes showing the signal state of the corresponding tlIndex
80
NODESET_TLSLINKMARKERS = 2,
81
/// @brief auto-generated TLS models
82
NODESET_TLSMODELS = 4,
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::PositionAttitudeTransform> body;
134
osg::ref_ptr<osg::Material> mat;
135
osg::ref_ptr<osg::Switch> lights;
136
bool active;
137
138
void activateMaterial(bool state = true) {
139
osg::ref_ptr<osg::StateSet> ss = body->getOrCreateStateSet();
140
if (state) {
141
ss->setAttribute(mat, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
142
} else {
143
ss->setAttribute(mat, osg::StateAttribute::OFF);
144
}
145
}
146
};
147
148
/// @brief constructor
149
GUIOSGView(FXComposite* p, GUIMainWindow& app,
150
GUISUMOViewParent* parent, GUINet& net, FXGLVisual* glVis,
151
FXGLCanvas* share);
152
153
/// @brief destructor
154
virtual ~GUIOSGView();
155
156
/// @brief Returns the cursor's x/y position within the network
157
Position getPositionInformation() const override;
158
159
/// @brief confirm 3D view to viewport editor
160
bool is3DView() const override;
161
162
/// @brief builds the view toolbars
163
virtual void buildViewToolBars(GUIGlChildWindow*) override;
164
165
/// @brief recenters the view
166
void recenterView() override;
167
168
/** @brief centers to the chosen artifact
169
* @param[in] id The id of the artifact to center to
170
* @param[in] applyZoom Whether to zoom in
171
* @param[in] zoomDist The distance in m to use for the zoom, values < 0 means: use the centeringBoundary
172
* @note caller is responsible for calling update
173
*/
174
//void centerTo(GUIGlID id, bool applyZoom, double zoomDist = 20);
175
176
/// @brief update the viewport chooser with the current view values
177
void updateViewportValues() override;
178
179
/// @brief show viewport editor
180
void showViewportEditor() override;
181
182
/// @brief applies the given viewport settings
183
void setViewportFromToRot(const Position& lookFrom, const Position& lookAt, double rotation) override;
184
185
/// @brief copy the viewport to the given view
186
void copyViewportTo(GUISUMOAbstractView* view) override;
187
188
/** @brief Starts vehicle tracking
189
* @param[in] id The glID of the vehicle to track
190
*/
191
void startTrack(int id) override;
192
193
/** @brief Stops vehicle tracking
194
*/
195
void stopTrack() override;
196
197
/** @brief Returns the id of the tracked vehicle (-1 if none)
198
* @return The glID of the vehicle to track
199
*/
200
GUIGlID getTrackedID() const override;
201
202
bool setColorScheme(const std::string& name) override;
203
204
/// @brief handle mouse click in gaming mode
205
void onGamingClick(Position pos) override;
206
207
/// @brief get the current simulation time
208
SUMOTime getCurrentTimeStep() const override;
209
210
void removeVeh(MSVehicle* veh);
211
void removeTransportable(MSTransportable* t);
212
213
/// @brief added some callback to OSG to resize
214
void position(int x, int y, int w, int h) override;
215
void resize(int w, int h) override;
216
217
// callback
218
long onConfigure(FXObject*, FXSelector, void*) override;
219
long onKeyPress(FXObject*, FXSelector, void*) override;
220
long onKeyRelease(FXObject*, FXSelector, void*) override;
221
long onLeftBtnPress(FXObject*, FXSelector, void*) override;
222
long onLeftBtnRelease(FXObject*, FXSelector, void*) override;
223
long onMiddleBtnPress(FXObject*, FXSelector, void*) override;
224
long onMiddleBtnRelease(FXObject*, FXSelector, void*) override;
225
long onRightBtnPress(FXObject*, FXSelector, void*) override;
226
long onRightBtnRelease(FXObject*, FXSelector, void*) override;
227
//long onMotion(FXObject*, FXSelector, void*);
228
long onMouseMove(FXObject*, FXSelector, void*) override;
229
long onPaint(FXObject*, FXSelector, void*) override;
230
long onIdle(FXObject* sender, FXSelector sel, void* ptr);
231
232
/// @brief interaction with the simulation
233
long onCmdCloseLane(FXObject*, FXSelector, void*) override;
234
long onCmdCloseEdge(FXObject*, FXSelector, void*) override;
235
long onCmdAddRerouter(FXObject*, FXSelector, void*) override;
236
237
/// @brief highlight edges according to reachability
238
long onCmdShowReachability(FXObject*, FXSelector, void*) override;
239
240
/// @brief reset graphical settings when forced to refresh the view (triggered by ViewSettings)
241
long onVisualizationChange(FXObject*, FXSelector, void*) override;
242
243
// @brief get the new camera position given a zoom value
244
void zoom2Pos(Position& camera, Position& lookAt, double zoom) override;
245
246
// @brief convert RGBColor 0..255 RGBA values to osg::Vec4 0..1 vector
247
static osg::Vec4d toOSGColorVector(RGBColor c, bool useAlpha = false);
248
249
// @brief Overwrite the HUD text
250
void updateHUDText(const std::string text);
251
252
protected:
253
/// @brief Store the normalized OSG window cursor coordinates
254
void setWindowCursorPosition(float x, float y);
255
256
void updatePositionInformation() const;
257
258
/// @brief Compute the world coordinate on the ground plane given the normalized cursor position inside the OSG view (range X, Y [-1;1])
259
bool getPositionAtCursor(float xNorm, float yNorm, Position& pos) const;
260
261
/// @brief returns the GUIGlObject under the cursor using OSG ray intersecting
262
std::vector<GUIGlObject*> getGUIGlObjectsUnderCursor();
263
264
/* @brief Find GUILane which intersects with a ray from the camera to the stored cursor position
265
* @return The first found GUILane found or nullptr
266
*/
267
GUILane* getLaneUnderCursor() override;
268
269
/// @brief implement the current view settings in OSG
270
void adoptViewSettings();
271
272
private:
273
double calculateRotation(const osg::Vec3d& lookFrom, const osg::Vec3d& lookAt, const osg::Vec3d& up);
274
275
/// @brief inform HUD about the current window size to let it reposition
276
void updateHUDPosition(int width, int height);
277
278
class FXOSGAdapter : public osgViewer::GraphicsWindow {
279
public:
280
FXOSGAdapter(GUISUMOAbstractView* parent, FXCursor* cursor);
281
void grabFocus();
282
void grabFocusIfPointerInWindow() {}
283
void useCursor(bool cursorOn);
284
285
bool makeCurrentImplementation();
286
bool releaseContext();
287
void swapBuffersImplementation();
288
289
// not implemented yet...just use dummy implementation to get working.
290
bool valid() const {
291
return true;
292
}
293
bool realizeImplementation() {
294
return true;
295
}
296
bool isRealizedImplementation() const {
297
return true;
298
}
299
void closeImplementation() {}
300
bool releaseContextImplementation() {
301
return true;
302
}
303
void requestWarpPointer(float x, float y) {
304
int xRound = std::lround(x);
305
int yRound = std::lround(y);
306
int xPrev, yPrev;
307
unsigned int buttons;
308
myParent->getCursorPosition(xPrev, yPrev, buttons);
309
if (xRound - xPrev != 0 || yRound - yPrev != 0) {
310
myParent->setCursorPosition(xRound, yRound);
311
getEventQueue()->mouseWarped(x, y);
312
}
313
}
314
315
protected:
316
~FXOSGAdapter();
317
private:
318
GUISUMOAbstractView* const myParent;
319
FXCursor* const myOldCursor;
320
};
321
322
class PlaneMoverCallback : public osg::Callback {
323
public:
324
PlaneMoverCallback(osg::Camera* camera) : myCamera(camera) {};
325
virtual bool run(osg::Object* object, osg::Object* /* data */) override {
326
osg::MatrixTransform* mt = dynamic_cast<osg::MatrixTransform*>(object);
327
osg::Vec3d lookFrom, lookAt, up;
328
myCamera->getViewMatrixAsLookAt(lookFrom, lookAt, up);
329
osg::Vec3d direction = lookAt - lookFrom;
330
direction.normalize();
331
osg::Vec3d lookAtGround = lookFrom - direction * (lookFrom.z() / direction.z());
332
osg::Matrixd translateMatrix;
333
translateMatrix.makeTranslate(lookAtGround.x(), lookAtGround.y(), 0.);
334
double angle = atan2(direction.y(), direction.x());
335
osg::Matrixd rotMatrix = osg::Matrixd::rotate(angle, osg::Z_AXIS);
336
mt->setMatrix(rotMatrix * translateMatrix);
337
return true;
338
}
339
protected:
340
~PlaneMoverCallback() {};
341
private:
342
osg::Camera* myCamera;
343
};
344
345
class PickHandler : public osgGA::GUIEventHandler {
346
public:
347
PickHandler(GUIOSGView* parent) : myParent(parent), myDrag(false) {};
348
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);
349
using osgGA::GUIEventHandler::handle; // to silence the warning C4266 about a hidden function
350
protected:
351
~PickHandler() {};
352
private:
353
GUIOSGView* const myParent;
354
bool myDrag;
355
};
356
357
class ExcludeFromNearFarComputationCallback : public osg::NodeCallback {
358
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) {
359
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
360
// Default value
361
osg::CullSettings::ComputeNearFarMode oldMode = osg::CullSettings::COMPUTE_NEAR_FAR_USING_BOUNDING_VOLUMES;
362
if (cv) {
363
oldMode = cv->getComputeNearFarMode();
364
cv->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
365
}
366
traverse(node, nv);
367
if (cv) {
368
cv->setComputeNearFarMode(oldMode);
369
}
370
}
371
};
372
373
374
375
protected:
376
GUIOSGView() {}
377
378
osg::ref_ptr<FXOSGAdapter> myAdapter;
379
osg::ref_ptr<osgViewer::Viewer> myViewer;
380
osg::ref_ptr<osg::Group> myRoot;
381
osg::ref_ptr<osg::MatrixTransform> myPlane;
382
osg::ref_ptr<osg::Camera> myHUD;
383
osg::ref_ptr<osg::Geode> myTextNode;
384
osg::ref_ptr<osgText::Text> myText;
385
386
private:
387
GUIVehicle* myTracked;
388
osg::ref_ptr<GUIOSGManipulator> myCameraManipulator;
389
SUMOTime myLastUpdate;
390
391
float myOSGNormalizedCursorX, myOSGNormalizedCursorY;
392
393
std::map<MSVehicle*, OSGMovable > myVehicles;
394
std::map<MSTransportable*, OSGMovable > myPersons;
395
396
osg::ref_ptr<osg::Node> myGreenLight;
397
osg::ref_ptr<osg::Node> myYellowLight;
398
osg::ref_ptr<osg::Node> myRedLight;
399
osg::ref_ptr<osg::Node> myRedYellowLight;
400
osg::ref_ptr<osg::Node> myPoleBase;
401
osg::ref_ptr<osg::Node> myPlaneTransform;
402
};
403
404
#endif
405
406