Incorporated Norman's optimized line/geometry intersection code.
This commit is contained in:
parent
3bf7269174
commit
8138c82b58
4 changed files with 668 additions and 334 deletions
|
@ -1,3 +1,7 @@
|
|||
// hitlist.cxx -
|
||||
// Height Over Terrain and Assosciated Routines for FlightGear based Scenery
|
||||
// Written by Norman Vine, started 2000.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
@ -26,115 +30,8 @@
|
|||
|
||||
#include "hitlist.hxx"
|
||||
|
||||
|
||||
extern ssgBranch *terrain_branch;
|
||||
|
||||
#if 0
|
||||
// check to see if the intersection point is
|
||||
// actually inside this face
|
||||
static bool pointInTriangle( sgdVec3 point, sgdVec3 tri[3] )
|
||||
{
|
||||
double xmin, xmax, ymin, ymax, zmin, zmax;
|
||||
|
||||
// punt if outside bouding cube
|
||||
if ( point[0] < (xmin = SG_MIN3 (tri[0][0], tri[1][0], tri[2][0])) ) {
|
||||
return false;
|
||||
} else if ( point[0] > (xmax = SG_MAX3 (tri[0][0], tri[1][0], tri[2][0])) )
|
||||
{
|
||||
return false;
|
||||
} else if ( point[1] < (ymin = SG_MIN3 (tri[0][1], tri[1][1], tri[2][1])) )
|
||||
{
|
||||
return false;
|
||||
} else if ( point[1] > (ymax = SG_MAX3 (tri[0][1], tri[1][1], tri[2][1])) )
|
||||
{
|
||||
return false;
|
||||
} else if ( point[2] < (zmin = SG_MIN3 (tri[0][2], tri[1][2], tri[2][2])) )
|
||||
{
|
||||
return false;
|
||||
} else if ( point[2] > (zmax = SG_MAX3 (tri[0][2], tri[1][2], tri[2][2])) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// (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.
|
||||
double dx = xmax - xmin;
|
||||
double dy = ymax - ymin;
|
||||
double dz = zmax - zmin;
|
||||
double min_dim = SG_MIN3 (dx, dy, dz);
|
||||
|
||||
//first, drop the smallest dimension so we only have to work
|
||||
//in 2d.
|
||||
double x1, y1, x2, y2, x3, y3, rx, ry;
|
||||
if ( fabs(min_dim-dx) <= SG_EPSILON ) {
|
||||
// x is the smallest dimension
|
||||
x1 = point[1];
|
||||
y1 = point[2];
|
||||
x2 = tri[0][1];
|
||||
y2 = tri[0][2];
|
||||
x3 = tri[1][1];
|
||||
y3 = tri[1][2];
|
||||
rx = tri[2][1];
|
||||
ry = tri[2][2];
|
||||
} else if ( fabs(min_dim-dy) <= SG_EPSILON ) {
|
||||
// y is the smallest dimension
|
||||
x1 = point[0];
|
||||
y1 = point[2];
|
||||
x2 = tri[0][0];
|
||||
y2 = tri[0][2];
|
||||
x3 = tri[1][0];
|
||||
y3 = tri[1][2];
|
||||
rx = tri[2][0];
|
||||
ry = tri[2][2];
|
||||
} else if ( fabs(min_dim-dz) <= SG_EPSILON ) {
|
||||
// z is the smallest dimension
|
||||
x1 = point[0];
|
||||
y1 = point[1];
|
||||
x2 = tri[0][0];
|
||||
y2 = tri[0][1];
|
||||
x3 = tri[1][0];
|
||||
y3 = tri[1][1];
|
||||
rx = tri[2][0];
|
||||
ry = tri[2][1];
|
||||
} else {
|
||||
// all dimensions are really small so lets call it close
|
||||
// enough and return a successful match
|
||||
return true;
|
||||
}
|
||||
|
||||
// check if intersection point is on the same side of p1 <-> p2 as p3
|
||||
double tmp = (y2 - y3) / (x2 - x3);
|
||||
int side1 = SG_SIGN (tmp * (rx - x3) + y3 - ry);
|
||||
int side2 = SG_SIGN (tmp * (x1 - x3) + y3 - y1);
|
||||
if ( side1 != side2 ) {
|
||||
// printf("failed side 1 check\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if intersection point is on correct side of p2 <-> p3 as p1
|
||||
tmp = (y3 - ry) / (x3 - rx);
|
||||
side1 = SG_SIGN (tmp * (x2 - rx) + ry - y2);
|
||||
side2 = SG_SIGN (tmp * (x1 - rx) + ry - y1);
|
||||
if ( side1 != side2 ) {
|
||||
// printf("failed side 2 check\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if intersection point is on correct side of p1 <-> p3 as p2
|
||||
tmp = (y2 - ry) / (x2 - rx);
|
||||
side1 = SG_SIGN (tmp * (x3 - rx) + ry - y3);
|
||||
side2 = SG_SIGN (tmp * (x1 - rx) + ry - y1);
|
||||
if ( side1 != side2 ) {
|
||||
// printf("failed side 3 check\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int sgdIsectInfLinePlane( sgdVec3 dst, const sgdVec3 l_org,
|
||||
const sgdVec3 l_vec, const sgdVec4 plane )
|
||||
{
|
||||
|
@ -153,60 +50,11 @@ static int sgdIsectInfLinePlane( sgdVec3 dst, const sgdVec3 l_org,
|
|||
}
|
||||
|
||||
|
||||
static void sgdXformPnt3 ( sgdVec3 dst, const sgVec3 src, const sgdMat4 mat )
|
||||
{
|
||||
SGDfloat t0 = src[ 0 ] ;
|
||||
SGDfloat t1 = src[ 1 ] ;
|
||||
SGDfloat t2 = src[ 2 ] ;
|
||||
|
||||
dst[0] = ( t0 * mat[ 0 ][ 0 ] +
|
||||
t1 * mat[ 1 ][ 0 ] +
|
||||
t2 * mat[ 2 ][ 0 ] +
|
||||
mat[ 3 ][ 0 ] ) ;
|
||||
|
||||
dst[1] = ( t0 * mat[ 0 ][ 1 ] +
|
||||
t1 * mat[ 1 ][ 1 ] +
|
||||
t2 * mat[ 2 ][ 1 ] +
|
||||
mat[ 3 ][ 1 ] ) ;
|
||||
|
||||
dst[2] = ( t0 * mat[ 0 ][ 2 ] +
|
||||
t1 * mat[ 1 ][ 2 ] +
|
||||
t2 * mat[ 2 ][ 2 ] +
|
||||
mat[ 3 ][ 2 ] ) ;
|
||||
}
|
||||
#endif // 0
|
||||
|
||||
|
||||
/*
|
||||
Find the intersection of an infinite line with a plane
|
||||
(the line being defined by a point and direction).
|
||||
|
||||
Norman Vine -- nhv@yahoo.com (with hacks by Steve)
|
||||
*/
|
||||
|
||||
int sgdIsectInfLinePlane( sgdVec3 dst, sgdVec3 l_org,
|
||||
sgdVec3 l_vec, sgdVec4 plane )
|
||||
{
|
||||
SGDfloat tmp = sgdScalarProductVec3 ( l_vec, plane ) ;
|
||||
|
||||
/* Is line parallel to plane? */
|
||||
|
||||
if ( sgdAbs ( tmp ) < DBL_EPSILON )
|
||||
return FALSE ;
|
||||
|
||||
sgdScaleVec3 ( dst, l_vec, -( sgdScalarProductVec3 ( l_org, plane )
|
||||
+ plane[3] ) / tmp ) ;
|
||||
sgdAddVec3 ( dst, l_org ) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Given a point and a triangle lying on the same plane
|
||||
* check to see if the point is inside the triangle
|
||||
*/
|
||||
bool sgdPointInTriangle( sgdVec3 point, sgdVec3 tri[3] )
|
||||
static bool sgdPointInTriangle( sgdVec3 point, sgdVec3 tri[3] )
|
||||
{
|
||||
sgdVec3 dif;
|
||||
|
||||
|
@ -297,6 +145,56 @@ bool sgdPointInTriangle( sgdVec3 point, sgdVec3 tri[3] )
|
|||
}
|
||||
|
||||
|
||||
inline static int isZeroAreaTri( sgdVec3 tri[3] )
|
||||
{
|
||||
return( sgdEqualVec3(tri[0], tri[1]) ||
|
||||
sgdEqualVec3(tri[1], tri[2]) ||
|
||||
sgdEqualVec3(tri[2], tri[0]) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a point and a triangle lying on the same plane
|
||||
* check to see if the point is inside the triangle
|
||||
*/
|
||||
|
||||
#if 0
|
||||
static bool PointInTri( sgdVec3 P, sgdVec3 V[3] )
|
||||
{
|
||||
sgdVec3 X,W1,W2;
|
||||
sgdSubVec3(X,P,V[0]);
|
||||
sgdSubVec3(W1,V[1],V[2]);
|
||||
sgdSubVec3(W2,V[2],V[0]);
|
||||
|
||||
sgdVec3 C;
|
||||
sgdVectorProductVec3(C, W1, W2);
|
||||
|
||||
double d = sgdScalarProductVec3(X,C);
|
||||
|
||||
// Test not needed if you KNOW point is on plane of triangle
|
||||
// and triangle is not degenerate
|
||||
if( d > -FLT_EPSILON && d < FLT_EPSILON )
|
||||
return false;
|
||||
|
||||
double u11 = sgdScalarProductVec3(W1,W1);
|
||||
double u22 = sgdScalarProductVec3(W2,W2);
|
||||
double u12 = sgdScalarProductVec3(W1,W2);
|
||||
|
||||
double y1 = sgdScalarProductVec3(X,W1);
|
||||
double y2 = sgdScalarProductVec3(X,W2);
|
||||
double z1 = (y1*u22 - y2*u12)/d;
|
||||
|
||||
if( z1>0 || z1>1 )
|
||||
return false;
|
||||
|
||||
double z2 = (y2*u11 - y1*u12)/d;
|
||||
|
||||
if( z2>0 || z2>1 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
Find the intersection of an infinite line with a leaf
|
||||
the line being defined by a point and direction.
|
||||
|
@ -314,12 +212,21 @@ bool sgdPointInTriangle( sgdVec3 point, sgdVec3 tri[3] )
|
|||
Returns:
|
||||
true if intersection found
|
||||
false otherwise
|
||||
|
||||
!!! WARNING !!!
|
||||
If you need an exhaustive list of hitpoints YOU MUST use
|
||||
the generic version of this function as the specialized
|
||||
versions will do an early out of expensive tests if the point
|
||||
can not be the closest one found
|
||||
!!! WARNING !!!
|
||||
*/
|
||||
int FGHitList::IntersectLeaf( ssgLeaf *leaf, sgdMat4 m,
|
||||
sgdVec3 orig, sgdVec3 dir )
|
||||
{
|
||||
int num_hits = 0;
|
||||
for ( int i = 0; i < leaf->getNumTriangles(); ++i ) {
|
||||
int i = 0;
|
||||
|
||||
for ( ; i < leaf->getNumTriangles(); ++i ) {
|
||||
short i1, i2, i3;
|
||||
leaf->getTriangle( i, &i1, &i2, &i3 );
|
||||
|
||||
|
@ -328,37 +235,15 @@ int FGHitList::IntersectLeaf( ssgLeaf *leaf, sgdMat4 m,
|
|||
sgdSetVec3( tri[1], leaf->getVertex( i2 ) );
|
||||
sgdSetVec3( tri[2], leaf->getVertex( i3 ) );
|
||||
|
||||
//avoid division by zero when two points are the same
|
||||
if ( sgdEqualVec3(tri[0], tri[1]) ||
|
||||
sgdEqualVec3(tri[1], tri[2]) ||
|
||||
sgdEqualVec3(tri[2], tri[0]) ) {
|
||||
// avoid division by zero when two points are the same
|
||||
if( isZeroAreaTri( tri ) )
|
||||
continue;
|
||||
}
|
||||
|
||||
sgdVec4 plane;
|
||||
sgdMakePlane( plane, tri[0], tri[1], tri[2] );
|
||||
|
||||
sgdVec3 point;
|
||||
|
||||
//inlined IsectInfLinePlane( point dst, orig, dir, plane )
|
||||
SGDfloat tmp = sgdScalarProductVec3 ( dir, plane ) ;
|
||||
|
||||
/* Is line parallel to plane? */
|
||||
if ( sgdAbs ( tmp ) < DBL_EPSILON )
|
||||
continue ;
|
||||
|
||||
sgdScaleVec3 ( point, dir,
|
||||
-( sgdScalarProductVec3 ( orig, plane ) + plane[3] )
|
||||
/ tmp ) ;
|
||||
|
||||
sgdAddVec3 ( point, orig ) ;
|
||||
// end of inlined intersection
|
||||
#if 0
|
||||
if( pointInTriangle( point, tri ) ) {
|
||||
add(leaf,i,point,plane);
|
||||
num_hits++;
|
||||
}
|
||||
#endif // 0
|
||||
if( sgdIsectInfLinePlane( point, orig, dir, plane ) ) {
|
||||
if( sgdPointInTriangle( point, tri ) ) {
|
||||
// transform point into passed into desired coordinate frame
|
||||
sgdXformPnt3( point, point, m );
|
||||
|
@ -366,20 +251,305 @@ int FGHitList::IntersectLeaf( ssgLeaf *leaf, sgdMat4 m,
|
|||
num_hits++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return num_hits;
|
||||
}
|
||||
|
||||
|
||||
//=================
|
||||
int FGHitList::IntersectPolyOrFanLeaf( ssgLeaf *leaf, sgdMat4 m,
|
||||
sgdVec3 orig, sgdVec3 dir )
|
||||
{
|
||||
double tmp_dist;
|
||||
|
||||
// number of hits but there could be more that
|
||||
// were not found because of short circut switch !
|
||||
// so you may want to use the unspecialized IntersectLeaf()
|
||||
int num_hits = 0;
|
||||
|
||||
int ntri = leaf->getNumTriangles();
|
||||
for ( int n = 0; n < ntri; ++n ) {
|
||||
sgdVec3 tri[3];
|
||||
|
||||
if ( !n ) {
|
||||
sgdSetVec3( tri[0], leaf->getVertex( short(0) ) );
|
||||
sgdSetVec3( tri[1], leaf->getVertex( short(1) ) );
|
||||
sgdSetVec3( tri[2], leaf->getVertex( short(2) ) );
|
||||
} else {
|
||||
sgdCopyVec3( tri[1], tri[2] );
|
||||
sgdSetVec3( tri[2], leaf->getVertex( short(n+2) ) );
|
||||
}
|
||||
|
||||
if( isZeroAreaTri( tri ) )
|
||||
continue;
|
||||
|
||||
sgdVec4 plane;
|
||||
sgdMakePlane( plane, tri[0], tri[1], tri[2] );
|
||||
|
||||
sgdVec3 point;
|
||||
|
||||
//inlined IsectInfLinePlane( point dst, orig, dir, plane )
|
||||
{
|
||||
SGDfloat tmp = sgdScalarProductVec3 ( dir, plane ) ;
|
||||
|
||||
/* Is line parallel to plane? */
|
||||
if ( sgdAbs ( tmp ) < FLT_EPSILON /*DBL_EPSILON*/ )
|
||||
continue ;
|
||||
|
||||
sgdScaleVec3 ( point, dir,
|
||||
-( sgdScalarProductVec3 ( orig, plane ) + plane[3] )
|
||||
/ tmp ) ;
|
||||
|
||||
sgdAddVec3 ( point, orig ) ;
|
||||
} // end of inlined intersection routine
|
||||
|
||||
// short circut if this point is further away then a previous hit
|
||||
tmp_dist = sgdScalarProductVec3(point,point);
|
||||
if( tmp_dist > test_dist )
|
||||
continue;
|
||||
|
||||
if( sgdPointInTriangle( point, tri ) ) {
|
||||
// transform point into passed coordinate frame
|
||||
sgdXformPnt3( point, point, m );
|
||||
add(leaf,n,point,plane);
|
||||
test_dist = tmp_dist;
|
||||
num_hits++;
|
||||
}
|
||||
}
|
||||
return num_hits;
|
||||
}
|
||||
|
||||
|
||||
//===============
|
||||
|
||||
int FGHitList::IntersectTriLeaf( ssgLeaf *leaf, sgdMat4 m,
|
||||
sgdVec3 orig, sgdVec3 dir )
|
||||
{
|
||||
double tmp_dist;
|
||||
|
||||
// number of hits but there could be more that
|
||||
// were not found because of short circut switch !
|
||||
// so you may want to use the unspecialized IntersectLeaf()
|
||||
int num_hits = 0;
|
||||
|
||||
int ntri = leaf->getNumTriangles();
|
||||
for ( int n = 0; n < ntri; ++n ) {
|
||||
sgdVec3 tri[3];
|
||||
sgdSetVec3( tri[0], leaf->getVertex( short(n*3) ) );
|
||||
sgdSetVec3( tri[1], leaf->getVertex( short(n*3+1) ) );
|
||||
sgdSetVec3( tri[2], leaf->getVertex( short(n*3+2) ) );
|
||||
|
||||
// avoid division by zero when two points are the same
|
||||
if( isZeroAreaTri( tri ) )
|
||||
continue;
|
||||
|
||||
sgdVec4 plane;
|
||||
sgdMakePlane( plane, tri[0], tri[1], tri[2] );
|
||||
|
||||
sgdVec3 point;
|
||||
//inlined IsectInfLinePlane( point dst, orig, dir, plane )
|
||||
{
|
||||
SGDfloat tmp = sgdScalarProductVec3 ( dir, plane ) ;
|
||||
|
||||
/* Is line parallel to plane? */
|
||||
if ( sgdAbs ( tmp ) < FLT_EPSILON /*DBL_EPSILON*/ )
|
||||
continue ;
|
||||
|
||||
sgdScaleVec3 ( point, dir,
|
||||
-( sgdScalarProductVec3 ( orig, plane ) + plane[3] )
|
||||
/ tmp ) ;
|
||||
|
||||
sgdAddVec3 ( point, orig ) ;
|
||||
} // end of inlined intersection routine
|
||||
|
||||
// short circut if this point is further away then a previous hit
|
||||
tmp_dist = sgdScalarProductVec3(point,point);
|
||||
if( tmp_dist > test_dist )
|
||||
continue;
|
||||
|
||||
if( sgdPointInTriangle( point, tri ) ) {
|
||||
// transform point into passed coordinate frame
|
||||
sgdXformPnt3( point, point, m );
|
||||
add(leaf,n,point,plane);
|
||||
test_dist = tmp_dist;
|
||||
num_hits++;
|
||||
}
|
||||
}
|
||||
return num_hits;
|
||||
}
|
||||
|
||||
//============================
|
||||
|
||||
int FGHitList::IntersectStripLeaf( ssgLeaf *leaf, sgdMat4 m,
|
||||
sgdVec3 orig, sgdVec3 dir )
|
||||
{
|
||||
double tmp_dist;
|
||||
|
||||
// number of hits but there could be more that
|
||||
// were not found because of short circut switch !
|
||||
// so you may want to use the unspecialized IntersectLeaf()
|
||||
int num_hits = 0;
|
||||
|
||||
int ntri = leaf->getNumTriangles();
|
||||
for ( int n = 0; n < ntri; ++n ) {
|
||||
sgdVec3 tri[3];
|
||||
|
||||
if ( !n ) {
|
||||
sgdSetVec3( tri[0], leaf->getVertex( short(0) ) );
|
||||
sgdSetVec3( tri[1], leaf->getVertex( short(1) ) );
|
||||
sgdSetVec3( tri[2], leaf->getVertex( short(2) ) );
|
||||
} else {
|
||||
if ( n & 1 ) {
|
||||
sgdSetVec3( tri[0], leaf->getVertex( short(n+2) ) );
|
||||
sgdCopyVec3( tri[1], tri[2] );
|
||||
sgdCopyVec3( tri[2], tri[1] );
|
||||
|
||||
} else {
|
||||
sgdCopyVec3( tri[0], tri[1] );
|
||||
sgdCopyVec3( tri[1], tri[2] );
|
||||
sgdSetVec3( tri[2], leaf->getVertex( short(n+2) ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( isZeroAreaTri( tri ) )
|
||||
continue;
|
||||
|
||||
sgdVec4 plane;
|
||||
sgdMakePlane( plane, tri[0], tri[1], tri[2] );
|
||||
|
||||
sgdVec3 point;
|
||||
|
||||
//inlined IsectInfLinePlane( point dst, orig, dir, plane )
|
||||
{
|
||||
SGDfloat tmp = sgdScalarProductVec3 ( dir, plane ) ;
|
||||
|
||||
/* Is line parallel to plane? */
|
||||
if ( sgdAbs ( tmp ) < FLT_EPSILON /*DBL_EPSILON*/ )
|
||||
continue ;
|
||||
|
||||
sgdScaleVec3 ( point, dir,
|
||||
-( sgdScalarProductVec3 ( orig, plane ) + plane[3] )
|
||||
/ tmp ) ;
|
||||
|
||||
sgdAddVec3 ( point, orig ) ;
|
||||
} // end of inlined intersection routine
|
||||
|
||||
// short circut if this point is further away then a previous hit
|
||||
tmp_dist = sgdScalarProductVec3(point,point);
|
||||
if( tmp_dist > test_dist )
|
||||
continue;
|
||||
|
||||
if( sgdPointInTriangle( point, tri ) ) {
|
||||
// transform point into passed coordinate frame
|
||||
sgdXformPnt3( point, point, m );
|
||||
add(leaf,n,point,plane);
|
||||
test_dist = tmp_dist;
|
||||
num_hits++;
|
||||
}
|
||||
}
|
||||
return num_hits;
|
||||
}
|
||||
|
||||
// ======================
|
||||
|
||||
int FGHitList::IntersectQuadsLeaf( ssgLeaf *leaf, sgdMat4 m,
|
||||
sgdVec3 orig, sgdVec3 dir )
|
||||
{
|
||||
double tmp_dist;
|
||||
|
||||
// number of hits but there could be more that
|
||||
// were not found because of short circut switch !
|
||||
// so you may want to use the unspecialized IntersectLeaf()
|
||||
int num_hits = 0;
|
||||
|
||||
int ntri = leaf->getNumTriangles();
|
||||
for ( int n = 0; n < ntri; ++n ) {
|
||||
sgdVec3 tri[3];
|
||||
|
||||
sgdSetVec3( tri[0], leaf->getVertex( short(n*2) ) );
|
||||
sgdSetVec3( tri[1], leaf->getVertex( short(n*2+1) ) );
|
||||
sgdSetVec3( tri[2], leaf->getVertex( short(n*2 + 2 - (n&1)*4) ) );
|
||||
|
||||
if( isZeroAreaTri( tri ) )
|
||||
continue;
|
||||
|
||||
sgdVec4 plane;
|
||||
sgdMakePlane( plane, tri[0], tri[1], tri[2] );
|
||||
|
||||
sgdVec3 point;
|
||||
|
||||
//inlined IsectInfLinePlane( point dst, orig, dir, plane )
|
||||
{
|
||||
SGDfloat tmp = sgdScalarProductVec3 ( dir, plane ) ;
|
||||
|
||||
/* Is line parallel to plane? */
|
||||
if ( sgdAbs ( tmp ) < FLT_EPSILON /*DBL_EPSILON*/ )
|
||||
continue ;
|
||||
|
||||
sgdScaleVec3 ( point, dir,
|
||||
-( sgdScalarProductVec3 ( orig, plane ) + plane[3] )
|
||||
/ tmp ) ;
|
||||
|
||||
sgdAddVec3 ( point, orig ) ;
|
||||
} // end of inlined intersection routine
|
||||
|
||||
// short circut if this point is further away then a previous hit
|
||||
tmp_dist = sgdScalarProductVec3(point,point);
|
||||
if( tmp_dist > test_dist )
|
||||
continue;
|
||||
|
||||
if( sgdPointInTriangle( point, tri ) ) {
|
||||
// transform point into passed coordinate frame
|
||||
sgdXformPnt3( point, point, m );
|
||||
add(leaf,n,point,plane);
|
||||
test_dist = tmp_dist;
|
||||
num_hits++;
|
||||
}
|
||||
}
|
||||
return num_hits;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Need these because of mixed matrix types
|
||||
static void sgMultMat4(sgdMat4 dst, sgdMat4 m1, sgMat4 m2)
|
||||
{
|
||||
for ( int j = 0 ; j < 4 ; j++ ) {
|
||||
dst[0][j] = m2[0][0] * m1[0][j] +
|
||||
m2[0][1] * m1[1][j] +
|
||||
m2[0][2] * m1[2][j] +
|
||||
m2[0][3] * m1[3][j] ;
|
||||
|
||||
dst[1][j] = m2[1][0] * m1[0][j] +
|
||||
m2[1][1] * m1[1][j] +
|
||||
m2[1][2] * m1[2][j] +
|
||||
m2[1][3] * m1[3][j] ;
|
||||
|
||||
dst[2][j] = m2[2][0] * m1[0][j] +
|
||||
m2[2][1] * m1[1][j] +
|
||||
m2[2][2] * m1[2][j] +
|
||||
m2[2][3] * m1[3][j] ;
|
||||
|
||||
dst[3][j] = m2[3][0] * m1[0][j] +
|
||||
m2[3][1] * m1[1][j] +
|
||||
m2[3][2] * m1[2][j] +
|
||||
m2[3][3] * m1[3][j] ;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
void FGHitList::IntersectBranch( ssgBranch *branch, sgdMat4 m,
|
||||
sgdVec3 orig, sgdVec3 dir )
|
||||
{
|
||||
sgSphere *bsphere;
|
||||
|
||||
/* the lookat vector and matrix in branch's coordinate frame
|
||||
* but we won't determine these unless needed to,
|
||||
* but we won't determine these unless needed,
|
||||
* This 'lazy evaluation' is a result of profiling data */
|
||||
sgdVec3 _orig, _dir;
|
||||
sgdMat4 _m;
|
||||
sgdVec3 orig_leaf, dir_leaf;
|
||||
sgdMat4 m_leaf;
|
||||
|
||||
|
||||
// 'lazy evaluation' flag
|
||||
int first_time = 1;
|
||||
|
@ -389,12 +559,11 @@ void FGHitList::IntersectBranch( ssgBranch *branch, sgdMat4 m,
|
|||
kid = branch->getNextKid() )
|
||||
{
|
||||
if ( kid->getTraversalMask() & SSGTRAV_HOT ) {
|
||||
bsphere = kid->getBSphere();
|
||||
sgdVec3 center;
|
||||
sgdSetVec3( center,
|
||||
bsphere->getCenter()[0],
|
||||
bsphere->getCenter()[1],
|
||||
bsphere->getCenter()[2] );
|
||||
kid->getBSphere()->getCenter()[0],
|
||||
kid->getBSphere()->getCenter()[1],
|
||||
kid->getBSphere()->getCenter()[2] );
|
||||
sgdXformPnt3( center, m ) ;
|
||||
|
||||
// sgdClosestPointToLineDistSquared( center, orig, dir )
|
||||
|
@ -408,29 +577,54 @@ void FGHitList::IntersectBranch( ssgBranch *branch, sgdMat4 m,
|
|||
// doubles because of possible overflow
|
||||
#define SQUARE(x) (x*x)
|
||||
if( sgdScalarProductVec3(v, v)
|
||||
< SQUARE( double(bsphere->getRadius()) ) )
|
||||
< SQUARE( double(kid->getBSphere()->getRadius()) ) )
|
||||
{
|
||||
// possible intersections
|
||||
if ( kid->isAKindOf ( ssgTypeBranch() ) ) {
|
||||
sgdMat4 m_new;
|
||||
sgdCopyMat4(m_new, m);
|
||||
if ( kid->isA( ssgTypeTransform() ) ) {
|
||||
if ( kid->isA( ssgTypeTransform() ) )
|
||||
{
|
||||
sgMat4 fxform;
|
||||
((ssgTransform *)kid)->getTransform( fxform );
|
||||
sgdMat4 xform;
|
||||
sgdSetMat4( xform, fxform );
|
||||
sgdPreMultMat4( m_new, xform );
|
||||
sgMultMat4(m_new, m, fxform);
|
||||
} else {
|
||||
sgdCopyMat4(m_new, m);
|
||||
}
|
||||
IntersectBranch( (ssgBranch *)kid, m_new, orig, dir );
|
||||
} else if ( kid->isAKindOf( ssgTypeLeaf() ) ) {
|
||||
if( first_time) {
|
||||
if ( first_time ) {
|
||||
// OK we need these
|
||||
sgdTransposeNegateMat4( _m, m);
|
||||
sgdXformPnt3( _orig, orig, _m );
|
||||
sgdXformPnt3( _dir, dir, _m );
|
||||
sgdTransposeNegateMat4( m_leaf, m);
|
||||
sgdXformPnt3( orig_leaf, orig, m_leaf );
|
||||
sgdXformPnt3( dir_leaf, dir, m_leaf );
|
||||
first_time = 0;
|
||||
}
|
||||
IntersectLeaf( (ssgLeaf *)kid, m, _orig, _dir );
|
||||
|
||||
GLenum primType = ((ssgLeaf *)kid)->getPrimitiveType();
|
||||
|
||||
switch ( primType ) {
|
||||
case GL_POLYGON :
|
||||
case GL_TRIANGLE_FAN :
|
||||
IntersectPolyOrFanLeaf( (ssgLeaf *)kid, m,
|
||||
orig_leaf, dir_leaf );
|
||||
break;
|
||||
case GL_TRIANGLES :
|
||||
IntersectTriLeaf( (ssgLeaf *)kid, m,
|
||||
orig_leaf, dir_leaf );
|
||||
break;
|
||||
case GL_TRIANGLE_STRIP :
|
||||
case GL_QUAD_STRIP :
|
||||
IntersectStripLeaf( (ssgLeaf *)kid, m,
|
||||
orig_leaf, dir_leaf );
|
||||
break;
|
||||
case GL_QUADS :
|
||||
IntersectQuadsLeaf( (ssgLeaf *)kid, m,
|
||||
orig_leaf, dir_leaf );
|
||||
break;
|
||||
default:
|
||||
IntersectLeaf( (ssgLeaf *)kid, m,
|
||||
orig_leaf, dir_leaf );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// end of the line for this branch
|
||||
|
@ -441,13 +635,47 @@ void FGHitList::IntersectBranch( ssgBranch *branch, sgdMat4 m,
|
|||
}
|
||||
}
|
||||
|
||||
void ssgGetEntityTransform(ssgEntity *entity, sgMat4 m )
|
||||
{
|
||||
/*
|
||||
Walk backwards up the tree, transforming the
|
||||
vertex by all the matrices along the way.
|
||||
|
||||
// This expects the inital m to the identity transform
|
||||
Upwards recursion hurts my head.
|
||||
*/
|
||||
|
||||
sgMat4 mat ;
|
||||
|
||||
/*
|
||||
If this node has a parent - get the composite
|
||||
matrix for the parent.
|
||||
*/
|
||||
|
||||
if ( entity->getNumParents() > 0 )
|
||||
ssgGetEntityTransform ( entity->getParent(0), mat ) ;
|
||||
else
|
||||
sgMakeIdentMat4 ( mat ) ;
|
||||
|
||||
/*
|
||||
If this node has a transform - then concatenate it.
|
||||
*/
|
||||
|
||||
if ( entity -> isAKindOf ( ssgTypeTransform () ) ) {
|
||||
sgMat4 this_mat ;
|
||||
((ssgTransform *) entity) -> getTransform ( this_mat ) ;
|
||||
sgPostMultMat4 ( mat, this_mat ) ;
|
||||
}
|
||||
|
||||
sgCopyMat4 ( m, mat ) ;
|
||||
}
|
||||
#if 0
|
||||
// previously used method
|
||||
// This expects the inital m to be the identity transform
|
||||
void ssgGetEntityTransform(ssgEntity *branch, sgMat4 m )
|
||||
{
|
||||
for ( ssgEntity *parent = branch->getParent(0);
|
||||
parent != NULL;
|
||||
parent = parent->getNextParent() )
|
||||
parent = parent->getParent(0) )
|
||||
{
|
||||
// recurse till we are at the scene root
|
||||
// then just unwinding the stack should
|
||||
|
@ -460,7 +688,7 @@ void ssgGetEntityTransform(ssgEntity *branch, sgMat4 m )
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // 0
|
||||
|
||||
// return the passed entitity's bsphere's center point radius and
|
||||
// fully formed current model matrix for entity
|
||||
|
@ -475,53 +703,11 @@ void ssgGetCurrentBSphere( ssgEntity *entity, sgVec3 center,
|
|||
}
|
||||
|
||||
|
||||
void FGHitList::IntersectCachedLeaf( sgdMat4 m,
|
||||
sgdVec3 orig, sgdVec3 dir)
|
||||
{
|
||||
if ( last_hit() ) {
|
||||
float radius;
|
||||
sgVec3 fcenter;
|
||||
sgMat4 fxform;
|
||||
// ssgEntity *ent = last_hit();
|
||||
ssgGetCurrentBSphere( last_hit(), fcenter, &radius, fxform );
|
||||
sgdMat4 m;
|
||||
sgdVec3 center;
|
||||
sgdSetMat4( m, fxform );
|
||||
sgdXformPnt3( center, m );
|
||||
|
||||
if ( sgdClosestPointToLineDistSquared( center, orig, dir ) <
|
||||
double(radius*radius) )
|
||||
{
|
||||
IntersectLeaf( (ssgLeaf *)last_hit(), m, orig, dir );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FGHitList::Intersect( ssgBranch *scene, sgdVec3 orig, sgdVec3 dir ) {
|
||||
sgdMat4 m;
|
||||
|
||||
// #define USE_CACHED_HIT
|
||||
|
||||
#ifdef USE_CACHED_HIT
|
||||
// This optimization gives a slight speedup
|
||||
// but it precludes using the hitlist for dynamic
|
||||
// objects NHV
|
||||
init();
|
||||
if( last_hit() ) {
|
||||
sgdMakeIdentMat4 ( m ) ;
|
||||
IntersectCachedLeaf(m, orig, dir);
|
||||
}
|
||||
if( ! num_hits() ) {
|
||||
#endif
|
||||
|
||||
clear();
|
||||
sgdMakeIdentMat4 ( m ) ;
|
||||
IntersectBranch( scene, m, orig, dir);
|
||||
|
||||
#ifdef USE_CACHED_HIT
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -542,11 +728,20 @@ static inline Point3D operator + (const Point3D& a, const sgdVec3 b)
|
|||
}
|
||||
|
||||
|
||||
// Determine scenery altitude via ssg. Normally this just happens
|
||||
// when we render the scene, but we'd also like to be able to do this
|
||||
// explicitely. lat & lon are in radians. view_pos in current world
|
||||
// coordinate translated near (0,0,0) (in meters.) Returns result in
|
||||
// meters.
|
||||
/*
|
||||
* This method is faster
|
||||
*/
|
||||
|
||||
void FGHitList::Intersect( ssgBranch *scene, sgdMat4 m, sgdVec3 orig,
|
||||
sgdVec3 dir )
|
||||
{
|
||||
clear();
|
||||
IntersectBranch( scene, m, orig, dir);
|
||||
}
|
||||
|
||||
|
||||
// Determine scenery altitude via ssg.
|
||||
// returned results are in meters
|
||||
bool fgCurrentElev( sgdVec3 abs_view_pos, sgdVec3 scenery_center,
|
||||
FGHitList *hit_list,
|
||||
double *terrain_elev, double *radius, double *normal)
|
||||
|
@ -557,7 +752,9 @@ bool fgCurrentElev( sgdVec3 abs_view_pos, sgdVec3 scenery_center,
|
|||
sgdVec3 orig, dir;
|
||||
sgdCopyVec3(orig, view_pos );
|
||||
sgdCopyVec3(dir, abs_view_pos );
|
||||
// sgdNormalizeVec3(dir);
|
||||
|
||||
// !! why is terrain not globals->get_terrain()
|
||||
hit_list->Intersect( terrain_branch, orig, dir );
|
||||
|
||||
int this_hit=0;
|
||||
|
@ -565,17 +762,20 @@ bool fgCurrentElev( sgdVec3 abs_view_pos, sgdVec3 scenery_center,
|
|||
double result = -9999;
|
||||
Point3D sc(scenery_center[0], scenery_center[1], scenery_center[2]) ;
|
||||
|
||||
// cout << "hits = ";
|
||||
int hitcount = hit_list->num_hits();
|
||||
for ( int i = 0; i < hitcount; ++i ) {
|
||||
geoc = sgCartToPolar3d( sc + hit_list->get_point(i) );
|
||||
double lat_geod, alt, sea_level_r;
|
||||
sgGeocToGeod(geoc.lat(), geoc.radius(), &lat_geod,
|
||||
&alt, &sea_level_r);
|
||||
// cout << alt << " ";
|
||||
if ( alt > result && alt < 10000 ) {
|
||||
result = alt;
|
||||
this_hit = i;
|
||||
}
|
||||
}
|
||||
// cout << endl;
|
||||
|
||||
if ( result > -9000 ) {
|
||||
*terrain_elev = result;
|
||||
|
@ -598,3 +798,71 @@ bool fgCurrentElev( sgdVec3 abs_view_pos, sgdVec3 scenery_center,
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Determine scenery altitude via ssg.
|
||||
// returned results are in meters
|
||||
bool fgCurrentElev( sgdVec3 abs_view_pos, sgdVec3 scenery_center,
|
||||
ssgTransform *terra_transform,
|
||||
FGHitList *hit_list,
|
||||
double *terrain_elev, double *radius, double *normal)
|
||||
{
|
||||
#ifndef FAST_HITLIST__TEST
|
||||
return fgCurrentElev( abs_view_pos, scenery_center, hit_list,
|
||||
terrain_elev,radius,normal);
|
||||
#else
|
||||
sgdVec3 view_pos;
|
||||
sgdSubVec3( view_pos, abs_view_pos, scenery_center );
|
||||
|
||||
sgdVec3 orig, dir;
|
||||
sgdCopyVec3(orig, view_pos );
|
||||
|
||||
sgdCopyVec3(dir, abs_view_pos );
|
||||
sgdNormalizeVec3(dir);
|
||||
|
||||
sgMat4 fxform;
|
||||
sgMakeIdentMat4 ( fxform ) ;
|
||||
ssgGetEntityTransform( terra_transform, fxform );
|
||||
|
||||
sgdMat4 xform;
|
||||
sgdSetMat4(xform,fxform);
|
||||
hit_list->Intersect( terra_transform, xform, orig, dir );
|
||||
|
||||
int this_hit=0;
|
||||
Point3D geoc;
|
||||
double result = -9999;
|
||||
Point3D sc(scenery_center[0], scenery_center[1], scenery_center[2]) ;
|
||||
|
||||
int hitcount = hit_list->num_hits();
|
||||
for ( int i = 0; i < hitcount; ++i ) {
|
||||
geoc = sgCartToPolar3d( sc + hit_list->get_point(i) );
|
||||
double lat_geod, alt, sea_level_r;
|
||||
sgGeocToGeod(geoc.lat(), geoc.radius(), &lat_geod,
|
||||
&alt, &sea_level_r);
|
||||
if ( alt > result && alt < 20000 ) {
|
||||
result = alt;
|
||||
this_hit = i;
|
||||
}
|
||||
}
|
||||
|
||||
if ( result > -9000 ) {
|
||||
*terrain_elev = result;
|
||||
*radius = geoc.radius();
|
||||
sgVec3 tmp;
|
||||
sgSetVec3(tmp, hit_list->get_normal(this_hit));
|
||||
// cout << "cur_normal: " << tmp[0] << " " << tmp[1] << " "
|
||||
// << tmp[2] << endl;
|
||||
/* ssgState *IntersectedLeafState =
|
||||
((ssgLeaf*)hit_list->get_entity(this_hit))->getState(); */
|
||||
CurrentNormalInLocalPlane(tmp, tmp);
|
||||
sgdSetVec3( normal, tmp );
|
||||
// cout << "NED: " << tmp[0] << " " << tmp[1] << " " << tmp[2] << endl;
|
||||
return true;
|
||||
} else {
|
||||
SG_LOG( SG_TERRAIN, SG_DEBUG, "DOING FULL TERRAIN INTERSECTION" );
|
||||
return fgCurrentElev( abs_view_pos, scenery_center, hit_list,
|
||||
terrain_elev,radius,normal);
|
||||
}
|
||||
#endif // !FAST_HITLIST__TEST
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
// hitlist.hxx
|
||||
// Height Over Terrain and Assosciated Routines for FlightGear based Scenery
|
||||
// Written by Norman Vine, started 2000.
|
||||
|
||||
#ifndef _HITLIST_HXX
|
||||
#define _HITLIST_HXX
|
||||
|
||||
|
@ -11,8 +15,9 @@
|
|||
|
||||
#include <plib/ssg.h>
|
||||
|
||||
SG_USING_STD(vector);
|
||||
#define FAST_HITLIST__TEST 1
|
||||
|
||||
SG_USING_STD(vector);
|
||||
|
||||
class FGHitRec {
|
||||
|
||||
|
@ -44,11 +49,12 @@ private:
|
|||
|
||||
ssgEntity *last;
|
||||
vector < FGHitRec > list;
|
||||
double test_dist;
|
||||
|
||||
public:
|
||||
|
||||
FGHitList() { last = NULL; }
|
||||
void init(void) { list.clear(); }
|
||||
FGHitList() { last = NULL; test_dist=DBL_MAX; }
|
||||
void init(void) { list.clear(); test_dist=DBL_MAX; }
|
||||
void clear(void) { init(); last = NULL; }
|
||||
void add( ssgEntity *ent, int idx, sgdVec3 point, sgdVec3 normal ) {
|
||||
list.push_back( FGHitRec( ent,idx,point,normal) );
|
||||
|
@ -63,24 +69,47 @@ public:
|
|||
|
||||
void Intersect( ssgBranch *branch,
|
||||
sgdVec3 orig, sgdVec3 dir );
|
||||
void Intersect( ssgBranch *scene, sgdMat4 m,
|
||||
sgdVec3 orig, sgdVec3 dir );
|
||||
|
||||
void IntersectBranch( ssgBranch *branch, sgdMat4 m,
|
||||
sgdVec3 orig, sgdVec3 dir);
|
||||
|
||||
void IntersectCachedLeaf( sgdMat4 m,
|
||||
sgdVec3 orig, sgdVec3 dir);
|
||||
void IntersectCachedLeaf( sgdVec3 orig, sgdVec3 dir);
|
||||
|
||||
int IntersectLeaf( ssgLeaf *leaf, sgdMat4 m,
|
||||
sgdVec3 orig, sgdVec3 dir );
|
||||
|
||||
int IntersectPolyOrFanLeaf( ssgLeaf *leaf, sgdMat4 m,
|
||||
sgdVec3 orig, sgdVec3 dir );
|
||||
|
||||
int IntersectTriLeaf( ssgLeaf *leaf, sgdMat4 m,
|
||||
sgdVec3 orig, sgdVec3 dir );
|
||||
|
||||
int IntersectStripLeaf( ssgLeaf *leaf, sgdMat4 m,
|
||||
sgdVec3 orig, sgdVec3 dir );
|
||||
|
||||
int IntersectQuadsLeaf( ssgLeaf *leaf, sgdMat4 m,
|
||||
sgdVec3 orig, sgdVec3 dir );
|
||||
};
|
||||
|
||||
|
||||
// Associated function, assuming a wgs84 world with 0,0,0 at the
|
||||
// center, find the current terrain intersection elevation for the
|
||||
// point specified.
|
||||
bool fgCurrentElev( sgdVec3 abs_view_pos, sgdVec3 scenery_center,
|
||||
bool fgCurrentElev( sgdVec3 abs_view_pos,
|
||||
sgdVec3 scenery_center,
|
||||
ssgTransform *terra_transform,
|
||||
FGHitList *hit_list,
|
||||
double *terrain_elev, double *radius, double *normal );
|
||||
double *terrain_elev,
|
||||
double *radius,
|
||||
double *normal );
|
||||
|
||||
bool fgCurrentElev( sgdVec3 abs_view_pos,
|
||||
sgdVec3 scenery_center,
|
||||
FGHitList *hit_list,
|
||||
double *terrain_elev,
|
||||
double *radius,
|
||||
double *normal );
|
||||
|
||||
#endif // _HITLIST_HXX
|
||||
|
|
|
@ -266,6 +266,12 @@ public:
|
|||
* graph for this tile.
|
||||
*/
|
||||
void disconnect_ssg_nodes();
|
||||
|
||||
|
||||
/**
|
||||
* return the SSG Transform node for the terrain
|
||||
*/
|
||||
inline ssgTransform *get_terra_transform() { return terra_transform; }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -292,6 +292,7 @@ int FGTileMgr::update( double lon, double lat ) {
|
|||
// happen in the render thread because model loading can trigger
|
||||
// texture loading which involves use of the opengl api.
|
||||
if ( !model_queue.empty() ) {
|
||||
// cout << "loading next model ..." << endl;
|
||||
// load the next tile in the queue
|
||||
#ifdef ENABLE_THREADS
|
||||
FGDeferredModel* dm = model_queue.pop();
|
||||
|
@ -311,6 +312,8 @@ int FGTileMgr::update( double lon, double lat ) {
|
|||
delete dm;
|
||||
}
|
||||
|
||||
// cout << "current elevation (ssg) == " << scenery.get_cur_elev() << endl;
|
||||
|
||||
previous_bucket = current_bucket;
|
||||
last_longitude = longitude;
|
||||
last_latitude = latitude;
|
||||
|
@ -334,6 +337,7 @@ int FGTileMgr::update( double lon, double lat ) {
|
|||
e->add_ssg_nodes( terrain_branch,
|
||||
gnd_lights_branch,
|
||||
rwy_lights_branch );
|
||||
// cout << "Adding ssg nodes for "
|
||||
}
|
||||
|
||||
sgdVec3 sc;
|
||||
|
@ -345,6 +349,7 @@ int FGTileMgr::update( double lon, double lat ) {
|
|||
#if 0
|
||||
if ( scenery.center == Point3D(0.0) ) {
|
||||
// initializing
|
||||
cout << "initializing scenery current elevation ... " << endl;
|
||||
sgdVec3 tmp_abs_view_pos;
|
||||
|
||||
Point3D geod_pos = Point3D( longitude * SGD_DEGREES_TO_RADIANS,
|
||||
|
@ -354,6 +359,7 @@ int FGTileMgr::update( double lon, double lat ) {
|
|||
scenery.center = tmp;
|
||||
sgdSetVec3( tmp_abs_view_pos, tmp.x(), tmp.y(), tmp.z() );
|
||||
|
||||
// cout << "abs_view_pos = " << tmp_abs_view_pos << endl;
|
||||
prep_ssg_nodes();
|
||||
|
||||
double tmp_elev;
|
||||
|
@ -364,8 +370,25 @@ int FGTileMgr::update( double lon, double lat ) {
|
|||
} else {
|
||||
scenery.set_cur_elev( 0.0 );
|
||||
}
|
||||
// cout << "result = " << scenery.get_cur_elev() << endl;
|
||||
} else {
|
||||
#endif
|
||||
|
||||
/*
|
||||
cout << "abs view pos = "
|
||||
<< globals->get_current_view()->get_abs_view_pos()[0] << ","
|
||||
<< globals->get_current_view()->get_abs_view_pos()[1] << ","
|
||||
<< globals->get_current_view()->get_abs_view_pos()[2]
|
||||
<< " view pos = "
|
||||
<< globals->get_current_view()->get_view_pos()[0] << ","
|
||||
<< globals->get_current_view()->get_view_pos()[1] << ","
|
||||
<< globals->get_current_view()->get_view_pos()[2]
|
||||
<< endl;
|
||||
cout << "current_tile = " << current_tile << endl;
|
||||
cout << "Scenery center = " << sc[0] << "," << sc[1] << "," << sc[2]
|
||||
<< endl;
|
||||
*/
|
||||
|
||||
// overridden with actual values if a terrain intersection is
|
||||
// found
|
||||
double hit_elev = -9999.0;
|
||||
|
@ -376,8 +399,13 @@ int FGTileMgr::update( double lon, double lat ) {
|
|||
if ( fabs(sc[0]) > 1.0 || fabs(sc[1]) > 1.0 || fabs(sc[2]) > 1.0 ) {
|
||||
// scenery center has been properly defined so any hit
|
||||
// should be valid (and not just luck)
|
||||
sgdSetVec3( sc,
|
||||
scenery.get_center()[0],
|
||||
scenery.get_center()[1],
|
||||
scenery.get_center()[2] );
|
||||
hit = fgCurrentElev(globals->get_current_view()->get_abs_view_pos(),
|
||||
sc,
|
||||
current_tile->get_terra_transform(),
|
||||
&hit_list,
|
||||
&hit_elev,
|
||||
&hit_radius,
|
||||
|
@ -393,6 +421,8 @@ int FGTileMgr::update( double lon, double lat ) {
|
|||
scenery.set_cur_radius( 0.0 );
|
||||
scenery.set_cur_normal( hit_normal );
|
||||
}
|
||||
// cout << "Current elevation = " << scenery.get_cur_elev() << endl;
|
||||
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
@ -413,6 +443,7 @@ void FGTileMgr::prep_ssg_nodes() {
|
|||
tile_cache.reset_traversal();
|
||||
|
||||
while ( ! tile_cache.at_end() ) {
|
||||
// cout << "processing a tile" << endl;
|
||||
if ( (e = tile_cache.get_current()) ) {
|
||||
e->prep_ssg_node( scenery.get_center(), vis);
|
||||
} else {
|
||||
|
|
Loading…
Add table
Reference in a new issue