]> git.mxchange.org Git - flightgear.git/blob - Scenery/obj.c
Working on new scenery subsystem.
[flightgear.git] / Scenery / obj.c
1 /**************************************************************************
2  * obj.c -- routines to handle WaveFront .obj format files.
3  *
4  * Written by Curtis Olson, started October 1997.
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 <stdio.h>
32 #include <GL/glut.h>
33
34 #include "obj.h"
35 #include "scenery.h"
36
37 #include "../constants.h"
38 #include "../types.h"
39 #include "../Math/fg_geodesy.h"
40 #include "../Math/polar.h"
41
42
43 #define MAXNODES 100000
44
45 float nodes[MAXNODES][3];
46
47
48 /* convert a geodetic point lon(arcsec), lat(arcsec), elev(meter) to
49  * a cartesian point */
50 struct fgCartesianPoint geod_to_cart(float geod[3]) {
51     struct fgCartesianPoint p;
52     double gc_lon, gc_lat, sl_radius;
53
54     /* printf("A geodetic point is (%.2f, %.2f, %.2f)\n", 
55            geod[0], geod[1], geod[2]); */
56
57     gc_lon = geod[0]*ARCSEC_TO_RAD;
58     fgGeodToGeoc(geod[1]*ARCSEC_TO_RAD, geod[2], &sl_radius, &gc_lat);
59
60     /* printf("A geocentric point is (%.2f, %.2f, %.2f)\n", gc_lon, 
61            gc_lat, sl_radius+geod[2]); */
62
63     p = fgPolarToCart(gc_lon, gc_lat, sl_radius+geod[2]);
64     
65     /* printf("A cart point is (%.8f, %.8f, %.8f)\n", p.x, p.y, p.z); */
66
67     return(p);
68 }
69
70
71 /* Load a .obj file and generate the GL call list */
72 GLint fgObjLoad(char *path) {
73     char line[256];
74     static GLfloat color[4] = { 0.5, 0.5, 0.25, 1.0 };
75     struct fgCartesianPoint p1, p2, p3, p4, ref;
76     GLint area;
77     FILE *f;
78     int first, ncount, n1, n2, n3, n4;
79
80     if ( (f = fopen(path, "r")) == NULL ) {
81         printf("Cannot open file: %s\n", path);
82         exit(-1);
83     }
84
85     area = glGenLists(1);
86     glNewList(area, GL_COMPILE);
87
88     /* glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color ); */
89     glColor3fv(color);
90
91     glBegin(GL_TRIANGLE_STRIP);
92
93     first = 1;
94     ncount = 1;
95
96     while ( fgets(line, 250, f) != NULL ) {
97         if ( line[0] == '#' ) {
98             /* comment -- ignore */
99         } else if ( line[0] == 'v' ) {
100             /* node (vertex) */
101             if ( ncount < MAXNODES ) {
102                 /* printf("vertex = %s", line); */
103                 sscanf(line, "v %f %f %f\n", 
104                        &nodes[ncount][0], &nodes[ncount][1], &nodes[ncount][2]);
105                 if ( ncount == 1 ) {
106                     /* first node becomes the reference point */
107                     ref = geod_to_cart(nodes[ncount]);
108                     scenery.center = ref;
109                 }
110                 ncount++;
111             } else {
112                 printf("Read too many nodes ... dying :-(\n");
113                 exit(-1);
114             }
115         } else if ( line[0] == 't' ) {
116             /* start a new triangle strip */
117
118             n1 = n2 = n3 = n4 = 0;
119
120             if ( !first ) {
121                 /* close out the previous structure and start the next */
122                 glEnd();
123                 glBegin(GL_TRIANGLE_STRIP);
124             } else {
125                 first = 0;
126             }
127
128             printf("new tri strip = %s", line);
129             sscanf(line, "t %d %d %d\n", &n1, &n2, &n3);
130
131             p1 = geod_to_cart(nodes[n1]);
132             p2 = geod_to_cart(nodes[n2]);
133             p3 = geod_to_cart(nodes[n3]);
134
135             glNormal3d(0.0, 0.0, -1.0);
136
137             glVertex3d(p1.x - ref.x, p1.y - ref.y, p1.z - ref.z);
138             glVertex3d(p2.x - ref.x, p2.y - ref.y, p2.z - ref.z);
139             glVertex3d(p3.x - ref.x, p3.y - ref.y, p3.z - ref.z);
140
141             if ( n4 > 0 ) {
142                 p4 = geod_to_cart(nodes[n4]);
143                 glVertex3d(p4.x - ref.x, p4.y - ref.y, p4.z - ref.z);
144             }
145         } else if ( line[0] == 'q' ) {
146             /* continue a triangle strip */
147             n1 = n2 = 0;
148
149             printf("continued tri strip = %s", line);
150             sscanf(line, "q %d %d\n", &n1, &n2);
151             printf("read %d %d\n", n1, n2);
152
153             p1 = geod_to_cart(nodes[n1]);
154             glVertex3d(p1.x - ref.x, p1.y - ref.y, p1.z - ref.z);
155
156             if ( n2 > 0 ) {
157                 p2 = geod_to_cart(nodes[n2]);
158                 glVertex3d(p2.x - ref.x, p2.y - ref.y, p2.z - ref.z);
159             }
160         } else {
161             printf("Unknown line in %s = %s\n", path, line);
162         }
163     }
164
165     glEnd();
166     glEndList();
167
168     fclose(f);
169
170     return(area);
171 }
172
173
174 /* $Log$
175 /* Revision 1.2  1997/10/30 12:38:45  curt
176 /* Working on new scenery subsystem.
177 /*
178  * Revision 1.1  1997/10/28 21:14:54  curt
179  * Initial revision.
180  *
181  */