ConvexPolyhedron3.h 3.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // David Eberly, Geometric Tools, Redmond WA 98052
  2. // Copyright (c) 1998-2020
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // https://www.boost.org/LICENSE_1_0.txt
  5. // https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
  6. // Version: 4.0.2019.08.13
  7. #pragma once
  8. #include <Mathematics/AlignedBox.h>
  9. #include <Mathematics/Vector4.h>
  10. #include <cstdint>
  11. #include <vector>
  12. namespace WwiseGTE
  13. {
  14. template <typename Real>
  15. class ConvexPolyhedron3
  16. {
  17. public:
  18. // Construction. The convex polyhedra represented by this class has
  19. // triangle faces that are counterclockwise ordered when viewed from
  20. // outside the polyhedron. No attempt is made to verify that the
  21. // polyhedron is convex; the caller is responsible for enforcing this.
  22. // The constructors move (not copy!) the input arrays. The
  23. // constructor succeeds when the number of vertices is at least 4 and
  24. // the number of indices is at least 12. If the constructor fails,
  25. // no move occurs and the member arrays have no elements.
  26. //
  27. // To support geometric algorithms that are formulated using convex
  28. // quadratic programming (such as computing the distance from a point
  29. // to a convex polyhedron), it is necessary to know the planes of the
  30. // faces and an axis-aligned bounding box. If you want either the
  31. // faces or the box, pass 'true' to the appropriate parameters. When
  32. // planes are generated, the normals are not created to be unit length
  33. // in order to support queries using exact rational arithmetic. If a
  34. // normal to a face is N = (n0,n1,n2) and V is a vertex of the face,
  35. // the plane is Dot(N,X-V) = 0 and is stored as
  36. // Dot(n0,n1,n2,-Dot(N,V)). The normals are computed to be outer
  37. // pointing.
  38. ConvexPolyhedron3() = default;
  39. ConvexPolyhedron3(std::vector<Vector3<Real>>&& inVertices, std::vector<int>&& inIndices,
  40. bool wantPlanes, bool wantAlignedBox)
  41. {
  42. if (inVertices.size() >= 4 && inIndices.size() >= 12)
  43. {
  44. vertices = std::move(inVertices);
  45. indices = std::move(inIndices);
  46. if (wantPlanes)
  47. {
  48. GeneratePlanes();
  49. }
  50. if (wantAlignedBox)
  51. {
  52. GenerateAlignedBox();
  53. }
  54. }
  55. }
  56. // If you modifty the vertices or indices and you want the new face
  57. // planes or aligned box computed, call these functions.
  58. void GeneratePlanes()
  59. {
  60. if (vertices.size() > 0 && indices.size() > 0)
  61. {
  62. uint32_t const numTriangles = static_cast<uint32_t>(indices.size()) / 3;
  63. planes.resize(numTriangles);
  64. for (uint32_t t = 0, i = 0; t < numTriangles; ++t)
  65. {
  66. Vector3<Real> V0 = vertices[indices[i++]];
  67. Vector3<Real> V1 = vertices[indices[i++]];
  68. Vector3<Real> V2 = vertices[indices[i++]];
  69. Vector3<Real> E1 = V1 - V0;
  70. Vector3<Real> E2 = V2 - V0;
  71. Vector3<Real> N = Cross(E1, E2);
  72. planes[t] = HLift(N, -Dot(N, V0));
  73. }
  74. }
  75. }
  76. void GenerateAlignedBox()
  77. {
  78. if (vertices.size() > 0 && indices.size() > 0)
  79. {
  80. ComputeExtremes(static_cast<int>(vertices.size()), vertices.data(),
  81. alignedBox.min, alignedBox.max);
  82. }
  83. }
  84. std::vector<Vector3<Real>> vertices;
  85. std::vector<int> indices;
  86. std::vector<Vector4<Real>> planes;
  87. AlignedBox3<Real> alignedBox;
  88. };
  89. }