#include "Triangle3.h" #include "Ray.h" #include "AxisAlignedBox3.h" namespace GtpVisibilityPreprocessor { Triangle3::Triangle3(const Vector3 &a, const Vector3 &b, const Vector3 &c) { Init(a, b, c); } void Triangle3::Init(const Vector3 &a, const Vector3 &b, const Vector3 &c) { mVertices[0] = a; mVertices[1] = b; mVertices[2] = c; } float Triangle3::GetSpatialAngle(const Vector3 &point) const { return 0.0f; } int Triangle3::CastRay(const Ray &ray, float &t, const float nearestT) const { // get triangle edge vectors and plane normal const Vector3 u = mVertices[1] - mVertices[0]; const Vector3 v = mVertices[2] - mVertices[0]; const Vector3 n = u * v; // cross product const Vector3 dir = ray.GetDir(); // ray direction vector const Vector3 w0 = ray.GetLoc() - mVertices[0]; // params to calc ray-plane intersect const float a = - DotProd(n, w0); const float b = DotProd(n, dir); if (fabs(b) < Limits::Small) { // ray is parallel to triangle plane if (a == 0) // ray lies in triangle plane { return Ray::INTERSECTION_OUT_OF_LIMITS; } else { return Ray::NO_INTERSECTION; // ray disjoint from plane } } // get intersect point of ray with triangle plane t = a / b; if (t < 0.0) // ray goes away from triangle { return Ray::NO_INTERSECTION; // => no intersect } // for a segment, also test if (r > 1.0) => no intersect // intersect point of ray and plane const Vector3 pt = ray.GetLoc() + t * dir; /////////////////////////////////////////////// //-- is point inside triangle? const Vector3 w = pt - mVertices[0]; const float uu = DotProd(u, u); const float uv = DotProd(u, v); const float vv = DotProd(v, v); const float wu = DotProd(w, u); const float wv = DotProd(w, v); const float D = uv * uv - uu * vv; // get and test parametric coords const float s = (uv * wv - vv * wu) / D; if (s < 0.0 || s > 1.0) // pt is outside triangle { return Ray::NO_INTERSECTION; } const float s2 = (uv * wu - uu * wv) / D; if (s2 < 0.0 || (s + s2) > 1.0) // pt is outside triangle { return Ray::NO_INTERSECTION; } return Ray::INTERSECTION; // I is in T } AxisAlignedBox3 Triangle3::GetBoundingBox() const { AxisAlignedBox3 box; box.Initialize(); box.Include(mVertices[0]); box.Include(mVertices[1]); box.Include(mVertices[2]); return box; } Vector3 Triangle3::GetNormal() const { const Vector3 v1 = mVertices[0] - mVertices[1]; const Vector3 v2 = mVertices[2]-mVertices[1]; return Normalize(CrossProd(v2, v1)); } Vector3 Triangle3::GetCenter() const { return (mVertices[0] + mVertices[1] + mVertices[2]) / 3.0f; } float Triangle3::GetArea() const { Vector3 v1=mVertices[0]-mVertices[1], v2=mVertices[2]-mVertices[1]; return 0.5f * Magnitude(CrossProd(v2, v1)); } }