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 Sphere::IntersectFunc(const Sphere* spheres, RTCRay& rtcRay, size_t item) { Ray &ray = Ray::FromRTCRay(rtcRay); const Sphere& sphere = spheres[item]; const Vector v = ray.org - sphere.m_Pos; const float A = ray.dir.squaredNorm(); const float B = 2.0f * v.dot(ray.dir); const float C = v.squaredNorm() - sphere.m_Radius*sphere.m_Radius; const float D = B*B - 4.0f*A*C; if (D < 0.0f) return; const float Q = sqrtf(D); const float rcpA = Rcp(A); const float t0 = 0.5f*rcpA*(-B-Q); const float t1 = 0.5f*rcpA*(-B+Q); if ((ray.tnear < t0) & (t0 < ray.tfar)) { ray.u = 0.0f; ray.v = 0.0f; ray.tfar = t0; ray.geomID = sphere.m_GeomID; ray.primID = item; ray.Ng = ray.org + t0*ray.dir - sphere.m_Pos; } if ((ray.tnear < t1) & (t1 < ray.tfar)) { ray.u = 0.0f; ray.v = 0.0f; ray.tfar = t1; ray.geomID = sphere.m_GeomID; ray.primID = item; ray.Ng = ray.org + t1*ray.dir - sphere.m_Pos; } }
/*! compute inverse matrix */ COMPILER_FORCEINLINE const LinearSpace3 Inverse() const { return Rcp(Det())*Adjoint(); }
template<typename T> COMPILER_FORCEINLINE LinearSpace3<T> operator/(const LinearSpace3<T>& a, const T & b) { return a * Rcp(b); }