Can now select a region of the map and it only draws that bit and at higher sample...
[tecorrec.git] / geo / tcObserver.cpp
blobcabe46e3077342cdf9a1b6ef60e15402f1f16a05
1 /***************************************************************************
2 * This file is part of Tecorrec. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
4 * *
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. *
9 * *
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. *
14 * *
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 ***************************************************************************/
20 /**
21 * @file tcObserver.cpp
22 * @brief Viewing information for an observer.
25 #include "tcObserver.h"
26 #include <glMatrix.h>
28 #include <GL/gl.h>
30 #include <cmath>
33 * Constructors + destructor
36 /// Primary constructor.
37 tcObserver::tcObserver()
38 : m_focus(0.0, 0.0)
39 , m_focusAltitude(1000e3)
40 , m_view(0, M_PI/2)
41 , m_range(100e3)
45 /// Destructor.
46 tcObserver::~tcObserver()
51 * Main interface
54 /// Set up the OpenGL projection matrix for this observer.
55 void tcObserver::setupProjection(double aspect) const
57 glMatrixMode(GL_PROJECTION);
58 glLoadIdentity();
59 #define SIZE 5.0
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)
67 glPushMatrix();
68 glScalef(size, size, size);
69 glBegin(GL_LINES);
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);
86 glEnd();
88 glPointSize(5);
89 glEnable(GL_POINT_SMOOTH);
90 glBegin(GL_POINTS);
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);
104 glEnd();
105 glPointSize(1);
106 glPopMatrix();
109 /// Set up the OpenGL modelview matrix for this observer.
110 void tcObserver::setupModelView() const
112 glLoadIdentity();
114 // Translate to focus
115 glTranslatef(0.0f, 0.0f, -m_range);
117 //drawAxes(50e3f);
119 // Rotate to surface space
120 glMultMatrix(m_view);
122 //drawAxes(50e3f);
124 // Translate to origin
125 glTranslatef(0.0f, 0.0f, -m_focusAltitude);
127 // Rotate to model space
128 glMultMatrix(m_focus);
130 //drawAxes(1000e3f);
134 * Mutators
137 /// Adjust the focus directly.
138 void tcObserver::setFocus(const tcGeo& focus, double altitude)
140 m_focus = focus;
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)
164 m_range *= exp(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);
180 * Accessors
183 /// Get the current focus position.
184 tcGeo tcObserver::focus() const
186 return m_focus;
189 /// Get the current range from the focus.
190 double tcObserver::range() const
192 return m_range;
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]),
211 -NEAR_DISTANCE);
212 // Normalize
213 toNear.normalize();
214 // Rotate into modelview
215 return (toNear * m_view.operator maths::Matrix<3,double>()) * m_focus.operator maths::Matrix<3,double>();