1 /***************************************************************************
2 * This file is part of Tecorrec. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
5 * Tecorrec is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 2 of the License, or *
8 * (at your option) any later version. *
10 * Tecorrec is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with Tecorrec. If not, write to the Free Software Foundation, *
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
21 * @file tcObserver.cpp
22 * @brief Viewing information for an observer.
25 #include "tcObserver.h"
33 * Constructors + destructor
36 /// Primary constructor.
37 tcObserver::tcObserver()
39 , m_focusAltitude(1000e3
)
46 tcObserver::~tcObserver()
54 /// Set up the OpenGL projection matrix for this observer.
55 void tcObserver::setupProjection(double aspect
) const
57 glMatrixMode(GL_PROJECTION
);
60 #define NEAR_DISTANCE 10.0
61 glFrustum(-SIZE
*aspect
, SIZE
*aspect
, -SIZE
, SIZE
, NEAR_DISTANCE
, 20000e3
);
62 glMatrixMode(GL_MODELVIEW
);
65 void drawAxes(float size
)
68 glScalef(size
, size
, size
);
71 glColor3f(1.0f
, 1.0f
, 1.0f
);
72 glVertex3f(0.0f
, 0.0f
, 0.0f
);
73 glColor3f(0.0f
, 1.0f
, 1.0f
);
74 glVertex3f(1.0f
, 0.0f
, 0.0f
);
76 glColor3f(1.0f
, 1.0f
, 1.0f
);
77 glVertex3f(0.0f
, 0.0f
, 0.0f
);
78 glColor3f(1.0f
, 0.0f
, 1.0f
);
79 glVertex3f(0.0f
, 1.0f
, 0.0f
);
81 glColor3f(1.0f
, 1.0f
, 1.0f
);
82 glVertex3f(0.0f
, 0.0f
, 0.0f
);
83 glColor3f(1.0f
, 1.0f
, 0.0f
);
84 glVertex3f(0.0f
, 0.0f
, 1.0f
);
89 glEnable(GL_POINT_SMOOTH
);
92 glColor3f(1.0f
, 1.0f
, 1.0f
);
93 glVertex3f(0.0f
, 0.0f
, 0.0f
);
95 glColor3f(0.0f
, 1.0f
, 1.0f
);
96 glVertex3f(1.0f
, 0.0f
, 0.0f
);
98 glColor3f(1.0f
, 0.0f
, 1.0f
);
99 glVertex3f(0.0f
, 1.0f
, 0.0f
);
101 glColor3f(1.0f
, 1.0f
, 0.0f
);
102 glVertex3f(0.0f
, 0.0f
, 1.0f
);
109 /// Set up the OpenGL modelview matrix for this observer.
110 void tcObserver::setupModelView() const
114 // Translate to focus
115 glTranslatef(0.0f
, 0.0f
, -m_range
);
119 // Rotate to surface space
120 glMultMatrix(m_view
);
124 // Translate to origin
125 glTranslatef(0.0f
, 0.0f
, -m_focusAltitude
);
127 // Rotate to model space
128 glMultMatrix(m_focus
);
137 /// Adjust the focus directly.
138 void tcObserver::setFocus(const tcGeo
& focus
, double altitude
)
141 m_focusAltitude
= altitude
;
144 /// Adjust the focus altitude.
145 void tcObserver::setFocusAltitude(double altitude
)
147 m_focusAltitude
= altitude
;
150 /// Make a local transformation of the focus.
151 void tcObserver::moveFocusRelative(double dx
, double dy
)
153 dx
*= 2.0 * m_range
/ m_focusAltitude
;
154 dy
*= 2.0 * m_range
/ m_focusAltitude
;
155 m_focus
.setLat(m_focus
.lat() - sin(m_view
.azim()) * dx
156 + cos(m_view
.azim()) * dy
);
157 m_focus
.setLon(m_focus
.lon() - cos(m_view
.azim()) * dx
158 - sin(m_view
.azim()) * dy
);
161 /// Adjust the range exponentially.
162 void tcObserver::adjustRange(double x
)
167 /// Adjust the azimuth in radians.
168 void tcObserver::adjustAzimuth(double daz
)
170 m_view
.setAzim(m_view
.azim() + daz
);
173 /// Adjust the elevation in radians.
174 void tcObserver::adjustElevation(double del
)
176 m_view
.setElev(m_view
.elev() + del
);
183 /// Get the current focus position.
184 tcGeo
tcObserver::focus() const
189 /// Get the current range from the focus.
190 double tcObserver::range() const
195 /// Get the position of the actual observer.
196 maths::Vector
<3,double> tcObserver::position() const
198 // transform m_view*m_range+(0,0,m_focusAltitude) into object space
199 maths::Vector
<3,double> focusOrientedObs
= m_view
;
200 focusOrientedObs
*= m_range
;
201 focusOrientedObs
[2] += m_focusAltitude
;
202 return focusOrientedObs
* m_focus
.operator maths::Matrix
<3,double>();
205 /// Get a ray into the scene from a point on the screen.
206 maths::Vector
<3,double> tcObserver::ray(const maths::Vector
<2,double>& pos
, double aspect
)
208 // Vector to near plane
209 maths::Vector
<3,double> toNear(SIZE
*aspect
*(-1.0 + 2.0*pos
[0]),
210 SIZE
*(-1.0 + 2.0*pos
[1]),
214 // Rotate into modelview
215 return (toNear
* m_view
.operator maths::Matrix
<3,double>()) * m_focus
.operator maths::Matrix
<3,double>();