bool operator()(const Triangle& tri) const { bool b = tri.CCEncompasses(m_iterVertex); if (b) { HandleEdge(tri.GetVertex(0), tri.GetVertex(1)); HandleEdge(tri.GetVertex(1), tri.GetVertex(2)); HandleEdge(tri.GetVertex(2), tri.GetVertex(0)); } return b; }
bool operator()(const Triangle& tri) const { for (int i = 0; i < 3; ++i) { const Vertex* p = tri.GetVertex(i); if (p >= m_pSuperTriangle && p < m_pSuperTriangle + 3) { return true; } } return false; }
bool TerrainBlock::PointInTriangle(Triangle& tri,Vector3& point) { Vector3* a = tri.GetVertex(0); Vector3* b = tri.GetVertex(1); Vector3* c = tri.GetVertex(2); Vector3 v0 = (*b) - (*a); Vector3 v1 = (*c)- (*a); Vector3 v2 = point - (*a); float d00 = v0.dotProduct(v0); float d01 = v0.dotProduct(v1); float d02 = v0.dotProduct(v2); float d11 = v1.dotProduct(v1); float d12 = v1.dotProduct(v2); float invDenom = 1 / (d00 * d11 - d01 * d01); float u = (d11 * d02 - d01*d12) * invDenom; float v = (d00 * d12 - d01*d02) * invDenom; return (u >=0) && (v>=0) && (u+v<1); }
void Mesh::CalculateVertexNormals() { // Clear all vertex normals for( unsigned int i = 0; i < this->_vertices.size(); ++i ) { Vertex* vertex = this->_vertices.at(i); if( vertex ) { vertex->Normal() = 0.0f; } } // Sum all adjacent triangle normals for( unsigned int i = 0; i < this->_triangles.size(); ++i ) { Triangle* triangle = this->_triangles.at(i); if( triangle ) { if( triangle->IsValid() ) { for( unsigned int j = 0; j < 3; ++j ) { Vertex* vertex = triangle->GetVertex(j); vertex->Normal() += triangle->GetNormal(); } } } } // Normalize all vertex normals for( unsigned int i = 0; i < this->_vertices.size(); ++i ) { Vertex* vertex = this->_vertices.at(i); if( vertex ) { vertex->Normal().Normalize(); } } }
bool BasicPrimitiveTests::IntersectingLineAgainstTriangle(const Line & line, const Triangle & triangle, Eigen::Vector3f & rtn_point) { /* Main Idea: -> Tests if line's intersection with triangle plane is inside triangle -> Using scalar triple products to compute signed tetrahedral volumes -> Which are then used to compute barycentric coordinates of the line-triangle plane intersection. Let: -> Triangle ABC -> Line through PQ -> Intersection point R -> between line and triangle's plane To only determine intersection: -> R must be inside triangle -> R must be to left of AB, BC, CA if ABC is counter-clockwise vertex ordering. -> Use scalar triple products to determine winding of AB, BC, CA compared to PQ: -> u, v, w >= 0 -> u = [PQ PC PB] -> v = [PQ PA PC] -> w = [PQ PB PA] To obtain intersection point: -> Volumes of tetrahedra RBCP, RCAP, RABP, proportional to areas of base triangles RBC, RCA, RAB because they all have same height. -> Barycentric points: -> u = ( [PQ PC PB] / [PQ PC PB] + [PQ PA PC] + [PQ PB PA] ) -> v = ( [PQ PA PC] / [PQ PC PB] + [PQ PA PC] + [PQ PB PA] ) -> w = ( [PQ PB PA] / [PQ PC PB] + [PQ PA PC] + [PQ PB PA] ) */ Eigen::Vector3f PQ = -line.GetDirection(); Eigen::Vector3f PA = triangle.GetVertex(0) - line.GetPoint(); Eigen::Vector3f PB = triangle.GetVertex(1) - line.GetPoint(); Eigen::Vector3f PC = triangle.GetVertex(2) - line.GetPoint(); Eigen::Vector3f barycentric_coords; barycentric_coords[0] = ScalarTripleProduct(PQ, PC, PB); if (barycentric_coords[0] < 0.0f) return false; barycentric_coords[1] = ScalarTripleProduct(PQ, PA, PC); if (barycentric_coords[1] < 0.0f) return false; barycentric_coords[2] = ScalarTripleProduct(PQ, PB, PA); if (barycentric_coords[2] < 0.0f) return false; float sum = barycentric_coords[0] + barycentric_coords[1] + barycentric_coords[2]; if (sum < EPSILON) { float s, s0, s1, s2, t; LineSegment edge_AB = LineSegment(triangle.GetVertex(0), triangle.GetVertex(1)); if (!IntersectLineAgainstSegment(line, edge_AB, s0, t)) s0 = FLT_MAX; LineSegment edge_BC = LineSegment(triangle.GetVertex(1), triangle.GetVertex(2)); if (!IntersectLineAgainstSegment(line, edge_AB, s1, t)) s1 = FLT_MAX; LineSegment edge_AC = LineSegment(triangle.GetVertex(0), triangle.GetVertex(2)); if (!IntersectLineAgainstSegment(line, edge_AB, s2, t)) s2 = FLT_MAX; s = std::min(std::min(s0, s1), s2); line.GetPointAt(s, rtn_point); return true; } float denom = 1.0f / sum; barycentric_coords *= denom; rtn_point = triangle.GetVertex(0) * barycentric_coords[0] + triangle.GetVertex(1) * barycentric_coords[1] + triangle.GetVertex(2) * barycentric_coords[2]; return true; }