1 /* splittris.c -- reassemble the pieces produced by splittris
3 * Written by Curtis Olson, started January 1998.
5 * Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
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.
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.
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.
22 * (Log is kept at end of this file) */
27 #include <stdlib.h> /* for atoi() */
29 #include <sys/stat.h> /* for stat() */
30 #include <unistd.h> /* for stat() */
32 #include "assemtris.h"
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>
44 static double nodes[MAX_NODES][3];
48 fgBUCKET ne_index, nw_index, sw_index, se_index;
49 fgBUCKET north_index, south_index, east_index, west_index;
52 /* return the file base name ( foo/bar/file.ext = file.ext ) */
53 void extract_file(char *in, char *base) {
59 while ( (i >= 0) && (in[i] != '/') ) {
68 /* return the file path name ( foo/bar/file.ext = foo/bar ) */
69 void extract_path(char *in, char *base) {
76 while ( (i >= 0) && (in[i] != '/') ) {
84 /* check if a file exists */
85 int file_exists(char *file) {
89 printf("checking %s ... ", file);
91 result = stat(file, &stat_buf);
94 /* stat failed, no file */
95 printf("not found.\n");
98 /* stat succeeded, file exists */
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];
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) ) {
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) ) {
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) ) {
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) ) {
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) ) {
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) ) {
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) ) {
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) ) {
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) ) {
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) ) {
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) ) {
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) ) {
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) ) {
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) ) {
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) ) {
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) ) {
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) ) {
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) ) {
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) ) {
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) ) {
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) ) {
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) ) {
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) ) {
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) ) {
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) ) {
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) {
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);
306 printf("not opening\n");
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 ==
317 void read_nodes(FILE *fp, double offset_lon, double offset_lat) {
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]);
325 nodes[nodecount][0] += offset_lon;
326 nodes[nodecount][1] += offset_lat;
329 printf("read_nodes(%d) %.2f %.2f %.2f %s", nodecount,
330 nodes[nodecount][0], nodes[nodecount][1],
331 nodes[nodecount][2], line);
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;
344 ne = my_open(basename, basepath, ".ne");
345 read_nodes(ne, 0.1, 0.1);
348 nw = my_open(basename, basepath, ".nw");
349 read_nodes(nw, -0.1, 0.1);
352 se = my_open(basename, basepath, ".se");
353 read_nodes(se, 0.1, -0.1);
356 sw = my_open(basename, basepath, ".sw");
357 read_nodes(sw, -0.1, -0.1);
360 north = my_open(basename, basepath, ".north");
361 read_nodes(north, 0.0, 0.1);
364 south = my_open(basename, basepath, ".south");
365 read_nodes(south, 0.0, -0.1);
368 east = my_open(basename, basepath, ".east");
369 read_nodes(east, 0.1, 0.0);
372 west = my_open(basename, basepath, ".west");
373 read_nodes(west, -0.1, 0.0);
376 body = my_open(basename, basepath, ".body");
377 read_nodes(body, 0.0, 0.0);
382 /* dump in WaveFront .obj format */
383 void dump_nodes(char *basename) {
388 /* generate output file name */
389 strcpy(file, basename);
392 strcat(file, ".node");
395 printf("Creating node file: %s\n", file);
396 printf(" writing vertices in .node format.\n");
397 fp = fopen(file, "w");
399 fprintf(fp, "%d 2 1 0\n", nodecount);
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]);
411 int main(int argc, char **argv) {
412 char basename[256], basepath[256], temp[256];
416 strcpy(basename, argv[1]);
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);
424 /* find the index of the current file */
425 extract_file(basename, temp);
430 tmp_index = atoi(temp);
431 printf("%ld\n", tmp_index);
432 fgBucketParseIndex(tmp_index, &my_index);
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);
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);
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);
454 /* load the input data files */
455 build_node_list(basename, basepath);
457 /* dump in WaveFront .obj format */
458 dump_nodes(basename);
465 /* Revision 1.9 1998/07/04 00:55:39 curt
466 /* typedef'd struct fgBUCKET.
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.
472 * Revision 1.7 1998/04/14 02:26:00 curt
473 * Code reorganizations. Added a Lib/ directory for more general libraries.
475 * Revision 1.6 1998/04/08 22:54:58 curt
476 * Adopted Gnu automake/autoconf system.
478 * Revision 1.5 1998/03/03 16:00:52 curt
479 * More c++ compile tweaks.
481 * Revision 1.4 1998/01/31 00:41:23 curt
482 * Made a few changes converting floats to doubles.
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/
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
492 * Revision 1.1 1998/01/15 02:45:26 curt