1
0
Fork 0

Add basic fgFACE methods contributed by Charlie Hotchkiss.

intersect optimization from Norman Vine.
This commit is contained in:
curt 1998-07-22 21:41:42 +00:00
parent 0347fcc173
commit f8356621c1
2 changed files with 128 additions and 32 deletions

View file

@ -37,11 +37,61 @@
#define FG_MAX(A,B) ((A) > (B) ? (A) : (B)) #define FG_MAX(A,B) ((A) > (B) ? (A) : (B))
fgFACE :: fgFACE () :
n1(0), n2(0), n3(0)
{
}
fgFACE :: ~fgFACE()
{
}
fgFACE :: fgFACE( const fgFACE & image ) :
n1( image.n1), n2( image.n2), n3( image.n3)
{
}
bool fgFACE :: operator < (const fgFACE & rhs )
{
return ( n1 < rhs.n1 ? true : false);
}
bool fgFACE :: operator == (const fgFACE & rhs )
{
return ((n1 == rhs.n1) && (n2 == rhs.n2) && ( n3 == rhs.n3));
}
// Constructor // Constructor
fgFRAGMENT::fgFRAGMENT ( void ) { fgFRAGMENT::fgFRAGMENT ( void ) {
} }
// Copy constructor
fgFRAGMENT :: fgFRAGMENT ( const fgFRAGMENT & rhs ) :
center ( rhs.center ),
bounding_radius( rhs.bounding_radius ),
material_ptr ( rhs.material_ptr ),
tile_ptr ( rhs.tile_ptr ),
display_list ( rhs.display_list ),
faces ( rhs.faces )
{
}
fgFRAGMENT & fgFRAGMENT :: operator = ( const fgFRAGMENT & rhs )
{
if(!(this == &rhs )) {
center = rhs.center;
bounding_radius = rhs.bounding_radius;
material_ptr = rhs.material_ptr;
tile_ptr = rhs.tile_ptr;
// display_list = rhs.display_list;
faces = rhs.faces;
}
return *this;
}
// Add a face to the face list // Add a face to the face list
void fgFRAGMENT::add_face(int n1, int n2, int n3) { void fgFRAGMENT::add_face(int n1, int n2, int n3) {
fgFACE face; fgFACE face;
@ -115,6 +165,7 @@ int fgFRAGMENT::intersect( fgPoint3d *end0, fgPoint3d *end1, int side_flag,
fgFACE face; fgFACE face;
MAT3vec v1, v2, n, center; MAT3vec v1, v2, n, center;
double p1[3], p2[3], p3[3]; double p1[3], p2[3], p3[3];
double x, y, z; // temporary holding spot for result
double a, b, c, d; double a, b, c, d;
double x0, y0, z0, x1, y1, z1, a1, b1, c1; double x0, y0, z0, x1, y1, z1, a1, b1, c1;
double t1, t2, t3; double t1, t2, t3;
@ -191,12 +242,11 @@ int fgFRAGMENT::intersect( fgPoint3d *end0, fgPoint3d *end1, int side_flag,
// printf("a = %.2f t1 = %.2f t2 = %.2f\n", a, t1, t2); // printf("a = %.2f t1 = %.2f t2 = %.2f\n", a, t1, t2);
if ( fabs(a + t1 + t2) > FG_EPSILON ) { if ( fabs(a + t1 + t2) > FG_EPSILON ) {
result->x = (t1*x0 - b*y0 + t2*x0 - c*z0 + d) / (a + t1 + t2); x = (t1*x0 - b*y0 + t2*x0 - c*z0 + d) / (a + t1 + t2);
t3 = a1 * (result->x - x0); t3 = a1 * (x - x0);
result->y = b1 * t3 + y0; y = b1 * t3 + y0;
result->z = c1 * t3 + z0; z = c1 * t3 + z0;
// printf("result(d) = %.2f\n", // printf("result(d) = %.2f\n", a * x + b * y + c * z);
// a * result->x + b * result->y + c * result->z);
} else { } else {
// no intersection point // no intersection point
continue; continue;
@ -205,16 +255,17 @@ int fgFRAGMENT::intersect( fgPoint3d *end0, fgPoint3d *end1, int side_flag,
if ( side_flag ) { if ( side_flag ) {
// check to see if end0 and end1 are on opposite sides of // check to see if end0 and end1 are on opposite sides of
// plane // plane
if ( (result->x - x0) > FG_EPSILON ) { if ( (x - x0) > FG_EPSILON ) {
t1 = result->x; t2 = x0; t3 = x1; t1 = x; t2 = x0; t3 = x1;
} else if ( (result->y - y0) > FG_EPSILON ) { } else if ( (y - y0) > FG_EPSILON ) {
t1 = result->y; t2 = y0; t3 = y1; t1 = y; t2 = y0; t3 = y1;
} else if ( (result->z - z0) > FG_EPSILON ) { } else if ( (z - z0) > FG_EPSILON ) {
t1 = result->z; t2 = z0; t3 = z1; t1 = z; t2 = z0; t3 = z1;
} else { } else {
// everything is too close together to tell the difference // everything is too close together to tell the difference
// so the current intersection point should work as good // so the current intersection point should work as good
// as any // as any
result->x = x; result->y = y; result->z = z;
return(1); return(1);
} }
side1 = FG_SIGN (t1 - t2); side1 = FG_SIGN (t1 - t2);
@ -236,17 +287,17 @@ int fgFRAGMENT::intersect( fgPoint3d *end0, fgPoint3d *end1, int side_flag,
// printf("bounding cube = %.2f,%.2f,%.2f %.2f,%.2f,%.2f\n", // printf("bounding cube = %.2f,%.2f,%.2f %.2f,%.2f,%.2f\n",
// xmin, ymin, zmin, xmax, ymax, zmax); // xmin, ymin, zmin, xmax, ymax, zmax);
// punt if outside bouding cube // punt if outside bouding cube
if ( result->x < xmin ) { if ( x < xmin ) {
continue; continue;
} else if ( result->x > xmax ) { } else if ( x > xmax ) {
continue; continue;
} else if ( result->y < ymin ) { } else if ( y < ymin ) {
continue; continue;
} else if ( result->y > ymax ) { } else if ( y > ymax ) {
continue; continue;
} else if ( result->z < zmin ) { } else if ( z < zmin ) {
continue; continue;
} else if ( result->z > zmax ) { } else if ( z > zmax ) {
continue; continue;
} }
@ -264,22 +315,23 @@ int fgFRAGMENT::intersect( fgPoint3d *end0, fgPoint3d *end1, int side_flag,
x1 = p1[1]; y1 = p1[2]; x1 = p1[1]; y1 = p1[2];
x2 = p2[1]; y2 = p2[2]; x2 = p2[1]; y2 = p2[2];
x3 = p3[1]; y3 = p3[2]; x3 = p3[1]; y3 = p3[2];
rx = result->y; ry = result->z; rx = y; ry = z;
} else if ( fabs(min_dim - dy) <= FG_EPSILON ) { } else if ( fabs(min_dim - dy) <= FG_EPSILON ) {
// y is the smallest dimension // y is the smallest dimension
x1 = p1[0]; y1 = p1[2]; x1 = p1[0]; y1 = p1[2];
x2 = p2[0]; y2 = p2[2]; x2 = p2[0]; y2 = p2[2];
x3 = p3[0]; y3 = p3[2]; x3 = p3[0]; y3 = p3[2];
rx = result->x; ry = result->z; rx = x; ry = z;
} else if ( fabs(min_dim - dz) <= FG_EPSILON ) { } else if ( fabs(min_dim - dz) <= FG_EPSILON ) {
// z is the smallest dimension // z is the smallest dimension
x1 = p1[0]; y1 = p1[1]; x1 = p1[0]; y1 = p1[1];
x2 = p2[0]; y2 = p2[1]; x2 = p2[0]; y2 = p2[1];
x3 = p3[0]; y3 = p3[1]; x3 = p3[0]; y3 = p3[1];
rx = result->x; ry = result->y; rx = x; ry = y;
} else { } else {
// all dimensions are really small so lets call it close // all dimensions are really small so lets call it close
// enough and return a successful match // enough and return a successful match
result->x = x; result->y = y; result->z = z;
return(1); return(1);
} }
@ -307,8 +359,8 @@ int fgFRAGMENT::intersect( fgPoint3d *end0, fgPoint3d *end1, int side_flag,
continue; continue;
} }
// printf( "intersection point = %.2f %.2f %.2f\n", // printf( "intersection point = %.2f %.2f %.2f\n", x, y, z);
// result->x, result->y, result->z); result->x = x; result->y = y; result->z = z;
return(1); return(1);
} }
@ -332,6 +384,28 @@ fgFRAGMENT::~fgFRAGMENT ( void ) {
} }
// equality operator
bool fgFRAGMENT :: operator == ( const fgFRAGMENT & rhs)
{
if(( center.x - rhs.center.x ) < FG_EPSILON) {
if(( center.y - rhs.center.y) < FG_EPSILON) {
if(( center.z - rhs.center.z) < FG_EPSILON) {
return true;
}
}
}
return false;
}
// comparison operator
bool fgFRAGMENT :: operator < ( const fgFRAGMENT &rhs)
{
// This is completely arbitrary. It satisfies RW's STL implementation
return bounding_radius < rhs.bounding_radius;
}
// Constructor // Constructor
fgTILE::fgTILE ( void ) { fgTILE::fgTILE ( void ) {
nodes = new double[MAX_NODES][3]; nodes = new double[MAX_NODES][3];
@ -345,6 +419,10 @@ fgTILE::~fgTILE ( void ) {
// $Log$ // $Log$
// Revision 1.4 1998/07/22 21:41:42 curt
// Add basic fgFACE methods contributed by Charlie Hotchkiss.
// intersect optimization from Norman Vine.
//
// Revision 1.3 1998/07/16 17:34:24 curt // Revision 1.3 1998/07/16 17:34:24 curt
// Ground collision detection optimizations contributed by Norman Vine. // Ground collision detection optimizations contributed by Norman Vine.
// //

View file

@ -47,22 +47,30 @@ extern "C" void *memset(void *, int, size_t);
#endif #endif
#include <list> // STL list #include <list> // STL list
#ifdef NEEDNAMESPACESTD
using namespace std;
#endif
#include <Bucket/bucketutils.h> #include <Bucket/bucketutils.h>
#include <Include/fg_types.h> #include <Include/fg_types.h>
#include <Math/mat3.h> #include <Math/mat3.h>
#ifdef NEEDNAMESPACESTD
using namespace std;
#endif
// Maximum nodes per tile // Maximum nodes per tile
#define MAX_NODES 1000 #define MAX_NODES 1000
typedef struct { class fgFACE {
public:
int n1, n2, n3; int n1, n2, n3;
} fgFACE;
fgFACE();
~fgFACE();
fgFACE( const fgFACE & image );
bool operator < ( const fgFACE & rhs );
bool operator == ( const fgFACE & rhs );
};
// Object fragment data class // Object fragment data class
@ -95,9 +103,6 @@ public:
// face list (this indexes into the master tile vertex list) // face list (this indexes into the master tile vertex list)
list < fgFACE > faces; list < fgFACE > faces;
// Constructor
fgFRAGMENT ( void );
// Add a face to the face list // Add a face to the face list
void add_face(int n1, int n2, int n3); void add_face(int n1, int n2, int n3);
@ -109,8 +114,17 @@ public:
int intersect( fgPoint3d *end0, fgPoint3d *end1, int side_flag, int intersect( fgPoint3d *end0, fgPoint3d *end1, int side_flag,
fgPoint3d *result); fgPoint3d *result);
// Constructors
fgFRAGMENT ();
fgFRAGMENT ( const fgFRAGMENT &image );
// Destructor // Destructor
~fgFRAGMENT ( void ); ~fgFRAGMENT ( );
// operators
fgFRAGMENT & operator = ( const fgFRAGMENT & rhs );
bool operator == ( const fgFRAGMENT & rhs );
bool operator < ( const fgFRAGMENT & rhs );
}; };
@ -149,6 +163,10 @@ public:
// $Log$ // $Log$
// Revision 1.12 1998/07/22 21:41:42 curt
// Add basic fgFACE methods contributed by Charlie Hotchkiss.
// intersect optimization from Norman Vine.
//
// Revision 1.11 1998/07/12 03:18:28 curt // Revision 1.11 1998/07/12 03:18:28 curt
// Added ground collision detection. This involved: // Added ground collision detection. This involved:
// - saving the entire vertex list for each tile with the tile records. // - saving the entire vertex list for each tile with the tile records.