Transform scenery coordinates earlier in pipeline when scenery is being
created, not when it is being loaded. Precalculate normals for each node as average of the normals of each containing polygon so Garoude shading is now supportable.
This commit is contained in:
parent
62872fb302
commit
273bd9bc6e
2 changed files with 119 additions and 104 deletions
211
Scenery/obj.c
211
Scenery/obj.c
|
@ -29,73 +29,31 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include <GL/glut.h>
|
#include <GL/glut.h>
|
||||||
|
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "scenery.h"
|
#include "scenery.h"
|
||||||
|
|
||||||
#include "../constants.h"
|
|
||||||
#include "../types.h"
|
|
||||||
#include "../Math/fg_geodesy.h"
|
|
||||||
#include "../Math/mat3.h"
|
#include "../Math/mat3.h"
|
||||||
#include "../Math/polar.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define MAXNODES 100000
|
#define MAXNODES 100000
|
||||||
|
|
||||||
float nodes[MAXNODES][3];
|
float nodes[MAXNODES][3];
|
||||||
|
float normals[MAXNODES][3];
|
||||||
|
|
||||||
/* convert a geodetic point lon(arcsec), lat(arcsec), elev(meter) to
|
|
||||||
* a cartesian point */
|
|
||||||
struct fgCartesianPoint geod_to_cart(float geod[3]) {
|
|
||||||
struct fgCartesianPoint p;
|
|
||||||
double gc_lon, gc_lat, sl_radius;
|
|
||||||
|
|
||||||
/* printf("A geodetic point is (%.2f, %.2f, %.2f)\n",
|
|
||||||
geod[0], geod[1], geod[2]); */
|
|
||||||
|
|
||||||
gc_lon = geod[0]*ARCSEC_TO_RAD;
|
|
||||||
fgGeodToGeoc(geod[1]*ARCSEC_TO_RAD, geod[2], &sl_radius, &gc_lat);
|
|
||||||
|
|
||||||
/* printf("A geocentric point is (%.2f, %.2f, %.2f)\n", gc_lon,
|
|
||||||
gc_lat, sl_radius+geod[2]); */
|
|
||||||
|
|
||||||
p = fgPolarToCart(gc_lon, gc_lat, sl_radius+geod[2]);
|
|
||||||
|
|
||||||
/* printf("A cart point is (%.8f, %.8f, %.8f)\n", p.x, p.y, p.z); */
|
|
||||||
|
|
||||||
return(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* given three points defining a triangle, calculate the normal */
|
|
||||||
void calc_normal(struct fgCartesianPoint p1, struct fgCartesianPoint p2,
|
|
||||||
struct fgCartesianPoint p3, double normal[3])
|
|
||||||
{
|
|
||||||
double v1[3], v2[3];
|
|
||||||
float temp;
|
|
||||||
|
|
||||||
v1[0] = p2.x - p1.x; v1[1] = p2.y - p1.y; v1[2] = p2.z - p1.z;
|
|
||||||
v2[0] = p3.x - p1.x; v2[1] = p3.y - p1.y; v2[2] = p3.z - p1.z;
|
|
||||||
|
|
||||||
MAT3cross_product(normal, v1, v2);
|
|
||||||
MAT3_NORMALIZE_VEC(normal,temp);
|
|
||||||
|
|
||||||
printf("Normal = %.2f %.2f %.2f\n", normal[0], normal[1], normal[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Load a .obj file and generate the GL call list */
|
/* Load a .obj file and generate the GL call list */
|
||||||
GLint fgObjLoad(char *path) {
|
GLint fgObjLoad(char *path) {
|
||||||
char line[256];
|
char line[256];
|
||||||
static GLfloat color[4] = { 0.5, 0.5, 0.25, 1.0 };
|
static GLfloat color[4] = { 0.5, 0.5, 0.25, 1.0 };
|
||||||
struct fgCartesianPoint p1, p2, p3, p4, ref, last1, last2;
|
double v1[3], v2[3], approx_normal[3], dot_prod, temp;
|
||||||
|
struct fgCartesianPoint ref;
|
||||||
GLint area;
|
GLint area;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
double normal[3];
|
int first, ncount, vncount, n1, n2, n3, n4;
|
||||||
int first, ncount, n1, n2, n3, n4;
|
|
||||||
int toggle = 0;
|
|
||||||
|
|
||||||
if ( (f = fopen(path, "r")) == NULL ) {
|
if ( (f = fopen(path, "r")) == NULL ) {
|
||||||
printf("Cannot open file: %s\n", path);
|
printf("Cannot open file: %s\n", path);
|
||||||
|
@ -108,15 +66,14 @@ GLint fgObjLoad(char *path) {
|
||||||
/* glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color ); */
|
/* glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color ); */
|
||||||
glColor3fv(color);
|
glColor3fv(color);
|
||||||
|
|
||||||
glBegin(GL_TRIANGLE_STRIP);
|
|
||||||
|
|
||||||
first = 1;
|
first = 1;
|
||||||
ncount = 1;
|
ncount = 1;
|
||||||
|
vncount = 1;
|
||||||
|
|
||||||
while ( fgets(line, 250, f) != NULL ) {
|
while ( fgets(line, 250, f) != NULL ) {
|
||||||
if ( line[0] == '#' ) {
|
if ( line[0] == '#' ) {
|
||||||
/* comment -- ignore */
|
/* comment -- ignore */
|
||||||
} else if ( line[0] == 'v' ) {
|
} else if ( strncmp(line, "v ", 2) == 0 ) {
|
||||||
/* node (vertex) */
|
/* node (vertex) */
|
||||||
if ( ncount < MAXNODES ) {
|
if ( ncount < MAXNODES ) {
|
||||||
/* printf("vertex = %s", line); */
|
/* printf("vertex = %s", line); */
|
||||||
|
@ -124,7 +81,9 @@ GLint fgObjLoad(char *path) {
|
||||||
&nodes[ncount][0], &nodes[ncount][1], &nodes[ncount][2]);
|
&nodes[ncount][0], &nodes[ncount][1], &nodes[ncount][2]);
|
||||||
if ( ncount == 1 ) {
|
if ( ncount == 1 ) {
|
||||||
/* first node becomes the reference point */
|
/* first node becomes the reference point */
|
||||||
ref = geod_to_cart(nodes[ncount]);
|
ref.x = nodes[ncount][0];
|
||||||
|
ref.y = nodes[ncount][1];
|
||||||
|
ref.z = nodes[ncount][2];
|
||||||
scenery.center = ref;
|
scenery.center = ref;
|
||||||
}
|
}
|
||||||
ncount++;
|
ncount++;
|
||||||
|
@ -132,82 +91,126 @@ GLint fgObjLoad(char *path) {
|
||||||
printf("Read too many nodes ... dying :-(\n");
|
printf("Read too many nodes ... dying :-(\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
} else if ( strncmp(line, "vn ", 3) == 0 ) {
|
||||||
|
/* vertex normal */
|
||||||
|
if ( vncount < MAXNODES ) {
|
||||||
|
/* printf("vertex normal = %s", line); */
|
||||||
|
sscanf(line, "vn %f %f %f\n",
|
||||||
|
&normals[vncount][0], &normals[vncount][1],
|
||||||
|
&normals[vncount][2]);
|
||||||
|
vncount++;
|
||||||
|
} else {
|
||||||
|
printf("Read too many vertex normals ... dying :-(\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
} else if ( line[0] == 't' ) {
|
} else if ( line[0] == 't' ) {
|
||||||
/* start a new triangle strip */
|
/* start a new triangle strip */
|
||||||
|
|
||||||
n1 = n2 = n3 = n4 = 0;
|
n1 = n2 = n3 = n4 = 0;
|
||||||
toggle = 0;
|
|
||||||
|
|
||||||
if ( !first ) {
|
if ( !first ) {
|
||||||
/* close out the previous structure and start the next */
|
/* close out the previous structure and start the next */
|
||||||
glEnd();
|
glEnd();
|
||||||
glBegin(GL_TRIANGLE_STRIP);
|
|
||||||
} else {
|
} else {
|
||||||
first = 0;
|
first = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glBegin(GL_TRIANGLE_STRIP);
|
||||||
|
|
||||||
printf("new tri strip = %s", line);
|
printf("new tri strip = %s", line);
|
||||||
sscanf(line, "t %d %d %d %d\n", &n1, &n2, &n3, &n4);
|
sscanf(line, "t %d %d %d %d\n", &n1, &n2, &n3, &n4);
|
||||||
|
|
||||||
p1 = geod_to_cart(nodes[n1]);
|
|
||||||
p2 = geod_to_cart(nodes[n2]);
|
|
||||||
p3 = geod_to_cart(nodes[n3]);
|
|
||||||
|
|
||||||
printf("(t) = ");
|
printf("(t) = ");
|
||||||
calc_normal(p1, p2, p3, normal);
|
|
||||||
glNormal3d(normal[0], normal[1], normal[2]);
|
|
||||||
glVertex3d(p1.x - ref.x, p1.y - ref.y, p1.z - ref.z);
|
|
||||||
glVertex3d(p2.x - ref.x, p2.y - ref.y, p2.z - ref.z);
|
|
||||||
glVertex3d(p3.x - ref.x, p3.y - ref.y, p3.z - ref.z);
|
|
||||||
|
|
||||||
last1 = p2;
|
/* try to get the proper rotation by calculating an
|
||||||
last2 = p3;
|
* approximate normal and seeing if it is close to the
|
||||||
|
* precalculated normal */
|
||||||
|
v1[0] = nodes[n2][0] - nodes[n1][0];
|
||||||
|
v1[1] = nodes[n2][1] - nodes[n1][1];
|
||||||
|
v1[2] = nodes[n2][2] - nodes[n1][2];
|
||||||
|
v2[0] = nodes[n3][0] - nodes[n1][0];
|
||||||
|
v2[1] = nodes[n3][1] - nodes[n1][1];
|
||||||
|
v2[2] = nodes[n3][2] - nodes[n1][2];
|
||||||
|
MAT3cross_product(approx_normal, v1, v2);
|
||||||
|
MAT3_NORMALIZE_VEC(approx_normal,temp);
|
||||||
|
printf("Approx normal = %.2f %.2f %.2f\n", approx_normal[0],
|
||||||
|
approx_normal[1], approx_normal[2]);
|
||||||
|
dot_prod = MAT3_DOT_PRODUCT(normals[n1], approx_normal);
|
||||||
|
printf("Dot product = %.4f\n", dot_prod);
|
||||||
|
/* angle = acos(dot_prod); */
|
||||||
|
/* printf("Normal ANGLE = %.3f rads.\n", angle); */
|
||||||
|
|
||||||
|
glNormal3d(normals[n1][0], normals[n1][1], normals[n1][2]);
|
||||||
|
glVertex3d(nodes[n1][0] - ref.x, nodes[n1][1] - ref.y,
|
||||||
|
nodes[n1][2] - ref.z);
|
||||||
|
|
||||||
|
if ( dot_prod > 0 ) {
|
||||||
|
glNormal3d(normals[n2][0], normals[n2][1], normals[n2][2]);
|
||||||
|
glVertex3d(nodes[n2][0] - ref.x, nodes[n2][1] - ref.y,
|
||||||
|
nodes[n2][2] - ref.z);
|
||||||
|
|
||||||
|
glNormal3d(normals[n3][0], normals[n3][1], normals[n3][2]);
|
||||||
|
glVertex3d(nodes[n3][0] - ref.x, nodes[n3][1] - ref.y,
|
||||||
|
nodes[n3][2] - ref.z);
|
||||||
|
} else {
|
||||||
|
printf("Reversing\n");
|
||||||
|
glNormal3d(normals[n3][0], normals[n3][1], normals[n3][2]);
|
||||||
|
glVertex3d(nodes[n3][0] - ref.x, nodes[n3][1] - ref.y,
|
||||||
|
nodes[n3][2] - ref.z);
|
||||||
|
|
||||||
|
glNormal3d(normals[n2][0], normals[n2][1], normals[n2][2]);
|
||||||
|
glVertex3d(nodes[n2][0] - ref.x, nodes[n2][1] - ref.y,
|
||||||
|
nodes[n2][2] - ref.z);
|
||||||
|
}
|
||||||
|
|
||||||
if ( n4 > 0 ) {
|
if ( n4 > 0 ) {
|
||||||
p4 = geod_to_cart(nodes[n4]);
|
glNormal3d(normals[n4][0], normals[n4][1], normals[n4][2]);
|
||||||
printf("(t) cont = ");
|
glVertex3d(nodes[n4][0] - ref.x, nodes[n4][1] - ref.y,
|
||||||
calc_normal(last2, last1, p4, normal);
|
nodes[n4][2] - ref.z);
|
||||||
glNormal3d(normal[0], normal[1], normal[2]);
|
|
||||||
glVertex3d(p4.x - ref.x, p4.y - ref.y, p4.z - ref.z);
|
|
||||||
|
|
||||||
last1 = last2;
|
|
||||||
last2 = p4;
|
|
||||||
toggle = 1 - toggle;
|
|
||||||
}
|
}
|
||||||
|
} else if ( line[0] == 'f' ) {
|
||||||
|
/* unoptimized face */
|
||||||
|
|
||||||
|
if ( !first ) {
|
||||||
|
/* close out the previous structure and start the next */
|
||||||
|
glEnd();
|
||||||
|
} else {
|
||||||
|
first = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
glBegin(GL_TRIANGLES);
|
||||||
|
|
||||||
|
printf("new triangle = %s", line);
|
||||||
|
sscanf(line, "f %d %d %d\n", &n1, &n2, &n3);
|
||||||
|
|
||||||
|
glNormal3d(normals[n1][0], normals[n1][1], normals[n1][2]);
|
||||||
|
glVertex3d(nodes[n1][0] - ref.x, nodes[n1][1] - ref.y,
|
||||||
|
nodes[n1][2] - ref.z);
|
||||||
|
|
||||||
|
glNormal3d(normals[n2][0], normals[n2][1], normals[n2][2]);
|
||||||
|
glVertex3d(nodes[n2][0] - ref.x, nodes[n2][1] - ref.y,
|
||||||
|
nodes[n2][2] - ref.z);
|
||||||
|
|
||||||
|
glNormal3d(normals[n3][0], normals[n3][1], normals[n3][2]);
|
||||||
|
glVertex3d(nodes[n3][0] - ref.x, nodes[n3][1] - ref.y,
|
||||||
|
nodes[n3][2] - ref.z);
|
||||||
} else if ( line[0] == 'q' ) {
|
} else if ( line[0] == 'q' ) {
|
||||||
/* continue a triangle strip */
|
/* continue a triangle strip */
|
||||||
n1 = n2 = 0;
|
n1 = n2 = 0;
|
||||||
|
|
||||||
printf("continued tri strip = %s", line);
|
printf("continued tri strip = %s ", line);
|
||||||
sscanf(line, "q %d %d\n", &n1, &n2);
|
sscanf(line, "q %d %d\n", &n1, &n2);
|
||||||
printf("read %d %d\n", n1, n2);
|
printf("read %d %d\n", n1, n2);
|
||||||
|
|
||||||
p1 = geod_to_cart(nodes[n1]);
|
glNormal3d(normals[n1][0], normals[n1][1], normals[n1][2]);
|
||||||
|
glVertex3d(nodes[n1][0] - ref.x, nodes[n1][1] - ref.y,
|
||||||
printf("(q) = ");
|
nodes[n1][2] - ref.z);
|
||||||
if ( toggle ) {
|
|
||||||
calc_normal(last1, last2, p1, normal);
|
|
||||||
} else {
|
|
||||||
calc_normal(last1, p1, last2, normal);
|
|
||||||
}
|
|
||||||
glNormal3d(normal[0], normal[1], normal[2]);
|
|
||||||
glVertex3d(p1.x - ref.x, p1.y - ref.y, p1.z - ref.z);
|
|
||||||
|
|
||||||
last1 = last2;
|
|
||||||
last2 = p1;
|
|
||||||
toggle = 1 - toggle;
|
|
||||||
|
|
||||||
if ( n2 > 0 ) {
|
if ( n2 > 0 ) {
|
||||||
p2 = geod_to_cart(nodes[n2]);
|
printf(" (cont)\n");
|
||||||
|
glNormal3d(normals[n2][0], normals[n2][1], normals[n2][2]);
|
||||||
printf("(q) cont = ");
|
glVertex3d(nodes[n2][0] - ref.x, nodes[n2][1] - ref.y,
|
||||||
calc_normal(last1, last2, p2, normal);
|
nodes[n2][2] - ref.z);
|
||||||
glNormal3d(normal[0], normal[1], normal[2]);
|
|
||||||
glVertex3d(p2.x - ref.x, p2.y - ref.y, p2.z - ref.z);
|
|
||||||
|
|
||||||
last1 = last2;
|
|
||||||
last2 = p2;
|
|
||||||
toggle = 1 - toggle;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("Unknown line in %s = %s\n", path, line);
|
printf("Unknown line in %s = %s\n", path, line);
|
||||||
|
@ -224,9 +227,15 @@ GLint fgObjLoad(char *path) {
|
||||||
|
|
||||||
|
|
||||||
/* $Log$
|
/* $Log$
|
||||||
/* Revision 1.3 1997/10/31 04:49:12 curt
|
/* Revision 1.4 1997/11/14 00:26:49 curt
|
||||||
/* Tweaking vertex orders.
|
/* Transform scenery coordinates earlier in pipeline when scenery is being
|
||||||
|
/* created, not when it is being loaded. Precalculate normals for each node
|
||||||
|
/* as average of the normals of each containing polygon so Garoude shading is
|
||||||
|
/* now supportable.
|
||||||
/*
|
/*
|
||||||
|
* Revision 1.3 1997/10/31 04:49:12 curt
|
||||||
|
* Tweaking vertex orders.
|
||||||
|
*
|
||||||
* Revision 1.2 1997/10/30 12:38:45 curt
|
* Revision 1.2 1997/10/30 12:38:45 curt
|
||||||
* Working on new scenery subsystem.
|
* Working on new scenery subsystem.
|
||||||
*
|
*
|
||||||
|
|
|
@ -232,7 +232,7 @@ void fgTimeUpdate(struct FLIGHT *f, struct fgTIME *t) {
|
||||||
/* get current Unix calendar time (in seconds) */
|
/* get current Unix calendar time (in seconds) */
|
||||||
warp += 60;
|
warp += 60;
|
||||||
/* warp = 0; */
|
/* warp = 0; */
|
||||||
t->cur_time = time(NULL);
|
t->cur_time = time(NULL) + 43200;
|
||||||
t->cur_time += warp;
|
t->cur_time += warp;
|
||||||
printf("Current Unix calendar time = %ld warp = %ld\n", t->cur_time, warp);
|
printf("Current Unix calendar time = %ld warp = %ld\n", t->cur_time, warp);
|
||||||
|
|
||||||
|
@ -284,9 +284,15 @@ void fgTimeUpdate(struct FLIGHT *f, struct fgTIME *t) {
|
||||||
|
|
||||||
|
|
||||||
/* $Log$
|
/* $Log$
|
||||||
/* Revision 1.8 1997/10/25 03:30:08 curt
|
/* Revision 1.9 1997/11/14 00:26:50 curt
|
||||||
/* Misc. tweaks.
|
/* Transform scenery coordinates earlier in pipeline when scenery is being
|
||||||
|
/* created, not when it is being loaded. Precalculate normals for each node
|
||||||
|
/* as average of the normals of each containing polygon so Garoude shading is
|
||||||
|
/* now supportable.
|
||||||
/*
|
/*
|
||||||
|
* Revision 1.8 1997/10/25 03:30:08 curt
|
||||||
|
* Misc. tweaks.
|
||||||
|
*
|
||||||
* Revision 1.7 1997/09/23 00:29:50 curt
|
* Revision 1.7 1997/09/23 00:29:50 curt
|
||||||
* Tweaks to get things to compile with gcc-win32.
|
* Tweaks to get things to compile with gcc-win32.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue