]> git.mxchange.org Git - flightgear.git/blob - AssemTris/assemtris.c
typedef'd struct fgBUCKET.
[flightgear.git] / AssemTris / assemtris.c
1 /* splittris.c -- reassemble the pieces produced by splittris
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 modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU 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 #include <math.h>
26 #include <stdio.h>
27 #include <stdlib.h>   /* for atoi() */
28 #include <string.h>
29 #include <sys/stat.h> /* for stat() */
30 #include <unistd.h>   /* for stat() */
31
32 #include "assemtris.h"
33
34 #include <Include/fg_constants.h>
35 #include <Include/fg_types.h>
36 // #include <Math/fg_geodesy.h>
37 // #include <Math/mat3.h>
38 // #include <Math/polar.h>
39 #include <Bucket/bucketutils.h>
40
41
42 int nodecount = 0;
43
44 static double nodes[MAX_NODES][3];
45
46
47 fgBUCKET my_index;
48 fgBUCKET ne_index, nw_index, sw_index, se_index;
49 fgBUCKET north_index, south_index, east_index, west_index;
50
51
52 /* return the file base name ( foo/bar/file.ext = file.ext ) */
53 void extract_file(char *in, char *base) {
54     int len, i;
55
56     len = strlen(in);
57
58     i = len - 1;
59     while ( (i >= 0) && (in[i] != '/') ) {
60         i--;
61     }
62
63     in += (i + 1);
64     strcpy(base, in);
65 }
66
67
68 /* return the file path name ( foo/bar/file.ext = foo/bar ) */
69 void extract_path(char *in, char *base) {
70     int len, i;
71
72     len = strlen(in);
73     strcpy(base, in);
74
75     i = len - 1;
76     while ( (i >= 0) && (in[i] != '/') ) {
77         i--;
78     }
79
80     base[i] = '\0';
81 }
82
83
84 /* check if a file exists */
85 int file_exists(char *file) {
86     struct stat stat_buf;
87     int result;
88
89     printf("checking %s ... ", file);
90
91     result = stat(file, &stat_buf);
92
93     if ( result != 0 ) {
94         /* stat failed, no file */
95         printf("not found.\n");
96         return(0);
97     } else {
98         /* stat succeeded, file exists */
99         printf("exists.\n");
100         return(1);
101     }
102 }
103
104
105 /* check to see if a shared object exists */
106 int shared_object_exists(char *basepath, char *ext, char *file) {
107     char scene_path[256];
108     long int index;
109
110     if ( strcmp(ext, ".sw") == 0 ) {
111         fgBucketGenBasePath(&my_index, scene_path);
112         index = fgBucketGenIndex(&my_index);
113         sprintf(file, "%s/%s/%ld.1.sw", basepath, scene_path, index);
114         if ( file_exists(file) ) {
115             return(1);
116         }
117         fgBucketGenBasePath(&west_index, scene_path);
118         index = fgBucketGenIndex(&west_index);
119         sprintf(file, "%s/%s/%ld.1.se", basepath, scene_path, index);
120         if ( file_exists(file) ) {
121             return(1);
122         }
123         fgBucketGenBasePath(&sw_index, scene_path);
124         index = fgBucketGenIndex(&sw_index);
125         sprintf(file, "%s/%s/%ld.1.ne", basepath, scene_path, index);
126         if ( file_exists(file) ) {
127             return(1);
128         }
129         fgBucketGenBasePath(&south_index, scene_path);
130         index = fgBucketGenIndex(&south_index);
131         sprintf(file, "%s/%s/%ld.1.nw", basepath, scene_path, index);
132         if ( file_exists(file) ) {
133             return(1);
134         }
135     }
136
137     if ( strcmp(ext, ".se") == 0 ) {
138         fgBucketGenBasePath(&my_index, scene_path);
139         index = fgBucketGenIndex(&my_index);
140         sprintf(file, "%s/%s/%ld.1.se", basepath, scene_path, index);
141         if ( file_exists(file) ) {
142             return(1);
143         }
144         fgBucketGenBasePath(&east_index, scene_path);
145         index = fgBucketGenIndex(&east_index);
146         sprintf(file, "%s/%s/%ld.1.sw", basepath, scene_path, index);
147         if ( file_exists(file) ) {
148             return(1);
149         }
150         fgBucketGenBasePath(&se_index, scene_path);
151         index = fgBucketGenIndex(&se_index);
152         sprintf(file, "%s/%s/%ld.1.nw", basepath, scene_path, index);
153         if ( file_exists(file) ) {
154             return(1);
155         }
156         fgBucketGenBasePath(&south_index, scene_path);
157         index = fgBucketGenIndex(&south_index);
158         sprintf(file, "%s/%s/%ld.1.ne", basepath, scene_path, index);
159         if ( file_exists(file) ) {
160             return(1);
161         }
162     }
163
164     if ( strcmp(ext, ".ne") == 0 ) {
165         fgBucketGenBasePath(&my_index, scene_path);
166         index = fgBucketGenIndex(&my_index);
167         sprintf(file, "%s/%s/%ld.1.ne", basepath, scene_path, index);
168         if ( file_exists(file) ) {
169             return(1);
170         }
171         fgBucketGenBasePath(&east_index, scene_path);
172         index = fgBucketGenIndex(&east_index);
173         sprintf(file, "%s/%s/%ld.1.nw", basepath, scene_path, index);
174         if ( file_exists(file) ) {
175             return(1);
176         }
177         fgBucketGenBasePath(&ne_index, scene_path);
178         index = fgBucketGenIndex(&ne_index);
179         sprintf(file, "%s/%s/%ld.1.sw", basepath, scene_path, index);
180         if ( file_exists(file) ) {
181             return(1);
182         }
183         fgBucketGenBasePath(&north_index, scene_path);
184         index = fgBucketGenIndex(&north_index);
185         sprintf(file, "%s/%s/%ld.1.se", basepath, scene_path, index);
186         if ( file_exists(file) ) {
187             return(1);
188         }
189     }
190
191     if ( strcmp(ext, ".nw") == 0 ) {
192         fgBucketGenBasePath(&my_index, scene_path);
193         index = fgBucketGenIndex(&my_index);
194         sprintf(file, "%s/%s/%ld.1.nw", basepath, scene_path, index);
195         if ( file_exists(file) ) {
196             return(1);
197         }
198         fgBucketGenBasePath(&west_index, scene_path);
199         index = fgBucketGenIndex(&west_index);
200         sprintf(file, "%s/%s/%ld.1.ne", basepath, scene_path, index);
201         if ( file_exists(file) ) {
202             return(1);
203         }
204         fgBucketGenBasePath(&nw_index, scene_path);
205         index = fgBucketGenIndex(&nw_index);
206         sprintf(file, "%s/%s/%ld.1.se", basepath, scene_path, index);
207         if ( file_exists(file) ) {
208             return(1);
209         }
210         fgBucketGenBasePath(&north_index, scene_path);
211         index = fgBucketGenIndex(&north_index);
212         sprintf(file, "%s/%s/%ld.1.sw", basepath, scene_path, index);
213         if ( file_exists(file) ) {
214             return(1);
215         }
216     }
217
218     if ( strcmp(ext, ".south") == 0 ) {
219         fgBucketGenBasePath(&my_index, scene_path);
220         index = fgBucketGenIndex(&my_index);
221         sprintf(file, "%s/%s/%ld.1.south", basepath, scene_path, index);
222         if ( file_exists(file) ) {
223             return(1);
224         }
225         fgBucketGenBasePath(&south_index, scene_path);
226         index = fgBucketGenIndex(&south_index);
227         sprintf(file, "%s/%s/%ld.1.north", basepath, scene_path, index);
228         if ( file_exists(file) ) {
229             return(1);
230         }
231     }
232
233     if ( strcmp(ext, ".north") == 0 ) {
234         fgBucketGenBasePath(&my_index, scene_path);
235         index = fgBucketGenIndex(&my_index);
236         sprintf(file, "%s/%s/%ld.1.north", basepath, scene_path, index);
237         if ( file_exists(file) ) {
238             return(1);
239         }
240         fgBucketGenBasePath(&north_index, scene_path);
241         index = fgBucketGenIndex(&north_index);
242         sprintf(file, "%s/%s/%ld.1.south", basepath, scene_path, index);
243         if ( file_exists(file) ) {
244             return(1);
245         }
246     }
247
248     if ( strcmp(ext, ".west") == 0 ) {
249         fgBucketGenBasePath(&my_index, scene_path);
250         index = fgBucketGenIndex(&my_index);
251         sprintf(file, "%s/%s/%ld.1.west", basepath, scene_path, index);
252         if ( file_exists(file) ) {
253             return(1);
254         }
255         fgBucketGenBasePath(&west_index, scene_path);
256         index = fgBucketGenIndex(&west_index);
257         sprintf(file, "%s/%s/%ld.1.east", basepath, scene_path, index);
258         if ( file_exists(file) ) {
259             return(1);
260         }
261     }
262
263     if ( strcmp(ext, ".east") == 0 ) {
264         fgBucketGenBasePath(&my_index, scene_path);
265         index = fgBucketGenIndex(&my_index);
266         sprintf(file, "%s/%s/%ld.1.east", basepath, scene_path, index);
267         if ( file_exists(file) ) {
268             return(1);
269         }
270         fgBucketGenBasePath(&east_index, scene_path);
271         index = fgBucketGenIndex(&east_index);
272         sprintf(file, "%s/%s/%ld.1.west", basepath, scene_path, index);
273         if ( file_exists(file) ) {
274             return(1);
275         }
276     }
277
278     if ( strcmp(ext, ".body") == 0 ) {
279         fgBucketGenBasePath(&my_index, scene_path);
280         index = fgBucketGenIndex(&my_index);
281         sprintf(file, "%s/%s/%ld.1.body", basepath, scene_path, index);
282         if ( file_exists(file) ) {
283             return(1);
284         }
285     }
286
287     return(0);
288 }
289
290
291 /* my custom file opening routine ... don't open if a shared edge or
292  * vertex alread exists */
293 FILE *my_open(char *basename, char *basepath, char *ext) {
294     FILE *fp;
295     char filename[256];
296
297     /* check if a shared object already exists */
298     if ( shared_object_exists(basepath, ext, filename) ) {
299         /* not an actual file open error, but we've already got the
300          * shared edge, so we don't want to create another one */
301         fp = fopen(filename, "r");
302         printf("Opening %s\n", filename);
303         return(fp);
304     } else {
305         /* open the file */
306         printf("not opening\n");
307         return(NULL);
308     }
309 }
310
311
312 /* given a file pointer, read all the gdn (geodetic nodes from it.)
313    The specified offset values (in arcsec) are used to overlap the
314    edges of the tile slightly to cover gaps induced by floating point
315    precision problems.  1 arcsec == about 100 feet so 0.01 arcsec ==
316    about 1 foot */
317 void read_nodes(FILE *fp, double offset_lon, double offset_lat) {
318     char line[256];
319
320     while ( fgets(line, 250, fp) != NULL ) {
321         if ( strncmp(line, "gdn ", 4) == 0 ) {
322             sscanf(line, "gdn %lf %lf %lf\n", &nodes[nodecount][0], 
323                    &nodes[nodecount][1], &nodes[nodecount][2]);
324
325             nodes[nodecount][0] += offset_lon;
326             nodes[nodecount][1] += offset_lat;
327
328             /*
329             printf("read_nodes(%d) %.2f %.2f %.2f %s", nodecount, 
330                    nodes[nodecount][0], nodes[nodecount][1], 
331                    nodes[nodecount][2], line);
332                    */
333             nodecount++;
334         }
335     }
336 }
337
338
339 /* load in nodes from the various split and shared pieces to
340  * reconstruct a tile */
341 void build_node_list(char *basename, char *basepath) {
342     FILE *ne, *nw, *se, *sw, *north, *south, *east, *west, *body;
343
344     ne = my_open(basename, basepath, ".ne");
345     read_nodes(ne, 0.1, 0.1);
346     fclose(ne);
347
348     nw = my_open(basename, basepath, ".nw");
349     read_nodes(nw, -0.1, 0.1);
350     fclose(nw);
351
352     se = my_open(basename, basepath, ".se");
353     read_nodes(se, 0.1, -0.1);
354     fclose(se);
355
356     sw = my_open(basename, basepath, ".sw");
357     read_nodes(sw, -0.1, -0.1);
358     fclose(sw);
359
360     north = my_open(basename, basepath, ".north");
361     read_nodes(north, 0.0, 0.1);
362     fclose(north);
363
364     south = my_open(basename, basepath, ".south");
365     read_nodes(south, 0.0, -0.1);
366     fclose(south);
367
368     east = my_open(basename, basepath, ".east");
369     read_nodes(east, 0.1, 0.0);
370     fclose(east);
371
372     west = my_open(basename, basepath, ".west");
373     read_nodes(west, -0.1, 0.0);
374     fclose(west);
375
376     body = my_open(basename, basepath, ".body");
377     read_nodes(body, 0.0, 0.0);
378     fclose(body);
379 }
380
381
382 /* dump in WaveFront .obj format */
383 void dump_nodes(char *basename) {
384     char file[256];
385     FILE *fp;
386     int i, len;
387
388     /* generate output file name */
389     strcpy(file, basename);
390     len = strlen(file);
391     file[len-2] = '\0';
392     strcat(file, ".node");
393     
394     /* dump vertices */
395     printf("Creating node file:  %s\n", file);
396     printf("  writing vertices in .node format.\n");
397     fp = fopen(file, "w");
398
399     fprintf(fp, "%d 2 1 0\n", nodecount);
400
401     /* now write out actual node data */
402     for ( i = 0; i < nodecount; i++ ) {
403         fprintf(fp, "%d %.2f %.2f %.2f 0\n", i + 1,
404                nodes[i][0], nodes[i][1], nodes[i][2]);
405     }
406
407     fclose(fp);
408 }
409
410
411 int main(int argc, char **argv) {
412     char basename[256], basepath[256], temp[256];
413     long int tmp_index;
414     int len;
415
416     strcpy(basename, argv[1]);
417
418     /* find the base path of the file */
419     extract_path(basename, basepath);
420     extract_path(basepath, basepath);
421     extract_path(basepath, basepath);
422     printf("%s\n", basepath);
423
424     /* find the index of the current file */
425     extract_file(basename, temp);
426     len = strlen(temp);
427     if ( len >= 2 ) {
428         temp[len-2] = '\0';
429     }
430     tmp_index = atoi(temp);
431     printf("%ld\n", tmp_index);
432     fgBucketParseIndex(tmp_index, &my_index);
433
434     printf("bucket = %d %d %d %d\n", 
435            my_index.lon, my_index.lat, my_index.x, my_index.y);
436     /* generate the indexes of the neighbors */
437     fgBucketOffset(&my_index, &ne_index,  1,  1);
438     fgBucketOffset(&my_index, &nw_index, -1,  1);
439     fgBucketOffset(&my_index, &se_index,  1, -1);
440     fgBucketOffset(&my_index, &sw_index, -1, -1);
441
442     fgBucketOffset(&my_index, &north_index,  0,  1);
443     fgBucketOffset(&my_index, &south_index,  0, -1);
444     fgBucketOffset(&my_index, &east_index,  1,  0);
445     fgBucketOffset(&my_index, &west_index, -1,  0);
446
447     /*
448     printf("Corner indexes = %ld %ld %ld %ld\n", 
449            ne_index, nw_index, sw_index, se_index);
450     printf("Edge indexes = %ld %ld %ld %ld\n",
451            north_index, south_index, east_index, west_index);
452            */
453
454     /* load the input data files */
455     build_node_list(basename, basepath);
456
457     /* dump in WaveFront .obj format */
458     dump_nodes(basename);
459
460     return(0);
461 }
462
463
464 /* $Log$
465 /* Revision 1.9  1998/07/04 00:55:39  curt
466 /* typedef'd struct fgBUCKET.
467 /*
468  * Revision 1.8  1998/06/01 17:58:19  curt
469  * Added a slight border overlap to try to minimize pixel wide gaps between
470  * tiles due to round off error.  This is not a perfect solution, but helps.
471  *
472  * Revision 1.7  1998/04/14 02:26:00  curt
473  * Code reorganizations.  Added a Lib/ directory for more general libraries.
474  *
475  * Revision 1.6  1998/04/08 22:54:58  curt
476  * Adopted Gnu automake/autoconf system.
477  *
478  * Revision 1.5  1998/03/03 16:00:52  curt
479  * More c++ compile tweaks.
480  *
481  * Revision 1.4  1998/01/31 00:41:23  curt
482  * Made a few changes converting floats to doubles.
483  *
484  * Revision 1.3  1998/01/27 18:37:00  curt
485  * Lots of updates to get back in sync with changes made over in .../Src/
486  *
487  * Revision 1.2  1998/01/15 21:33:36  curt
488  * Assembling triangles and building a new .node file with the proper shared
489  * vertices now works.  Now we just have to use the shared normals and we'll
490  * be all set.
491  *
492  * Revision 1.1  1998/01/15 02:45:26  curt
493  * Initial revision.
494  *
495  */