ConvexHullBuilder2D.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #pragma once
  4. #include <Jolt/Core/NonCopyable.h>
  5. //#define JPH_CONVEX_BUILDER_2D_DEBUG
  6. JPH_NAMESPACE_BEGIN
  7. /// A convex hull builder that tries to create 2D hulls as accurately as possible. Used for offline processing.
  8. class ConvexHullBuilder2D : public NonCopyable
  9. {
  10. public:
  11. using Positions = Array<Vec3>;
  12. using Edges = Array<int>;
  13. /// Constructor
  14. /// @param inPositions Positions used to make the hull. Uses X and Y component of Vec3 only!
  15. explicit ConvexHullBuilder2D(const Positions &inPositions);
  16. /// Destructor
  17. ~ConvexHullBuilder2D();
  18. /// Result enum that indicates how the hull got created
  19. enum class EResult
  20. {
  21. Success, ///< Hull building finished successfully
  22. MaxVerticesReached, ///< Hull building finished successfully, but the desired accuracy was not reached because the max vertices limit was reached
  23. };
  24. /// Takes all positions as provided by the constructor and use them to build a hull
  25. /// Any points that are closer to the hull than inTolerance will be discarded
  26. /// @param inIdx1 , inIdx2 , inIdx3 The indices to use as initial hull (in any order)
  27. /// @param inMaxVertices Max vertices to allow in the hull. Specify INT_MAX if there is no limit.
  28. /// @param inTolerance Max distance that a point is allowed to be outside of the hull
  29. /// @param outEdges On success this will contain the list of indices that form the hull (counter clockwise)
  30. /// @return Status code that reports if the hull was created or not
  31. EResult Initialize(int inIdx1, int inIdx2, int inIdx3, int inMaxVertices, float inTolerance, Edges &outEdges);
  32. private:
  33. #ifdef JPH_CONVEX_BUILDER_2D_DEBUG
  34. /// Factor to scale convex hull when debug drawing the construction process
  35. static constexpr float cDrawScale = 10.0f;
  36. #endif
  37. class Edge;
  38. /// Frees all edges
  39. void FreeEdges();
  40. /// Assigns a position to one of the supplied edges based on which edge is closest.
  41. /// @param inPositionIdx Index of the position to add
  42. /// @param inEdges List of edges to consider
  43. void AssignPointToEdge(int inPositionIdx, const Array<Edge *> &inEdges) const;
  44. #ifdef JPH_CONVEX_BUILDER_2D_DEBUG
  45. /// Draw state of algorithm
  46. void DrawState();
  47. #endif
  48. #ifdef JPH_ENABLE_ASSERTS
  49. /// Validate that the edge structure is intact
  50. void ValidateEdges() const;
  51. #endif
  52. using ConflictList = Array<int>;
  53. /// Linked list of edges
  54. class Edge
  55. {
  56. public:
  57. JPH_OVERRIDE_NEW_DELETE
  58. /// Constructor
  59. explicit Edge(int inStartIdx) : mStartIdx(inStartIdx) { }
  60. /// Calculate the center of the edge and the edge normal
  61. void CalculateNormalAndCenter(const Vec3 *inPositions);
  62. /// Check if this edge is facing inPosition
  63. inline bool IsFacing(Vec3Arg inPosition) const { return mNormal.Dot(inPosition - mCenter) > 0.0f; }
  64. Vec3 mNormal; ///< Normal of the edge (not normalized)
  65. Vec3 mCenter; ///< Center of the edge
  66. ConflictList mConflictList; ///< Positions associated with this edge (that are closest to this edge). Last entry is the one furthest away from the edge, remainder is unsorted.
  67. Edge * mPrevEdge = nullptr; ///< Previous edge in cicular list
  68. Edge * mNextEdge = nullptr; ///< Next edge in circular list
  69. int mStartIdx; ///< Position index of start of this edge
  70. float mFurthestPointDistanceSq = 0.0f; ///< Squared distance of furtest point from the conflict list to the edge
  71. };
  72. const Positions & mPositions; ///< List of positions (some of them are part of the hull)
  73. Edge * mFirstEdge = nullptr; ///< First edge of the hull
  74. int mNumEdges = 0; ///< Number of edges in hull
  75. #ifdef JPH_CONVEX_BUILDER_2D_DEBUG
  76. Vec3 mOffset; ///< Offset to use for state drawing
  77. Vec3 mDelta; ///< Delta offset between next states
  78. #endif
  79. };
  80. JPH_NAMESPACE_END