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;
		}
Ejemplo n.º 3
0
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;
	
}