]> git.mxchange.org Git - flightgear.git/blob - Scenery/tilecache.cxx
b6af2640b30a6b8618c90f4727f2a74af0b18e2d
[flightgear.git] / Scenery / tilecache.cxx
1 // tilecache.cxx -- routines to handle scenery tile caching
2 //
3 // Written by Curtis Olson, started January 1998.
4 //
5 // Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 // $Id$
22 // (Log is kept at end of this file)
23
24
25 #ifdef HAVE_CONFIG_H
26 #  include <config.h>
27 #endif
28
29 #ifdef HAVE_WINDOWS_H
30 #  include <windows.h>
31 #endif
32
33 #include <GL/glut.h>
34 #include <XGL/xgl.h>
35
36 #include <Airports/genapt.hxx>
37 #include <Bucket/bucketutils.h>
38 #include <Debug/fg_debug.h>
39 #include <Main/options.hxx>
40 #include <Main/views.hxx>
41 #include <Objects/obj.hxx>
42
43 #include "tile.hxx"
44 #include "tilecache.hxx"
45
46
47 // the tile cache
48 fgTILECACHE global_tile_cache;
49
50
51 // Constructor
52 fgTILECACHE::fgTILECACHE( void ) {
53 }
54
55
56 // Initialize the tile cache subsystem
57 void
58 fgTILECACHE::init( void )
59 {
60     int i;
61
62     fgPrintf(FG_TERRAIN, FG_INFO, "Initializing the tile cache.\n");
63
64     for ( i = 0; i < FG_TILE_CACHE_SIZE; i++ ) {
65         tile_cache[i].used = 0;
66     }
67 }
68
69
70 // Search for the specified "bucket" in the cache
71 int
72 fgTILECACHE::exists( fgBUCKET *p )
73 {
74     int i;
75
76     for ( i = 0; i < FG_TILE_CACHE_SIZE; i++ ) {
77         if ( tile_cache[i].tile_bucket.lon == p->lon ) {
78             if ( tile_cache[i].tile_bucket.lat == p->lat ) {
79                 if ( tile_cache[i].tile_bucket.x == p->x ) {
80                     if ( tile_cache[i].tile_bucket.y == p->y ) {
81                         fgPrintf( FG_TERRAIN, FG_DEBUG, 
82                                   "TILE EXISTS in cache ... index = %d\n", i );
83                         return( i );
84                     }
85                 }
86             }
87         }
88     }
89     
90     return( -1 );
91 }
92
93
94 // Fill in a tile cache entry with real data for the specified bucket
95 void
96 fgTILECACHE::fill_in( int index, fgBUCKET *p )
97 {
98     string root, tile_path, apt_path;
99     char index_str[256];
100     char base_path[256];
101
102     // Mark this cache entry as used
103     tile_cache[index].used = 1;
104
105     // Update the bucket
106     tile_cache[index].tile_bucket.lon = p->lon;
107     tile_cache[index].tile_bucket.lat = p->lat;
108     tile_cache[index].tile_bucket.x = p->x;
109     tile_cache[index].tile_bucket.y = p->y;
110
111     // Load the appropriate data file and built tile fragment list
112     fgBucketGenBasePath(p, base_path);
113     root = current_options.get_fg_root();
114     sprintf( index_str, "%ld", fgBucketGenIndex(p) );
115
116     tile_path = root + "/Scenery/" + base_path + "/" + index_str;
117     fgObjLoad( tile_path.c_str(), &tile_cache[index] );
118
119     // cout << " ncount before = " << tile_cache[index].ncount << "\n";
120     // cout << " fragments before = " << tile_cache[index].fragment_list.size()
121     //      << "\n";
122
123     apt_path = tile_path + ".apt";
124     fgAptGenerate( apt_path, &tile_cache[index] );
125
126     // cout << " ncount after = " << tile_cache[index].ncount << "\n";
127     // cout << " fragments after = " << tile_cache[index].fragment_list.size()
128     //      << "\n";
129 }
130
131
132 // Free a tile cache entry
133 void
134 fgTILECACHE::entry_free( int index )
135 {
136     fgFRAGMENT *fragment;
137
138     // Mark this cache entry as un-used
139     tile_cache[index].used = 0;
140
141     // Update the bucket
142     fgPrintf( FG_TERRAIN, FG_DEBUG, 
143               "FREEING TILE = (%d %d %d %d)\n",
144               tile_cache[index].tile_bucket.lon, 
145               tile_cache[index].tile_bucket.lat, 
146               tile_cache[index].tile_bucket.x,
147               tile_cache[index].tile_bucket.y );
148
149     // Step through the fragment list, deleting the display list, then
150     // the fragment, until the list is empty.
151     while ( tile_cache[index].fragment_list.size() ) {
152         list < fgFRAGMENT > :: iterator current =
153             tile_cache[index].fragment_list.begin();
154         fragment = &(*current);
155         xglDeleteLists( fragment->display_list, 1 );
156
157         tile_cache[index].fragment_list.pop_front();
158     }
159 }
160
161
162 // Return the specified tile cache entry 
163 fgTILE *
164 fgTILECACHE::get_tile( int index )
165 {
166     return ( &tile_cache[index] );
167 }
168
169
170 // Return index of next available slot in tile cache
171 int
172 fgTILECACHE::next_avail( void )
173 {
174     fgVIEW *v;
175     Point3D delta;
176     int i;
177     float max, med, min, tmp;
178     float dist, max_dist;
179     int max_index;
180     
181     v = &current_view;
182
183     max_dist = 0.0;
184     max_index = 0;
185
186     for ( i = 0; i < FG_TILE_CACHE_SIZE; i++ ) {
187         if ( tile_cache[i].used == 0 ) {
188             return(i);
189         } else {
190             // calculate approximate distance from view point
191             fgPrintf( FG_TERRAIN, FG_DEBUG,
192                       "DIST Abs view pos = %.4f, %.4f, %.4f\n", 
193                       v->abs_view_pos.x(), v->abs_view_pos.y(),
194                       v->abs_view_pos.z() );
195             fgPrintf( FG_TERRAIN, FG_DEBUG,
196                       "    ref point = %.4f, %.4f, %.4f\n", 
197                       tile_cache[i].center.x(), tile_cache[i].center.y(),
198                       tile_cache[i].center.z());
199
200             delta.setx( fabs(tile_cache[i].center.x() - v->abs_view_pos.x() ) );
201             delta.sety( fabs(tile_cache[i].center.y() - v->abs_view_pos.y() ) );
202             delta.setz( fabs(tile_cache[i].center.z() - v->abs_view_pos.z() ) );
203
204             max = delta.x(); med = delta.y(); min = delta.z();
205             if ( max < med ) {
206                 tmp = max; max = med; med = tmp;
207             }
208             if ( max < min ) {
209                 tmp = max; max = min; min = tmp;
210             }
211             dist = max + (med + min) / 4;
212
213             fgPrintf( FG_TERRAIN, FG_DEBUG, "    distance = %.2f\n", dist);
214
215             if ( dist > max_dist ) {
216                 max_dist = dist;
217                 max_index = i;
218             }
219         }
220     }
221
222     // If we made it this far, then there were no open cache entries.
223     // We will instead free the furthest cache entry and return it's
224     // index.
225     
226     entry_free( max_index );
227     return( max_index );
228 }
229
230
231 // Destructor
232 fgTILECACHE::~fgTILECACHE( void ) {
233 }
234
235
236 // $Log$
237 // Revision 1.18  1998/10/16 18:12:28  curt
238 // Fixed a bug in the conversion to Point3D.
239 //
240 // Revision 1.17  1998/10/16 00:55:48  curt
241 // Converted to Point3D class.
242 //
243 // Revision 1.16  1998/09/14 12:45:23  curt
244 // minor tweaks.
245 //
246 // Revision 1.15  1998/08/27 17:02:10  curt
247 // Contributions from Bernie Bright <bbright@c031.aone.net.au>
248 // - use strings for fg_root and airport_id and added methods to return
249 //   them as strings,
250 // - inlined all access methods,
251 // - made the parsing functions private methods,
252 // - deleted some unused functions.
253 // - propogated some of these changes out a bit further.
254 //
255 // Revision 1.14  1998/08/25 16:52:43  curt
256 // material.cxx material.hxx obj.cxx obj.hxx texload.c texload.h moved to
257 //   ../Objects
258 //
259 // Revision 1.13  1998/07/13 21:02:00  curt
260 // Wrote access functions for current fgOPTIONS.
261 //
262 // Revision 1.12  1998/07/12 03:18:29  curt
263 // Added ground collision detection.  This involved:
264 // - saving the entire vertex list for each tile with the tile records.
265 // - saving the face list for each fragment with the fragment records.
266 // - code to intersect the current vertical line with the proper face in
267 //   an efficient manner as possible.
268 // Fixed a bug where the tiles weren't being shifted to "near" (0,0,0)
269 //
270 // Revision 1.11  1998/07/04 00:54:30  curt
271 // Added automatic mipmap generation.
272 //
273 // When rendering fragments, use saved model view matrix from associated tile
274 // rather than recalculating it with push() translate() pop().
275 //
276 // Revision 1.10  1998/05/23 14:09:22  curt
277 // Added tile.cxx and tile.hxx.
278 // Working on rewriting the tile management system so a tile is just a list
279 // fragments, and the fragment record contains the display list for that fragment.
280 //
281 // Revision 1.9  1998/05/20 20:53:54  curt
282 // Moved global ref point and radius (bounding sphere info, and offset) to
283 // data file rather than calculating it on the fly.
284 // Fixed polygon winding problem in scenery generation stage rather than
285 // compensating for it on the fly.
286 // Made a fgTILECACHE class.
287 //
288 // Revision 1.8  1998/05/16 13:09:57  curt
289 // Beginning to add support for view frustum culling.
290 // Added some temporary code to calculate bouding radius, until the
291 //   scenery generation tools and scenery can be updated.
292 //
293 // Revision 1.7  1998/05/13 18:26:41  curt
294 // Root path info moved to fgOPTIONS.
295 //
296 // Revision 1.6  1998/05/02 01:52:17  curt
297 // Playing around with texture coordinates.
298 //
299 // Revision 1.5  1998/04/30 12:35:31  curt
300 // Added a command line rendering option specify smooth/flat shading.
301 //
302 // Revision 1.4  1998/04/28 01:21:43  curt
303 // Tweaked texture parameter calculations to keep the number smaller.  This
304 // avoids the "swimming" problem.
305 // Type-ified fgTIME and fgVIEW.
306 //
307 // Revision 1.3  1998/04/25 22:06:32  curt
308 // Edited cvs log messages in source files ... bad bad bad!
309 //
310 // Revision 1.2  1998/04/24 00:51:08  curt
311 // Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
312 // Tweaked the scenery file extentions to be "file.obj" (uncompressed)
313 // or "file.obz" (compressed.)
314 //
315 // Revision 1.1  1998/04/22 13:22:46  curt
316 // C++ - ifing the code a bit.
317 //
318 // Revision 1.11  1998/04/18 04:14:07  curt
319 // Moved fg_debug.c to it's own library.
320 //
321 // Revision 1.10  1998/04/14 02:23:17  curt
322 // Code reorganizations.  Added a Lib/ directory for more general libraries.
323 //
324 // Revision 1.9  1998/04/08 23:30:07  curt
325 // Adopted Gnu automake/autoconf system.
326 //
327 // Revision 1.8  1998/04/03 22:11:38  curt
328 // Converting to Gnu autoconf system.
329 //
330 // Revision 1.7  1998/02/01 03:39:55  curt
331 // Minor tweaks.
332 //
333 // Revision 1.6  1998/01/31 00:43:26  curt
334 // Added MetroWorks patches from Carmen Volpe.
335 //
336 // Revision 1.5  1998/01/29 00:51:39  curt
337 // First pass at tile cache, dynamic tile loading and tile unloading now works.
338 //
339 // Revision 1.4  1998/01/27 03:26:43  curt
340 // Playing with new fgPrintf command.
341 //
342 // Revision 1.3  1998/01/27 00:48:03  curt
343 // Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
344 // system and commandline/config file processing code.
345 //
346 // Revision 1.2  1998/01/26 15:55:24  curt
347 // Progressing on building dynamic scenery system.
348 //
349 // Revision 1.1  1998/01/24 00:03:29  curt
350 // Initial revision.
351
352
353