float3 Triangle::RandomPointInside(LCG &rng) const { float epsilon = 1e-3f; ///@todo rng.Float() returns [0,1[, but to be completely uniform, we'd need [0,1] here. float s = rng.Float(epsilon, 1.f - epsilon);//1e-2f, 1.f - 1e-2f); float t = rng.Float(epsilon, 1.f - epsilon);//1e-2f, 1.f - 1e-2f if (s + t >= 1.f) { s = 1.f - s; t = 1.f - t; } #ifdef MATH_ASSERT_CORRECTNESS float3 pt = Point(s, t); float2 uv = BarycentricUV(pt); assert(uv.x >= 0.f); assert(uv.y >= 0.f); assert(uv.x + uv.y <= 1.f); float3 uvw = BarycentricUVW(pt); assert(uvw.x >= 0.f); assert(uvw.y >= 0.f); assert(uvw.z >= 0.f); assert(EqualAbs(uvw.x + uvw.y + uvw.z, 1.f)); #endif return Point(s, t); }
bool Triangle::Contains(const float3 &point, float triangleThickness) const { if (PlaneCCW().Distance(point) > triangleThickness) // The winding order of the triangle plane does not matter. return false; ///@todo The plane-point distance test is omitted in Real-Time Collision Detection. p. 25. A bug in the book? float3 br = BarycentricUVW(point); return br.y >= 0.f && br.z >= 0.f && (br.y + br.z) <= 1.f; }
bool Triangle::Contains(const float3 &point, float triangleThickness) const { if (PlaneCCW().Distance(point) > triangleThickness) // The winding order of the triangle plane does not matter. return false; ///@todo The plane-point distance test is omitted in Real-Time Collision Detection. p. 25. A bug in the book? float3 br = BarycentricUVW(point); return br.x >= -1e-3f && br.y >= -1e-3f && br.z >= -1e-3f; // Allow for a small epsilon to properly account for points very near the edges of the triangle. }
float2 Triangle::BarycentricUV(const float3 &point) const { float3 uvw = BarycentricUVW(point); return float2(uvw.y, uvw.z); }