Added ground collision detection. This involved:
- saving the entire vertex list for each tile with the tile records. - saving the face list for each fragment with the fragment records. - code to intersect the current vertical line with the proper face in an efficient manner as possible. Fixed a bug where the tiles weren't being shifted to "near" (0,0,0)
This commit is contained in:
parent
330c78ac73
commit
262b2f0607
7 changed files with 485 additions and 112 deletions
153
Scenery/obj.cxx
153
Scenery/obj.cxx
|
@ -60,10 +60,7 @@ using namespace std;
|
||||||
#include "tile.hxx"
|
#include "tile.hxx"
|
||||||
|
|
||||||
|
|
||||||
#define MAXNODES 100000
|
static double normals[MAX_NODES][3];
|
||||||
|
|
||||||
static double nodes[MAXNODES][3];
|
|
||||||
static double normals[MAXNODES][3];
|
|
||||||
|
|
||||||
|
|
||||||
// given three points defining a triangle, calculate the normal
|
// given three points defining a triangle, calculate the normal
|
||||||
|
@ -106,7 +103,7 @@ fgPoint3d calc_tex_coords(double *node, fgPoint3d *ref) {
|
||||||
|
|
||||||
|
|
||||||
// Load a .obj file and build the GL fragment list
|
// Load a .obj file and build the GL fragment list
|
||||||
int fgObjLoad(char *path, fgTILE *tile) {
|
int fgObjLoad(char *path, fgTILE *t) {
|
||||||
fgOPTIONS *o;
|
fgOPTIONS *o;
|
||||||
fgFRAGMENT fragment;
|
fgFRAGMENT fragment;
|
||||||
fgPoint3d pp;
|
fgPoint3d pp;
|
||||||
|
@ -116,7 +113,7 @@ int fgObjLoad(char *path, fgTILE *tile) {
|
||||||
// GLfloat sgenparams[] = { 1.0, 0.0, 0.0, 0.0 };
|
// GLfloat sgenparams[] = { 1.0, 0.0, 0.0, 0.0 };
|
||||||
GLint display_list;
|
GLint display_list;
|
||||||
fgFile f;
|
fgFile f;
|
||||||
int in_fragment, in_faces, ncount, vncount, n1, n2, n3, n4;
|
int in_fragment, in_faces, vncount, n1, n2, n3, n4;
|
||||||
int last1, last2, odd;
|
int last1, last2, odd;
|
||||||
|
|
||||||
o = ¤t_options;
|
o = ¤t_options;
|
||||||
|
@ -140,9 +137,9 @@ int fgObjLoad(char *path, fgTILE *tile) {
|
||||||
}
|
}
|
||||||
|
|
||||||
in_fragment = 0;
|
in_fragment = 0;
|
||||||
ncount = 1;
|
t->ncount = 1;
|
||||||
vncount = 1;
|
vncount = 1;
|
||||||
tile->bounding_radius = 0.0;
|
t->bounding_radius = 0.0;
|
||||||
|
|
||||||
while ( fggets(f, line, 250) != NULL ) {
|
while ( fggets(f, line, 250) != NULL ) {
|
||||||
if ( line[0] == '#' ) {
|
if ( line[0] == '#' ) {
|
||||||
|
@ -152,8 +149,8 @@ int fgObjLoad(char *path, fgTILE *tile) {
|
||||||
} else if ( strncmp(line, "gbs ", 4) == 0 ) {
|
} else if ( strncmp(line, "gbs ", 4) == 0 ) {
|
||||||
// reference point (center offset)
|
// reference point (center offset)
|
||||||
sscanf(line, "gbs %lf %lf %lf %lf\n",
|
sscanf(line, "gbs %lf %lf %lf %lf\n",
|
||||||
&tile->center.x, &tile->center.y, &tile->center.z,
|
&t->center.x, &t->center.y, &t->center.z,
|
||||||
&tile->bounding_radius);
|
&t->bounding_radius);
|
||||||
} else if ( strncmp(line, "bs ", 3) == 0 ) {
|
} else if ( strncmp(line, "bs ", 3) == 0 ) {
|
||||||
// reference point (center offset)
|
// reference point (center offset)
|
||||||
sscanf(line, "bs %lf %lf %lf %lf\n",
|
sscanf(line, "bs %lf %lf %lf %lf\n",
|
||||||
|
@ -161,20 +158,21 @@ int fgObjLoad(char *path, fgTILE *tile) {
|
||||||
&fragment.bounding_radius);
|
&fragment.bounding_radius);
|
||||||
} else if ( strncmp(line, "v ", 2) == 0 ) {
|
} else if ( strncmp(line, "v ", 2) == 0 ) {
|
||||||
// node (vertex)
|
// node (vertex)
|
||||||
if ( ncount < MAXNODES ) {
|
if ( t->ncount < MAX_NODES ) {
|
||||||
// fgPrintf( FG_TERRAIN, FG_DEBUG, "vertex = %s", line);
|
// fgPrintf( FG_TERRAIN, FG_DEBUG, "vertex = %s", line);
|
||||||
sscanf(line, "v %lf %lf %lf\n",
|
sscanf(line, "v %lf %lf %lf\n",
|
||||||
&nodes[ncount][0], &nodes[ncount][1],
|
&(t->nodes[t->ncount][0]), &(t->nodes[t->ncount][1]),
|
||||||
&nodes[ncount][2]);
|
&(t->nodes[t->ncount][2]));
|
||||||
|
|
||||||
|
t->ncount++;
|
||||||
|
|
||||||
ncount++;
|
|
||||||
} else {
|
} else {
|
||||||
fgPrintf( FG_TERRAIN, FG_EXIT,
|
fgPrintf( FG_TERRAIN, FG_EXIT,
|
||||||
"Read too many nodes ... dying :-(\n");
|
"Read too many nodes ... dying :-(\n");
|
||||||
}
|
}
|
||||||
} else if ( strncmp(line, "vn ", 3) == 0 ) {
|
} else if ( strncmp(line, "vn ", 3) == 0 ) {
|
||||||
// vertex normal
|
// vertex normal
|
||||||
if ( vncount < MAXNODES ) {
|
if ( vncount < MAX_NODES ) {
|
||||||
// fgPrintf( FG_TERRAIN, FG_DEBUG, "vertex normal = %s", line);
|
// fgPrintf( FG_TERRAIN, FG_DEBUG, "vertex normal = %s", line);
|
||||||
sscanf(line, "vn %lf %lf %lf\n",
|
sscanf(line, "vn %lf %lf %lf\n",
|
||||||
&normals[vncount][0], &normals[vncount][1],
|
&normals[vncount][0], &normals[vncount][1],
|
||||||
|
@ -197,7 +195,7 @@ int fgObjLoad(char *path, fgTILE *tile) {
|
||||||
fragment.display_list = display_list;
|
fragment.display_list = display_list;
|
||||||
|
|
||||||
// push this fragment onto the tile's object list
|
// push this fragment onto the tile's object list
|
||||||
tile->fragment_list.push_back(fragment);
|
t->fragment_list.push_back(fragment);
|
||||||
} else {
|
} else {
|
||||||
in_fragment = 1;
|
in_fragment = 1;
|
||||||
}
|
}
|
||||||
|
@ -206,11 +204,19 @@ int fgObjLoad(char *path, fgTILE *tile) {
|
||||||
xglNewList(display_list, GL_COMPILE);
|
xglNewList(display_list, GL_COMPILE);
|
||||||
in_faces = 0;
|
in_faces = 0;
|
||||||
|
|
||||||
|
// reset the existing face list
|
||||||
|
// printf("cleaning a fragment with %d faces\n",
|
||||||
|
// fragment.faces.size());
|
||||||
|
while ( fragment.faces.size() ) {
|
||||||
|
// printf("emptying face list\n");
|
||||||
|
fragment.faces.pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
// scan the material line
|
// scan the material line
|
||||||
sscanf(line, "usemtl %s\n", material);
|
sscanf(line, "usemtl %s\n", material);
|
||||||
|
|
||||||
// give the fragment a pointer back to the tile
|
// give the fragment a pointer back to the tile
|
||||||
(fgTILE *)fragment.tile_ptr = tile;
|
(fgTILE *)fragment.tile_ptr = t;
|
||||||
|
|
||||||
// find this material in the properties list
|
// find this material in the properties list
|
||||||
map < string, fgMATERIAL, less<string> > :: iterator myfind =
|
map < string, fgMATERIAL, less<string> > :: iterator myfind =
|
||||||
|
@ -239,6 +245,8 @@ int fgObjLoad(char *path, fgTILE *tile) {
|
||||||
// fgPrintf( FG_TERRAIN, FG_DEBUG, " new tri strip = %s", line);
|
// fgPrintf( FG_TERRAIN, FG_DEBUG, " 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);
|
||||||
|
|
||||||
|
fragment.add_face(n1, n2, n3);
|
||||||
|
|
||||||
// fgPrintf( FG_TERRAIN, FG_DEBUG, "(t) = ");
|
// fgPrintf( FG_TERRAIN, FG_DEBUG, "(t) = ");
|
||||||
|
|
||||||
xglBegin(GL_TRIANGLE_STRIP);
|
xglBegin(GL_TRIANGLE_STRIP);
|
||||||
|
@ -251,45 +259,45 @@ int fgObjLoad(char *path, fgTILE *tile) {
|
||||||
// (averaged) normals
|
// (averaged) normals
|
||||||
MAT3_SCALE_VEC(normal, normals[n1], scale);
|
MAT3_SCALE_VEC(normal, normals[n1], scale);
|
||||||
xglNormal3dv(normal);
|
xglNormal3dv(normal);
|
||||||
pp = calc_tex_coords(nodes[n1], &tile->center);
|
pp = calc_tex_coords(t->nodes[n1], &t->center);
|
||||||
xglTexCoord2f(pp.lon, pp.lat);
|
xglTexCoord2f(pp.lon, pp.lat);
|
||||||
xglVertex3d(nodes[n1][0], nodes[n1][1], nodes[n1][2]);
|
xglVertex3d(t->nodes[n1][0], t->nodes[n1][1], t->nodes[n1][2]);
|
||||||
|
|
||||||
MAT3_SCALE_VEC(normal, normals[n2], scale);
|
MAT3_SCALE_VEC(normal, normals[n2], scale);
|
||||||
xglNormal3dv(normal);
|
xglNormal3dv(normal);
|
||||||
pp = calc_tex_coords(nodes[n2], &tile->center);
|
pp = calc_tex_coords(t->nodes[n2], &t->center);
|
||||||
xglTexCoord2f(pp.lon, pp.lat);
|
xglTexCoord2f(pp.lon, pp.lat);
|
||||||
xglVertex3d(nodes[n2][0], nodes[n2][1], nodes[n2][2]);
|
xglVertex3d(t->nodes[n2][0], t->nodes[n2][1], t->nodes[n2][2]);
|
||||||
|
|
||||||
MAT3_SCALE_VEC(normal, normals[n3], scale);
|
MAT3_SCALE_VEC(normal, normals[n3], scale);
|
||||||
xglNormal3dv(normal);
|
xglNormal3dv(normal);
|
||||||
pp = calc_tex_coords(nodes[n3], &tile->center);
|
pp = calc_tex_coords(t->nodes[n3], &t->center);
|
||||||
xglTexCoord2f(pp.lon, pp.lat);
|
xglTexCoord2f(pp.lon, pp.lat);
|
||||||
xglVertex3d(nodes[n3][0], nodes[n3][1], nodes[n3][2]);
|
xglVertex3d(t->nodes[n3][0], t->nodes[n3][1], t->nodes[n3][2]);
|
||||||
} else {
|
} else {
|
||||||
// Shading model is "GL_FLAT" so calculate per face
|
// Shading model is "GL_FLAT" so calculate per face
|
||||||
// normals on the fly.
|
// normals on the fly.
|
||||||
if ( odd ) {
|
if ( odd ) {
|
||||||
calc_normal(nodes[n1], nodes[n2],
|
calc_normal(t->nodes[n1], t->nodes[n2],
|
||||||
nodes[n3], approx_normal);
|
t->nodes[n3], approx_normal);
|
||||||
} else {
|
} else {
|
||||||
calc_normal(nodes[n2], nodes[n1],
|
calc_normal(t->nodes[n2], t->nodes[n1],
|
||||||
nodes[n3], approx_normal);
|
t->nodes[n3], approx_normal);
|
||||||
}
|
}
|
||||||
MAT3_SCALE_VEC(normal, approx_normal, scale);
|
MAT3_SCALE_VEC(normal, approx_normal, scale);
|
||||||
xglNormal3dv(normal);
|
xglNormal3dv(normal);
|
||||||
|
|
||||||
pp = calc_tex_coords(nodes[n1], &tile->center);
|
pp = calc_tex_coords(t->nodes[n1], &t->center);
|
||||||
xglTexCoord2f(pp.lon, pp.lat);
|
xglTexCoord2f(pp.lon, pp.lat);
|
||||||
xglVertex3d(nodes[n1][0], nodes[n1][1], nodes[n1][2]);
|
xglVertex3d(t->nodes[n1][0], t->nodes[n1][1], t->nodes[n1][2]);
|
||||||
|
|
||||||
pp = calc_tex_coords(nodes[n2], &tile->center);
|
pp = calc_tex_coords(t->nodes[n2], &t->center);
|
||||||
xglTexCoord2f(pp.lon, pp.lat);
|
xglTexCoord2f(pp.lon, pp.lat);
|
||||||
xglVertex3d(nodes[n2][0], nodes[n2][1], nodes[n2][2]);
|
xglVertex3d(t->nodes[n2][0], t->nodes[n2][1], t->nodes[n2][2]);
|
||||||
|
|
||||||
pp = calc_tex_coords(nodes[n3], &tile->center);
|
pp = calc_tex_coords(t->nodes[n3], &t->center);
|
||||||
xglTexCoord2f(pp.lon, pp.lat);
|
xglTexCoord2f(pp.lon, pp.lat);
|
||||||
xglVertex3d(nodes[n3][0], nodes[n3][1], nodes[n3][2]);
|
xglVertex3d(t->nodes[n3][0], t->nodes[n3][1], t->nodes[n3][2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
odd = 1 - odd;
|
odd = 1 - odd;
|
||||||
|
@ -297,18 +305,21 @@ int fgObjLoad(char *path, fgTILE *tile) {
|
||||||
last2 = n3;
|
last2 = n3;
|
||||||
|
|
||||||
if ( n4 > 0 ) {
|
if ( n4 > 0 ) {
|
||||||
|
fragment.add_face(n3, n2, n4);
|
||||||
|
|
||||||
if ( o->shading ) {
|
if ( o->shading ) {
|
||||||
// Shading model is "GL_SMOOTH"
|
// Shading model is "GL_SMOOTH"
|
||||||
MAT3_SCALE_VEC(normal, normals[n4], scale);
|
MAT3_SCALE_VEC(normal, normals[n4], scale);
|
||||||
} else {
|
} else {
|
||||||
// Shading model is "GL_FLAT"
|
// Shading model is "GL_FLAT"
|
||||||
calc_normal(nodes[n3], nodes[n2], nodes[n4], approx_normal);
|
calc_normal(t->nodes[n3], t->nodes[n2], t->nodes[n4],
|
||||||
|
approx_normal);
|
||||||
MAT3_SCALE_VEC(normal, approx_normal, scale);
|
MAT3_SCALE_VEC(normal, approx_normal, scale);
|
||||||
}
|
}
|
||||||
xglNormal3dv(normal);
|
xglNormal3dv(normal);
|
||||||
pp = calc_tex_coords(nodes[n4], &tile->center);
|
pp = calc_tex_coords(t->nodes[n4], &t->center);
|
||||||
xglTexCoord2f(pp.lon, pp.lat);
|
xglTexCoord2f(pp.lon, pp.lat);
|
||||||
xglVertex3d(nodes[n4][0], nodes[n4][1], nodes[n4][2]);
|
xglVertex3d(t->nodes[n4][0], t->nodes[n4][1], t->nodes[n4][2]);
|
||||||
|
|
||||||
odd = 1 - odd;
|
odd = 1 - odd;
|
||||||
last1 = n3;
|
last1 = n3;
|
||||||
|
@ -325,20 +336,22 @@ int fgObjLoad(char *path, fgTILE *tile) {
|
||||||
// fgPrintf( FG_TERRAIN, FG_DEBUG, "new triangle = %s", line);*/
|
// fgPrintf( FG_TERRAIN, FG_DEBUG, "new triangle = %s", line);*/
|
||||||
sscanf(line, "f %d %d %d\n", &n1, &n2, &n3);
|
sscanf(line, "f %d %d %d\n", &n1, &n2, &n3);
|
||||||
|
|
||||||
|
fragment.add_face(n1, n2, n3);
|
||||||
|
|
||||||
xglNormal3d(normals[n1][0], normals[n1][1], normals[n1][2]);
|
xglNormal3d(normals[n1][0], normals[n1][1], normals[n1][2]);
|
||||||
pp = calc_tex_coords(nodes[n1], &tile->center);
|
pp = calc_tex_coords(t->nodes[n1], &t->center);
|
||||||
xglTexCoord2f(pp.lon, pp.lat);
|
xglTexCoord2f(pp.lon, pp.lat);
|
||||||
xglVertex3d(nodes[n1][0], nodes[n1][1], nodes[n1][2]);
|
xglVertex3d(t->nodes[n1][0], t->nodes[n1][1], t->nodes[n1][2]);
|
||||||
|
|
||||||
xglNormal3d(normals[n2][0], normals[n2][1], normals[n2][2]);
|
xglNormal3d(normals[n2][0], normals[n2][1], normals[n2][2]);
|
||||||
pp = calc_tex_coords(nodes[n2], &tile->center);
|
pp = calc_tex_coords(t->nodes[n2], &t->center);
|
||||||
xglTexCoord2f(pp.lon, pp.lat);
|
xglTexCoord2f(pp.lon, pp.lat);
|
||||||
xglVertex3d(nodes[n2][0], nodes[n2][1], nodes[n2][2]);
|
xglVertex3d(t->nodes[n2][0], t->nodes[n2][1], t->nodes[n2][2]);
|
||||||
|
|
||||||
xglNormal3d(normals[n3][0], normals[n3][1], normals[n3][2]);
|
xglNormal3d(normals[n3][0], normals[n3][1], normals[n3][2]);
|
||||||
pp = calc_tex_coords(nodes[n3], &tile->center);
|
pp = calc_tex_coords(t->nodes[n3], &t->center);
|
||||||
xglTexCoord2f(pp.lon, pp.lat);
|
xglTexCoord2f(pp.lon, pp.lat);
|
||||||
xglVertex3d(nodes[n3][0], nodes[n3][1], nodes[n3][2]);
|
xglVertex3d(t->nodes[n3][0], t->nodes[n3][1], t->nodes[n3][2]);
|
||||||
} else if ( line[0] == 'q' ) {
|
} else if ( line[0] == 'q' ) {
|
||||||
// continue a triangle strip
|
// continue a triangle strip
|
||||||
n1 = n2 = 0;
|
n1 = n2 = 0;
|
||||||
|
@ -348,6 +361,12 @@ int fgObjLoad(char *path, fgTILE *tile) {
|
||||||
sscanf(line, "q %d %d\n", &n1, &n2);
|
sscanf(line, "q %d %d\n", &n1, &n2);
|
||||||
// fgPrintf( FG_TERRAIN, FG_DEBUG, "read %d %d\n", n1, n2);
|
// fgPrintf( FG_TERRAIN, FG_DEBUG, "read %d %d\n", n1, n2);
|
||||||
|
|
||||||
|
if ( odd ) {
|
||||||
|
fragment.add_face(last1, last2, n1);
|
||||||
|
} else {
|
||||||
|
fragment.add_face(last2, last1, n1);
|
||||||
|
}
|
||||||
|
|
||||||
if ( o->shading ) {
|
if ( o->shading ) {
|
||||||
// Shading model is "GL_SMOOTH"
|
// Shading model is "GL_SMOOTH"
|
||||||
MAT3_SCALE_VEC(normal, normals[n1], scale);
|
MAT3_SCALE_VEC(normal, normals[n1], scale);
|
||||||
|
@ -355,19 +374,19 @@ int fgObjLoad(char *path, fgTILE *tile) {
|
||||||
} else {
|
} else {
|
||||||
// Shading model is "GL_FLAT"
|
// Shading model is "GL_FLAT"
|
||||||
if ( odd ) {
|
if ( odd ) {
|
||||||
calc_normal(nodes[last1], nodes[last2], nodes[n1],
|
calc_normal(t->nodes[last1], t->nodes[last2], t->nodes[n1],
|
||||||
approx_normal);
|
approx_normal);
|
||||||
} else {
|
} else {
|
||||||
calc_normal(nodes[last2], nodes[last1], nodes[n1],
|
calc_normal(t->nodes[last2], t->nodes[last1], t->nodes[n1],
|
||||||
approx_normal);
|
approx_normal);
|
||||||
}
|
}
|
||||||
MAT3_SCALE_VEC(normal, approx_normal, scale);
|
MAT3_SCALE_VEC(normal, approx_normal, scale);
|
||||||
xglNormal3dv(normal);
|
xglNormal3dv(normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
pp = calc_tex_coords(nodes[n1], &tile->center);
|
pp = calc_tex_coords(t->nodes[n1], &t->center);
|
||||||
xglTexCoord2f(pp.lon, pp.lat);
|
xglTexCoord2f(pp.lon, pp.lat);
|
||||||
xglVertex3d(nodes[n1][0], nodes[n1][1], nodes[n1][2]);
|
xglVertex3d(t->nodes[n1][0], t->nodes[n1][1], t->nodes[n1][2]);
|
||||||
|
|
||||||
odd = 1 - odd;
|
odd = 1 - odd;
|
||||||
last1 = last2;
|
last1 = last2;
|
||||||
|
@ -376,6 +395,12 @@ int fgObjLoad(char *path, fgTILE *tile) {
|
||||||
if ( n2 > 0 ) {
|
if ( n2 > 0 ) {
|
||||||
// fgPrintf( FG_TERRAIN, FG_DEBUG, " (cont)\n");
|
// fgPrintf( FG_TERRAIN, FG_DEBUG, " (cont)\n");
|
||||||
|
|
||||||
|
if ( odd ) {
|
||||||
|
fragment.add_face(last1, last2, n2);
|
||||||
|
} else {
|
||||||
|
fragment.add_face(last2, last1, n2);
|
||||||
|
}
|
||||||
|
|
||||||
if ( o->shading ) {
|
if ( o->shading ) {
|
||||||
// Shading model is "GL_SMOOTH"
|
// Shading model is "GL_SMOOTH"
|
||||||
MAT3_SCALE_VEC(normal, normals[n2], scale);
|
MAT3_SCALE_VEC(normal, normals[n2], scale);
|
||||||
|
@ -383,19 +408,19 @@ int fgObjLoad(char *path, fgTILE *tile) {
|
||||||
} else {
|
} else {
|
||||||
// Shading model is "GL_FLAT"
|
// Shading model is "GL_FLAT"
|
||||||
if ( odd ) {
|
if ( odd ) {
|
||||||
calc_normal(nodes[last1], nodes[last2], nodes[n2],
|
calc_normal(t->nodes[last1], t->nodes[last2],
|
||||||
approx_normal);
|
t->nodes[n2], approx_normal);
|
||||||
} else {
|
} else {
|
||||||
calc_normal(nodes[last2], nodes[last1], nodes[n2],
|
calc_normal(t->nodes[last2], t->nodes[last1],
|
||||||
approx_normal);
|
t->nodes[n2], approx_normal);
|
||||||
}
|
}
|
||||||
MAT3_SCALE_VEC(normal, approx_normal, scale);
|
MAT3_SCALE_VEC(normal, approx_normal, scale);
|
||||||
xglNormal3dv(normal);
|
xglNormal3dv(normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
pp = calc_tex_coords(nodes[n2], &tile->center);
|
pp = calc_tex_coords(t->nodes[n2], &t->center);
|
||||||
xglTexCoord2f(pp.lon, pp.lat);
|
xglTexCoord2f(pp.lon, pp.lat);
|
||||||
xglVertex3d(nodes[n2][0], nodes[n2][1], nodes[n2][2]);
|
xglVertex3d(t->nodes[n2][0], t->nodes[n2][1], t->nodes[n2][2]);
|
||||||
|
|
||||||
odd = 1 -odd;
|
odd = 1 -odd;
|
||||||
last1 = last2;
|
last1 = last2;
|
||||||
|
@ -416,20 +441,20 @@ int fgObjLoad(char *path, fgTILE *tile) {
|
||||||
fragment.display_list = display_list;
|
fragment.display_list = display_list;
|
||||||
|
|
||||||
// push this fragment onto the tile's object list
|
// push this fragment onto the tile's object list
|
||||||
tile->fragment_list.push_back(fragment);
|
t->fragment_list.push_back(fragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw normal vectors (for visually verifying normals)
|
// Draw normal vectors (for visually verifying normals)
|
||||||
/*
|
/*
|
||||||
xglBegin(GL_LINES);
|
xglBegin(GL_LINES);
|
||||||
xglColor3f(0.0, 0.0, 0.0);
|
xglColor3f(0.0, 0.0, 0.0);
|
||||||
for ( i = 0; i < ncount; i++ ) {
|
for ( i = 0; i < t->ncount; i++ ) {
|
||||||
xglVertex3d(nodes[i][0],
|
xglVertex3d(t->nodes[i][0],
|
||||||
nodes[i][1] ,
|
t->nodes[i][1] ,
|
||||||
nodes[i][2]);
|
t->nodes[i][2]);
|
||||||
xglVertex3d(nodes[i][0] + 500*normals[i][0],
|
xglVertex3d(t->nodes[i][0] + 500*normals[i][0],
|
||||||
nodes[i][1] + 500*normals[i][1],
|
t->nodes[i][1] + 500*normals[i][1],
|
||||||
nodes[i][2] + 500*normals[i][2]);
|
t->nodes[i][2] + 500*normals[i][2]);
|
||||||
}
|
}
|
||||||
xglEnd();
|
xglEnd();
|
||||||
*/
|
*/
|
||||||
|
@ -441,6 +466,14 @@ int fgObjLoad(char *path, fgTILE *tile) {
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.18 1998/07/12 03:18:27 curt
|
||||||
|
// Added ground collision detection. This involved:
|
||||||
|
// - saving the entire vertex list for each tile with the tile records.
|
||||||
|
// - saving the face list for each fragment with the fragment records.
|
||||||
|
// - code to intersect the current vertical line with the proper face in
|
||||||
|
// an efficient manner as possible.
|
||||||
|
// Fixed a bug where the tiles weren't being shifted to "near" (0,0,0)
|
||||||
|
//
|
||||||
// Revision 1.17 1998/07/08 14:47:21 curt
|
// Revision 1.17 1998/07/08 14:47:21 curt
|
||||||
// Fix GL_MODULATE vs. GL_DECAL problem introduced by splash screen.
|
// Fix GL_MODULATE vs. GL_DECAL problem introduced by splash screen.
|
||||||
// polare3d.h renamed to polar3d.hxx
|
// polare3d.h renamed to polar3d.hxx
|
||||||
|
|
|
@ -66,31 +66,8 @@ int fgSceneryInit( void ) {
|
||||||
|
|
||||||
fgPrintf(FG_TERRAIN, FG_INFO, "Initializing scenery subsystem\n");
|
fgPrintf(FG_TERRAIN, FG_INFO, "Initializing scenery subsystem\n");
|
||||||
|
|
||||||
#ifdef 0
|
scenery.cur_elev = -9999;
|
||||||
/* set the default terrain detail level */
|
|
||||||
// scenery.terrain_skip = 6;
|
|
||||||
|
|
||||||
/* temp: load in a demo texture */
|
|
||||||
path[0] = '\0';
|
|
||||||
strcat(path, o->fg_root);
|
|
||||||
strcat(path, "/Textures/");
|
|
||||||
strcat(path, "desert.rgb");
|
|
||||||
|
|
||||||
// Try uncompressed
|
|
||||||
if ( (texbuf = read_rgb_texture(path, &width, &height)) == NULL ) {
|
|
||||||
// Try compressed
|
|
||||||
strcpy(fgpath, path);
|
|
||||||
strcat(fgpath, ".gz");
|
|
||||||
if ( (texbuf = read_rgb_texture(fgpath, &width, &height)) == NULL ) {
|
|
||||||
fgPrintf( FG_GENERAL, FG_EXIT, "Error in loading texture %s\n",
|
|
||||||
path );
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xglTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0,
|
|
||||||
GL_RGB, GL_UNSIGNED_BYTE, texbuf);
|
|
||||||
#endif // 0
|
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,11 +102,19 @@ void fgSceneryRender( void ) {
|
||||||
|
|
||||||
|
|
||||||
/* $Log$
|
/* $Log$
|
||||||
/* Revision 1.5 1998/06/17 21:36:41 curt
|
/* Revision 1.6 1998/07/12 03:18:27 curt
|
||||||
/* Load and manage multiple textures defined in the Materials library.
|
/* Added ground collision detection. This involved:
|
||||||
/* Boost max material fagments for each material property to 800.
|
/* - saving the entire vertex list for each tile with the tile records.
|
||||||
/* Multiple texture support when rendering.
|
/* - saving the face list for each fragment with the fragment records.
|
||||||
|
/* - code to intersect the current vertical line with the proper face in
|
||||||
|
/* an efficient manner as possible.
|
||||||
|
/* Fixed a bug where the tiles weren't being shifted to "near" (0,0,0)
|
||||||
/*
|
/*
|
||||||
|
* Revision 1.5 1998/06/17 21:36:41 curt
|
||||||
|
* Load and manage multiple textures defined in the Materials library.
|
||||||
|
* Boost max material fagments for each material property to 800.
|
||||||
|
* Multiple texture support when rendering.
|
||||||
|
*
|
||||||
* Revision 1.4 1998/05/13 18:26:40 curt
|
* Revision 1.4 1998/05/13 18:26:40 curt
|
||||||
* Root path info moved to fgOPTIONS.
|
* Root path info moved to fgOPTIONS.
|
||||||
*
|
*
|
||||||
|
|
|
@ -38,9 +38,6 @@
|
||||||
|
|
||||||
/* Define a structure containing global scenery parameters */
|
/* Define a structure containing global scenery parameters */
|
||||||
struct fgSCENERY {
|
struct fgSCENERY {
|
||||||
/* number of terrain data points to skip */
|
|
||||||
int terrain_skip;
|
|
||||||
|
|
||||||
/* center of current scenery chunk */
|
/* center of current scenery chunk */
|
||||||
fgPoint3d center;
|
fgPoint3d center;
|
||||||
|
|
||||||
|
@ -49,6 +46,10 @@ struct fgSCENERY {
|
||||||
|
|
||||||
/* angle of sun relative to current local horizontal */
|
/* angle of sun relative to current local horizontal */
|
||||||
double sun_angle;
|
double sun_angle;
|
||||||
|
|
||||||
|
// elevation of terrain at our current lat/lon (based on the
|
||||||
|
// actual drawn polygons)
|
||||||
|
double cur_elev;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct fgSCENERY scenery;
|
extern struct fgSCENERY scenery;
|
||||||
|
@ -71,12 +72,20 @@ void fgSceneryRender( void );
|
||||||
|
|
||||||
|
|
||||||
/* $Log$
|
/* $Log$
|
||||||
/* Revision 1.3 1998/07/08 14:47:22 curt
|
/* Revision 1.4 1998/07/12 03:18:28 curt
|
||||||
/* Fix GL_MODULATE vs. GL_DECAL problem introduced by splash screen.
|
/* Added ground collision detection. This involved:
|
||||||
/* polare3d.h renamed to polar3d.hxx
|
/* - saving the entire vertex list for each tile with the tile records.
|
||||||
/* fg{Cartesian,Polar}Point3d consolodated.
|
/* - saving the face list for each fragment with the fragment records.
|
||||||
/* Added some initial support for calculating local current ground elevation.
|
/* - code to intersect the current vertical line with the proper face in
|
||||||
|
/* an efficient manner as possible.
|
||||||
|
/* Fixed a bug where the tiles weren't being shifted to "near" (0,0,0)
|
||||||
/*
|
/*
|
||||||
|
* Revision 1.3 1998/07/08 14:47:22 curt
|
||||||
|
* Fix GL_MODULATE vs. GL_DECAL problem introduced by splash screen.
|
||||||
|
* polare3d.h renamed to polar3d.hxx
|
||||||
|
* fg{Cartesian,Polar}Point3d consolodated.
|
||||||
|
* Added some initial support for calculating local current ground elevation.
|
||||||
|
*
|
||||||
* Revision 1.2 1998/05/02 01:52:16 curt
|
* Revision 1.2 1998/05/02 01:52:16 curt
|
||||||
* Playing around with texture coordinates.
|
* Playing around with texture coordinates.
|
||||||
*
|
*
|
||||||
|
|
271
Scenery/tile.cxx
271
Scenery/tile.cxx
|
@ -22,6 +22,10 @@
|
||||||
// (Log is kept at end of this file)
|
// (Log is kept at end of this file)
|
||||||
|
|
||||||
|
|
||||||
|
#include <Include/fg_constants.h>
|
||||||
|
#include <Include/fg_types.h>
|
||||||
|
#include <Math/mat3.h>
|
||||||
|
|
||||||
#include "tile.hxx"
|
#include "tile.hxx"
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,22 +34,289 @@ fgFRAGMENT::fgFRAGMENT ( void ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Add a face to the face list
|
||||||
|
void fgFRAGMENT::add_face(int n1, int n2, int n3) {
|
||||||
|
fgFACE face;
|
||||||
|
|
||||||
|
face.n1 = n1;
|
||||||
|
face.n2 = n2;
|
||||||
|
face.n3 = n3;
|
||||||
|
|
||||||
|
faces.push_back(face);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// return the sign of a value
|
||||||
|
static int fg_sign( double x ) {
|
||||||
|
if ( x >= 0 ) {
|
||||||
|
return(1);
|
||||||
|
} else {
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// return the minimum of the three values
|
||||||
|
static double fg_min( double a, double b, double c ) {
|
||||||
|
double result;
|
||||||
|
result = a;
|
||||||
|
if (result > b) result = b;
|
||||||
|
if (result > c) result = c;
|
||||||
|
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// return the maximum of the three values
|
||||||
|
static double fg_max( double a, double b, double c ) {
|
||||||
|
double result;
|
||||||
|
result = a;
|
||||||
|
if (result < b) result = b;
|
||||||
|
if (result < c) result = c;
|
||||||
|
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// test if line intesects with this fragment. p0 and p1 are the two
|
||||||
|
// line end points of the line. If side_flag is true, check to see
|
||||||
|
// that end points are on opposite sides of face. Returns 1 if it
|
||||||
|
// does, 0 otherwise. If it intesects, result is the point of
|
||||||
|
// intersection
|
||||||
|
|
||||||
|
int fgFRAGMENT::intersect( fgPoint3d *end0, fgPoint3d *end1, int side_flag,
|
||||||
|
fgPoint3d *result)
|
||||||
|
{
|
||||||
|
fgTILE *t;
|
||||||
|
fgFACE face;
|
||||||
|
MAT3vec v1, v2, n, center;
|
||||||
|
double p1[3], p2[3], p3[3];
|
||||||
|
double a, b, c, d;
|
||||||
|
double x0, y0, z0, x1, y1, z1, a1, b1, c1;
|
||||||
|
double t1, t2, t3;
|
||||||
|
double xmin, xmax, ymin, ymax, zmin, zmax;
|
||||||
|
double dx, dy, dz, min_dim, x2, y2, x3, y3, rx, ry;
|
||||||
|
int side1, side2;
|
||||||
|
list < fgFACE > :: iterator current;
|
||||||
|
list < fgFACE > :: iterator last;
|
||||||
|
|
||||||
|
// find the associated tile
|
||||||
|
t = (fgTILE *)tile_ptr;
|
||||||
|
|
||||||
|
// printf("Intersecting\n");
|
||||||
|
|
||||||
|
// traverse the face list for this fragment
|
||||||
|
current = faces.begin();
|
||||||
|
last = faces.end();
|
||||||
|
while ( current != last ) {
|
||||||
|
face = *current;
|
||||||
|
current++;
|
||||||
|
|
||||||
|
// printf(".");
|
||||||
|
|
||||||
|
// get face vertex coordinates
|
||||||
|
center[0] = t->center.x;
|
||||||
|
center[1] = t->center.y;
|
||||||
|
center[2] = t->center.z;
|
||||||
|
|
||||||
|
MAT3_ADD_VEC(p1, t->nodes[face.n1], center);
|
||||||
|
MAT3_ADD_VEC(p2, t->nodes[face.n2], center);
|
||||||
|
MAT3_ADD_VEC(p3, t->nodes[face.n3], center);
|
||||||
|
|
||||||
|
// printf("point 1 = %.2f %.2f %.2f\n", p1[0], p1[1], p1[2]);
|
||||||
|
// printf("point 2 = %.2f %.2f %.2f\n", p2[0], p2[1], p2[2]);
|
||||||
|
// printf("point 3 = %.2f %.2f %.2f\n", p3[0], p3[1], p3[2]);
|
||||||
|
|
||||||
|
// calculate two edge vectors, and the face normal
|
||||||
|
MAT3_SUB_VEC(v1, p2, p1);
|
||||||
|
MAT3_SUB_VEC(v2, p3, p1);
|
||||||
|
MAT3cross_product(n, v1, v2);
|
||||||
|
|
||||||
|
// calculate the plane coefficients for the plane defined by
|
||||||
|
// this face. If n is the normal vector, n = (a, b, c) and p1
|
||||||
|
// is a point on the plane, p1 = (x0, y0, z0), then the
|
||||||
|
// equation of the line is a(x-x0) + b(y-y0) + c(z-z0) = 0
|
||||||
|
a = n[0];
|
||||||
|
b = n[1];
|
||||||
|
c = n[2];
|
||||||
|
d = a * p1[0] + b * p1[1] + c * p1[2];
|
||||||
|
// printf("a, b, c, d = %.2f %.2f %.2f %.2f\n", a, b, c, d);
|
||||||
|
|
||||||
|
// printf("p1(d) = %.2f\n", a * p1[0] + b * p1[1] + c * p1[2]);
|
||||||
|
// printf("p2(d) = %.2f\n", a * p2[0] + b * p2[1] + c * p2[2]);
|
||||||
|
// printf("p3(d) = %.2f\n", a * p3[0] + b * p3[1] + c * p3[2]);
|
||||||
|
|
||||||
|
// calculate the line coefficients for the specified line
|
||||||
|
x0 = end0->x; x1 = end1->x;
|
||||||
|
y0 = end0->y; y1 = end1->y;
|
||||||
|
z0 = end0->z; z1 = end1->z;
|
||||||
|
|
||||||
|
a1 = x1 - x0;
|
||||||
|
b1 = y1 - y0;
|
||||||
|
c1 = z1 - z0;
|
||||||
|
|
||||||
|
// intersect the specified line with this plane
|
||||||
|
t1 = b * b1 / a1;
|
||||||
|
t2 = c * c1 / a1;
|
||||||
|
|
||||||
|
// printf("a = %.2f t1 = %.2f t2 = %.2f\n", a, t1, t2);
|
||||||
|
|
||||||
|
if ( fabs(a + t1 + t2) > FG_EPSILON ) {
|
||||||
|
result->x = (t1*x0 - b*y0 + t2*x0 - c*z0 + d) / (a + t1 + t2);
|
||||||
|
result->y = (b1/a1) * (result->x - x0) + y0;
|
||||||
|
result->z = (c1/a1) * (result->x - x0) + z0;
|
||||||
|
// printf("result(d) = %.2f\n",
|
||||||
|
// a * result->x + b * result->y + c * result->z);
|
||||||
|
} else {
|
||||||
|
// no intersection point
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( side_flag ) {
|
||||||
|
// check to see if end0 and end1 are on opposite sides of
|
||||||
|
// plane
|
||||||
|
if ( (result->x - x0) > FG_EPSILON ) {
|
||||||
|
t1 = result->x; t2 = x0; t3 = x1;
|
||||||
|
} else if ( (result->y - y0) > FG_EPSILON ) {
|
||||||
|
t1 = result->y; t2 = y0; t3 = y1;
|
||||||
|
} else if ( (result->z - z0) > FG_EPSILON ) {
|
||||||
|
t1 = result->z; t2 = z0; t3 = z1;
|
||||||
|
} else {
|
||||||
|
// everything is too close together to tell the difference
|
||||||
|
// so the current intersection point should work as good
|
||||||
|
// as any
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
if ( fg_sign(t1 - t2) == fg_sign(t1 - t3) ) {
|
||||||
|
// same side, punt
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check to see if intersection point is in the bounding
|
||||||
|
// cube of the face
|
||||||
|
xmin = fg_min(p1[0], p2[0], p3[0]);
|
||||||
|
xmax = fg_max(p1[0], p2[0], p3[0]);
|
||||||
|
ymin = fg_min(p1[1], p2[1], p3[1]);
|
||||||
|
ymax = fg_max(p1[1], p2[1], p3[1]);
|
||||||
|
zmin = fg_min(p1[2], p2[2], p3[2]);
|
||||||
|
zmax = fg_max(p1[2], p2[2], p3[2]);
|
||||||
|
// printf("bounding cube = %.2f,%.2f,%.2f %.2f,%.2f,%.2f\n",
|
||||||
|
// xmin, ymin, zmin, xmax, ymax, zmax);
|
||||||
|
// punt if outside bouding cube
|
||||||
|
if ( result->x < xmin ) {
|
||||||
|
continue;
|
||||||
|
} else if ( result->x > xmax ) {
|
||||||
|
continue;
|
||||||
|
} else if ( result->y < ymin ) {
|
||||||
|
continue;
|
||||||
|
} else if ( result->y > ymax ) {
|
||||||
|
continue;
|
||||||
|
} else if ( result->z < zmin ) {
|
||||||
|
continue;
|
||||||
|
} else if ( result->z > zmax ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// (finally) check to see if the intersection point is
|
||||||
|
// actually inside this face
|
||||||
|
|
||||||
|
//first, drop the smallest dimension so we only have to work
|
||||||
|
//in 2d.
|
||||||
|
dx = xmax - xmin;
|
||||||
|
dy = ymax - ymin;
|
||||||
|
dz = zmax - zmin;
|
||||||
|
min_dim = fg_min(dx, dy, dz);
|
||||||
|
if ( fabs(min_dim - dx) <= FG_EPSILON ) {
|
||||||
|
// x is the smallest dimension
|
||||||
|
x1 = p1[1]; y1 = p1[2];
|
||||||
|
x2 = p2[1]; y2 = p2[2];
|
||||||
|
x3 = p3[1]; y3 = p3[2];
|
||||||
|
rx = result->y; ry = result->z;
|
||||||
|
} else if ( fabs(min_dim - dy) <= FG_EPSILON ) {
|
||||||
|
// y is the smallest dimension
|
||||||
|
x1 = p1[0]; y1 = p1[2];
|
||||||
|
x2 = p2[0]; y2 = p2[2];
|
||||||
|
x3 = p3[0]; y3 = p3[2];
|
||||||
|
rx = result->x; ry = result->z;
|
||||||
|
} else if ( fabs(min_dim - dz) <= FG_EPSILON ) {
|
||||||
|
// z is the smallest dimension
|
||||||
|
x1 = p1[0]; y1 = p1[1];
|
||||||
|
x2 = p2[0]; y2 = p2[1];
|
||||||
|
x3 = p3[0]; y3 = p3[1];
|
||||||
|
rx = result->x; ry = result->y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if intersection point is on the same side of p1 <-> p2 as p3
|
||||||
|
side1 = fg_sign((y1 - y2) * ((x3) - x2) / (x1 - x2) + y2 - (y3));
|
||||||
|
side2 = fg_sign((y1 - y2) * ((rx) - x2) / (x1 - x2) + y2 - (ry));
|
||||||
|
if ( side1 != side2 ) {
|
||||||
|
// printf("failed side 1 check\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if intersection point is on correct side of p2 <-> p3 as p1
|
||||||
|
side1 = fg_sign((y2 - y3) * ((x1) - x3) / (x2 - x3) + y3 - (y1));
|
||||||
|
side2 = fg_sign((y2 - y3) * ((rx) - x3) / (x2 - x3) + y3 - (ry));
|
||||||
|
if ( side1 != side2 ) {
|
||||||
|
// printf("failed side 2 check\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if intersection point is on correct side of p1 <-> p3 as p2
|
||||||
|
side1 = fg_sign((y1 - y3) * ((x2) - x3) / (x1 - x3) + y3 - (y2));
|
||||||
|
side2 = fg_sign((y1 - y3) * ((rx) - x3) / (x1 - x3) + y3 - (ry));
|
||||||
|
if ( side1 != side2 ) {
|
||||||
|
// printf("failed side 3 check\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// printf( "intersection point = %.2f %.2f %.2f\n",
|
||||||
|
// result->x, result->y, result->z);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// printf("\n");
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
fgFRAGMENT::~fgFRAGMENT ( void ) {
|
fgFRAGMENT::~fgFRAGMENT ( void ) {
|
||||||
|
// Step through the face list deleting the items until the list is
|
||||||
|
// empty
|
||||||
|
|
||||||
|
// printf("destructing a fragment with %d faces\n", faces.size());
|
||||||
|
|
||||||
|
while ( faces.size() ) {
|
||||||
|
// printf("emptying face list\n");
|
||||||
|
faces.pop_front();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
fgTILE::fgTILE ( void ) {
|
fgTILE::fgTILE ( void ) {
|
||||||
|
nodes = new double[MAX_NODES][3];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
fgTILE::~fgTILE ( void ) {
|
fgTILE::~fgTILE ( void ) {
|
||||||
|
free(nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.2 1998/07/12 03:18:28 curt
|
||||||
|
// Added ground collision detection. This involved:
|
||||||
|
// - saving the entire vertex list for each tile with the tile records.
|
||||||
|
// - saving the face list for each fragment with the fragment records.
|
||||||
|
// - code to intersect the current vertical line with the proper face in
|
||||||
|
// an efficient manner as possible.
|
||||||
|
// Fixed a bug where the tiles weren't being shifted to "near" (0,0,0)
|
||||||
|
//
|
||||||
// Revision 1.1 1998/05/23 14:09:21 curt
|
// Revision 1.1 1998/05/23 14:09:21 curt
|
||||||
// Added tile.cxx and tile.hxx.
|
// Added tile.cxx and tile.hxx.
|
||||||
// Working on rewriting the tile management system so a tile is just a list
|
// Working on rewriting the tile management system so a tile is just a list
|
||||||
|
|
|
@ -53,6 +53,16 @@ using namespace std;
|
||||||
|
|
||||||
#include <Bucket/bucketutils.h>
|
#include <Bucket/bucketutils.h>
|
||||||
#include <Include/fg_types.h>
|
#include <Include/fg_types.h>
|
||||||
|
#include <Math/mat3.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Maximum nodes per tile
|
||||||
|
#define MAX_NODES 1000
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int n1, n2, n3;
|
||||||
|
} fgFACE;
|
||||||
|
|
||||||
|
|
||||||
// Object fragment data class
|
// Object fragment data class
|
||||||
|
@ -82,9 +92,23 @@ public:
|
||||||
// OpenGL display list for fragment data
|
// OpenGL display list for fragment data
|
||||||
GLint display_list;
|
GLint display_list;
|
||||||
|
|
||||||
|
// face list (this indexes into the master tile vertex list)
|
||||||
|
list < fgFACE > faces;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
fgFRAGMENT ( void );
|
fgFRAGMENT ( void );
|
||||||
|
|
||||||
|
// Add a face to the face list
|
||||||
|
void add_face(int n1, int n2, int n3);
|
||||||
|
|
||||||
|
// test if line intesects with this fragment. p0 and p1 are the
|
||||||
|
// two line end points of the line. If side_flag is true, check
|
||||||
|
// to see that end points are on opposite sides of face. Returns
|
||||||
|
// 1 if it does, 0 otherwise. If it intesects, result is the
|
||||||
|
// point of intersection
|
||||||
|
int intersect( fgPoint3d *end0, fgPoint3d *end1, int side_flag,
|
||||||
|
fgPoint3d *result);
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
~fgFRAGMENT ( void );
|
~fgFRAGMENT ( void );
|
||||||
};
|
};
|
||||||
|
@ -95,6 +119,10 @@ class fgTILE {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
// node list (the per fragment face lists reference this node list)
|
||||||
|
double (*nodes)[3];
|
||||||
|
int ncount;
|
||||||
|
|
||||||
// culling data for whole tile (course grain culling)
|
// culling data for whole tile (course grain culling)
|
||||||
fgPoint3d center;
|
fgPoint3d center;
|
||||||
double bounding_radius;
|
double bounding_radius;
|
||||||
|
@ -121,6 +149,14 @@ public:
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.11 1998/07/12 03:18:28 curt
|
||||||
|
// Added ground collision detection. This involved:
|
||||||
|
// - saving the entire vertex list for each tile with the tile records.
|
||||||
|
// - saving the face list for each fragment with the fragment records.
|
||||||
|
// - code to intersect the current vertical line with the proper face in
|
||||||
|
// an efficient manner as possible.
|
||||||
|
// Fixed a bug where the tiles weren't being shifted to "near" (0,0,0)
|
||||||
|
//
|
||||||
// Revision 1.10 1998/07/08 14:47:22 curt
|
// Revision 1.10 1998/07/08 14:47:22 curt
|
||||||
// Fix GL_MODULATE vs. GL_DECAL problem introduced by splash screen.
|
// Fix GL_MODULATE vs. GL_DECAL problem introduced by splash screen.
|
||||||
// polare3d.h renamed to polar3d.hxx
|
// polare3d.h renamed to polar3d.hxx
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include <Main/views.hxx>
|
#include <Main/views.hxx>
|
||||||
|
|
||||||
#include "obj.hxx"
|
#include "obj.hxx"
|
||||||
|
#include "tile.hxx"
|
||||||
#include "tilecache.hxx"
|
#include "tilecache.hxx"
|
||||||
|
|
||||||
|
|
||||||
|
@ -117,7 +118,7 @@ void fgTILECACHE::EntryFillIn( int index, fgBUCKET *p ) {
|
||||||
|
|
||||||
// Free a tile cache entry
|
// Free a tile cache entry
|
||||||
void fgTILECACHE::EntryFree( int index ) {
|
void fgTILECACHE::EntryFree( int index ) {
|
||||||
fgFRAGMENT fragment;
|
fgFRAGMENT *fragment;
|
||||||
|
|
||||||
// Mark this cache entry as un-used
|
// Mark this cache entry as un-used
|
||||||
tile_cache[index].used = 0;
|
tile_cache[index].used = 0;
|
||||||
|
@ -133,8 +134,11 @@ void fgTILECACHE::EntryFree( int index ) {
|
||||||
// Step through the fragment list, deleting the display list, then
|
// Step through the fragment list, deleting the display list, then
|
||||||
// the fragment, until the list is empty.
|
// the fragment, until the list is empty.
|
||||||
while ( tile_cache[index].fragment_list.size() ) {
|
while ( tile_cache[index].fragment_list.size() ) {
|
||||||
fragment = tile_cache[index].fragment_list.front();
|
list < fgFRAGMENT > :: iterator current =
|
||||||
xglDeleteLists( fragment.display_list, 1 );
|
tile_cache[index].fragment_list.begin();
|
||||||
|
fragment = &(*current);
|
||||||
|
xglDeleteLists( fragment->display_list, 1 );
|
||||||
|
|
||||||
tile_cache[index].fragment_list.pop_front();
|
tile_cache[index].fragment_list.pop_front();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,6 +213,14 @@ fgTILECACHE::~fgTILECACHE( void ) {
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.12 1998/07/12 03:18:29 curt
|
||||||
|
// Added ground collision detection. This involved:
|
||||||
|
// - saving the entire vertex list for each tile with the tile records.
|
||||||
|
// - saving the face list for each fragment with the fragment records.
|
||||||
|
// - code to intersect the current vertical line with the proper face in
|
||||||
|
// an efficient manner as possible.
|
||||||
|
// Fixed a bug where the tiles weren't being shifted to "near" (0,0,0)
|
||||||
|
//
|
||||||
// Revision 1.11 1998/07/04 00:54:30 curt
|
// Revision 1.11 1998/07/04 00:54:30 curt
|
||||||
// Added automatic mipmap generation.
|
// Added automatic mipmap generation.
|
||||||
//
|
//
|
||||||
|
|
|
@ -316,13 +316,13 @@ void fgTileMgrRender( void ) {
|
||||||
fgTILECACHE *c;
|
fgTILECACHE *c;
|
||||||
fgFLIGHT *f;
|
fgFLIGHT *f;
|
||||||
fgOPTIONS *o;
|
fgOPTIONS *o;
|
||||||
fgTILE *t;
|
fgTILE *t, *last_tile_ptr;
|
||||||
fgVIEW *v;
|
fgVIEW *v;
|
||||||
fgBUCKET p;
|
fgBUCKET p;
|
||||||
fgPoint3d frag_offset, fc, pp;
|
fgPoint3d frag_offset, pp;
|
||||||
|
fgPoint3d earth_center, result;
|
||||||
fgFRAGMENT *frag_ptr;
|
fgFRAGMENT *frag_ptr;
|
||||||
fgMATERIAL *mtl_ptr;
|
fgMATERIAL *mtl_ptr;
|
||||||
fgTILE *last_tile_ptr;
|
|
||||||
GLdouble *m;
|
GLdouble *m;
|
||||||
double dist, min_dist, lat_geod, alt, sea_level_r;
|
double dist, min_dist, lat_geod, alt, sea_level_r;
|
||||||
double x, y, z;
|
double x, y, z;
|
||||||
|
@ -343,6 +343,14 @@ void fgTileMgrRender( void ) {
|
||||||
index = c->Exists(&p);
|
index = c->Exists(&p);
|
||||||
t = c->GetTile(index);
|
t = c->GetTile(index);
|
||||||
|
|
||||||
|
scenery.next_center.x = t->center.x;
|
||||||
|
scenery.next_center.y = t->center.y;
|
||||||
|
scenery.next_center.z = t->center.z;
|
||||||
|
|
||||||
|
earth_center.x = 0.0;
|
||||||
|
earth_center.y = 0.0;
|
||||||
|
earth_center.z = 0.0;
|
||||||
|
|
||||||
fgPrintf( FG_TERRAIN, FG_DEBUG,
|
fgPrintf( FG_TERRAIN, FG_DEBUG,
|
||||||
"Pos = (%.2f, %.2f) Current bucket = %d %d %d %d Index = %ld\n",
|
"Pos = (%.2f, %.2f) Current bucket = %d %d %d %d Index = %ld\n",
|
||||||
FG_Longitude * RAD_TO_DEG, FG_Latitude * RAD_TO_DEG,
|
FG_Longitude * RAD_TO_DEG, FG_Latitude * RAD_TO_DEG,
|
||||||
|
@ -370,6 +378,7 @@ void fgTileMgrRender( void ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the model_view transformation matrix for this tile
|
// Calculate the model_view transformation matrix for this tile
|
||||||
|
// This is equivalent to doing a glTranslatef(x, y, z);
|
||||||
m[12] = m[0] * x + m[4] * y + m[8] * z + m[12];
|
m[12] = m[0] * x + m[4] * y + m[8] * z + m[12];
|
||||||
m[13] = m[1] * x + m[5] * y + m[9] * z + m[13];
|
m[13] = m[1] * x + m[5] * y + m[9] * z + m[13];
|
||||||
m[14] = m[2] * x + m[6] * y + m[10] * z + m[14];
|
m[14] = m[2] * x + m[6] * y + m[10] * z + m[14];
|
||||||
|
@ -378,7 +387,12 @@ void fgTileMgrRender( void ) {
|
||||||
// temp ... calc current terrain elevation
|
// temp ... calc current terrain elevation
|
||||||
// calculate distance from vertical tangent line at
|
// calculate distance from vertical tangent line at
|
||||||
// current position to center of tile.
|
// current position to center of tile.
|
||||||
dist = point_line_dist(&(t->offset), &(v->view_pos), v->local_up);
|
|
||||||
|
/* printf("distance = %.2f, bounding radius = %.2f\n",
|
||||||
|
point_line_dist(&(t->offset), &(v->view_pos), v->local_up),
|
||||||
|
t->bounding_radius); */
|
||||||
|
|
||||||
|
dist = point_line_dist(&(t->center), &(v->abs_view_pos), v->local_up);
|
||||||
if ( dist < t->bounding_radius ) {
|
if ( dist < t->bounding_radius ) {
|
||||||
|
|
||||||
// traverse fragment list for tile
|
// traverse fragment list for tile
|
||||||
|
@ -388,23 +402,28 @@ void fgTileMgrRender( void ) {
|
||||||
while ( current != last ) {
|
while ( current != last ) {
|
||||||
frag_ptr = &(*current);
|
frag_ptr = &(*current);
|
||||||
current++;
|
current++;
|
||||||
dist = point_line_dist( &(frag_ptr->center), &(v->view_pos),
|
/* printf("distance = %.2f, bounding radius = %.2f\n",
|
||||||
v->local_up);
|
point_line_dist( &(frag_ptr->center),
|
||||||
|
&(v->abs_view_pos), v->local_up),
|
||||||
|
frag_ptr->bounding_radius); */
|
||||||
|
|
||||||
|
dist = point_line_dist( &(frag_ptr->center),
|
||||||
|
&(v->abs_view_pos), v->local_up);
|
||||||
if ( dist <= frag_ptr->bounding_radius ) {
|
if ( dist <= frag_ptr->bounding_radius ) {
|
||||||
if ( dist < min_dist ) {
|
if ( frag_ptr->intersect( &(v->abs_view_pos),
|
||||||
min_dist = dist;
|
&earth_center, 0, &result ) ) {
|
||||||
// compute geocentric coordinates of tile center
|
// compute geocentric coordinates of tile center
|
||||||
pp = fgCartToPolar3d(frag_ptr->center);
|
pp = fgCartToPolar3d(result);
|
||||||
// convert to geodetic coordinates
|
// convert to geodetic coordinates
|
||||||
fgGeocToGeod(pp.lat, pp.radius, &lat_geod,
|
fgGeocToGeod(pp.lat, pp.radius, &lat_geod,
|
||||||
&alt, &sea_level_r);
|
&alt, &sea_level_r);
|
||||||
|
// printf("alt = %.2f\n", alt);
|
||||||
|
scenery.cur_elev = alt;
|
||||||
|
// exit this loop since we found an intersection
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( min_dist <= t->bounding_radius ) {
|
|
||||||
printf("min_dist = %.2f alt = %.2f\n", min_dist, alt);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Course (tile based) culling
|
// Course (tile based) culling
|
||||||
|
@ -531,6 +550,14 @@ void fgTileMgrRender( void ) {
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.24 1998/07/12 03:18:29 curt
|
||||||
|
// Added ground collision detection. This involved:
|
||||||
|
// - saving the entire vertex list for each tile with the tile records.
|
||||||
|
// - saving the face list for each fragment with the fragment records.
|
||||||
|
// - code to intersect the current vertical line with the proper face in
|
||||||
|
// an efficient manner as possible.
|
||||||
|
// Fixed a bug where the tiles weren't being shifted to "near" (0,0,0)
|
||||||
|
//
|
||||||
// Revision 1.23 1998/07/08 14:47:23 curt
|
// Revision 1.23 1998/07/08 14:47:23 curt
|
||||||
// Fix GL_MODULATE vs. GL_DECAL problem introduced by splash screen.
|
// Fix GL_MODULATE vs. GL_DECAL problem introduced by splash screen.
|
||||||
// polare3d.h renamed to polar3d.hxx
|
// polare3d.h renamed to polar3d.hxx
|
||||||
|
|
Loading…
Add table
Reference in a new issue