// 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 namespace WwiseGTE { template class ConvexPolyhedron3 { public: // Construction. The convex polyhedra represented by this class has // triangle faces that are counterclockwise ordered when viewed from // outside the polyhedron. No attempt is made to verify that the // polyhedron is convex; the caller is responsible for enforcing this. // The constructors move (not copy!) the input arrays. The // constructor succeeds when the number of vertices is at least 4 and // the number of indices is at least 12. If the constructor fails, // no move occurs and the member arrays have no elements. // // To support geometric algorithms that are formulated using convex // quadratic programming (such as computing the distance from a point // to a convex polyhedron), it is necessary to know the planes of the // faces and an axis-aligned bounding box. If you want either the // faces or the box, pass 'true' to the appropriate parameters. When // planes are generated, the normals are not created to be unit length // in order to support queries using exact rational arithmetic. If a // normal to a face is N = (n0,n1,n2) and V is a vertex of the face, // the plane is Dot(N,X-V) = 0 and is stored as // Dot(n0,n1,n2,-Dot(N,V)). The normals are computed to be outer // pointing. ConvexPolyhedron3() = default; ConvexPolyhedron3(std::vector>&& inVertices, std::vector&& inIndices, bool wantPlanes, bool wantAlignedBox) { if (inVertices.size() >= 4 && inIndices.size() >= 12) { vertices = std::move(inVertices); indices = std::move(inIndices); if (wantPlanes) { GeneratePlanes(); } if (wantAlignedBox) { GenerateAlignedBox(); } } } // If you modifty the vertices or indices and you want the new face // planes or aligned box computed, call these functions. void GeneratePlanes() { if (vertices.size() > 0 && indices.size() > 0) { uint32_t const numTriangles = static_cast(indices.size()) / 3; planes.resize(numTriangles); for (uint32_t t = 0, i = 0; t < numTriangles; ++t) { Vector3 V0 = vertices[indices[i++]]; Vector3 V1 = vertices[indices[i++]]; Vector3 V2 = vertices[indices[i++]]; Vector3 E1 = V1 - V0; Vector3 E2 = V2 - V0; Vector3 N = Cross(E1, E2); planes[t] = HLift(N, -Dot(N, V0)); } } } void GenerateAlignedBox() { if (vertices.size() > 0 && indices.size() > 0) { ComputeExtremes(static_cast(vertices.size()), vertices.data(), alignedBox.min, alignedBox.max); } } std::vector> vertices; std::vector indices; std::vector> planes; AlignedBox3 alignedBox; }; }