123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
- // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
- // SPDX-License-Identifier: MIT
- #pragma once
- #include <Jolt/Core/NonCopyable.h>
- //#define JPH_CONVEX_BUILDER_2D_DEBUG
- JPH_NAMESPACE_BEGIN
- /// A convex hull builder that tries to create 2D hulls as accurately as possible. Used for offline processing.
- class JPH_EXPORT ConvexHullBuilder2D : public NonCopyable
- {
- public:
- using Positions = Array<Vec3>;
- using Edges = Array<int>;
- /// Constructor
- /// @param inPositions Positions used to make the hull. Uses X and Y component of Vec3 only!
- explicit ConvexHullBuilder2D(const Positions &inPositions);
- /// Destructor
- ~ConvexHullBuilder2D();
- /// Result enum that indicates how the hull got created
- enum class EResult
- {
- Success, ///< Hull building finished successfully
- MaxVerticesReached, ///< Hull building finished successfully, but the desired accuracy was not reached because the max vertices limit was reached
- };
- /// Takes all positions as provided by the constructor and use them to build a hull
- /// Any points that are closer to the hull than inTolerance will be discarded
- /// @param inIdx1 , inIdx2 , inIdx3 The indices to use as initial hull (in any order)
- /// @param inMaxVertices Max vertices to allow in the hull. Specify INT_MAX if there is no limit.
- /// @param inTolerance Max distance that a point is allowed to be outside of the hull
- /// @param outEdges On success this will contain the list of indices that form the hull (counter clockwise)
- /// @return Status code that reports if the hull was created or not
- EResult Initialize(int inIdx1, int inIdx2, int inIdx3, int inMaxVertices, float inTolerance, Edges &outEdges);
- private:
- #ifdef JPH_CONVEX_BUILDER_2D_DEBUG
- /// Factor to scale convex hull when debug drawing the construction process
- static constexpr Real cDrawScale = 10;
- #endif
- class Edge;
- /// Frees all edges
- void FreeEdges();
- /// Assigns a position to one of the supplied edges based on which edge is closest.
- /// @param inPositionIdx Index of the position to add
- /// @param inEdges List of edges to consider
- void AssignPointToEdge(int inPositionIdx, const Array<Edge *> &inEdges) const;
- #ifdef JPH_CONVEX_BUILDER_2D_DEBUG
- /// Draw state of algorithm
- void DrawState();
- #endif
- #ifdef JPH_ENABLE_ASSERTS
- /// Validate that the edge structure is intact
- void ValidateEdges() const;
- #endif
- using ConflictList = Array<int>;
- /// Linked list of edges
- class Edge
- {
- public:
- JPH_OVERRIDE_NEW_DELETE
- /// Constructor
- explicit Edge(int inStartIdx) : mStartIdx(inStartIdx) { }
- /// Calculate the center of the edge and the edge normal
- void CalculateNormalAndCenter(const Vec3 *inPositions);
- /// Check if this edge is facing inPosition
- inline bool IsFacing(Vec3Arg inPosition) const { return mNormal.Dot(inPosition - mCenter) > 0.0f; }
- Vec3 mNormal; ///< Normal of the edge (not normalized)
- Vec3 mCenter; ///< Center of the edge
- 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.
- Edge * mPrevEdge = nullptr; ///< Previous edge in cicular list
- Edge * mNextEdge = nullptr; ///< Next edge in circular list
- int mStartIdx; ///< Position index of start of this edge
- float mFurthestPointDistanceSq = 0.0f; ///< Squared distance of furtest point from the conflict list to the edge
- };
- const Positions & mPositions; ///< List of positions (some of them are part of the hull)
- Edge * mFirstEdge = nullptr; ///< First edge of the hull
- int mNumEdges = 0; ///< Number of edges in hull
- #ifdef JPH_CONVEX_BUILDER_2D_DEBUG
- RVec3 mOffset; ///< Offset to use for state drawing
- Vec3 mDelta; ///< Delta offset between next states
- #endif
- };
- JPH_NAMESPACE_END
|