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 ***************************************************************************/
22 * @brief Manages data for a globe.
26 #include "tcPhotographyData.h"
27 #include "tcLandsatData.h"
28 #include "tcSrtmModel.h"
37 * Constructors + destructor
40 /// Primary constructor.
41 tcGlobe::tcGlobe(double meanRadius
)
42 : m_meanRadius(meanRadius
)
43 , m_elevation(new tcSrtmModel())
46 addDataSet(new tcLandsatData("/home/james/cs/pro/data/LE71950281999206EDC01/"));
58 /// Add a dataset to the globe.
59 void tcGlobe::addDataSet(tcPhotographyData
* data
)
61 m_data
.push_back(data
);
68 /// Draw a line of latitude.
69 void tcGlobe::drawLineOfLatitude(double latitude
) const
71 double z
= sin(latitude
) * m_meanRadius
;
72 double xy
= cos(latitude
) * m_meanRadius
;
73 glBegin(GL_LINE_LOOP
);
75 for (int lon
= 0; lon
< 360; ++lon
)
77 glVertex3d(xy
*sin(M_PI
/180*lon
), xy
*cos(M_PI
/180*lon
), z
);
84 void tcGlobe::renderCell(tcObserver
* const observer
, const tcGeo
& swCorner
, const tcGeo
& neCorner
) const
86 // Find the square distances to each corner
88 glGetv(GL_MODELVIEW_MATRIX
, &modelview
);
89 tcGeo geoCorners
[4] = {
90 tcGeo(swCorner
.lon(), swCorner
.lat()),
91 tcGeo(swCorner
.lon(), neCorner
.lat()),
92 tcGeo(neCorner
.lon(), neCorner
.lat()),
93 tcGeo(neCorner
.lon(), swCorner
.lat())
95 GLvec3d cartCorners
[4];
97 for (int i
= 0; i
< 4; ++i
)
99 cartCorners
[i
] = (GLvec3d
)geoCorners
[i
] * m_meanRadius
;
100 toCorners
[i
] = (modelview
*(cartCorners
[i
], 1.0)).slice
<0,3>().sqr();
101 // Cull faces which are roughly backfacing
102 if ((modelview
*(cartCorners
[i
], 0.0))[2] <= 0.0)
108 // Decide whether to subdivide
109 float diagonal
= (cartCorners
[0]-cartCorners
[2]).sqr()*4;
110 bool subdivide
= true;
111 // If it is disproportionately tall, only subdivide horizontally
112 bool tall
= (cartCorners
[1] - cartCorners
[0]) > (cartCorners
[3] - cartCorners
[0]).sqr()*4.0;
113 for (int i
= 0; i
< 4; ++i
)
115 if (toCorners
[i
] > diagonal
)
124 glColor3f(0.0f
, 0.0f
, 1.0f
);
128 glColor3f(1.0f
, 0.5f
, 0.0f
);
132 glBegin(GL_LINE_LOOP
);
133 for (int i
= 0; i
< 4; ++i
)
135 glVertex3(cartCorners
[i
]);
145 renderCell(observer
, geoCorners
[0], (geoCorners
[3] + geoCorners
[2]) * 0.5);
147 renderCell(observer
, (geoCorners
[0] + geoCorners
[1]) * 0.5, geoCorners
[2]);
152 renderCell(observer
, geoCorners
[0], (geoCorners
[0] + geoCorners
[2]) * 0.5);
154 renderCell(observer
, (geoCorners
[0] + geoCorners
[3]) * 0.5, (geoCorners
[3] + geoCorners
[2]) * 0.5);
156 renderCell(observer
, (geoCorners
[0] + geoCorners
[1]) * 0.5, (geoCorners
[1] + geoCorners
[2]) * 0.5);
158 renderCell(observer
, (geoCorners
[0] + geoCorners
[2]) * 0.5, geoCorners
[2]);
164 const int resolution
= 16;
165 for (int i
= 0; i
< resolution
; ++i
)
167 glBegin(GL_TRIANGLE_STRIP
);
169 for (int j
= 0; j
<= resolution
; ++j
)
171 for (int k
= 0; k
< 2; ++k
)
173 double dlon
= (neCorner
.lon()-swCorner
.lon()) / resolution
;
174 double dlat
= (neCorner
.lat()-swCorner
.lat()) / resolution
;
175 tcGeo coord
= swCorner
+ tcGeo((i
+k
) * dlon
, j
* dlat
);
176 bool accurate
= false;
177 double alt
= m_elevation
->altitudeAt(coord
, &accurate
);
180 glColor4f(0.0f
, 0.0f
, 0.5f
, 0.5f
);
184 glColor4f(1.0f
, 1.0f
-(float)alt
/3278.0f
, 0.0f
, 1.0f
);
187 double rad
= m_meanRadius
+ alt
;
188 glVertex3(dir
* rad
);
196 /// Render from the POV of an observer.
197 void tcGlobe::render(tcObserver
* const observer
)
199 /// @todo use a really simple fragment shader to cull backfacing lines
202 glColor3f(0.0f
, 1.0f
, 0.0f
);
203 for (int lat
= -75; lat
<= 75; lat
+= 15)
207 drawLineOfLatitude(M_PI
/180*lat
);
211 double tropic
= (23.0 + 26.0/60 + 22.0/3600) * M_PI
/180;
213 glColor3f(1.0f
, 0.0f
, 0.0f
);
214 drawLineOfLatitude(0.0);
215 // Tropics (Capricorn and Cancer)
216 glColor3f(1.0f
, 0.0f
, 1.0f
);
217 drawLineOfLatitude(-tropic
);
218 glColor3f(1.0f
, 1.0f
, 0.0f
);
219 drawLineOfLatitude(+tropic
);
220 // Arctic and Antarctic Circles
221 glColor3f(1.0f
, 1.0f
, 1.0f
);
222 drawLineOfLatitude(+M_PI
/2 - tropic
);
223 drawLineOfLatitude(-M_PI
/2 + tropic
);
225 // Lines of longitude
226 for (int lon
= 0; lon
< 360; lon
+= 15)
228 double x
= sin(M_PI
/180*lon
) * m_meanRadius
;
229 double y
= -cos(M_PI
/180*lon
) * m_meanRadius
;
235 glColor3f(1.0f
, lon
/180, 0.0f
);
242 glBegin(GL_LINE_STRIP
);
244 for (int lat
= minLat
; lat
<= maxLat
; ++lat
)
246 double z
= cos(M_PI
/180*lat
) * m_meanRadius
;
247 double xy
= sin(M_PI
/180*lat
);
248 glVertex3d(xy
*x
, xy
*y
, z
);
255 glColor3f(0.0f
, 1.0f
, 0.0f
);
260 // Draw data diagramatically
261 foreach (tcPhotographyData
* data
, m_data
)
263 data
->renderSchematic(m_meanRadius
, observer
);
269 for (int lon
= -180; lon
< 180; lon
+= dlon
)
271 for (int lat
= -90; lat
< 90; lat
+= dlat
)
273 tcGeo
sw(M_PI
/180 * (lon
), M_PI
/180 * (lat
));
274 tcGeo
ne(M_PI
/180 * (lon
+dlon
), M_PI
/180 * (lat
+dlat
));
275 renderCell(observer
, sw
, ne
);
284 /// Get the mean radius.
285 double tcGlobe::meanRadius() const