void TriangleMesh::PostIntersect(Intersection &isect) const { const Triangle &tri = m_Triangles[isect.primID]; Normal &Ng = isect.Ng; float u = isect.uv[0], v = isect.uv[1], w = 1.0f-u-v; Point2 st0, st1, st2; if(m_STs.size() == 0) { st0 = Point2(0.f, 0.f); st1 = Point2(1.f, 0.f); st2 = Point2(0.f, 1.f); isect.st = isect.uv; } else { st0 = m_STs[tri.idx[0]]; st1 = m_STs[tri.idx[1]]; st2 = m_STs[tri.idx[2]]; isect.st = w*st0 + u*st1 + v*st2; } if(m_Normals.size() == 0) { isect.Ns = Ng; } else { const Normal &n0 = m_Normals[tri.idx[0]]; const Normal &n1 = m_Normals[tri.idx[1]]; const Normal &n2 = m_Normals[tri.idx[2]]; //Vector dPdu = p1 - p0, dPdv = p2 - p2; Normal Ns = w*n0 + u*n1 + v*n2; float sqLen = Ns.squaredNorm(); //Ns = sqLen > 0.f ? Ns*Rsqrt(sqLen) : isect.Ng; if(sqLen > 0.f) Ns *= Rsqrt(sqLen); else Ns = isect.Ng; if (Ns.dot(Ng) < 0.f) Ns = -Ns; isect.Ns = Ns; } if(Ng.squaredNorm() <= 0.f) { // Degenerated triangle isect.dPds = Vector(0.f); isect.dPdt = Vector(0.f); } else { const PointA &p0 = m_Vertices[tri.idx[0]]; const PointA &p1 = m_Vertices[tri.idx[1]]; const PointA &p2 = m_Vertices[tri.idx[2]]; Vector dP1 = p1 - p0, dP2 = p2 - p0; Vector2 dST1 = st1 - st0, dST2 = st2 - st0; float determinant = dST1[0] * dST2[1] - dST1[1] * dST2[0]; if(determinant == 0.f) { // Degenerated st CoordinateSystem(Ng, isect.dPds, isect.dPdt); } else { float invDet = Rcp(determinant); isect.dPds = ( dST2[1] * dP1 - dST1[1] * dP2)*invDet; isect.dPdt = (-dST2[0] * dP1 + dST1[0] * dP2)*invDet; } } }
//---------------------------------------------------------------------------------- // //---------------------------------------------------------------------------------- void Vector3D::Normal( Vector3D& o, const Vector3D& in ) { float inv = Rsqrt( in.X * in.X + in.Y * in.Y + in.Z * in.Z ); o.X = in.X * inv; o.Y = in.Y * inv; o.Z = in.Z * inv; }