]> git.mxchange.org Git - flightgear.git/commitdiff
Beginning to add support for view frustum culling.
authorcurt <curt>
Sat, 16 May 1998 13:09:57 +0000 (13:09 +0000)
committercurt <curt>
Sat, 16 May 1998 13:09:57 +0000 (13:09 +0000)
Added some temporary code to calculate bouding radius, until the
  scenery generation tools and scenery can be updated.

Scenery/obj.cxx
Scenery/tilecache.cxx
Scenery/tilecache.hxx
Scenery/tilemgr.cxx

index 53bb6985e1346e2ce12a710e2857f8e6d4bb6de3..f7e635f2d625d9d8311045e749bd8009ec9ac6bd 100644 (file)
@@ -56,7 +56,8 @@ static double normals[MAXNODES][3];
 
 
 /* given three points defining a triangle, calculate the normal */
-void calc_normal(double p1[3], double p2[3], double p3[3], double normal[3])
+static void calc_normal(double p1[3], double p2[3], 
+                       double p3[3], double normal[3])
 {
     double v1[3], v2[3];
     double temp;
@@ -93,12 +94,19 @@ fgPolarPoint3d calc_tex_coords(double *node, fgCartesianPoint3d *ref) {
 }
 
 
+// Calculate distance between (0,0,0) and the specified point
+static double calc_dist(double *p) {
+    return ( sqrt(p[0]*p[0] + p[1]*p[1] + p[2]*p[2]) );
+}
+
+
 /* Load a .obj file and generate the GL call list */
 GLint fgObjLoad(char *path, fgCartesianPoint3d *ref, double *radius) {
     fgOPTIONS *o;
+    fgCartesianPoint3d cp;
     fgPolarPoint3d pp;
     char fgpath[256], line[256], winding_str[256];
-    double approx_normal[3], normal[3], scale;
+    double approx_normal[3], normal[3], scale, dist;
     // double x, y, z, xmax, xmin, ymax, ymin, zmax, zmin;
     // GLfloat sgenparams[] = { 1.0, 0.0, 0.0, 0.0 };
     GLint tile;
@@ -146,6 +154,7 @@ GLint fgObjLoad(char *path, fgCartesianPoint3d *ref, double *radius) {
     first = 1;
     ncount = 1;
     vncount = 1;
+    *radius = 0.0;
 
     while ( fggets(f, line, 250) != NULL ) {
        if ( line[0] == '#' ) {
@@ -163,27 +172,14 @@ GLint fgObjLoad(char *path, fgCartesianPoint3d *ref, double *radius) {
                       &nodes[ncount][0], &nodes[ncount][1], 
                       &nodes[ncount][2]);
 
-               /* first time through set min's and max'es */
-               /*
-               if ( ncount == 1 ) {
-                   xmin = x;
-                   xmax = x;
-                   ymin = y;
-                   ymax = y;
-                   zmin = z;
-                   zmax = z;
+               // temporary code to calculate bounding radius
+               dist = calc_dist(nodes[ncount]);
+               // printf("node = %.2f %.2f %.2f dist = %.2f\n", 
+               //        nodes[ncount][0], nodes[ncount][1], nodes[ncount][2],
+               //        dist);
+               if ( (dist > *radius) && (dist < 100000.0) ) {
+                   *radius = dist;
                }
-               */
-    
-               /* keep track of min/max vertex values */
-               /*
-               if ( x < xmin ) xmin = x;
-               if ( x > xmax ) xmax = x;
-               if ( y < ymin ) ymin = y;
-               if ( y > ymax ) ymax = y;
-               if ( z < zmin ) zmin = z;
-               if ( z > zmax ) zmax = z;               
-               */
 
                ncount++;
            } else {
@@ -448,9 +444,14 @@ GLint fgObjLoad(char *path, fgCartesianPoint3d *ref, double *radius) {
 
 
 /* $Log$
-/* Revision 1.3  1998/05/03 00:48:01  curt
-/* Updated texture coordinate fmod() parameter.
+/* Revision 1.4  1998/05/16 13:09:57  curt
+/* Beginning to add support for view frustum culling.
+/* Added some temporary code to calculate bouding radius, until the
+/*   scenery generation tools and scenery can be updated.
 /*
+ * Revision 1.3  1998/05/03 00:48:01  curt
+ * Updated texture coordinate fmod() parameter.
+ *
  * Revision 1.2  1998/05/02 01:52:14  curt
  * Playing around with texture coordinates.
  *
index dc1bb32001cc1608380dcc7b8e8c1831dd5d6e4c..61c5b6194573c546fae75fcd95e4f789677dd229 100644 (file)
@@ -131,13 +131,16 @@ void fgTileCacheEntryFree( int index ) {
 
 /* Return info for a tile cache entry */
 void fgTileCacheEntryInfo( int index, GLint *display_list, 
-                          fgCartesianPoint3d *local_ref ) {
+                          fgCartesianPoint3d *local_ref,
+                          double *radius ) {
     *display_list = tile_cache[index].display_list;
     /* fgPrintf(FG_TERRAIN, FG_DEBUG, "Display list = %d\n", *display_list); */
 
     local_ref->x = tile_cache[index].local_ref.x;
     local_ref->y = tile_cache[index].local_ref.y;
     local_ref->z = tile_cache[index].local_ref.z;
+
+    *radius = tile_cache[index].bounding_radius;
 }
 
 
@@ -199,9 +202,14 @@ int fgTileCacheNextAvail( void ) {
 
 
 /* $Log$
-/* Revision 1.7  1998/05/13 18:26:41  curt
-/* Root path info moved to fgOPTIONS.
+/* Revision 1.8  1998/05/16 13:09:57  curt
+/* Beginning to add support for view frustum culling.
+/* Added some temporary code to calculate bouding radius, until the
+/*   scenery generation tools and scenery can be updated.
 /*
+ * Revision 1.7  1998/05/13 18:26:41  curt
+ * Root path info moved to fgOPTIONS.
+ *
  * Revision 1.6  1998/05/02 01:52:17  curt
  * Playing around with texture coordinates.
  *
index 436602a622908bf301545c363d8c53ddc736a67c..9d208088093d020cbfbfa7a6448edc2d466e0f21 100644 (file)
@@ -49,7 +49,7 @@
 
 /* For best results ... i.e. to avoid tile load problems and blank areas
  *
- * FG_TILE_CACHE_SIZE >= (o->tile_radius + 1) ** 2 */
+ * FG_TILE_CACHE_SIZE >= (o->tile_diameter + 1) ** 2 */
 #define FG_TILE_CACHE_SIZE 121
 
 
@@ -81,17 +81,23 @@ void fgTileCacheEntryFillIn( int index, struct fgBUCKET *p );
 
 /* Return info for a tile cache entry */
 void fgTileCacheEntryInfo( int index, GLint *display_list, 
-                          fgCartesianPoint3d *local_ref );
+                          fgCartesianPoint3d *local_ref,
+                          double *radius );
 
 
 #endif /* _TILECACHE_HXX */
 
 
 /* $Log$
-/* Revision 1.6  1998/05/07 23:15:20  curt
-/* Fixed a glTexImage2D() usage bug where width and height were mis-swapped.
-/* Added support for --tile-radius=n option.
+/* Revision 1.7  1998/05/16 13:09:57  curt
+/* Beginning to add support for view frustum culling.
+/* Added some temporary code to calculate bouding radius, until the
+/*   scenery generation tools and scenery can be updated.
 /*
+ * Revision 1.6  1998/05/07 23:15:20  curt
+ * Fixed a glTexImage2D() usage bug where width and height were mis-swapped.
+ * Added support for --tile-radius=n option.
+ *
  * Revision 1.5  1998/05/02 01:52:17  curt
  * Playing around with texture coordinates.
  *
index df64c5993d11e1c4bd6a090417adecf8cf0376ba..dbf36ac227e001304c6c13efd59fe5892173d043 100644 (file)
 #include <Include/fg_constants.h>
 #include <Include/fg_types.h>
 #include <Main/options.hxx>
+#include <Main/views.hxx>
+#include <Math/mat3.h>
 
 
-#define FG_LOCAL_X_Y         81  /* max(o->tile_radius) ** 2 */
+#define FG_LOCAL_X_Y         81  /* max(o->tile_diameter) ** 2 */
 
 
 /* closest (potentially viewable) tiles, centered on current tile.
@@ -90,8 +92,8 @@ int fgTileMgrUpdate( void ) {
     o = &current_options;
 
     fgBucketFind(FG_Longitude * RAD_TO_DEG, FG_Latitude * RAD_TO_DEG, &p1);
-    dw = o->tile_radius / 2;
-    dh = o->tile_radius / 2;
+    dw = o->tile_diameter / 2;
+    dh = o->tile_diameter / 2;
 
     if ( (p1.lon == p_last.lon) && (p1.lat == p_last.lat) &&
         (p1.x == p_last.x) && (p1.y == p_last.y) ) {
@@ -105,16 +107,16 @@ int fgTileMgrUpdate( void ) {
        fgPrintf( FG_TERRAIN, FG_INFO, "  Updating Tile list for %d,%d %d,%d\n",
                  p1.lon, p1.lat, p1.x, p1.y);
        fgPrintf( FG_TERRAIN, FG_INFO, "  Loading %d tiles\n", 
-                 o->tile_radius * o->tile_radius);
+                 o->tile_diameter * o->tile_diameter);
 
        /* wipe tile cache */
        fgTileCacheInit();
 
        /* build the local area list and update cache */
-       for ( j = 0; j < o->tile_radius; j++ ) {
-           for ( i = 0; i < o->tile_radius; i++ ) {
+       for ( j = 0; j < o->tile_diameter; j++ ) {
+           for ( i = 0; i < o->tile_diameter; i++ ) {
                fgBucketOffset(&p1, &p2, i - dw, j - dh);
-               fgTileMgrLoadTile(&p2, &tiles[(j*o->tile_radius) + i]);
+               fgTileMgrLoadTile(&p2, &tiles[(j*o->tile_diameter) + i]);
            }
        }
     } else {
@@ -131,54 +133,54 @@ int fgTileMgrUpdate( void ) {
        if ( (p1.lon > p_last.lon) ||
             ( (p1.lon == p_last.lon) && (p1.x > p_last.x) ) ) {
            fgPrintf( FG_TERRAIN, FG_INFO, "  Loading %d tiles\n", 
-                     o->tile_radius);
-           for ( j = 0; j < o->tile_radius; j++ ) {
+                     o->tile_diameter);
+           for ( j = 0; j < o->tile_diameter; j++ ) {
                /* scrolling East */
-               for ( i = 0; i < o->tile_radius - 1; i++ ) {
-                   tiles[(j*o->tile_radius) + i] = tiles[(j*o->tile_radius) + i + 1];
+               for ( i = 0; i < o->tile_diameter - 1; i++ ) {
+                   tiles[(j*o->tile_diameter) + i] = tiles[(j*o->tile_diameter) + i + 1];
                }
                /* load in new column */
                fgBucketOffset(&p_last, &p2, dw + 1, j - dh);
-               fgTileMgrLoadTile(&p2, &tiles[(j*o->tile_radius) + o->tile_radius - 1]);
+               fgTileMgrLoadTile(&p2, &tiles[(j*o->tile_diameter) + o->tile_diameter - 1]);
            }
        } else if ( (p1.lon < p_last.lon) ||
                    ( (p1.lon == p_last.lon) && (p1.x < p_last.x) ) ) {
            fgPrintf( FG_TERRAIN, FG_INFO, "  Loading %d tiles\n", 
-                     o->tile_radius);
-           for ( j = 0; j < o->tile_radius; j++ ) {
+                     o->tile_diameter);
+           for ( j = 0; j < o->tile_diameter; j++ ) {
                /* scrolling West */
-               for ( i = o->tile_radius - 1; i > 0; i-- ) {
-                   tiles[(j*o->tile_radius) + i] = tiles[(j*o->tile_radius) + i - 1];
+               for ( i = o->tile_diameter - 1; i > 0; i-- ) {
+                   tiles[(j*o->tile_diameter) + i] = tiles[(j*o->tile_diameter) + i - 1];
                }
                /* load in new column */
                fgBucketOffset(&p_last, &p2, -dw - 1, j - dh);
-               fgTileMgrLoadTile(&p2, &tiles[(j*o->tile_radius) + 0]);
+               fgTileMgrLoadTile(&p2, &tiles[(j*o->tile_diameter) + 0]);
            }
        }
 
        if ( (p1.lat > p_last.lat) ||
             ( (p1.lat == p_last.lat) && (p1.y > p_last.y) ) ) {
            fgPrintf( FG_TERRAIN, FG_INFO, "  Loading %d tiles\n", 
-                     o->tile_radius);
-           for ( i = 0; i < o->tile_radius; i++ ) {
+                     o->tile_diameter);
+           for ( i = 0; i < o->tile_diameter; i++ ) {
                /* scrolling North */
-               for ( j = 0; j < o->tile_radius - 1; j++ ) {
-                   tiles[(j * o->tile_radius) + i] =
-                       tiles[((j+1) * o->tile_radius) + i];
+               for ( j = 0; j < o->tile_diameter - 1; j++ ) {
+                   tiles[(j * o->tile_diameter) + i] =
+                       tiles[((j+1) * o->tile_diameter) + i];
                }
                /* load in new column */
                fgBucketOffset(&p_last, &p2, i - dw, dh + 1);
-               fgTileMgrLoadTile(&p2, &tiles[((o->tile_radius-1)*o->tile_radius) + i]);
+               fgTileMgrLoadTile(&p2, &tiles[((o->tile_diameter-1)*o->tile_diameter) + i]);
            }
        } else if ( (p1.lat < p_last.lat) ||
                    ( (p1.lat == p_last.lat) && (p1.y < p_last.y) ) ) {
            fgPrintf( FG_TERRAIN, FG_INFO, "  Loading %d tiles\n", 
-                     o->tile_radius);
-           for ( i = 0; i < o->tile_radius; i++ ) {
+                     o->tile_diameter);
+           for ( i = 0; i < o->tile_diameter; i++ ) {
                /* scrolling South */
-               for ( j = o->tile_radius - 1; j > 0; j-- ) {
-                   tiles[(j * o->tile_radius) + i] = 
-                       tiles[((j-1) * o->tile_radius) + i];
+               for ( j = o->tile_diameter - 1; j > 0; j-- ) {
+                   tiles[(j * o->tile_diameter) + i] = 
+                       tiles[((j-1) * o->tile_diameter) + i];
                }
                /* load in new column */
                fgBucketOffset(&p_last, &p2, i - dw, -dh - 1);
@@ -194,15 +196,47 @@ int fgTileMgrUpdate( void ) {
 }
 
 
+// Calculate if point/radius is inside view frustum
+// 
+static int viewable( fgCartesianPoint3d *cp, double radius ) {
+    fgVIEW *v;
+    MAT3hvec world, eye;
+    int viewable = 1; // start by assuming it's viewable
+
+    v = &current_view;
+
+    MAT3_SET_HVEC(world, cp->x, cp->y, cp->z, 1.0);
+    MAT3mult_vec(eye, world, v->WORLD_TO_EYE);
+    // printf( "\nworld -> eye = %.2f %.2f %.2f  radius = %.2f\n", 
+    //         eye[0], eye[1], eye[2], radius);
+    
+    if ( eye[2] - radius > 0.0 ) {
+       // Check near clip plane
+       viewable = 0;
+    } else if ( eye[1] < -(v->slope_x) * (eye[0] + radius) ) {
+       // Check left edge
+       // y = m * (x - x0) = equation of a line intercepting X axis at x0
+       printf( "eye[1] = %.2f  slope_x = %.2f  radius = %.2f\n", 
+               eye[1], v->slope_x, radius);
+       viewable = 0;
+    }
+
+    return(viewable);
+}
+
+
 /* Render the local tiles */
 void fgTileMgrRender( void ) {
     fgFLIGHT *f;
     fgOPTIONS *o;
     struct fgBUCKET p;
-    fgCartesianPoint3d local_ref;
+    fgCartesianPoint3d local_ref, offset;
     GLint display_list;
+    double radius;
     int i;
     int index;
+    int culled = 0;
+    int drawn = 0;
 
     f = current_aircraft.flight;
     o = &current_options;
@@ -210,37 +244,52 @@ void fgTileMgrRender( void ) {
     /* Find current translation offset */
     fgBucketFind(FG_Longitude * RAD_TO_DEG, FG_Latitude * RAD_TO_DEG, &p);
     index = fgTileCacheExists(&p);
-    fgTileCacheEntryInfo(index, &display_list, &scenery.next_center );
+    fgTileCacheEntryInfo(index, &display_list, &scenery.next_center, &radius );
 
     fgPrintf( FG_TERRAIN, FG_DEBUG, 
              "Pos = (%.2f, %.2f) Current bucket = %d %d %d %d  Index = %ld\n", 
              FG_Longitude * RAD_TO_DEG, FG_Latitude * RAD_TO_DEG,
              p.lon, p.lat, p.x, p.y, fgBucketGenIndex(&p) );
 
-    for ( i = 0; i < (o->tile_radius * o->tile_radius); i++ ) {
+    for ( i = 0; i < (o->tile_diameter * o->tile_diameter); i++ ) {
        index = tiles[i];
        /* fgPrintf( FG_TERRAIN, FG_DEBUG, "Index = %d\n", index); */
-       fgTileCacheEntryInfo(index, &display_list, &local_ref );
+       fgTileCacheEntryInfo(index, &display_list, &local_ref, &radius );
 
        if ( display_list >= 0 ) {
-           xglPushMatrix();
-           xglTranslatef(local_ref.x - scenery.center.x,
-                         local_ref.y - scenery.center.y,
-                         local_ref.z - scenery.center.z);
-           /* xglTranslatef(-scenery.center.x, -scenery.center.y, 
-                         -scenery.center.z); */
-           xglCallList(display_list);
-           xglPopMatrix();
+
+           offset.x = local_ref.x - scenery.center.x;
+           offset.y = local_ref.y - scenery.center.y;
+           offset.z = local_ref.z - scenery.center.z;
+
+           if ( viewable(&offset, radius) ) {
+               drawn++;
+               xglPushMatrix();
+               xglTranslatef(offset.x, offset.y, offset.z);
+               xglCallList(display_list);
+               xglPopMatrix();
+           } else {
+               culled++;
+           }
        }
     }
+
+    printf("drawn = %d  culled = %d  saved = %.2f\n", drawn, culled, 
+          (double)culled / (double)(drawn + culled));
+
 }
 
 
 /* $Log$
-/* Revision 1.8  1998/05/07 23:15:21  curt
-/* Fixed a glTexImage2D() usage bug where width and height were mis-swapped.
-/* Added support for --tile-radius=n option.
+/* Revision 1.9  1998/05/16 13:09:58  curt
+/* Beginning to add support for view frustum culling.
+/* Added some temporary code to calculate bouding radius, until the
+/*   scenery generation tools and scenery can be updated.
 /*
+ * Revision 1.8  1998/05/07 23:15:21  curt
+ * Fixed a glTexImage2D() usage bug where width and height were mis-swapped.
+ * Added support for --tile-radius=n option.
+ *
  * Revision 1.7  1998/05/06 03:16:42  curt
  * Added an option to control square tile radius.
  *