// 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 namespace WwiseGTE { template class DCPQuery, AlignedBox> { public: struct Result { Real distance, sqrDistance; Vector boxClosest; }; Result operator()(Vector const& point, AlignedBox const& box) { // Translate the point and box so that the box has center at the // origin. Vector boxCenter, boxExtent; box.GetCenteredForm(boxCenter, boxExtent); Vector closest = point - boxCenter; Result result; DoQuery(closest, boxExtent, result); // Compute the closest point on the box. result.boxClosest = boxCenter + closest; return result; } protected: // On input, 'point' is the difference of the query point and the box // center. On output, 'point' is the point on the box closest to the // query point. void DoQuery(Vector& point, Vector const& boxExtent, Result& result) { result.sqrDistance = (Real)0; for (int i = 0; i < N; ++i) { if (point[i] < -boxExtent[i]) { Real delta = point[i] + boxExtent[i]; result.sqrDistance += delta * delta; point[i] = -boxExtent[i]; } else if (point[i] > boxExtent[i]) { Real delta = point[i] - boxExtent[i]; result.sqrDistance += delta * delta; point[i] = boxExtent[i]; } } result.distance = std::sqrt(result.sqrDistance); } }; // Template aliases for convenience. template using DCPPointAlignedBox = DCPQuery, AlignedBox>; template using DCPPoint2AlignedBox2 = DCPPointAlignedBox<2, Real>; template using DCPPoint3AlignedBox3 = DCPPointAlignedBox<3, Real>; }