+ sgdVec3 tri[3];
+
+ switch ( primType )
+ {
+ case GL_POLYGON :
+ SG_LOG( SG_TERRAIN, SG_ALERT,
+ "WARNING: dubiously handled GL_POLYGON" );
+ case GL_TRIANGLE_FAN :
+ /* SG_LOG( SG_TERRAIN, SG_ALERT,
+ "IntersectLeaf: GL_TRIANGLE_FAN" ); */
+ 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) ) );
+ }
+ break;
+ case GL_TRIANGLES :
+ /* SG_LOG( SG_TERRAIN, SG_DEBUG,
+ "IntersectLeaf: GL_TRIANGLES" ); */
+ 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) ) );
+ break;
+ case GL_QUAD_STRIP :
+ SG_LOG( SG_TERRAIN, SG_ALERT,
+ "WARNING: dubiously handled GL_QUAD_STRIP" );
+ case GL_TRIANGLE_STRIP :
+ /* SG_LOG( SG_TERRAIN, SG_ALERT,
+ "IntersectLeaf: GL_TRIANGLE_STRIP" ); */
+ 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 ) {
+ sgdCopyVec3( tri[0], tri[2] );
+ sgdSetVec3( tri[2], leaf->getVertex( short(n+2) ) );
+ } else {
+ sgdCopyVec3( tri[1], tri[2] );
+ sgdSetVec3( tri[2], leaf->getVertex( short(n+2) ) );
+ }
+ }
+ break;
+ case GL_QUADS :
+ SG_LOG( SG_TERRAIN, SG_ALERT,
+ "WARNING: dubiously handled GL_QUADS" );
+ 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) ) );
+ break;
+ default:
+ SG_LOG( SG_TERRAIN, SG_ALERT,
+ "WARNING: not-handled structure: " << primType );
+ return IntersectLeaf( leaf, m, orig, dir);
+ }
+
+ if( isZeroAreaTri( tri ) )
+ continue;
+
+ sgdVec4 plane;
+ sgdMakePlane( plane, tri[0], tri[1], tri[2] );
+
+ sgdVec3 point;
+
+ // find point of intersection of line from point org
+ // in direction dir with triangle's plane
+ SGDfloat tmp = sgdScalarProductVec3 ( dir, plane ) ;
+ /* Is line parallel to plane? */
+ if ( sgdAbs ( tmp ) < FLT_EPSILON /*DBL_EPSILON*/ )
+ continue ;
+
+ // find parametric point
+ sgdScaleVec3 ( point, dir,
+ -( sgdScalarProductVec3 ( orig, plane ) + plane[3] )
+ / tmp ) ;
+
+ // short circut if this point is further away then a previous hit
+ tmp_dist = sgdDistanceSquaredVec3(point, orig );
+ if( tmp_dist > test_dist )
+ continue;
+
+ // place parametric point in world
+ sgdAddVec3 ( point, orig ) ;
+
+ if( fgdPointInTriangle( point, tri ) ) {
+ // transform point into passed coordinate frame
+ sgdXformPnt3( point, point, m );
+ sgdXformPnt4(plane,plane,m);
+ add(leaf,n,point,plane);
+ test_dist = tmp_dist;
+ num_hits++;