Latest version of hitlist.cxx from Norman Vine:
- Addresses some ot the recent profiling results. - Added a 'lazy evaluation' in IntersectBranch and inlined a couple of HEAVILY called functions.
This commit is contained in:
parent
03b9ecf039
commit
9bae80d94a
1 changed files with 165 additions and 120 deletions
|
@ -39,15 +39,20 @@ static bool pointInTriangle( sgdVec3 point, sgdVec3 tri[3] )
|
||||||
// punt if outside bouding cube
|
// punt if outside bouding cube
|
||||||
if ( point[0] < (xmin = SG_MIN3 (tri[0][0], tri[1][0], tri[2][0])) ) {
|
if ( point[0] < (xmin = SG_MIN3 (tri[0][0], tri[1][0], tri[2][0])) ) {
|
||||||
return false;
|
return false;
|
||||||
} else if ( point[0] > (xmax = SG_MAX3 (tri[0][0], tri[1][0], tri[2][0])) ) {
|
} else if ( point[0] > (xmax = SG_MAX3 (tri[0][0], tri[1][0], tri[2][0])) )
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
} else if ( point[1] < (ymin = SG_MIN3 (tri[0][1], tri[1][1], tri[2][1])) ) {
|
} else if ( point[1] < (ymin = SG_MIN3 (tri[0][1], tri[1][1], tri[2][1])) )
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
} else if ( point[1] > (ymax = SG_MAX3 (tri[0][1], tri[1][1], tri[2][1])) ) {
|
} else if ( point[1] > (ymax = SG_MAX3 (tri[0][1], tri[1][1], tri[2][1])) )
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
} else if ( point[2] < (zmin = SG_MIN3 (tri[0][2], tri[1][2], tri[2][2])) ) {
|
} else if ( point[2] < (zmin = SG_MIN3 (tri[0][2], tri[1][2], tri[2][2])) )
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
} else if ( point[2] > (zmax = SG_MAX3 (tri[0][2], tri[1][2], tri[2][2])) ) {
|
} else if ( point[2] > (zmax = SG_MAX3 (tri[0][2], tri[1][2], tri[2][2])) )
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,15 +210,22 @@ bool sgdPointInTriangle( sgdVec3 point, sgdVec3 tri[3] )
|
||||||
{
|
{
|
||||||
sgdVec3 dif;
|
sgdVec3 dif;
|
||||||
|
|
||||||
int i;
|
|
||||||
for( i=0; i<3; i++ ) {
|
|
||||||
SGDfloat min, max;
|
SGDfloat min, max;
|
||||||
SG_MIN_MAX3 ( min, max, tri[0][i], tri[1][i], tri[2][i] );
|
|
||||||
// punt if outside bouding cube
|
// punt if outside bouding cube
|
||||||
if( (point[i] < min) || (point[i] > max) )
|
SG_MIN_MAX3 ( min, max, tri[0][0], tri[1][0], tri[2][0] );
|
||||||
|
if( (point[0] < min) || (point[0] > max) )
|
||||||
return false;
|
return false;
|
||||||
dif[i] = max - min;
|
dif[0] = max - min;
|
||||||
}
|
|
||||||
|
SG_MIN_MAX3 ( min, max, tri[0][1], tri[1][1], tri[2][1] );
|
||||||
|
if( (point[1] < min) || (point[1] > max) )
|
||||||
|
return false;
|
||||||
|
dif[1] = max - min;
|
||||||
|
|
||||||
|
SG_MIN_MAX3 ( min, max, tri[0][2], tri[1][2], tri[2][2] );
|
||||||
|
if( (point[2] < min) || (point[2] > max) )
|
||||||
|
return false;
|
||||||
|
dif[2] = max - min;
|
||||||
|
|
||||||
// drop the smallest dimension so we only have to work in 2d.
|
// drop the smallest dimension so we only have to work in 2d.
|
||||||
SGDfloat min_dim = SG_MIN3 (dif[0], dif[1], dif[2]);
|
SGDfloat min_dim = SG_MIN3 (dif[0], dif[1], dif[2]);
|
||||||
|
@ -327,7 +339,20 @@ int FGHitList::IntersectLeaf( ssgLeaf *leaf, sgdMat4 m,
|
||||||
sgdMakePlane( plane, tri[0], tri[1], tri[2] );
|
sgdMakePlane( plane, tri[0], tri[1], tri[2] );
|
||||||
|
|
||||||
sgdVec3 point;
|
sgdVec3 point;
|
||||||
if( sgdIsectInfLinePlane( point, orig, dir, plane ) ) {
|
|
||||||
|
//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 0
|
||||||
if( pointInTriangle( point, tri ) ) {
|
if( pointInTriangle( point, tri ) ) {
|
||||||
add(leaf,i,point,plane);
|
add(leaf,i,point,plane);
|
||||||
|
@ -341,21 +366,23 @@ int FGHitList::IntersectLeaf( ssgLeaf *leaf, sgdMat4 m,
|
||||||
num_hits++;
|
num_hits++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return num_hits;
|
return num_hits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FGHitList::IntersectBranch( ssgBranch *branch, sgdMat4 m,
|
void FGHitList::IntersectBranch( ssgBranch *branch, sgdMat4 m,
|
||||||
sgdVec3 orig, sgdVec3 dir )
|
sgdVec3 orig, sgdVec3 dir )
|
||||||
{
|
{
|
||||||
sgSphere *bsphere;
|
sgSphere *bsphere;
|
||||||
|
|
||||||
// lookat vector in branch's coordinate frame
|
/* the lookat vector and matrix in branch's coordinate frame
|
||||||
|
* but we won't determine these unless needed to,
|
||||||
|
* This 'lazy evaluation' is a result of profiling data */
|
||||||
sgdVec3 _orig, _dir;
|
sgdVec3 _orig, _dir;
|
||||||
sgdMat4 _m;
|
sgdMat4 _m;
|
||||||
sgdTransposeNegateMat4( _m, m);
|
|
||||||
sgdXformPnt3( _orig, orig, _m );
|
// 'lazy evaluation' flag
|
||||||
sgdXformPnt3( _dir, dir, _m );
|
int first_time = 1;
|
||||||
|
|
||||||
for ( ssgEntity *kid = branch->getKid( 0 );
|
for ( ssgEntity *kid = branch->getKid( 0 );
|
||||||
kid != NULL;
|
kid != NULL;
|
||||||
|
@ -363,14 +390,25 @@ void FGHitList::IntersectBranch( ssgBranch *branch, sgdMat4 m,
|
||||||
{
|
{
|
||||||
if ( kid->getTraversalMask() & SSGTRAV_HOT ) {
|
if ( kid->getTraversalMask() & SSGTRAV_HOT ) {
|
||||||
bsphere = kid->getBSphere();
|
bsphere = kid->getBSphere();
|
||||||
sgVec3 fcenter;
|
|
||||||
sgCopyVec3( fcenter, bsphere->getCenter() );
|
|
||||||
sgdVec3 center;
|
sgdVec3 center;
|
||||||
sgdSetVec3( center, fcenter );
|
sgdSetVec3( center,
|
||||||
|
bsphere->getCenter()[0],
|
||||||
|
bsphere->getCenter()[1],
|
||||||
|
bsphere->getCenter()[2] );
|
||||||
sgdXformPnt3( center, m ) ;
|
sgdXformPnt3( center, m ) ;
|
||||||
// watch out for overflow
|
|
||||||
if ( sgdClosestPointToLineDistSquared( center, orig, dir ) <
|
// sgdClosestPointToLineDistSquared( center, orig, dir )
|
||||||
double(bsphere->getRadius() * bsphere->getRadius()) )
|
// inlined here because because of profiling results
|
||||||
|
sgdVec3 u, u1, v;
|
||||||
|
sgdSubVec3(u, center, orig);
|
||||||
|
sgdScaleVec3( u1, dir, sgdScalarProductVec3(u,dir)
|
||||||
|
/ sgdScalarProductVec3(dir,dir) );
|
||||||
|
sgdSubVec3(v, u, u1);
|
||||||
|
|
||||||
|
// doubles because of possible overflow
|
||||||
|
#define SQUARE(x) (x*x)
|
||||||
|
if( sgdScalarProductVec3(v, v)
|
||||||
|
< SQUARE( double(bsphere->getRadius()) ) )
|
||||||
{
|
{
|
||||||
// possible intersections
|
// possible intersections
|
||||||
if ( kid->isAKindOf ( ssgTypeBranch() ) ) {
|
if ( kid->isAKindOf ( ssgTypeBranch() ) ) {
|
||||||
|
@ -385,6 +423,13 @@ void FGHitList::IntersectBranch( ssgBranch *branch, sgdMat4 m,
|
||||||
}
|
}
|
||||||
IntersectBranch( (ssgBranch *)kid, m_new, orig, dir );
|
IntersectBranch( (ssgBranch *)kid, m_new, orig, dir );
|
||||||
} else if ( kid->isAKindOf( ssgTypeLeaf() ) ) {
|
} else if ( kid->isAKindOf( ssgTypeLeaf() ) ) {
|
||||||
|
if( first_time) {
|
||||||
|
// OK we need these
|
||||||
|
sgdTransposeNegateMat4( _m, m);
|
||||||
|
sgdXformPnt3( _orig, orig, _m );
|
||||||
|
sgdXformPnt3( _dir, dir, _m );
|
||||||
|
first_time = 0;
|
||||||
|
}
|
||||||
IntersectLeaf( (ssgLeaf *)kid, m, _orig, _dir );
|
IntersectLeaf( (ssgLeaf *)kid, m, _orig, _dir );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Reference in a new issue