// David Eberly, Geometric Tools, Redmond WA 98052 // Copyright (c) 1998-2020 // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt // https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt // Version: 4.0.2019.08.13 #pragma once #include #include #include #include #include namespace WwiseGTE { template class TIQuery, Triangle3> { public: struct Result { bool intersect; // The number is 0 (no intersection), 1 (plane and triangle // intersect at a single point [vertex]), 2 (plane and triangle // intersect in a segment), or 3 (triangle is in the plane). // When the number is 2, the segment is either interior to the // triangle or is an edge of the triangle, the distinction stored // in 'isInterior'. int numIntersections; bool isInterior; }; Result operator()(Plane3 const& plane, Triangle3 const& triangle) { Result result; // Determine on which side of the plane the vertices lie. The // table of possibilities is listed next with n = numNegative, // p = numPositive, and z = numZero. // // n p z intersection // ------------------------------------ // 0 3 0 none // 0 2 1 vertex // 0 1 2 edge // 0 0 3 triangle in the plane // 1 2 0 segment (2 edges clipped) // 1 1 1 segment (1 edge clipped) // 1 0 2 edge // 2 1 0 segment (2 edges clipped) // 2 0 1 vertex // 3 0 0 none Real s[3]; int numPositive = 0, numNegative = 0, numZero = 0; for (int i = 0; i < 3; ++i) { s[i] = Dot(plane.normal, triangle.v[i]) - plane.constant; if (s[i] > (Real)0) { ++numPositive; } else if (s[i] < (Real)0) { ++numNegative; } else { ++numZero; } } if (numZero == 0 && numPositive > 0 && numNegative > 0) { result.intersect = true; result.numIntersections = 2; result.isInterior = true; return result; } if (numZero == 1) { result.intersect = true; for (int i = 0; i < 3; ++i) { if (s[i] == (Real)0) { if (numPositive == 2 || numNegative == 2) { result.numIntersections = 1; } else { result.numIntersections = 2; result.isInterior = true; } break; } } return result; } if (numZero == 2) { result.intersect = true; result.numIntersections = 2; result.isInterior = false; return result; } if (numZero == 3) { result.intersect = true; result.numIntersections = 3; } else { result.intersect = false; result.numIntersections = 0; } return result; } }; template class FIQuery, Triangle3> { public: struct Result { bool intersect; // The number is 0 (no intersection), 1 (plane and triangle // intersect at a single point [vertex]), 2 (plane and triangle // intersect in a segment), or 3 (triangle is in the plane). // When the number is 2, the segment is either interior to the // triangle or is an edge of the triangle, the distinction stored // in 'isInterior'. int numIntersections; bool isInterior; Vector3 point[3]; }; Result operator()(Plane3 const& plane, Triangle3 const& triangle) { Result result; // Determine on which side of the plane the vertices lie. The // table of possibilities is listed next with n = numNegative, // p = numPositive, and z = numZero. // // n p z intersection // ------------------------------------ // 0 3 0 none // 0 2 1 vertex // 0 1 2 edge // 0 0 3 triangle in the plane // 1 2 0 segment (2 edges clipped) // 1 1 1 segment (1 edge clipped) // 1 0 2 edge // 2 1 0 segment (2 edges clipped) // 2 0 1 vertex // 3 0 0 none Real s[3]; int numPositive = 0, numNegative = 0, numZero = 0; for (int i = 0; i < 3; ++i) { s[i] = Dot(plane.normal, triangle.v[i]) - plane.constant; if (s[i] > (Real)0) { ++numPositive; } else if (s[i] < (Real)0) { ++numNegative; } else { ++numZero; } } if (numZero == 0 && numPositive > 0 && numNegative > 0) { result.intersect = true; result.numIntersections = 2; result.isInterior = true; Real sign = (Real)3 - numPositive * (Real)2; for (int i0 = 0; i0 < 3; ++i0) { if (sign * s[i0] > (Real)0) { int i1 = (i0 + 1) % 3, i2 = (i0 + 2) % 3; Real t1 = s[i1] / (s[i1] - s[i0]); Real t2 = s[i2] / (s[i2] - s[i0]); result.point[0] = triangle.v[i1] + t1 * (triangle.v[i0] - triangle.v[i1]); result.point[1] = triangle.v[i2] + t2 * (triangle.v[i0] - triangle.v[i2]); break; } } return result; } if (numZero == 1) { result.intersect = true; for (int i0 = 0; i0 < 3; ++i0) { if (s[i0] == (Real)0) { int i1 = (i0 + 1) % 3, i2 = (i0 + 2) % 3; result.point[0] = triangle.v[i0]; if (numPositive == 2 || numNegative == 2) { result.numIntersections = 1; } else { result.numIntersections = 2; result.isInterior = true; Real t = s[i1] / (s[i1] - s[i2]); result.point[1] = triangle.v[i1] + t * (triangle.v[i2] - triangle.v[i1]); } break; } } return result; } if (numZero == 2) { result.intersect = true; result.numIntersections = 2; result.isInterior = false; for (int i0 = 0; i0 < 3; ++i0) { if (s[i0] != (Real)0) { int i1 = (i0 + 1) % 3, i2 = (i0 + 2) % 3; result.point[0] = triangle.v[i1]; result.point[1] = triangle.v[i2]; break; } } return result; } if (numZero == 3) { result.intersect = true; result.numIntersections = 3; result.point[0] = triangle.v[0]; result.point[1] = triangle.v[1]; result.point[2] = triangle.v[2]; } else { result.intersect = false; result.numIntersections = 0; } return result; } }; }