Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GUIOSGManipulator.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/****************************************************************************/
18// A custom camera manipulator to interact with the OSG view directly
19/****************************************************************************/
20#include <config.h>
21
25
26#include "GUIOSGManipulator.h"
27#include "GUIOSGView.h"
28
29#ifdef HAVE_OSG
30
31#define DEFAULT_MOVESPEED_MIN 1.0
32//#define DEFAULT_MOVESPEED_MAX 30.0
33//#define DEFAULT_MOVEACCEL 2.0
34
35static StringBijection<ManipulatorMode>::Entry ModeTextInitializer[] = {
36 {"Ego", MODE_EGO},
37 {"Walk", MODE_WALK},
38 {"Terrain", MODE_TERRAIN}
39};
40
41StringBijection<ManipulatorMode> ModeText(ModeTextInitializer, MODE_TERRAIN, false);
42
43
44// ===========================================================================
45// method definitions
46// ===========================================================================
47GUIOSGManipulator::GUIOSGManipulator(GUIOSGView* parent, ManipulatorMode initMode, bool verticalFixed, double /* eyeHeight */) :
48 myParent(parent), myCurrentMode(initMode), /*myWalkEyeHeight(eyeHeight),*/ myMoveSpeed(DEFAULT_MOVESPEED_MIN) {
49 setAllowThrow(false);
50 setVerticalAxisFixed(verticalFixed);
51}
52
53
54GUIOSGManipulator::~GUIOSGManipulator() {
55}
56
57
58bool
59GUIOSGManipulator::performMovementLeftMouseButton(const double eventTimeDelta, const double dx, const double dy) {
60 if (myCurrentMode == MODE_TERRAIN) {
61 return osgGA::TerrainManipulator::performMovementMiddleMouseButton(eventTimeDelta, dx, dy);
62 }
63 return false;
64}
65
66
67bool
68GUIOSGManipulator::performMovementMiddleMouseButton(const double eventTimeDelta, const double dx, const double dy) {
69 if (myCurrentMode == MODE_TERRAIN) {
70 return osgGA::TerrainManipulator::performMovementLeftMouseButton(eventTimeDelta, dx, dy);
71 }
72 return false;
73}
74
75
76bool
77GUIOSGManipulator::performMovementRightMouseButton(const double eventTimeDelta, const double dx, const double dy) {
78 if (myCurrentMode == MODE_TERRAIN) {
79 return osgGA::TerrainManipulator::performMovementRightMouseButton(eventTimeDelta, dx, -dy);
80 }
81 return false;
82}
83
84
85bool
86GUIOSGManipulator::handleMouseMove(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) {
87 if (myCurrentMode == MODE_EGO || myCurrentMode == MODE_WALK) {
88 return handleMouseDeltaMovement(ea, aa);
89 }
90 return false;
91}
92
93
94bool
95GUIOSGManipulator::handleMouseDrag(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) {
96 if (myCurrentMode == MODE_TERRAIN) {
97 return osgGA::TerrainManipulator::handleMouseDrag(ea, aa);
98 }
99 return handleMouseDeltaMovement(ea, aa);
100}
101
102
103bool
104GUIOSGManipulator::handleMousePush(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) {
105 if (myCurrentMode == MODE_TERRAIN) {
106 return osgGA::TerrainManipulator::handleMousePush(ea, aa);
107 }
108 return handleMouseDeltaMovement(ea, aa);
109}
110
111
112bool
113GUIOSGManipulator::handleMouseRelease(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) {
114 if (myCurrentMode == MODE_TERRAIN) {
115 return osgGA::TerrainManipulator::handleMouseRelease(ea, aa);
116 }
117 return false;
118}
119
120
121bool
122GUIOSGManipulator::handleMouseDeltaMovement(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) {
123 addMouseEvent(ea);
124 if (_ga_t0.get() == NULL || _ga_t1.get() == NULL) {
125 return false;
126 }
127 float dt = static_cast<float>(_ga_t0->getTime() - _ga_t1->getTime());
128 if (dt > 0.1) { // wait until the mouse movement is sufficiently smooth
129 return false;
130 }
131 float intensity = 50.;
132 float dx = _ga_t0->getXnormalized() * intensity * dt;
133 float dy = _ga_t0->getYnormalized() * intensity * dt;
134 if (dx == 0. && dy == 0.) {
135 return false;
136 }
137 centerMousePointer(ea, aa);
138 // calculate delta angles from dx and dy movements
139 if (performMouseDeltaMovement(dx, dy)) {
140 aa.requestRedraw();
141 }
142 return true;
143}
144
145
146bool
147GUIOSGManipulator::performMouseDeltaMovement(const float dx, const float dy) {
148 rotateYawPitch(_rotation, dx, dy, osg::Z_AXIS);
149 return true;
150}
151
152
153void GUIOSGManipulator::centerMousePointer(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) {
154 _mouseCenterX = (ea.getXmin() + ea.getXmax()) / 2.0f;
155 _mouseCenterY = (ea.getYmin() + ea.getYmax()) / 2.0f;
156 aa.requestWarpPointer(_mouseCenterX, _mouseCenterY);
157}
158
159
160void
161GUIOSGManipulator::rotateYawPitch(osg::Quat& rotation, const double yaw, const double pitch, const osg::Vec3d& localUp) {
162 bool verticalAxisFixed = (localUp != osg::Vec3d(0., 0., 0.));
163
164 // fix current rotation
165 if (verticalAxisFixed) {
166 fixVerticalAxis(rotation, localUp, true);
167 }
168
169 // rotations
170 osg::Quat rotateYaw(-yaw, verticalAxisFixed ? localUp : rotation * osg::Vec3d(0., 1., 0.));
171 osg::Quat rotatePitch;
172 osg::Quat newRotation;
173 osg::Vec3d cameraRight(rotation * osg::Vec3d(1., 0., 0.));
174
175 double my_dy = pitch;
176 int i = 0;
177 osg::Vec3f eye = _center - _rotation * osg::Vec3d(0., 0., -_distance);
178 do {
179 // rotations
180 rotatePitch.makeRotate(my_dy, cameraRight);
181 newRotation = rotation * rotateYaw * rotatePitch;
182
183 // update vertical axis
184 if (verticalAxisFixed) {
185 fixVerticalAxis(newRotation, localUp, false);
186 }
187
188 // check for viewer's up vector to be more than 90 degrees from "up" axis
189 osg::Vec3d newCameraUp = newRotation * osg::Vec3d(0., 1., 0.);
190 if (newCameraUp * localUp > 0.) {
191 // apply new rotation
192 setByMatrix(osg::Matrixd::rotate(newRotation) * osg::Matrixd::translate(eye));
193 return;
194 }
195 my_dy /= 2.;
196 if (++i == 20) {
197 setByMatrix(osg::Matrixd::rotate(rotation) * osg::Matrixd::rotate(rotateYaw) * osg::Matrixd::translate(eye));
198 return;
199 }
200 } while (true);
201}
202
203
204bool
205GUIOSGManipulator::handleKeyDown(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& /* aa */) {
206 bool result = false;
207 switch (ea.getKey()) {
208 case osgGA::GUIEventAdapter::KEY_Up:
209 myMove.z() -= myMoveSpeed;
210 result = true;
211 break;
212 case osgGA::GUIEventAdapter::KEY_Down:
213 myMove.z() += myMoveSpeed;
214 result = true;
215 break;
216 case osgGA::GUIEventAdapter::KEY_Right:
217 myMove.x() += myMoveSpeed;
218 result = true;
219 break;
220 case osgGA::GUIEventAdapter::KEY_Left:
221 myMove.x() -= myMoveSpeed;
222 result = true;
223 break;
224 }
225 _center += getMatrix().getRotate() * myMove;
226 return result;
227}
228
229
230bool
231GUIOSGManipulator::handleKeyUp(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& /* aa */) {
232 bool result = false;
233 switch (ea.getKey()) {
234 case osgGA::GUIEventAdapter::KEY_Up:
235 case osgGA::GUIEventAdapter::KEY_Down:
236 case osgGA::GUIEventAdapter::KEY_Right:
237 case osgGA::GUIEventAdapter::KEY_Left:
238 myMove.set(0, 0, 0);
239 return true;
240 case osgGA::GUIEventAdapter::KEY_F:
241 if (myCurrentMode == MODE_EGO) {
242 myCurrentMode = MODE_TERRAIN; // MODE_WALK disabled until it's fully implemented
243 } else if (myCurrentMode == MODE_WALK) {
244 myCurrentMode = MODE_TERRAIN;
245 } else {
246 myCurrentMode = MODE_EGO;
247 }
248 updateHUDText();
249 return true;
250 }
251 return result;
252}
253
254
255void
256GUIOSGManipulator::updateHUDText() {
257 myParent->updateHUDText(TLF("Currently in % camera mode. Press [F] to switch.", ModeText.getString(myCurrentMode)));
258}
259
260
261void
262GUIOSGManipulator::setByMatrix(const osg::Matrixd& matrix) {
263 _center = osg::Vec3d(0., 0., -_distance) * matrix;
264 _rotation = matrix.getRotate();
265
266 // fix current rotation
267 if (getVerticalAxisFixed()) {
268 fixVerticalAxis(_center, _rotation, true);
269 }
270}
271
272
273osg::Matrixd GUIOSGManipulator::getMatrix() const {
274 if (myCurrentMode == MODE_TERRAIN) {
275 return osg::Matrixd::translate(0., 0., _distance) *
276 osg::Matrixd::rotate(_rotation) *
277 osg::Matrixd::translate(_center);
278 } else {
279 osg::Vec3f eye = _center - _rotation * osg::Vec3d(0., 0., -_distance);
280 return osg::Matrixd::rotate(_rotation) * osg::Matrixd::translate(eye);
281 }
282}
283
284
285osg::Matrixd GUIOSGManipulator::getInverseMatrix() const {
286 if (myCurrentMode == MODE_TERRAIN) {
287 return osg::Matrixd::translate(-_center) *
288 osg::Matrixd::rotate(_rotation.inverse()) *
289 osg::Matrixd::translate(0.0, 0.0, -_distance);
290 } else {
291 osg::Vec3f eye = _center - _rotation * osg::Vec3d(0., 0., -_distance);
292 return osg::Matrixd::translate(-eye) * osg::Matrixd::rotate(_rotation.inverse());
293 }
294}
295
296#endif
#define TLF(string,...)
Definition MsgHandler.h:317