]> git.mxchange.org Git - flightgear.git/blob - Scenery/tilemgr.c
Incorporated Paul Bleisch's <bleisch@chromatic.com> new debug message
[flightgear.git] / Scenery / tilemgr.c
1 /**************************************************************************
2  * tilemgr.c -- routines to handle dynamic management of scenery tiles
3  *
4  * Written by Curtis Olson, started January 1998.
5  *
6  * Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of the
11  * License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  *
22  * $Id$
23  * (Log is kept at end of this file)
24  **************************************************************************/
25
26
27 #ifdef WIN32
28 #  include <windows.h>
29 #endif
30
31 #include <GL/glut.h>
32 #include <XGL/xgl.h>
33
34 #include <Scenery/scenery.h>
35 #include <Scenery/bucketutils.h>
36 #include <Scenery/obj.h>
37 #include <Scenery/tilecache.h>
38
39 #include <Aircraft/aircraft.h>
40 #include <Include/fg_constants.h>
41 #include <Include/fg_types.h>
42
43
44 #define FG_LOCAL_X           3   /* should be odd */
45 #define FG_LOCAL_Y           3   /* should be odd */
46 #define FG_LOCAL_X_Y         9   /* At least FG_LOCAL_X times FG_LOCAL_Y */
47
48 #define FG_TILE_CACHE_SIZE 100   /* Must be > FG_LOCAL_X_Y */
49
50
51 /* closest (potentially viewable) tiles, centered on current tile.
52  * This is an array of pointers to cache indexes. */
53 int tiles[FG_LOCAL_X_Y];
54
55 /* tile cache */
56 struct fgTILE tile_cache[FG_TILE_CACHE_SIZE];
57
58
59 /* Initialize the Tile Manager subsystem */
60 void fgTileMgrInit( void ) {
61     printf("Initializing Tile Manager subsystem.\n");
62
63     fgTileCacheInit();
64 }
65
66
67 /* load a tile */
68 void fgTileMgrLoadTile( struct fgBUCKET *p, int *index) {
69     printf("Updating for bucket %d %d %d %d\n", 
70            p->lon, p->lat, p->x, p->y);
71     
72     *index = fgTileCacheNextAvail();
73     printf("Selected cache index of %d\n", *index);
74     
75     fgTileCacheEntryFillIn(*index, p);
76 }
77
78
79 /* given the current lon/lat, fill in the array of local chunks.  If
80  * the chunk isn't already in the cache, then read it from disk. */
81 void fgTileMgrUpdate( void ) {
82     struct fgFLIGHT *f;
83     struct fgBUCKET p1, p2;
84     static struct fgBUCKET p_last = {-1000, 0, 0, 0};
85     int i, j, dw, dh;
86
87     f = &current_aircraft.flight;
88
89     fgBucketFind(FG_Longitude * RAD_TO_DEG, FG_Latitude * RAD_TO_DEG, &p1);
90     dw = FG_LOCAL_X / 2;
91     dh = FG_LOCAL_Y / 2;
92
93     if ( (p1.lon == p_last.lon) && (p1.lat == p_last.lat) && 
94          (p1.x == p_last.x) && (p1.y == p_last.y) ) {
95         /* same bucket as last time */
96         printf("Same bucket as last time\n");
97     } else if ( p_last.lon == -1000 ) {
98         /* First time through, initialize the system and load all
99          * relavant tiles */
100
101         printf("First time through ... \n");
102         printf("Updating Tile list for %d,%d %d,%d\n", 
103                p1.lon, p1.lat, p1.x, p1.y);
104
105         /* wipe tile cache */
106         fgTileCacheInit();
107
108         /* build the local area list and update cache */
109         for ( j = 0; j < FG_LOCAL_Y; j++ ) {
110             for ( i = 0; i < FG_LOCAL_X; i++ ) {
111                 fgBucketOffset(&p1, &p2, i - dw, j - dh);
112                 fgTileMgrLoadTile(&p2, &tiles[(j*FG_LOCAL_Y) + i]);
113             }
114         }
115     } else {
116         /* We've moved to a new bucket, we need to scroll our
117          * structures, and load in the new tiles */
118
119         /* CURRENTLY THIS ASSUMES WE CAN ONLY MOVE TO ADJACENT TILES.
120            AT ULTRA HIGH SPEEDS THIS ASSUMPTION MAY NOT BE VALID IF
121            THE AIRCRAFT CAN SKIP A TILE IN A SINGLE ITERATION. */
122
123         if ( (p1.lon > p_last.lon) || 
124              ( (p1.lon == p_last.lon) && (p1.x > p_last.x) ) ) {
125             for ( j = 0; j < FG_LOCAL_Y; j++ ) {
126                 /* scrolling East */
127                 for ( i = 0; i < FG_LOCAL_X - 1; i++ ) {
128                     tiles[(j*FG_LOCAL_Y) + i] = tiles[(j*FG_LOCAL_Y) + i + 1];
129                 }
130                 /* load in new column */
131                 fgBucketOffset(&p_last, &p2, dw + 1, j - dh);
132                 fgTileMgrLoadTile(&p2, &tiles[(j*FG_LOCAL_Y) + FG_LOCAL_X - 1]);
133             }
134         } else if ( (p1.lon < p_last.lon) || 
135                     ( (p1.lon == p_last.lon) && (p1.x < p_last.x) ) ) {
136             for ( j = 0; j < FG_LOCAL_Y; j++ ) {
137                 /* scrolling West */
138                 for ( i = FG_LOCAL_X - 1; i > 0; i-- ) {
139                     tiles[(j*FG_LOCAL_Y) + i] = tiles[(j*FG_LOCAL_Y) + i - 1];
140                 }
141                 /* load in new column */
142                 fgBucketOffset(&p_last, &p2, -dw - 1, j - dh);
143                 fgTileMgrLoadTile(&p2, &tiles[(j*FG_LOCAL_Y) + 0]);
144             }
145         }
146
147         if ( (p1.lat > p_last.lat) || 
148              ( (p1.lat == p_last.lat) && (p1.y > p_last.y) ) ) {
149             for ( i = 0; i < FG_LOCAL_X; i++ ) {
150                 /* scrolling North */
151                 for ( j = 0; j < FG_LOCAL_Y - 1; j++ ) {
152                     tiles[(j * FG_LOCAL_Y) + i] = 
153                         tiles[((j+1) * FG_LOCAL_Y) + i];
154                 }
155                 /* load in new column */
156                 fgBucketOffset(&p_last, &p2, i - dw, dh + 1);
157                 fgTileMgrLoadTile(&p2, 
158                     &tiles[((FG_LOCAL_Y-1)*FG_LOCAL_Y) + i]);
159             }
160         } else if ( (p1.lat < p_last.lat) || 
161                     ( (p1.lat == p_last.lat) && (p1.y < p_last.y) ) ) {
162             for ( i = 0; i < FG_LOCAL_X; i++ ) {
163                 /* scrolling South */
164                 for ( j = FG_LOCAL_Y - 1; j > 0; j-- ) {
165                     tiles[(j * FG_LOCAL_Y) + i] = 
166                         tiles[((j-1) * FG_LOCAL_Y) + i];
167                 }
168                 /* load in new column */
169                 fgBucketOffset(&p_last, &p2, i - dw, -dh - 1);
170                 fgTileMgrLoadTile(&p2, &tiles[0 + i]);
171             }
172         } 
173     }
174     p_last.lon = p1.lon;
175     p_last.lat = p1.lat;
176     p_last.x = p1.x;
177     p_last.y = p1.y;
178 }
179
180
181 /* Render the local tiles */
182 void fgTileMgrRender( void ) {
183     static GLfloat terrain_color[4] = { 0.6, 0.8, 0.4, 1.0 };
184     static GLfloat terrain_ambient[4];
185     static GLfloat terrain_diffuse[4];
186     struct fgCartesianPoint local_ref;
187     GLint display_list;
188     int i;
189     int index;
190
191     for ( i = 0; i < 4; i++ ) {
192         terrain_ambient[i] = terrain_color[i] * 0.5;
193         terrain_diffuse[i] = terrain_color[i];
194     }
195
196     xglMaterialfv(GL_FRONT, GL_AMBIENT, terrain_ambient);
197     xglMaterialfv(GL_FRONT, GL_DIFFUSE, terrain_diffuse);
198
199     for ( i = 0; i < FG_LOCAL_X_Y; i++ ) {
200         index = tiles[i];
201         /* printf("Index = %d\n", index); */
202         fgTileCacheEntryInfo(index, &display_list, &local_ref );
203
204         xglPushMatrix();
205         xglTranslatef(local_ref.x - scenery.center.x,
206                       local_ref.y - scenery.center.y,
207                       local_ref.z - scenery.center.z);
208         xglCallList(display_list);
209         xglPopMatrix();
210     }
211 }
212
213
214 /* $Log$
215 /* Revision 1.8  1998/01/27 00:48:04  curt
216 /* Incorporated Paul Bleisch's <bleisch@chromatic.com> new debug message
217 /* system and commandline/config file processing code.
218 /*
219  * Revision 1.7  1998/01/26 15:55:25  curt
220  * Progressing on building dynamic scenery system.
221  *
222  * Revision 1.6  1998/01/24 00:03:30  curt
223  * Initial revision.
224  *
225  * Revision 1.5  1998/01/19 19:27:18  curt
226  * Merged in make system changes from Bob Kuehne <rpk@sgi.com>
227  * This should simplify things tremendously.
228  *
229  * Revision 1.4  1998/01/19 18:40:38  curt
230  * Tons of little changes to clean up the code and to remove fatal errors
231  * when building with the c++ compiler.
232  *
233  * Revision 1.3  1998/01/13 00:23:11  curt
234  * Initial changes to support loading and management of scenery tiles.  Note,
235  * there's still a fair amount of work left to be done.
236  *
237  * Revision 1.2  1998/01/08 02:22:27  curt
238  * Continue working on basic features.
239  *
240  * Revision 1.1  1998/01/07 23:50:51  curt
241  * "area" renamed to "tile"
242  *
243  * Revision 1.2  1998/01/07 03:29:29  curt
244  * Given an arbitrary lat/lon, we can now:
245  *   generate a unique index for the chunk containing the lat/lon
246  *   generate a path name to the chunk file
247  *   build a list of the indexes of all the nearby areas.
248  *
249  * Revision 1.1  1998/01/07 02:05:48  curt
250  * Initial revision.
251  * */
252
253