Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GUIOSGPerspectiveChanger.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// Implementation of GUIPerspectiveChanger for OSG 3D views
19/****************************************************************************/
20#include <config.h>
21
22#include <fxkeys.h>
23#include <utils/geom/Boundary.h>
24#include <utils/geom/Position.h>
28
29
30// ===========================================================================
31// method definitions
32// ===========================================================================
34 GUIOSGView& callBack, const Boundary& viewPort) :
35 GUIPerspectiveChanger(callBack, viewPort),
36 myOrigWidth(viewPort.getWidth()),
37 myOrigHeight(viewPort.getHeight()),
38 myRotation(0) {
39 myCameraManipulator = callBack.myCameraManipulator;
40}
41
42
44
45
46bool
49 return false;
50}
51
52
53bool
56 return false;
57}
58
59
60bool
63 return false;
64}
65
66
68 //updateViewport();
69}
70
71
72double
76
77
78double
80 osg::Vec3d lookFrom, lookAt, up;
81 myCameraManipulator->getInverseMatrix().getLookAt(lookFrom, lookAt, up);
82 return lookFrom.x();
83}
84
85
86double
88 osg::Vec3d lookFrom, lookAt, up;
89 myCameraManipulator->getInverseMatrix().getLookAt(lookFrom, lookAt, up);
90 return lookFrom.y();
91}
92
93
94double
96 osg::Vec3d lookFrom, lookAt, up;
97 myCameraManipulator->getInverseMatrix().getLookAt(lookFrom, lookAt, up);
98 return lookFrom.z();
99}
100
101
102double
104 return 100.;
105}
106
107
108double
109GUIOSGPerspectiveChanger::zPos2Zoom(double /* zPos */) const {
110 return 100.;
111}
112
113
114double
115GUIOSGPerspectiveChanger::zoom2ZPos(double /* zoom */) const {
116 return getZPos();
117}
118
119
120void
122 myRotation = rotation;
123}
124
125
126void
127GUIOSGPerspectiveChanger::centerTo(const Position& pos, double radius, bool /* applyZoom */) {
128 // maintain view direction if possible and scale so that the position and the
129 // radius region around it are visible
130 osg::Vec3d lookFrom, lookAt, up, dir, orthoDir;
131 myCameraManipulator->getInverseMatrix().getLookAt(lookFrom, lookAt, up);
132 dir = lookAt - lookFrom;
133 // create helper vectors // check if parallel to z
134 if ((dir ^ osg::Z_AXIS).length() > 0) {
135 orthoDir[0] = -dir[1];
136 orthoDir[1] = dir[0];
137 up = osg::Z_AXIS;
138 } else {
139 orthoDir = -osg::X_AXIS;
140 up = osg::Y_AXIS;
141 }
142 orthoDir.normalize();
143 osg::Vec3d center(pos.x(), pos.y(), pos.z());
144 osg::Vec3d leftBorder = center + orthoDir * radius;
145 // construct new camera location which respects the fovy, resets the up vector
146 double fovy, aspectRatio, zNear, zFar;
147 dynamic_cast<GUIOSGView&>(myCallback).myViewer->getCamera()->getProjectionMatrixAsPerspective(fovy, aspectRatio, zNear, zFar);
148 double halfFovy = DEG2RAD(.5 * fovy);
149 osg::Vec3d outerFov = dir * cos(halfFovy) + orthoDir * sin(halfFovy);
150 osg::Vec3d radiusVec = leftBorder - center;
151 int sign = ((outerFov ^ radiusVec) * (outerFov ^ dir) > 0) ? 1 : -1;
152 osg::Vec3d camUpdate = center + dir * sign * (outerFov ^ radiusVec).length() / (outerFov ^ dir).length();
153 myCameraManipulator->setHomePosition(camUpdate, center, up);
154 myRotation = 0.;
155 dynamic_cast<GUIOSGView&>(myCallback).myViewer->home();
156 updateViewport(camUpdate);
157}
158
159
160void
161GUIOSGPerspectiveChanger::setViewport(double /* zoom */, double xPos, double yPos) {
162 setViewportFrom(xPos, yPos, 0.);
163}
164
165
166void
167GUIOSGPerspectiveChanger::setViewportFrom(double xPos, double yPos, double /* zPos */) {
168 // Keep camera orientation if possible and point it to point to (x,y,0) if possible.
169 // get current camera orientation
170 osg::Vec3d lookFrom, lookAt, up, dir;
171 myCameraManipulator->getInverseMatrix().getLookAt(lookFrom, lookAt, up);
172 dir = lookAt - lookFrom;
173 if ((dir.z() > 0. && lookFrom.z() >= 0.) || dir.z() == 0.) { // create bird view
174 lookFrom[0] = xPos;
175 lookFrom[1] = yPos;
176 lookAt = lookFrom - osg::Vec3d(0., 0., 1.);
177 } else { // shift current view to reach (x,y,0)
178 osg::Vec3d shift;
179 // compute the point on the ground which is in line with the camera direction (solve for z=0)
180 double factor = -lookFrom.z() / dir.z();
181 osg::Vec3d groundTarget = lookFrom + dir * factor;
182 shift[0] = xPos - groundTarget.x();
183 shift[1] = yPos - groundTarget.y();
184 lookFrom += shift;
185 lookAt += shift;
186 }
187 osg::Matrix m;
188 m.makeLookAt(lookFrom, lookAt, up);
189 myCameraManipulator->setByInverseMatrix(m);
190 updateViewport(lookFrom);
191}
192
193
194void
196 osg::Vec3d lookFrom, lookAt, up, dir;
197 myCameraManipulator->getInverseMatrix().getLookAt(lookFrom, lookAt, up);
198 updateViewport(lookFrom);
199}
200
201
202void
203GUIOSGPerspectiveChanger::updateViewport(osg::Vec3d& /* lookFrom */) {
204 osg::Vec3d bottomLeft = getPositionOnGround(-1., -1.);
205 osg::Vec3d bottomRight = getPositionOnGround(1., -1.);
206 osg::Vec3d topLeft = getPositionOnGround(1., -1.);
207 osg::Vec3d topRight = getPositionOnGround(1., 1.);
208 double xMin, xMax, yMin, yMax;
209 xMin = MIN4(bottomLeft.x(), bottomRight.x(), topLeft.x(), topRight.x());
210 xMax = MAX4(bottomLeft.x(), bottomRight.x(), topLeft.x(), topRight.x());
211 yMin = MIN4(bottomLeft.y(), bottomRight.y(), topLeft.y(), topRight.y());
212 yMax = MAX4(bottomLeft.y(), bottomRight.y(), topLeft.y(), topRight.y());
213 myViewPort.set(xMin, yMin, xMax, yMax);
214}
215
216
217osg::Vec3d
219 osg::Matrix VP = dynamic_cast<GUIOSGView&>(myCallback).myViewer->getCamera()->getViewMatrix() * dynamic_cast<GUIOSGView&>(myCallback).myViewer->getCamera()->getProjectionMatrix();
220 osg::Matrix inverseVP;
221 inverseVP.invert(VP);
222
223 // compute world near far
224 osg::Vec3d nearPoint(x, y, -1.);
225 osg::Vec3d farPoint(x, y, 1.);
226 osg::Vec3d nearPointWorld = nearPoint * inverseVP;
227 osg::Vec3d farPointWorld = farPoint * inverseVP;
228
229 // compute crossing with ground plane
230 osg::Vec3d ray = farPointWorld - nearPointWorld;
231 if (abs(ray.z()) > 0) {
232 return nearPointWorld + ray * (-nearPointWorld.z() / ray.z());
233 }
234 return osg::Vec3d(0., 0., 0.);
235}
236
237
238void
241
242
243void
245 setViewport(100., viewPort.getCenter().x(), viewPort.getCenter().y());
246}
#define DEG2RAD(x)
Definition GeomHelper.h:35
T MIN4(T a, T b, T c, T d)
Definition StdDefs.h:103
T MAX4(T a, T b, T c, T d)
Definition StdDefs.h:110
A class that stores a 2D geometrical boundary.
Definition Boundary.h:39
Position getCenter() const
Returns the center of the boundary.
Definition Boundary.cpp:112
void set(double xmin, double ymin, double xmax, double ymax)
Sets the boundary to the given values.
Definition Boundary.cpp:412
void setRotation(double rotation)
Sets the rotation.
double getYPos() const
Returns the y-offset of the field to show stored in this changer.
void updateViewport()
update the min/max coordinates of the view on the ground plane after changing the camera pos / direct...
GUIOSGPerspectiveChanger(GUIOSGView &callBack, const Boundary &viewPort)
void setViewportFrom(double xPos, double yPos, double zPos)
Alternative method for setting the viewport.
double getRotation() const
Returns the rotation of the canvas stored in this changer.
osg::Vec3d getPositionOnGround(double x, double y)
calculate the position on the ground (in world coordinates) given a normalised view coordinate (x,...
double getZPos() const
Returns the camera height corresponding to the current zoom factor.
double getXPos() const
Returns the x-offset of the field to show stored in this changer.
bool onMiddleBtnRelease(void *data)
called when user releases middle button
double zPos2Zoom(double zPos) const
Returns the zoom level that is achieved at a given camera height.
bool onRightBtnRelease(void *data)
called when user releases right button
double zoom2ZPos(double zoom) const
Returns the camera height at which the given zoom level is reached.
osg::ref_ptr< osgGA::TerrainManipulator > myCameraManipulator
the OSG camera structure to gather the view coordinates
double myRotation
the current rotation
void centerTo(const Position &pos, double radius, bool applyZoom=true)
Centers the view to the given position, setting it to a size that covers the radius....
bool onLeftBtnRelease(void *data)
mouse functions
void setViewport(double zoom, double xPos, double yPos)
Sets the viewport Used for: Adapting a new viewport.
double getZoom() const
Returns the zoom factor computed stored in this changer.
void onMouseMove(void *data)
called when user moves mouse
GUISUMOAbstractView & myCallback
The parent window (canvas to scale)
Boundary myViewPort
the intended viewport
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
double x() const
Returns the x-position.
Definition Position.h:55
double z() const
Returns the z-position.
Definition Position.h:65
double y() const
Returns the y-position.
Definition Position.h:60