//--------------------------------------------------------- // Test a line against a mesh // Select the closest front-facing triangle int CMesh::LineSelect( const Vector3 &LP1, const Vector3 &LP2 ) { Vector3 HitP; int nbHits = 0; int nSelTri = -1; float fDistance = 1000000000.0f; for (int nTri = 0; nTri < (int)mTriCount; nTri++ ) { if ( mTriFlags[ nTri ] & TF_BACKFACING ) continue; // Check only front facing triangles int nV = nTri*3; bool bHit = CheckLineTri( LP2, LP1, mVertices[ mIndices[nV] ], mVertices[ mIndices[nV+1] ], mVertices[ mIndices[nV+2] ], HitP ); if ( bHit ) { if ( HitP.distance( LP1 ) < fDistance ) { fDistance = HitP.distance( LP1 ); nSelTri = nTri; } nbHits++; } } selectTriangle( nSelTri ); return nbHits; }
// // returns false if the triangle is not within the frustum // bool TriInFrustum( CVec3 vTri[3], CVec3 Normals[4], CVec3 Points[8] ) { int i; // If all 3 points are to one side any frustum plane return false for( int x = 0; x < 4; x++ ) { for ( i = 0; i < 3; i++ ) { if ( Normals[x].Dot( vTri[i] - Points[x*2] ) < 0 ) break; } if ( i >= 3 ) return false; } // If any point is in the frustum, return true for ( i = 0; i < 3; i++ ) { if ( PointInFrustum( vTri[i], Normals, Points ) ) return true; } // If we didn't get quick result, do a slower but accurate test. // If any of the lines of the triangle are in the frustum, the triangle is in the frustum if ( LineInFrustum( vTri[0], vTri[1], Points ) ) return true; if ( LineInFrustum( vTri[1], vTri[2], Points ) ) return true; if ( LineInFrustum( vTri[2], vTri[0], Points ) ) return true; // If the frustum is completely inside the triangle, any frustum line into the screen will intersect the triangle CVec3 HitP; if ( CheckLineTri( Points[0], Points[1], vTri[0], vTri[1], vTri[2], HitP ) ) return true; return false; }
// // Test a line against a mesh // Selects the closest front-facing triangle // int CMesh::LineSelect( const CVec3 &LP1, const CVec3 &LP2 ) { CVec3 HitP; int nbHits = 0; int nSelTri = -1; float fDistance = 1000000000.0f; for (int nTri = 0; nTri < m_nbTris; nTri++ ) { if ( m_pTriFlags[ nTri ] & TF_BACKFACING ) continue; // Check only front facing triangles int nV = nTri*3; bool bHit = CheckLineTri( LP2, LP1, m_pVerts[ m_pTris[nV] ], m_pVerts[ m_pTris[nV+1] ], m_pVerts[ m_pTris[nV+2] ], HitP ); if ( bHit ) { if ( HitP.Distance( LP1 ) < fDistance ) { fDistance = HitP.Distance( LP1 ); nSelTri = nTri; } nbHits++; } } SelectTriangle( nSelTri ); return nbHits; }
// // LineInFrustum is much slower than it could be. I don't think it will be called very often, if it ever is I'll rewrite it. // It just constructs a 4-plane frustum box out of triangles, and uses the Line-Triangle test. // bool LineInFrustum( const CVec3 &LP1, const CVec3 &LP2, CVec3 Points[8] ) { CVec3 HitP; int List[24] = { 0, 1, 2, 1, 2, 3, 0, 1, 6, 1, 6, 7, 6, 7, 5, 6, 5, 4, 2, 3, 5, 2, 5, 4 }; for ( int x = 0; x < 8; x++ ) if ( CheckLineTri( LP1, LP2, Points[ List[x*3] ], Points[ List[x*3+1] ], Points[ List[x*3+2] ], HitP ) ) return true; return false; }