// 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 // Queries for intersection of objects with halfspaces. These are useful for // containment testing, object culling, and clipping. namespace WwiseGTE { template class TIQuery, Segment3> { public: struct Result { bool intersect; }; Result operator()(Halfspace3 const& halfspace, Segment3 const& segment) { Result result; // Project the segment endpoints onto the normal line. The plane // of the halfspace occurs at the origin (zero) of the normal // line. Real s[2]; for (int i = 0; i < 2; ++i) { s[i] = Dot(halfspace.normal, segment.p[i]) - halfspace.constant; } // The segment and halfspace intersect when the projection // interval maximum is nonnegative. result.intersect = (std::max(s[0], s[1]) >= (Real)0); return result; } }; template class FIQuery, Segment3> { public: struct Result { bool intersect; // The segment is clipped against the plane defining the // halfspace. The 'numPoints' is either 0 (no intersection), // 1 (point), or 2 (segment). int numPoints; Vector3 point[2]; }; Result operator()(Halfspace3 const& halfspace, Segment3 const& segment) { // Determine on which side of the plane the endpoints lie. The // table of possibilities is listed next with n = numNegative, // p = numPositive, and z = numZero. // // n p z intersection // ------------------------- // 0 2 0 segment (original) // 0 1 1 segment (original) // 0 0 2 segment (original) // 1 1 0 segment (clipped) // 1 0 1 point (endpoint) // 2 0 0 none Real s[2]; int numPositive = 0, numNegative = 0, numZero = 0; for (int i = 0; i < 2; ++i) { s[i] = Dot(halfspace.normal, segment.p[i]) - halfspace.constant; if (s[i] > (Real)0) { ++numPositive; } else if (s[i] < (Real)0) { ++numNegative; } else { ++numZero; } } Result result; if (numNegative == 0) { // The segment is in the halfspace. result.intersect = true; result.numPoints = 2; result.point[0] = segment.p[0]; result.point[1] = segment.p[1]; } else if (numNegative == 1) { result.intersect = true; result.numPoints = 1; if (numPositive == 1) { // The segment is intersected at an interior point. result.point[0] = segment.p[0] + (s[0] / (s[0] - s[1])) * (segment.p[1] - segment.p[0]); } else // numZero = 1 { // One segment endpoint is on the plane. if (s[0] == (Real)0) { result.point[0] = segment.p[0]; } else { result.point[0] = segment.p[1]; } } } else // numNegative == 2 { // The segment is outside the halfspace. (numNegative == 2) result.intersect = false; result.numPoints = 0; } return result; } }; }