diff --git a/Documentation/Doxyfile b/Documentation/Doxyfile index 040b3be0d3..1d101ac036 100644 --- a/Documentation/Doxyfile +++ b/Documentation/Doxyfile @@ -435,7 +435,7 @@ LOOKUP_CACHE_SIZE = 0 # normally produced when WARNINGS is set to YES. # The default value is: NO. -EXTRACT_ALL = YES +EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # be included in the documentation. diff --git a/PlayRho/Collision/AABB.hpp b/PlayRho/Collision/AABB.hpp index f2a56d5c28..742bc26b18 100644 --- a/PlayRho/Collision/AABB.hpp +++ b/PlayRho/Collision/AABB.hpp @@ -192,6 +192,7 @@ namespace playrho }; }; + /// @brief Gets an invalid AABB value. template <> constexpr AABB GetInvalid() noexcept { @@ -204,6 +205,7 @@ namespace playrho return (aabb.GetLowerBound() + aabb.GetUpperBound()) / Real{2}; } + /// @brief Gets dimensions of the given AABB. constexpr Length2D GetDimensions(const AABB aabb) noexcept { return aabb.GetUpperBound() - aabb.GetLowerBound(); @@ -224,35 +226,41 @@ namespace playrho return (GetX(dimensions) + GetY(dimensions)) * Real{2}; } + /// @brief Gets the AABB that minimally encloses the given AABBs. constexpr AABB GetEnclosingAABB(AABB a, AABB b) { return a.Include(b); } + /// @brief Gets the AABB that the result of displacing the given AABB by the given + /// displacement amount. constexpr AABB GetDisplacedAABB(AABB aabb, const Length2D displacement) { aabb.Displace(displacement); return aabb; } - + + /// @brief Gets the fattened AABB result. constexpr AABB GetFattenedAABB(AABB aabb, const Length amount) { aabb.Fatten(amount); return aabb; } + /// @brief Gets whether the two AABB objects are equal. constexpr bool operator== (const AABB lhs, const AABB rhs) { return (lhs.GetLowerBound() == rhs.GetLowerBound()) && (lhs.GetUpperBound() == rhs.GetUpperBound()); } + /// @brief Gets whether the two AABB objects are not equal. constexpr bool operator!= (const AABB lhs, const AABB rhs) { return !(lhs == rhs); } - // Tests for overlap between two axis aligned bounding boxes. - // @note This function's complexity is constant. + /// @brief Tests for overlap between two axis aligned bounding boxes. + /// @note This function's complexity is constant. constexpr bool TestOverlap(const AABB a, const AABB b) noexcept { const auto d1 = b.GetLowerBound() - a.GetUpperBound(); @@ -271,8 +279,10 @@ namespace playrho /// @return AABB for the proxy shape or the default AABB if the proxy has a zero vertex count. AABB ComputeAABB(const DistanceProxy& proxy, const Transformation xf) noexcept; + /// @brief Computes the AABB for the given shape with the given transformation. AABB ComputeAABB(const Shape& shape, const Transformation xf); + /// @brief Computes the AABB for the given body. AABB ComputeAABB(const Body& body); /// Gets the fixture's AABB. diff --git a/PlayRho/Collision/Collision.hpp b/PlayRho/Collision/Collision.hpp index 846267a055..07badf6b70 100644 --- a/PlayRho/Collision/Collision.hpp +++ b/PlayRho/Collision/Collision.hpp @@ -34,8 +34,9 @@ namespace playrho { class Manifold; - -/// This is used for determining the state of contact points. + +/// @brief Point state enumeration. +/// @note This is used for determining the state of contact points. enum class PointState { NullState, ///< point does not exist @@ -49,14 +50,18 @@ enum class PointState /// So state1 is either persist or remove while state2 is either add or persist. struct PointStates { + /// @brief State 1. PointState state1[MaxManifoldPoints] = {PointState::NullState, PointState::NullState}; + + /// @brief State 2. PointState state2[MaxManifoldPoints] = {PointState::NullState, PointState::NullState}; }; /// @brief Computes the point states given two manifolds. PointStates GetPointStates(const Manifold& manifold1, const Manifold& manifold2) noexcept; -/// Used for computing contact manifolds. +/// @brief Clip vertex. +/// @details Used for computing contact manifolds. /// @note This data structure is 12-bytes large (on at least one 64-bit platform). struct ClipVertex { @@ -64,7 +69,7 @@ struct ClipVertex ContactFeature cf; ///< Contact feature information. 4-bytes. }; -/// Clip list for ClipSegmentToLine. +/// @brief Clip list for ClipSegmentToLine. /// @sa ClipSegmentToLine. /// @note This data structure is at least 24-bytes large. using ClipList = ArrayList; diff --git a/PlayRho/Collision/ContactFeature.hpp b/PlayRho/Collision/ContactFeature.hpp index 2d175cd317..f8cfa2b60c 100644 --- a/PlayRho/Collision/ContactFeature.hpp +++ b/PlayRho/Collision/ContactFeature.hpp @@ -40,6 +40,7 @@ struct ContactFeature { using Index = std::uint8_t; ///< Index type. + /// @brief Type of the associated index value. enum Type : std::uint8_t { e_vertex = 0, @@ -54,42 +55,48 @@ struct ContactFeature Index indexB; ///< Feature index on shape B }; +/// @brief Gets the vertex vertex contact feature for the given indices. constexpr ContactFeature GetVertexVertexContactFeature(ContactFeature::Index a, ContactFeature::Index b) noexcept { return ContactFeature{ContactFeature::e_vertex, a, ContactFeature::e_vertex, b}; } +/// @brief Gets the vertex face contact feature for the given indices. constexpr ContactFeature GetVertexFaceContactFeature(ContactFeature::Index a, ContactFeature::Index b) noexcept { return ContactFeature{ContactFeature::e_vertex, a, ContactFeature::e_face, b}; } +/// @brief Gets the face vertex contact feature for the given indices. constexpr ContactFeature GetFaceVertexContactFeature(ContactFeature::Index a, ContactFeature::Index b) noexcept { return ContactFeature{ContactFeature::e_face, a, ContactFeature::e_vertex, b}; } +/// @brief Gets the face face contact feature for the given indices. constexpr ContactFeature GetFaceFaceContactFeature(ContactFeature::Index a, ContactFeature::Index b) noexcept { return ContactFeature{ContactFeature::e_face, a, ContactFeature::e_face, b}; } -/// Flips contact features information. +/// @brief Flips contact features information. constexpr ContactFeature Flip(ContactFeature val) noexcept { return ContactFeature{val.typeB, val.indexB, val.typeA, val.indexA}; } +/// @brief Determines if the given two contact features are equal. constexpr bool operator==(ContactFeature lhs, ContactFeature rhs) noexcept { return (lhs.typeA == rhs.typeA) && (lhs.indexA == rhs.indexA) && (lhs.typeB == rhs.typeB) && (lhs.indexB == rhs.indexB); } +/// @brief Determines if the given two contact features are not equal. constexpr bool operator!=(ContactFeature lhs, ContactFeature rhs) noexcept { return !(lhs == rhs); diff --git a/PlayRho/Collision/Distance.cpp b/PlayRho/Collision/Distance.cpp index 3b2ba222b8..5fc68ee360 100644 --- a/PlayRho/Collision/Distance.cpp +++ b/PlayRho/Collision/Distance.cpp @@ -46,6 +46,7 @@ namespace { const DistanceProxy& proxyA, const Transformation& xfA, const DistanceProxy& proxyB, const Transformation& xfB) { + /// @brief Size type. using size_type = std::remove_const::type; Simplex::Edges simplexEdges; diff --git a/PlayRho/Collision/Distance.hpp b/PlayRho/Collision/Distance.hpp index c25dc7f0ea..fcc93efb13 100644 --- a/PlayRho/Collision/Distance.hpp +++ b/PlayRho/Collision/Distance.hpp @@ -30,8 +30,8 @@ namespace playrho /// Witness Points. struct WitnessPoints { - Length2D a; - Length2D b; + Length2D a; ///< Point A. + Length2D b; ///< Point B. }; /// Gets the witness points of the given simplex. @@ -40,15 +40,18 @@ namespace playrho /// Distance Configuration. struct DistanceConf { + /// @brief Iteration type. using iteration_type = std::remove_const::type; - Simplex::Cache cache; - iteration_type maxIterations = DefaultMaxDistanceIters; + Simplex::Cache cache; ///< Cache. + iteration_type maxIterations = DefaultMaxDistanceIters; ///< Max iterations. }; /// @brief Distance Output. struct DistanceOutput { + + /// @brief State of the distance output. enum State: std::uint8_t { Unknown, @@ -58,6 +61,7 @@ namespace playrho HitMaxIters }; + /// @brief Iteration type. using iteration_type = std::remove_const::type; Simplex simplex; ///< Simplex. diff --git a/PlayRho/Collision/DistanceProxy.hpp b/PlayRho/Collision/DistanceProxy.hpp index 9f836d1f00..8f15c6f4b6 100644 --- a/PlayRho/Collision/DistanceProxy.hpp +++ b/PlayRho/Collision/DistanceProxy.hpp @@ -45,10 +45,12 @@ namespace playrho /// @details Must be big enough to hold max posible count of vertices. using size_type = std::remove_const::type; + /// @brief Invalid index. static constexpr size_type InvalidIndex = static_cast(-1); DistanceProxy() = default; + /// @brief Copy constructor. constexpr DistanceProxy(const DistanceProxy& copy) noexcept: m_vertices{copy.m_vertices}, m_normals{copy.m_normals}, @@ -114,6 +116,7 @@ namespace playrho return m_vertices[index]; } + /// @brief Gets the normal for the given index. auto GetNormal(size_type index) const noexcept { assert(index != InvalidIndex); @@ -129,8 +132,10 @@ namespace playrho Length m_vertexRadius = Length{0}; ///< Radius of the vertices of the associated shape. }; + /// @brief Determines with the two given distance proxies are equal. bool operator== (const DistanceProxy& lhs, const DistanceProxy& rhs) noexcept; + /// @brief Determines with the two given distance proxies are not equal. inline bool operator!= (const DistanceProxy& lhs, const DistanceProxy& rhs) noexcept { return !(lhs == rhs); @@ -146,8 +151,10 @@ namespace playrho /// @sa GetVertexCount(). DistanceProxy::size_type GetSupportIndex(const DistanceProxy& proxy, const Vec2 d) noexcept; + /// @brief Finds the lowest right most vertex in the given collection. std::size_t FindLowestRightMostVertex(Span vertices); + /// @brief Gets the convex hull for the given collection of vertices as a vector. std::vector GetConvexHullAsVector(Span vertices); /// Tests a point for containment in the given distance proxy. diff --git a/PlayRho/Collision/DynamicTree.hpp b/PlayRho/Collision/DynamicTree.hpp index 88b2968bd2..675a1ff17a 100644 --- a/PlayRho/Collision/DynamicTree.hpp +++ b/PlayRho/Collision/DynamicTree.hpp @@ -43,8 +43,13 @@ class DynamicTree { public: + /// @brief Size type. using size_type = std::remove_const::type; + + /// @brief Query callback type. using QueryCallback = std::function; + + /// @brief For each callback type. using ForEachCallback = std::function; /// @brief Ray cast callback function. @@ -54,6 +59,7 @@ class DynamicTree /// @brief Invalid index value. static constexpr size_type InvalidIndex = static_cast(-1); + /// @brief Gets the default initial node capacity. static constexpr size_type GetDefaultInitialNodeCapacity() noexcept; /// @brief Constructing the tree initializes the node pool. @@ -62,9 +68,11 @@ class DynamicTree /// @brief Destroys the tree, freeing the node pool. ~DynamicTree() noexcept; + /// @brief Copy constructor. DynamicTree(const DynamicTree& copy); - DynamicTree& operator=(const DynamicTree& copy); + /// @brief Assignment operator. + DynamicTree& operator= (const DynamicTree& copy); /// @brief Creates a new proxy. /// @details Creates a proxy for a tight fitting AABB and a userData pointer. @@ -88,6 +96,7 @@ class DynamicTree /// @return User data for the specified node. void* GetUserData(const size_type index) const noexcept; + /// @brief Sets the user data for the element at the given index to the given value. void SetUserData(const size_type index, void* value) noexcept; /// @brief Gets the AABB for a proxy. @@ -99,6 +108,7 @@ class DynamicTree /// @note The callback instance is called for each proxy that overlaps the supplied AABB. void Query(const AABB aabb, QueryCallback callback) const; + /// @brief Calls the given callback for each of the entries overlapping the given AABB. void ForEach(const AABB aabb, ForEachCallback callback) const; /// @brief Ray-cast against the proxies in the tree. @@ -131,6 +141,7 @@ class DynamicTree /// @return true if valid, false otherwise. bool ValidateMetrics(size_type index) const noexcept; + /// @brief Gets the root index. size_type GetRootIndex() const noexcept; /// @brief Gets the height of the binary tree. @@ -170,6 +181,7 @@ class DynamicTree /// @brief Gets the current node capacity of this tree. size_type GetNodeCapacity() const noexcept; + /// @brief Sets the node capacity to the given value. void SetNodeCapacity(size_type value); /// @brief Gets the current node count. @@ -292,6 +304,7 @@ inline DynamicTree::size_type DynamicTree::ComputeHeight() const noexcept return ComputeHeight(GetRootIndex()); } +/// @brief Tests for overlap of the elements identified in the given dynamic tree. inline bool TestOverlap(const DynamicTree& tree, DynamicTree::size_type proxyIdA, DynamicTree::size_type proxyIdB) { diff --git a/PlayRho/Collision/IndexPair.hpp b/PlayRho/Collision/IndexPair.hpp index c56efa30c5..0740ab608f 100644 --- a/PlayRho/Collision/IndexPair.hpp +++ b/PlayRho/Collision/IndexPair.hpp @@ -34,20 +34,24 @@ namespace playrho /// @details Must be big enough to hold max posible count of vertices. using size_type = std::remove_const::type; + /// @brief Invalid index. static constexpr size_type InvalidIndex = static_cast(-1); size_type a; ///< Index of vertex from shape A. size_type b; ///< Index of vertex from shape B. }; + /// @brief Invalid index pair value. constexpr auto InvalidIndexPair = IndexPair{IndexPair::InvalidIndex, IndexPair::InvalidIndex}; - constexpr inline bool operator == (IndexPair lhs, IndexPair rhs) + /// @brief Determines whether the two given index pairs are equal. + constexpr inline bool operator== (IndexPair lhs, IndexPair rhs) { return (lhs.a == rhs.a) && (lhs.b == rhs.b); } - constexpr inline bool operator != (IndexPair lhs, IndexPair rhs) + /// @brief Determines whether the two given index pairs are not equal. + constexpr inline bool operator!= (IndexPair lhs, IndexPair rhs) { return (lhs.a != rhs.a) || (lhs.b != rhs.b); } @@ -58,6 +62,7 @@ namespace playrho static_assert(MaxSimplexEdges == 3, "Invalid assumption about size of MaxSimplexEdges"); + /// @brief Gets the number of valid indices in the given collection of index pairs. constexpr inline std::size_t GetNumIndices(IndexPair3 pairs) noexcept { return std::size_t{3} diff --git a/PlayRho/Collision/Manifold.hpp b/PlayRho/Collision/Manifold.hpp index 508038b09a..f6c9629562 100644 --- a/PlayRho/Collision/Manifold.hpp +++ b/PlayRho/Collision/Manifold.hpp @@ -59,11 +59,14 @@ namespace playrho class Manifold { public: + + /// @brief Size type. using size_type = std::remove_const::type; /// Shape index type. using sidx_t = std::remove_const::type; + /// @brief Contact feature type. using cf_t = ContactFeature::Type; struct Conf; @@ -231,6 +234,7 @@ namespace playrho return Manifold{e_faceB, ln, lp, 2, {{mp1, mp2}}}; } + /// @brief Gets the face A manifold for the given data. static inline Manifold GetForFaceA(UnitVec2 na, sidx_t ia, Length2D pa) noexcept { return Manifold{e_faceA, na, pa, 0, {{ @@ -239,6 +243,7 @@ namespace playrho }}}; } + /// @brief Gets the face B manifold for the given data. static inline Manifold GetForFaceB(UnitVec2 nb, sidx_t ib, Length2D pb) noexcept { return Manifold{e_faceB, nb, pb, 0, {{ @@ -247,6 +252,7 @@ namespace playrho }}}; } + /// @brief Gets the face A manifold for the given data. static inline Manifold GetForFaceA(UnitVec2 na, sidx_t ia, Length2D pa, cf_t tb0, sidx_t ib0, Length2D pb0) noexcept { @@ -256,6 +262,7 @@ namespace playrho }}}; } + /// @brief Gets the face B manifold for the given data. static inline Manifold GetForFaceB(UnitVec2 nb, sidx_t ib, Length2D pb, cf_t ta0, sidx_t ia0, Length2D pa0) noexcept { @@ -265,6 +272,7 @@ namespace playrho }}}; } + /// @brief Gets the face A manifold for the given data. static inline Manifold GetForFaceA(UnitVec2 na, sidx_t ia, Length2D pa, cf_t tb0, sidx_t ib0, Length2D pb0, cf_t tb1, sidx_t ib1, Length2D pb1) noexcept @@ -275,6 +283,7 @@ namespace playrho }}}; } + /// @brief Gets the face B manifold for the given data. static inline Manifold GetForFaceB(UnitVec2 nb, sidx_t ib, Length2D pb, cf_t ta0, sidx_t ia0, Length2D pa0, cf_t ta1, sidx_t ia1, Length2D pa1) noexcept @@ -292,6 +301,7 @@ namespace playrho /// point count is zero, point data is undefined, and all other properties are invalid. Manifold() = default; + /// @brief Copy constructor. Manifold(const Manifold& copy) = default; /// Gets the type of this manifold. @@ -315,18 +325,21 @@ namespace playrho /// constexpr size_type GetPointCount() const noexcept { return m_pointCount; } + /// @brief Gets the contact feature for the given index. constexpr ContactFeature GetContactFeature(size_type index) const noexcept { assert(index < m_pointCount); return m_points[index].contactFeature; } + /// @brief Gets the contact impulses for the given index. constexpr ContactImpulses GetContactImpulses(size_type index) const noexcept { assert(index < m_pointCount); return ContactImpulses{m_points[index].normalImpulse, m_points[index].tangentImpulse}; } + /// @brief Sets the contact impulses for the given index. void SetContactImpulses(size_type index, ContactImpulses value) noexcept { assert(index < m_pointCount); @@ -334,12 +347,14 @@ namespace playrho m_points[index].tangentImpulse = value.m_tangent; } + /// @brief Gets the point identified by the given index. const Point& GetPoint(size_type index) const noexcept { assert((0 <= index) && (index < m_pointCount)); return m_points[index]; } + /// @brief Sets the point impulses for the given index. void SetPointImpulses(size_type index, Momentum n, Momentum t) { assert((index < m_pointCount) || (index < MaxManifoldPoints && n == Momentum{0} && t == Momentum{0})); @@ -355,6 +370,7 @@ namespace playrho /// @warning Behavior is undefined if this is called more than twice. void AddPoint(const Point& mp) noexcept; + /// @brief Adds a new point with the given data. void AddPoint(cf_t type, sidx_t index, Length2D point) noexcept; /// @brief Gets the local normal for a face-type manifold. @@ -383,6 +399,7 @@ namespace playrho return m_localPoint; } + /// @brief Gets the opposing point. constexpr Length2D GetOpposingPoint(size_type index) const noexcept { assert((0 <= index) && (index < m_pointCount)); @@ -424,12 +441,14 @@ namespace playrho /// @brief Configuration data for manifold calculation. struct Manifold::Conf { + /// @brief Linear slop. Length linearSlop = DefaultLinearSlop; /// Targetted depth of impact. /// @note Value must be less than twice the minimum vertex radius of any shape. Length targetDepth = DefaultLinearSlop * Real{3}; + /// @brief Tolerance. Length tolerance = DefaultLinearSlop / Real{4}; ///< Tolerance. /// Max. circles ratio. @@ -439,20 +458,25 @@ namespace playrho Real maxCirclesRatio = DefaultCirclesRatio; }; + /// @brief Gets the default manifold configuration. constexpr inline Manifold::Conf GetDefaultManifoldConf() noexcept { return Manifold::Conf{}; } + /// @brief Determines whether the two given manifold points are equal. bool operator==(const Manifold::Point& lhs, const Manifold::Point& rhs) noexcept; + /// @brief Determines whether the two given manifold points are not equal. bool operator!=(const Manifold::Point& lhs, const Manifold::Point& rhs) noexcept; - /// Equality operator. + /// @brief Manifold equality operator. /// @note In-so-far as manifold points are concerned, order doesn't matter; /// only whether the two manifolds have the same point set. bool operator==(const Manifold& lhs, const Manifold& rhs) noexcept; + /// @brief Manifold inequality operator. + /// @details Determines whether the two given manifolds are not equal. bool operator!=(const Manifold& lhs, const Manifold& rhs) noexcept; constexpr inline Manifold::Manifold(Type t, UnitVec2 ln, Length2D lp, size_type n, @@ -503,6 +527,7 @@ namespace playrho } } + /// @brief Gets whether the given manifold is valid. template <> constexpr inline bool IsValid(const Manifold& value) noexcept { @@ -534,6 +559,7 @@ namespace playrho ContactFeature::Index index); #endif + /// @brief Gets a unique name for the given manifold type. const char* GetName(Manifold::Type) noexcept; } // namespace playrho diff --git a/PlayRho/Collision/MassData.hpp b/PlayRho/Collision/MassData.hpp index 5c5f7f9da8..d6562f1199 100644 --- a/PlayRho/Collision/MassData.hpp +++ b/PlayRho/Collision/MassData.hpp @@ -55,11 +55,13 @@ namespace playrho { NonNegative I = NonNegative{0}; }; + /// @brief MassData equality operator. constexpr bool operator== (MassData lhs, MassData rhs) { return lhs.center == rhs.center && lhs.mass == rhs.mass && lhs.I == rhs.I; } + /// @brief MassData inequality operator. constexpr bool operator!= (MassData lhs, MassData rhs) { return !(lhs == rhs); @@ -101,6 +103,8 @@ namespace playrho { MassData GetMassData(const Length r, const NonNegative density, const Length2D v0, const Length2D v1); + /// @brief Gets the mass data for the given collection of vertices with the given + /// properties. MassData GetMassData(const Length vertexRadius, const NonNegative density, Span vertices); diff --git a/PlayRho/Collision/RayCastOutput.hpp b/PlayRho/Collision/RayCastOutput.hpp index 342e0d60d1..632b17e151 100644 --- a/PlayRho/Collision/RayCastOutput.hpp +++ b/PlayRho/Collision/RayCastOutput.hpp @@ -46,6 +46,7 @@ namespace playrho UnitInterval fraction = UnitInterval{0}; }; + /// @brief Ray cast output. using RayCastOutput = Optional; /// @brief Cast a ray against a circle of a given radius at the given location. diff --git a/PlayRho/Collision/SeparationFinder.hpp b/PlayRho/Collision/SeparationFinder.hpp index c5310adb2b..112d96eaec 100644 --- a/PlayRho/Collision/SeparationFinder.hpp +++ b/PlayRho/Collision/SeparationFinder.hpp @@ -111,8 +111,13 @@ namespace playrho { return Length{0}; } + /// @brief Gets the type. constexpr Type GetType() const noexcept; + + /// @brief Gets the axis. constexpr UnitVec2 GetAxis() const noexcept; + + /// @brief Gets the local point. constexpr Length2D GetLocalPoint() const noexcept; private: diff --git a/PlayRho/Collision/ShapeSeparation.hpp b/PlayRho/Collision/ShapeSeparation.hpp index 0fde80966b..6b38eac2c3 100644 --- a/PlayRho/Collision/ShapeSeparation.hpp +++ b/PlayRho/Collision/ShapeSeparation.hpp @@ -30,37 +30,49 @@ namespace playrho /// @details This structure is used to keep track of the best separating axis. struct IndexSeparation { + + /// @brief Distance type. using distance_type = Length; + + /// @brief Index type. using index_type = std::remove_const::type; + /// @brief Gets the invalid distance. static constexpr distance_type GetInvalidDistance() noexcept { return std::numeric_limits::max() * Meter; } + /// @brief Index type. static constexpr index_type InvalidIndex = static_cast(-1); - distance_type separation = GetInvalidDistance(); - index_type index = InvalidIndex; + distance_type separation = GetInvalidDistance(); ///< Separation. + index_type index = InvalidIndex; ///< Index. }; /// Index pair separation. /// @details This structure is used to keep track of the best separating axis. struct IndexPairSeparation { + + /// @brief Distance type. using distance_type = Length; + + /// @brief Index type. using index_type = std::remove_const::type; + /// @brief Gets the invalid distance. static constexpr distance_type GetInvalidDistance() noexcept { return std::numeric_limits::max() * Meter; } + /// @brief Invalid index. static constexpr index_type InvalidIndex = static_cast(-1); - distance_type separation = GetInvalidDistance(); - index_type index1 = InvalidIndex; - index_type index2 = InvalidIndex; + distance_type separation = GetInvalidDistance(); ///< Separation. + index_type index1 = InvalidIndex; ///< Index 1. + index_type index2 = InvalidIndex; ///< Index 2. }; /// @brief Gets the max separation information. diff --git a/PlayRho/Collision/Shapes/ChainShape.hpp b/PlayRho/Collision/Shapes/ChainShape.hpp index 67a9e6cd01..9221932580 100644 --- a/PlayRho/Collision/Shapes/ChainShape.hpp +++ b/PlayRho/Collision/Shapes/ChainShape.hpp @@ -41,6 +41,8 @@ class EdgeShape; class ChainShape: public Shape { public: + + /// @brief Gets the default vertex radius. static constexpr Length GetDefaultVertexRadius() noexcept { return DefaultLinearSlop * Real{2}; @@ -57,13 +59,16 @@ class ChainShape: public Shape std::vector vertices; }; + /// @brief Gets the default configuration. static Conf GetDefaultConf() noexcept { return Conf{}; } + /// @brief Initializing constructor. ChainShape(const Conf& conf = GetDefaultConf()); + /// @brief Copy constructor. ChainShape(const ChainShape& other) = default; virtual ~ChainShape() = default; @@ -89,6 +94,7 @@ class ChainShape: public Shape /// Get a vertex by index. Length2D GetVertex(ChildCounter index) const; + /// @brief Gets the normal at the given index. UnitVec2 GetNormal(ChildCounter index) const; private: @@ -118,12 +124,14 @@ inline UnitVec2 ChainShape::GetNormal(ChildCounter index) const return m_normals[index]; } +/// @brief Determines whether the given shape is looped. inline bool IsLooped(const ChainShape& shape) noexcept { const auto count = shape.GetVertexCount(); return (count > 1)? (shape.GetVertex(count - 1) == shape.GetVertex(0)): false; } +/// @brief Gets the next index after the given index for the given shape. inline ChildCounter GetNextIndex(const ChainShape& shape, ChildCounter index) noexcept { return GetModuloNext(index, shape.GetVertexCount()); diff --git a/PlayRho/Collision/Shapes/DiskShape.hpp b/PlayRho/Collision/Shapes/DiskShape.hpp index 96a33067cd..a284c971e3 100644 --- a/PlayRho/Collision/Shapes/DiskShape.hpp +++ b/PlayRho/Collision/Shapes/DiskShape.hpp @@ -37,6 +37,7 @@ class DiskShape : public Shape { public: + /// @brief Gets the default radius. static constexpr Length GetDefaultRadius() noexcept { return DefaultLinearSlop * Real{2}; @@ -59,6 +60,7 @@ class DiskShape : public Shape Length2D location = Length2D{}; }; + /// @brief Gets the default configuration. static constexpr Conf GetDefaultConf() noexcept; /// Initializing constructor. @@ -68,15 +70,18 @@ class DiskShape : public Shape // Intentionally empty. } + /// @brief Initializing constructor. explicit DiskShape(const Length radius, const Conf& conf = GetDefaultConf()) noexcept: Shape{conf}, m_location{conf.location} { SetVertexRadius(radius); } + /// @brief Copy constructor. DiskShape(const DiskShape&) = default; - DiskShape& operator=(const DiskShape& other) = default; + /// @brief Assignment operator. + DiskShape& operator= (const DiskShape& other) = default; /// Gets the number of child primitives. /// @return Positive non-zero count. @@ -91,12 +96,14 @@ class DiskShape : public Shape /// @return Mass data for this shape. MassData GetMassData() const noexcept override; + /// @brief Accepts the given visitor. void Accept(Visitor& visitor) const override; /// Gets the "radius" of the shape. /// @return Non-negative distance. Length GetRadius() const noexcept { return GetVertexRadius(); } + /// @brief Sets the radius to the given value. void SetRadius(Length radius) noexcept { SetVertexRadius(radius); @@ -108,6 +115,7 @@ class DiskShape : public Shape /// @sa SetPosition. Length2D GetLocation() const noexcept { return m_location; } + /// @brief Sets the location to the given value. void SetLocation(const Length2D value) noexcept { m_location = value; } private: diff --git a/PlayRho/Collision/Shapes/EdgeShape.hpp b/PlayRho/Collision/Shapes/EdgeShape.hpp index 8f70d05258..8c62774243 100644 --- a/PlayRho/Collision/Shapes/EdgeShape.hpp +++ b/PlayRho/Collision/Shapes/EdgeShape.hpp @@ -35,6 +35,8 @@ namespace playrho { class EdgeShape : public Shape { public: + + /// @brief Gets the default vertex radius. static constexpr Length GetDefaultVertexRadius() noexcept { return DefaultLinearSlop * Real{2}; @@ -59,15 +61,17 @@ class EdgeShape : public Shape return *this; } - Length2D vertex1 = Length2D{}; - Length2D vertex2 = Length2D{}; + Length2D vertex1 = Length2D{}; ///< Vertex 1. + Length2D vertex2 = Length2D{}; ///< Vertex 2. }; + /// @brief Gets the default configuration for an EdgeShape. static constexpr Conf GetDefaultConf() noexcept { return Conf{}; } + /// @brief Initializing constructor. EdgeShape(const Conf& conf = GetDefaultConf()) noexcept: Shape{conf}, m_vertices{conf.vertex1, conf.vertex2} @@ -76,6 +80,7 @@ class EdgeShape : public Shape m_normals[1] = -m_normals[0]; } + /// @brief Initializing constructor. EdgeShape(Length2D v1, Length2D v2, const Conf& conf = GetDefaultConf()) noexcept: Shape{conf}, m_vertices{v1, v2} @@ -84,6 +89,7 @@ class EdgeShape : public Shape m_normals[1] = -m_normals[0]; } + /// @brief Copy constructor. EdgeShape(const EdgeShape&) = default; /// @brief Gets the number of child primitives. @@ -104,10 +110,16 @@ class EdgeShape : public Shape /// @brief Sets this as an isolated edge. void Set(const Length2D v1, const Length2D v2); + /// @brief Gets vertex number 1 (of 2). Length2D GetVertex1() const noexcept { return m_vertices[0]; } + + /// @brief Gets vertex number 2 (of 2). Length2D GetVertex2() const noexcept { return m_vertices[1]; } + /// @brief Gets normal number 1 (of 2). UnitVec2 GetNormal1() const noexcept { return m_normals[0]; } + + /// @brief Gets normal number 2 (of 2). UnitVec2 GetNormal2() const noexcept { return m_normals[1]; } private: diff --git a/PlayRho/Collision/Shapes/MultiShape.hpp b/PlayRho/Collision/Shapes/MultiShape.hpp index 63eb24d354..76b3ec2a48 100644 --- a/PlayRho/Collision/Shapes/MultiShape.hpp +++ b/PlayRho/Collision/Shapes/MultiShape.hpp @@ -40,8 +40,10 @@ namespace playrho { /// using VertexCounter = std::remove_const::type; + /// @brief Invalid vertex. static constexpr auto InvalidVertex = static_cast(-1); + /// @brief Gets the default vertex radius for the MultiShape. static constexpr Length GetDefaultVertexRadius() noexcept { return DefaultLinearSlop * Real{2}; @@ -56,6 +58,7 @@ namespace playrho { } }; + /// @brief Gets the default configuration for a MultiShape. static constexpr Conf GetDefaultConf() noexcept { return Conf{}; @@ -71,6 +74,7 @@ namespace playrho { // Intentionally empty. } + /// @brief Copy constructor. MultiShape(const MultiShape&) = default; /// @brief Gets the number of child primitives. diff --git a/PlayRho/Collision/Shapes/PolygonShape.hpp b/PlayRho/Collision/Shapes/PolygonShape.hpp index 0b9e781db0..e3f136c5af 100644 --- a/PlayRho/Collision/Shapes/PolygonShape.hpp +++ b/PlayRho/Collision/Shapes/PolygonShape.hpp @@ -44,9 +44,10 @@ class PolygonShape : public Shape /// using VertexCounter = std::remove_const::type; - + /// @brief Invalid vertex. static constexpr auto InvalidVertex = static_cast(-1); + /// @brief Gets the default vertex radius for the PolygonShape. static constexpr Length GetDefaultVertexRadius() noexcept { return DefaultLinearSlop * Real{2}; @@ -61,6 +62,7 @@ class PolygonShape : public Shape } }; + /// @brief Gets the default configuration for a PolygonShape. static constexpr Conf GetDefaultConf() noexcept { return Conf{}; @@ -76,6 +78,7 @@ class PolygonShape : public Shape // Intentionally empty. } + /// @brief Copy constructor. PolygonShape(const PolygonShape&) = default; /// Initializing constructor for rectangles. @@ -125,6 +128,7 @@ class PolygonShape : public Shape /// @param hy the half-height. void SetAsBox(Length hx, Length hy) noexcept; + /// @brief Transforms this polygon by the given transformation. PolygonShape& Transform(Transformation xfm) noexcept; /// Gets the vertex count. @@ -151,11 +155,13 @@ class PolygonShape : public Shape return Span(&m_vertices[0], GetVertexCount()); } + /// @brief Gets the span of normals. Span GetNormals() const noexcept { return Span(&m_normals[0], GetVertexCount()); } + /// @brief Gets the centroid. Length2D GetCentroid() const noexcept { return m_centroid; } private: @@ -229,6 +235,7 @@ bool Validate(const PolygonShape& shape); /// @param angle the rotation of the box in local coordinates. void SetAsBox(PolygonShape& shape, Length hx, Length hy, const Length2D center, Angle angle) noexcept; +/// @brief Transforms the given shape by the given transformation. inline PolygonShape Transform(PolygonShape value, Transformation xfm) noexcept { return value.Transform(xfm); diff --git a/PlayRho/Collision/Shapes/Shape.hpp b/PlayRho/Collision/Shapes/Shape.hpp index 8c913be305..07a6dd2dbe 100644 --- a/PlayRho/Collision/Shapes/Shape.hpp +++ b/PlayRho/Collision/Shapes/Shape.hpp @@ -98,9 +98,16 @@ class Shape template struct Builder: Conf { + /// @brief Uses the given vertex radius. constexpr ConcreteConf& UseVertexRadius(NonNegative value) noexcept; + + /// @brief Uses the given friction. constexpr ConcreteConf& UseFriction(NonNegative value) noexcept; + + /// @brief Uses the given restitution. constexpr ConcreteConf& UseRestitution(Finite value) noexcept; + + /// @brief Uses the given density. constexpr ConcreteConf& UseDensity(NonNegative value) noexcept; }; @@ -121,6 +128,7 @@ class Shape // Intentionally empty. } + /// @brief Copy constructor. Shape(const Shape&) = default; virtual ~Shape() = default; @@ -241,31 +249,37 @@ class Shape::Visitor public: virtual ~Visitor() = default; + /// @brief Visits a DiskShape. virtual void Visit(const DiskShape&) { visited = true; } + /// @brief Visits an EdgeShape. virtual void Visit(const EdgeShape&) { visited = true; } + /// @brief Visits a PolygonShape. virtual void Visit(const PolygonShape&) { visited = true; } + /// @brief Visits a ChainShape. virtual void Visit(const ChainShape&) { visited = true; } + /// @brief Visits a MultiShape. virtual void Visit(const MultiShape&) { visited = true; } + /// @brief Is base visited. bool IsBaseVisited() const noexcept { return visited; diff --git a/PlayRho/Collision/Simplex.hpp b/PlayRho/Collision/Simplex.hpp index debe8bb90f..4812b68e63 100644 --- a/PlayRho/Collision/Simplex.hpp +++ b/PlayRho/Collision/Simplex.hpp @@ -81,8 +81,10 @@ namespace playrho public: Cache() = default; + /// @brief Copy constructor. Cache(const Cache& copy) = default; + /// @brief Initializing constructor. constexpr Cache(Real metric, IndexPair3 indices) noexcept; /// Gets the metric that was set. @@ -93,10 +95,13 @@ namespace playrho /// @return Value previously set. Real GetMetric() const noexcept; + /// @brief Is metric set. bool IsMetricSet() const noexcept; + /// @brief Gets indices. constexpr IndexPair3 GetIndices() const noexcept; + /// @brief Gets the index pair for the given index. constexpr IndexPair GetIndexPair(size_type index) const noexcept; private: @@ -104,6 +109,7 @@ namespace playrho IndexPair3 m_indices{InvalidIndexPair, InvalidIndexPair, InvalidIndexPair}; ///< Indices. @details Collection of index-pairs. }; + /// @brief Gets the cache value for the given edges. static Cache GetCache(const Simplex::Edges& edges) noexcept; /// Gets index pairs for the given edges collection. @@ -119,6 +125,7 @@ namespace playrho /// Gets the given simplex's "metric". static inline Real CalcMetric(const Edges& simplexEdges); + /// @brief Gets the Simplex for the given simplex edge. static Simplex Get(const SimplexEdge& s0) noexcept; /// Gets the simplex for the given 2 edges. @@ -148,12 +155,16 @@ namespace playrho Simplex() = default; + /// @brief Gets the edges. constexpr Edges GetEdges() const noexcept; + /// @brief Gets the give indexed simplex edge. const SimplexEdge& GetSimplexEdge(size_type index) const noexcept; + /// @brief Gets the coefficient for the given index. constexpr Real GetCoefficient(size_type index) const noexcept; + /// @brief Gets the size in number of simplex edges that this instance is made up of. constexpr size_type GetSize() const noexcept; private: @@ -300,6 +311,7 @@ namespace playrho return m_simplexEdges.size(); } + /// @brief Gets the scaled delta for the given indexed element of the given simplex. inline Length2D GetScaledDelta(const Simplex& simplex, Simplex::size_type index) { return GetPointDelta(simplex.GetSimplexEdge(index)) * simplex.GetCoefficient(index); diff --git a/PlayRho/Collision/SimplexEdge.hpp b/PlayRho/Collision/SimplexEdge.hpp index 79f16780b7..24e9984025 100644 --- a/PlayRho/Collision/SimplexEdge.hpp +++ b/PlayRho/Collision/SimplexEdge.hpp @@ -35,11 +35,14 @@ namespace playrho class SimplexEdge { public: + + /// @brief Index type. using index_type = IndexPair::size_type; /// Default constructor. SimplexEdge() = default; + /// @brief Copy constructor. constexpr SimplexEdge(const SimplexEdge& copy) = default; /// Initializing constructor. @@ -55,10 +58,13 @@ namespace playrho /// Gets point B (in world coordinates). constexpr auto GetPointB() const noexcept { return m_wB; } + /// @brief Gets index A. constexpr auto GetIndexA() const noexcept { return m_indexPair.a; } + /// @brief Gets index B. constexpr auto GetIndexB() const noexcept { return m_indexPair.b; } + /// @brief Gets the index pair. constexpr auto GetIndexPair() const noexcept { return m_indexPair; } private: @@ -79,14 +85,16 @@ namespace playrho return sv.GetPointB() - sv.GetPointA(); } - constexpr inline bool operator == (const SimplexEdge& lhs, const SimplexEdge& rhs) + /// @brief SimplexEdge equality operator. + constexpr inline bool operator== (const SimplexEdge& lhs, const SimplexEdge& rhs) { return (lhs.GetPointA() == rhs.GetPointA()) && (lhs.GetPointB() == rhs.GetPointB()) && (lhs.GetIndexPair() == rhs.GetIndexPair()); } - constexpr inline bool operator != (const SimplexEdge& lhs, const SimplexEdge& rhs) + /// @brief SimplexEdge inequality operator. + constexpr inline bool operator!= (const SimplexEdge& lhs, const SimplexEdge& rhs) { return !(lhs == rhs); } diff --git a/PlayRho/Collision/TimeOfImpact.hpp b/PlayRho/Collision/TimeOfImpact.hpp index 9a60711df8..ee7d5b2d85 100644 --- a/PlayRho/Collision/TimeOfImpact.hpp +++ b/PlayRho/Collision/TimeOfImpact.hpp @@ -28,7 +28,7 @@ namespace playrho { class Shape; class DistanceProxy; - /// Time of impact configuration. + /// @brief Time of impact configuration. /// /// @details These parameters effect time of impact calculations by limiting the definitions /// of time and impact. If total radius is expressed as TR, and target depth as TD, then: @@ -48,26 +48,43 @@ namespace playrho { /// struct ToiConf { + /// @brief Root iteration type. using root_iter_type = std::remove_const::type; + + /// @brief TOI iteration type. using toi_iter_type = std::remove_const::type; + + /// @brief Distance iteration type. using dist_iter_type = std::remove_const::type; + /// @brief Uses the given time max value. constexpr ToiConf& UseTimeMax(Real value) noexcept; + + /// @brief Uses the given target depth value. constexpr ToiConf& UseTargetDepth(Length value) noexcept; + + /// @brief Uses the given tolerance value. constexpr ToiConf& UseTolerance(Length value) noexcept; + + /// @brief Uses the given max root iterations value. constexpr ToiConf& UseMaxRootIters(root_iter_type value) noexcept; + + /// @brief Uses the given max TOI iterations value. constexpr ToiConf& UseMaxToiIters(toi_iter_type value) noexcept; + + /// @brief Uses the given max distance iterations value. constexpr ToiConf& UseMaxDistIters(dist_iter_type value) noexcept; + /// @brief T-Max. Real tMax = 1; - /// Targetted depth of impact. + /// @brief Targetted depth of impact. /// @note Value must be less than twice the minimum vertex radius of any shape. Length targetDepth = DefaultLinearSlop * Real{3}; Length tolerance = DefaultLinearSlop / Real{4}; ///< Tolerance. - /// Maximum number of root finder iterations. + /// @brief Maximum number of root finder iterations. /// @details This is the maximum number of iterations for calculating the 1D root of /// f(t) - (totalRadius - targetDepth) < tolerance /// where f(t) is the distance between the shapes at time t, @@ -78,9 +95,10 @@ namespace playrho { toi_iter_type maxToiIters = DefaultMaxToiIters; ///< Max time of impact iterations. - dist_iter_type maxDistIters = DefaultMaxDistanceIters; + dist_iter_type maxDistIters = DefaultMaxDistanceIters; ///< Max distance iterations. }; + /// @brief Gets the default time of impact configuration. constexpr auto GetDefaultToiConf() { return ToiConf{}; @@ -122,15 +140,27 @@ namespace playrho { return *this; } - /// TimeOfImpact Output data. + /// @brief TimeOfImpact Output data. class TOIOutput { public: + + /// @brief TOI iterations type. using toi_iter_type = std::remove_const::type; + + /// @brief Distance iterations type. using dist_iter_type = std::remove_const::type; + + /// @brief Root iterations type. using root_iter_type = std::remove_const::type; + + /// @brief TOI iterations sum type. using toi_sum_type = Wider::type; + + /// @brief Distance iterations sum type. using dist_sum_type = Wider::type; + + /// @brief Root iterations sum type. using root_sum_type = Wider::type; /// @brief Time of impact statistics. @@ -147,6 +177,7 @@ namespace playrho { root_sum_type sum_root_iters = 0; ///< Sum total of root finder iterations. }; + /// @brief State. enum State: std::uint16_t { e_unknown, @@ -158,27 +189,33 @@ namespace playrho { TOIOutput() = default; + /// @brief Initializing constructor. constexpr TOIOutput(State state, Real time, Stats stats): m_state(state), m_time(time), m_stats(stats) { assert(time >= 0); assert(time <= 1); } - /// Gets the state at time factor. + /// @brief Gets the state at time factor. State get_state() const noexcept { return m_state; } - /// Gets time factor at which state occurs. + /// @brief Gets time factor at which state occurs. /// @return Time factor in range of [0,1] into the future. Real get_t() const noexcept { return m_time; } + /// @brief Gets the TOI iterations. toi_iter_type get_toi_iters() const noexcept { return m_stats.toi_iters; } + /// @brief Gets the sum distance iterations. dist_sum_type get_sum_dist_iters() const noexcept { return m_stats.sum_dist_iters; } + /// @brief Gets the max distance iterations. dist_iter_type get_max_dist_iters() const noexcept { return m_stats.max_dist_iters; } + /// @brief Gets the sum root iterations. root_sum_type get_sum_root_iters() const noexcept { return m_stats.sum_root_iters; } + /// @brief Gets the max root iterations. root_iter_type get_max_root_iters() const noexcept { return m_stats.max_root_iters; } private: @@ -187,7 +224,8 @@ namespace playrho { Stats m_stats; }; - /// Gets the time of impact for two disjoint convex sets using the Separating Axis Theorem. + /// @brief Gets the time of impact for two disjoint convex sets using the + /// Separating Axis Theorem. /// /// @details /// Computes the upper bound on time before two shapes penetrate too much. diff --git a/PlayRho/Collision/WorldManifold.hpp b/PlayRho/Collision/WorldManifold.hpp index 88f513c75d..5781362529 100644 --- a/PlayRho/Collision/WorldManifold.hpp +++ b/PlayRho/Collision/WorldManifold.hpp @@ -36,6 +36,8 @@ namespace playrho class WorldManifold { public: + + /// @brief Size type. using size_type = std::remove_const::type; private: @@ -69,6 +71,7 @@ namespace playrho /// normal, invalid points, and invalid separations. WorldManifold() = default; + /// @brief Initializing constructor. constexpr explicit WorldManifold(UnitVec2 normal) noexcept: m_normal{normal}, m_count{0} { @@ -76,6 +79,7 @@ namespace playrho // Intentionally empty. } + /// @brief Initializing constructor. constexpr explicit WorldManifold(UnitVec2 normal, PointData ps0) noexcept: m_normal{normal}, m_count{1}, m_points{ps0.location, GetInvalid()}, @@ -86,6 +90,7 @@ namespace playrho // Intentionally empty. } + /// @brief Initializing constructor. constexpr explicit WorldManifold(UnitVec2 normal, PointData ps0, PointData ps1) noexcept: m_normal{normal}, m_count{2}, m_points{ps0.location, ps1.location}, @@ -142,6 +147,7 @@ namespace playrho return m_separations[index]; } + /// @brief Gets the given index contact impulses. ContactImpulses GetImpulses(size_type index) const noexcept { assert(index < MaxManifoldPoints); diff --git a/PlayRho/Common/AllocatedArray.hpp b/PlayRho/Common/AllocatedArray.hpp index 9e2c48c9b1..1139277c9e 100644 --- a/PlayRho/Common/AllocatedArray.hpp +++ b/PlayRho/Common/AllocatedArray.hpp @@ -20,25 +20,48 @@ template > class AllocatedArray { public: + + /// @brief Size type. using size_type = std::size_t; + + /// @brief Value type. using value_type = T; + + /// @brief Constant value type. using const_value_type = const value_type; + + /// @brief Reference type. using reference = value_type&; + + /// @brief Constant reference type. using const_reference = const value_type&; + + /// @brief Pointer type. using pointer = value_type*; + + /// @brief Constant pointer type. using const_pointer = const value_type*; + + /// @brief Difference type. using difference_type = std::ptrdiff_t; + + /// @brief Deleter type. using deleter_type = Deleter; + /// @brief Iterator alias. using iterator = pointer; + + /// @brief Constant iterator alias. using const_iterator = const_pointer; + /// @brief Initializing constructor. constexpr AllocatedArray(size_type max_size, pointer data, deleter_type deleter = noop_deleter): m_max_size{max_size}, m_data{data}, m_deleter{deleter} { assert(data); } + /// @brief Destructor. ~AllocatedArray() noexcept { m_deleter(m_data); @@ -48,6 +71,7 @@ class AllocatedArray AllocatedArray() = delete; AllocatedArray(const AllocatedArray& copy) = delete; + /// @brief Move constructor. AllocatedArray(AllocatedArray&& other) noexcept: m_max_size{other.m_max_size}, m_size{other.m_size}, m_data{other.m_data}, m_deleter{other.m_deleter} { @@ -55,49 +79,73 @@ class AllocatedArray other.m_data = nullptr; } + /// @brief Gets the current size of this array. size_type size() const noexcept { return m_size; } + + /// @brief Gets the maximum size this array can possibly get to. size_type max_size() const noexcept { return m_max_size; } + + /// @brief Determines whether this array is empty. bool empty() const noexcept { return size() == 0; } + /// @brief Gets a direct pointer to this array's memory. pointer data() const noexcept { return m_data; } + /// @brief Indexed operator. reference operator[](size_type i) { assert(i < m_size); return m_data[i]; } + /// @brief Indexed operator. const_reference operator[](size_type i) const { assert(i < m_size); return m_data[i]; } + /// @brief Gets the "begin" iterator value for this array. iterator begin() { return iterator{m_data}; } + + /// @brief Gets the "end" iterator value for this array. iterator end() { return iterator{m_data + size()}; } + + /// @brief Gets the "begin" iterator value for this array. const_iterator begin() const { return const_iterator{m_data}; } + + /// @brief Gets the "end" iterator value for this array. const_iterator end() const { return const_iterator{m_data + size()}; } + /// @brief Gets the "begin" iterator value for this array. const_iterator cbegin() const { return const_iterator{m_data}; } + + /// @brief Gets the "end" iterator value for this array. const_iterator cend() const { return const_iterator{m_data + size()}; } + /// @brief Gets a reference to the "back" element of this array. + /// @warning Behavior is undefined if the size of this array is less than 1. reference back() noexcept { assert(m_size > 0); return m_data[m_size - 1]; } + /// @brief Gets a reference to the "back" element of this array. + /// @warning Behavior is undefined if the size of this array is less than 1. const_reference back() const noexcept { assert(m_size > 0); return m_data[m_size - 1]; } + /// @brief Clears this array. void clear() noexcept { m_size = 0; } + /// @brief Push "back" the given value. void push_back(const_reference value) { assert(m_size < m_max_size); @@ -105,6 +153,7 @@ class AllocatedArray ++m_size; } + /// @brief Pop "back". void pop_back() noexcept { assert(m_size > 0); diff --git a/PlayRho/Common/ArrayList.hpp b/PlayRho/Common/ArrayList.hpp index c94fa5bc02..9a46f901a4 100644 --- a/PlayRho/Common/ArrayList.hpp +++ b/PlayRho/Common/ArrayList.hpp @@ -32,11 +32,22 @@ namespace playrho class ArrayList { public: + /// @brief Size type. using size_type = SIZE_TYPE; + + /// @brief Value type. using value_type = VALUE_TYPE; + + /// @brief Reference type. using reference = value_type&; + + /// @brief Constant reference type. using const_reference = const value_type&; + + /// @brief Pointer type. using pointer = value_type*; + + /// @brief Constant pointer type. using const_pointer = const value_type*; constexpr ArrayList() noexcept @@ -52,6 +63,7 @@ namespace playrho // Intentionally empty } + /// @brief Assignment operator. template > ArrayList& operator= (const ArrayList& copy) { @@ -149,6 +161,7 @@ namespace playrho std::array m_elements; }; + /// @brief ArrayList append operator. template ArrayList& operator+= (ArrayList& lhs, const typename ArrayList::data_type& rhs) { @@ -156,6 +169,7 @@ namespace playrho return lhs; } + /// @brief ArrayList add operator. template ArrayList operator+ (ArrayList lhs, const typename ArrayList::data_type& rhs) { diff --git a/PlayRho/Common/BlockAllocator.cpp b/PlayRho/Common/BlockAllocator.cpp index 90ed209232..5ceee05cdb 100644 --- a/PlayRho/Common/BlockAllocator.cpp +++ b/PlayRho/Common/BlockAllocator.cpp @@ -72,16 +72,16 @@ static constexpr std::uint8_t s_blockSizeLookup[BlockAllocator::MaxBlockSize + 1 /// @brief Chunk. struct BlockAllocator::Chunk { - using size_type = std::size_t; + using size_type = std::size_t; ///< Size type. - size_type blockSize; - Block* blocks; + size_type blockSize; ///< Block size. + Block* blocks; ///< Pointer to blocks. }; /// @brief Block. struct BlockAllocator::Block { - Block* next; + Block* next; ///< Next block. }; BlockAllocator::BlockAllocator(): diff --git a/PlayRho/Common/BlockAllocator.hpp b/PlayRho/Common/BlockAllocator.hpp index 7282e9447e..3f57a43aab 100644 --- a/PlayRho/Common/BlockAllocator.hpp +++ b/PlayRho/Common/BlockAllocator.hpp @@ -34,11 +34,20 @@ namespace playrho { class BlockAllocator { public: + + /// @brief Size type. using size_type = std::size_t; - static constexpr auto ChunkSize = size_type{16 * 1024}; ///< Chunk size. - static constexpr auto MaxBlockSize = size_type{640}; ///< Max block size (before using external allocator). + /// @brief Chunk size. + static constexpr auto ChunkSize = size_type{16 * 1024}; + + /// @brief Max block size (before using external allocator). + static constexpr auto MaxBlockSize = size_type{640}; + + /// @brief Block sizes. static constexpr auto BlockSizes = size_type{14}; + + /// @brief Chunk array increment. static constexpr auto ChunkArrayIncrement = size_type{128}; BlockAllocator(); @@ -52,7 +61,8 @@ namespace playrho { /// memory is returned. /// @sa Alloc. void* Allocate(size_type n); - + + /// @brief Allocates an array. template T* AllocateArray(size_type n) { @@ -67,6 +77,7 @@ namespace playrho { /// @note This resets the chunk-count back to zero. void Clear(); + /// @brief Gets the chunk count. auto GetChunkCount() const noexcept { return m_chunkCount; @@ -82,6 +93,8 @@ namespace playrho { Block* m_freeLists[BlockSizes]; }; + /// @brief Deletes the given pointer by calling the pointed-to object's destructor and + /// returning it to the given allocator. template inline void Delete(const T* p, BlockAllocator& allocator) { @@ -92,26 +105,35 @@ namespace playrho { /// Blockl Deallocator. struct BlockDeallocator { + /// @brief Size type. using size_type = BlockAllocator::size_type; BlockDeallocator() = default; + + /// @brief Initializing constructor. + constexpr BlockDeallocator(BlockAllocator* a, size_type n) noexcept: + allocator{a}, nelem{n} + { + // Intentionally empty. + } - constexpr BlockDeallocator(BlockAllocator* a, size_type n) noexcept: allocator{a}, nelem{n} {} - + /// @brief Default operator. void operator()(void *p) noexcept { allocator->Free(p, nelem); } - BlockAllocator* allocator; - size_type nelem; + BlockAllocator* allocator; ///< Allocator pointer. + size_type nelem; ///< Number of elements. }; + /// @brief BlockAllocator equality operator. inline bool operator==(const BlockAllocator& a, const BlockAllocator& b) { return &a == &b; } + /// @brief BlockAllocator inequality operator. inline bool operator!=(const BlockAllocator& a, const BlockAllocator& b) { return &a != &b; diff --git a/PlayRho/Common/BoundedValue.hpp b/PlayRho/Common/BoundedValue.hpp index a02a70ce0e..fc1bdac12c 100644 --- a/PlayRho/Common/BoundedValue.hpp +++ b/PlayRho/Common/BoundedValue.hpp @@ -29,6 +29,7 @@ namespace playrho { + /// @brief Lo value check. enum class LoValueCheck { Any, @@ -38,6 +39,7 @@ namespace playrho { NonZero }; + /// @brief Hi value check. enum class HiValueCheck { Any, @@ -51,7 +53,10 @@ namespace playrho { template struct ValueCheckHelper { + /// @brief Has one. static constexpr bool has_one = false; + + /// @brief Gets the "one" value. static constexpr T one() noexcept { return T(0); } }; @@ -59,10 +64,14 @@ namespace playrho { template struct ValueCheckHelper::value>::type> { + /// @brief Has one. static constexpr bool has_one = true; + + /// @brief Gets the "one" value. static constexpr T one() noexcept { return T(1); } }; + /// @brief Checks if the given value is above negative infinity. template constexpr void CheckIfAboveNegInf(typename std::enable_if::value, T>::type value) { @@ -75,6 +84,7 @@ namespace playrho { } } + /// @brief Checks if the given value is above negative infinity. template constexpr void CheckIfAboveNegInf(typename std::enable_if::value, T>::type ) { @@ -82,18 +92,31 @@ namespace playrho { } /// @brief Bounded value. + /// @note While this works well enough for use in the PlayRho library, I'm not keen on + /// its current implementation. template class BoundedValue { public: + /// @brief Value type. using value_type = T; + + /// @brief Remove pointer type. using remove_pointer_type = typename std::remove_pointer::type; + + /// @brief Exception type. using exception_type = InvalidArgument; + + /// @brief This type. using this_type = BoundedValue; + /// @brief Gets the lo check. static constexpr LoValueCheck GetLoCheck() { return lo; } + + /// @brief Gets the hi check. static constexpr HiValueCheck GetHiCheck() { return hi; } + /// @brief Performs the lo check. static constexpr void DoLoCheck(value_type value) { switch (GetLoCheck()) @@ -124,6 +147,7 @@ namespace playrho { } } + /// @brief Performs the hi check. static constexpr void DoHiCheck(value_type value) { switch (GetHiCheck()) @@ -164,18 +188,21 @@ namespace playrho { } } + /// @brief Initializing constructor. constexpr BoundedValue(value_type value): m_value{value} { DoLoCheck(value); DoHiCheck(value); } + /// @brief Assignment operator. constexpr BoundedValue& operator= (const this_type& other) noexcept { m_value = other.m_value; return *this; } + /// @brief Assignment operator. constexpr BoundedValue& operator= (const T& value) { DoLoCheck(value); @@ -184,22 +211,26 @@ namespace playrho { return *this; } + /// @brief Gets the underlying value. constexpr value_type get() const noexcept { return m_value; } + /// @brief Gets the underlying value. constexpr operator value_type () const noexcept { return m_value; } + /// @brief Member of pointer operator. template constexpr typename std::enable_if::value, U>::type operator-> () const { return m_value; } + /// @brief Indirection operator. template constexpr typename std::enable_if::value, remove_pointer_type>::type& operator* () const @@ -213,12 +244,14 @@ namespace playrho { // Common logical operations for BoundedValue OP BoundedValue + /// @brief BoundedValue equality operator. template constexpr bool operator== (const BoundedValue lhs, const BoundedValue rhs) { return T{lhs} == T{rhs}; } + /// @brief BoundedValue inequality operator. template constexpr bool operator!= (const BoundedValue lhs, const BoundedValue rhs) { @@ -227,48 +260,56 @@ namespace playrho { // Logical operations for numerical BoundedValue OP BoundedValue + /// @brief BoundedValue less-than or equal-to operator. template constexpr bool operator<= (const BoundedValue lhs, const BoundedValue rhs) { return T{lhs} <= T{rhs}; } + /// @brief BoundedValue greater-than or equal-to operator. template constexpr bool operator>= (const BoundedValue lhs, const BoundedValue rhs) { return T{lhs} >= T{rhs}; } + /// @brief BoundedValue less-than operator. template constexpr bool operator< (const BoundedValue lhs, const BoundedValue rhs) { return T{lhs} < T{rhs}; } + /// @brief BoundedValue greater-than operator. template constexpr bool operator> (const BoundedValue lhs, const BoundedValue rhs) { return T{lhs} > T{rhs}; } + /// @brief BoundedValue multiplication operator. template constexpr auto operator* (const BoundedValue lhs, const BoundedValue rhs) { return T{lhs} * T{rhs}; } + /// @brief BoundedValue division operator. template constexpr auto operator/ (const BoundedValue lhs, const BoundedValue rhs) { return T{lhs} / T{rhs}; } + /// @brief BoundedValue addition operator. template constexpr auto operator+ (const BoundedValue lhs, const BoundedValue rhs) { return T{lhs} + T{rhs}; } + /// @brief BoundedValue subtraction operator. template constexpr auto operator- (const BoundedValue lhs, const BoundedValue rhs) { @@ -277,12 +318,14 @@ namespace playrho { // Commmon logical operations for BoundedValue OP T + /// @brief BoundedValue equality operator. template constexpr bool operator== (const BoundedValue lhs, const T rhs) { return T{lhs} == rhs; } + /// @brief BoundedValue inequality operator. template constexpr bool operator!= (const BoundedValue lhs, const T rhs) { @@ -291,48 +334,56 @@ namespace playrho { // Logical operations for numerical BoundedValue OP T + /// @brief BoundedValue less-than or equal-to operator. template constexpr bool operator<= (const BoundedValue lhs, const T rhs) { return T{lhs} <= rhs; } + /// @brief BoundedValue greater-than or equal-to operator. template constexpr bool operator>= (const BoundedValue lhs, const T rhs) { return T{lhs} >= rhs; } + /// @brief BoundedValue less-than operator. template constexpr bool operator< (const BoundedValue lhs, const T rhs) { return T{lhs} < rhs; } + /// @brief BoundedValue greater-than operator. template constexpr bool operator> (const BoundedValue lhs, const T rhs) { return T{lhs} > rhs; } + /// @brief BoundedValue multiplication operator. template constexpr auto operator* (const BoundedValue lhs, const U rhs) { return T{lhs} * rhs; } + /// @brief BoundedValue division operator. template constexpr auto operator/ (const BoundedValue lhs, const U rhs) { return T{lhs} / rhs; } + /// @brief BoundedValue addition operator. template constexpr auto operator+ (const BoundedValue lhs, const U rhs) { return T{lhs} + rhs; } + /// @brief BoundedValue subtraction operator. template constexpr auto operator- (const BoundedValue lhs, const U rhs) { @@ -341,12 +392,14 @@ namespace playrho { // Commmon logical operations for T OP BoundedValue + /// @brief BoundedValue equality operator. template constexpr bool operator== (const T lhs, const BoundedValue rhs) { return lhs == T{rhs}; } + /// @brief BoundedValue inequality operator. template constexpr bool operator!= (const T lhs, const BoundedValue rhs) { @@ -355,48 +408,56 @@ namespace playrho { // Logical operations for numerical T OP BoundedValue + /// @brief BoundedValue less-than or equal-to operator. template constexpr bool operator<= (const T lhs, const BoundedValue rhs) { return lhs <= T{rhs}; } + /// @brief BoundedValue greater-than or equal-to operator. template constexpr bool operator>= (const T lhs, const BoundedValue rhs) { return lhs >= T{rhs}; } + /// @brief BoundedValue less-than operator. template constexpr bool operator< (const T lhs, const BoundedValue rhs) { return lhs < T{rhs}; } + /// @brief BoundedValue greater-than operator. template constexpr bool operator> (const T lhs, const BoundedValue rhs) { return lhs > T{rhs}; } + /// @brief BoundedValue multiplication operator. template constexpr auto operator* (const U lhs, const BoundedValue rhs) { return lhs * T{rhs}; } + /// @brief BoundedValue division operator. template constexpr auto operator/ (const U lhs, const BoundedValue rhs) { return lhs / T{rhs}; } + /// @brief BoundedValue addition operator. template constexpr auto operator+ (const U lhs, const BoundedValue rhs) { return lhs + T{rhs}; } + /// @brief BoundedValue subtraction operator. template constexpr auto operator- (const U lhs, const BoundedValue rhs) { @@ -407,23 +468,29 @@ namespace playrho { // Common useful aliases... + /// @brief Non negative bounded value type. template using NonNegative = typename std::enable_if::value, BoundedValue >::type; + /// @brief Non positive bounded value type. template using NonPositive = BoundedValue; + /// @brief Positive bounded value type. template using Positive = BoundedValue; + /// @brief Negative bounded value type. template using Negative = BoundedValue; + /// @brief Finite bounded value type. template using Finite = BoundedValue; + /// @brief Non zero bounded value type. template using NonZero = typename std::enable_if::value, BoundedValue>::type; @@ -434,9 +501,11 @@ namespace playrho { using NonNull = typename std::enable_if::value, BoundedValue>::type; + /// @brief Unit interval bounded value type. template using UnitInterval = BoundedValue; + /// @brief BoundedValue stream output operator. template ::std::ostream& operator<<(::std::ostream& os, const BoundedValue& value) { diff --git a/PlayRho/Common/CodeDumper.hpp b/PlayRho/Common/CodeDumper.hpp index f06abdb8ad..c1a30bd68a 100644 --- a/PlayRho/Common/CodeDumper.hpp +++ b/PlayRho/Common/CodeDumper.hpp @@ -59,23 +59,31 @@ namespace playrho /// Dump joint to the log file. void Dump(const FrictionJoint& joint, std::size_t index); + /// @brief Dumps the joint to the log file. void Dump(const GearJoint& joint, std::size_t index); + /// @brief Dumps the joint to the log file. void Dump(const MotorJoint& joint, std::size_t index); + /// @brief Dumps the joint to the log file. void Dump(const MouseJoint& joint, std::size_t index); + /// @brief Dumps the joint to the log file. void Dump(const PrismaticJoint& joint, std::size_t index); /// Dump joint to dmLog void Dump(const PulleyJoint& joint, std::size_t index); + /// @brief Dumps the joint to the log file. void Dump(const RevoluteJoint& joint, std::size_t index); + /// @brief Dumps the joint to the log file. void Dump(const RopeJoint& joint, std::size_t index); + /// @brief Dumps the joint to the log file. void Dump(const WeldJoint& joint, std::size_t index); + /// @brief Dumps the joint to the log file. void Dump(const WheelJoint& joint, std::size_t index); } // namespace playrho diff --git a/PlayRho/Common/DynamicMemory.hpp b/PlayRho/Common/DynamicMemory.hpp index 2e42374d68..0bc66d1962 100644 --- a/PlayRho/Common/DynamicMemory.hpp +++ b/PlayRho/Common/DynamicMemory.hpp @@ -28,25 +28,30 @@ namespace playrho { // Memory Allocation - /// Implement this function to use your own memory allocator. + /// @brief Allocates memory. + /// @note Implement this function to use your own memory allocator. void* Alloc(std::size_t size); + /// @brief Allocates memory. template T* Alloc(std::size_t size) { return static_cast(Alloc(size * sizeof(T))); } - /// Implement this function to use your own memory allocator. + /// @brief Reallocates memory. + /// @note Implement this function to use your own memory allocator. void* Realloc(void* ptr, std::size_t new_size); + /// @brief Reallocates memory. template T* Realloc(T* ptr, std::size_t size) { return static_cast(Realloc(static_cast(ptr), size * sizeof(T))); } - /// If you implement Alloc, you should also implement this function. + /// @brief Frees memory. + /// @note If you implement Alloc, you should also implement this function. void Free(void* mem); } // namespace playrho diff --git a/PlayRho/Common/Fixed.hpp b/PlayRho/Common/Fixed.hpp index 7752dec85f..9e51dbbeae 100644 --- a/PlayRho/Common/Fixed.hpp +++ b/PlayRho/Common/Fixed.hpp @@ -44,10 +44,17 @@ namespace playrho class Fixed { public: + + /// @brief Value type. using value_type = BASE_TYPE; + + /// @brief Fraction bits. static constexpr unsigned int FractionBits = FRACTION_BITS; + + /// @brief Scale factor. static constexpr value_type ScaleFactor = static_cast(1u << FractionBits); + /// @brief Compare result enumeration. enum class CmpResult { Incomparable, @@ -56,33 +63,39 @@ namespace playrho GreaterThan }; + /// @brief Gets the min value this type is capable of expressing. static constexpr Fixed GetMin() noexcept { return Fixed{1, scalar_type{1}}; } + /// @brief Gets an infinite value for this type. static constexpr Fixed GetInfinity() noexcept { return Fixed{numeric_limits::max(), scalar_type{1}}; } + /// @brief Gets the max value this type is capable of expressing. static constexpr Fixed GetMax() noexcept { // max reserved for +inf return Fixed{numeric_limits::max() - 1, scalar_type{1}}; } + /// @brief Gets a NaN value for this type. static constexpr Fixed GetNaN() noexcept { return Fixed{numeric_limits::lowest(), scalar_type{1}}; } + /// @brief Gets the negative infinity value for this type. static constexpr Fixed GetNegativeInfinity() noexcept { // lowest reserved for NaN return Fixed{numeric_limits::lowest() + 1, scalar_type{1}}; } + /// @brief Gets the lowest value this type is capable of expressing. static constexpr Fixed GetLowest() noexcept { // lowest reserved for NaN @@ -90,6 +103,7 @@ namespace playrho return Fixed{numeric_limits::lowest() + 2, scalar_type{1}}; } + /// @brief Gets the value from a floating point value. template static constexpr value_type GetFromFloat(T val) noexcept { @@ -101,6 +115,7 @@ namespace playrho static_cast(val * ScaleFactor); } + /// @brief Gets the value from a signed integral value. template static constexpr value_type GetFromSignedInt(T val) noexcept { @@ -111,6 +126,7 @@ namespace playrho static_cast(val * ScaleFactor); } + /// @brief Gets the value from an unsigned integral value. template static constexpr value_type GetFromUnsignedInt(T val) noexcept { @@ -122,72 +138,84 @@ namespace playrho Fixed() = default; + /// @brief Initializing constructor. constexpr Fixed(long double val) noexcept: m_value{GetFromFloat(val)} { // Intentionally empty } + /// @brief Initializing constructor. constexpr Fixed(double val) noexcept: m_value{GetFromFloat(val)} { // Intentionally empty } + /// @brief Initializing constructor. constexpr Fixed(float val) noexcept: m_value{GetFromFloat(val)} { // Intentionally empty } + /// @brief Initializing constructor. constexpr Fixed(unsigned long long val) noexcept: m_value{GetFromUnsignedInt(val)} { // Intentionally empty. } + /// @brief Initializing constructor. constexpr Fixed(unsigned long val) noexcept: m_value{GetFromUnsignedInt(val)} { // Intentionally empty. } + /// @brief Initializing constructor. constexpr Fixed(unsigned int val) noexcept: m_value{GetFromUnsignedInt(val)} { // Intentionally empty. } + /// @brief Initializing constructor. constexpr Fixed(long long val) noexcept: m_value{GetFromSignedInt(val)} { // Intentionally empty. } + /// @brief Initializing constructor. constexpr Fixed(long val) noexcept: - m_value{GetFromSignedInt(val)} + m_value{GetFromSignedInt(val)} { // Intentionally empty. } + /// @brief Initializing constructor. constexpr Fixed(int val) noexcept: m_value{GetFromSignedInt(val)} { // Intentionally empty. } + /// @brief Initializing constructor. constexpr Fixed(short val) noexcept: m_value{GetFromSignedInt(val)} { // Intentionally empty. } + /// @brief Initializing constructor. constexpr Fixed(value_type val, unsigned int fraction) noexcept: m_value{static_cast(static_cast(val * ScaleFactor) | fraction)} { // Intentionally empty. } + /// @brief Initializing constructor. template constexpr Fixed(const Fixed val) noexcept: Fixed(static_cast(val)) @@ -197,6 +225,7 @@ namespace playrho // Methods + /// @brief Converts the value to the expressed type. template constexpr T ConvertTo() const noexcept { @@ -205,6 +234,7 @@ namespace playrho m_value / static_cast(ScaleFactor); } + /// @brief Compares this value to the given one. constexpr CmpResult Compare(const Fixed other) const noexcept { if (isnan() || other.isnan()) @@ -224,79 +254,94 @@ namespace playrho // Unary operations + /// @brief Long double operator. explicit constexpr operator long double() const noexcept { return ConvertTo(); } + /// @brief Double operator. explicit constexpr operator double() const noexcept { return ConvertTo(); } + /// @brief Float operator. explicit constexpr operator float() const noexcept { return ConvertTo(); } + /// @brief Long long operator. explicit constexpr operator long long() const noexcept { return m_value / ScaleFactor; } + /// @brief Long operator. explicit constexpr operator long() const noexcept { return m_value / ScaleFactor; } + /// @brief Unsigned long long operator. explicit constexpr operator unsigned long long() const noexcept { // Behavior is undefined if m_value is negative return static_cast(m_value / ScaleFactor); } + /// @brief Unsigned long operator. explicit constexpr operator unsigned long() const noexcept { // Behavior is undefined if m_value is negative return static_cast(m_value / ScaleFactor); } + /// @brief Unsigned int operator. explicit constexpr operator unsigned int() const noexcept { // Behavior is undefined if m_value is negative return static_cast(m_value / ScaleFactor); } + /// @brief int operator. explicit constexpr operator int() const noexcept { return static_cast(m_value / ScaleFactor); } + /// @brief short operator. explicit constexpr operator short() const noexcept { return static_cast(m_value / ScaleFactor); } + /// @brief Negation operator. constexpr Fixed operator- () const noexcept { return (isnan())? *this: Fixed{-m_value, scalar_type{1}}; } + /// @brief Positive operator. constexpr Fixed operator+ () const noexcept { return *this; } + /// @brief bool operator. explicit constexpr operator bool() const noexcept { return m_value != 0; } + /// @brief Logical not operator. constexpr bool operator! () const noexcept { return m_value == 0; } + /// @brief Addition assignment operator. constexpr Fixed& operator+= (Fixed val) noexcept { if (isnan() || val.isnan() @@ -335,6 +380,7 @@ namespace playrho return *this; } + /// @brief Subtraction assignment operator. constexpr Fixed& operator-= (Fixed val) noexcept { if (isnan() || val.isnan() @@ -373,6 +419,7 @@ namespace playrho return *this; } + /// @brief Multiplication assignment operator. constexpr Fixed& operator*= (Fixed val) noexcept { if (isnan() || val.isnan()) @@ -418,6 +465,7 @@ namespace playrho return *this; } + /// @brief Division assignment operator. constexpr Fixed& operator/= (Fixed val) noexcept { if (isnan() || val.isnan()) @@ -464,6 +512,7 @@ namespace playrho return *this; } + /// @brief Modulo operator. constexpr Fixed& operator%= (Fixed val) noexcept { assert(!isnan()); @@ -473,17 +522,20 @@ namespace playrho return *this; } + /// @brief Is finite. constexpr bool isfinite() const noexcept { return (m_value > GetNegativeInfinity().m_value) && (m_value < GetInfinity().m_value); } + /// @brief Is NaN. constexpr bool isnan() const noexcept { return m_value == GetNaN().m_value; } + /// @brief Gets this value's sign. constexpr int getsign() const noexcept { return (m_value >= 0)? +1: -1; @@ -510,37 +562,44 @@ namespace playrho value_type m_value; }; + /// @brief Equality operator. template constexpr bool operator== (Fixed lhs, Fixed rhs) noexcept { return lhs.Compare(rhs) == Fixed::CmpResult::Equal; } + /// @brief Inequality operator. template constexpr bool operator!= (Fixed lhs, Fixed rhs) noexcept { return lhs.Compare(rhs) != Fixed::CmpResult::Equal; } + /// @brief Less-than operator. template constexpr bool operator< (Fixed lhs, Fixed rhs) noexcept { return lhs.Compare(rhs) == Fixed::CmpResult::LessThan; } + /// @brief Greater-than operator. template constexpr bool operator> (Fixed lhs, Fixed rhs) noexcept { return lhs.Compare(rhs) == Fixed::CmpResult::GreaterThan; } + /// @brief Less-than or equal-to operator. template constexpr bool operator<= (Fixed lhs, Fixed rhs) noexcept { const auto result = lhs.Compare(rhs); - return result == Fixed::CmpResult::LessThan || result == Fixed::CmpResult::Equal; + return result == Fixed::CmpResult::LessThan || + result == Fixed::CmpResult::Equal; } + /// @brief Greater-than or equal-to operator. template constexpr bool operator>= (Fixed lhs, Fixed rhs) noexcept { @@ -548,6 +607,7 @@ namespace playrho return result == Fixed::CmpResult::GreaterThan || result == Fixed::CmpResult::Equal; } + /// @brief Addition operator. template constexpr Fixed operator+ (Fixed lhs, Fixed rhs) noexcept { @@ -555,6 +615,7 @@ namespace playrho return lhs; } + /// @brief Subtraction operator. template constexpr Fixed operator- (Fixed lhs, Fixed rhs) noexcept { @@ -562,6 +623,7 @@ namespace playrho return lhs; } + /// @brief Multiplication operator. template constexpr Fixed operator* (Fixed lhs, Fixed rhs) noexcept { @@ -569,6 +631,7 @@ namespace playrho return lhs; } + /// @brief Division operator. template constexpr Fixed operator/ (Fixed lhs, Fixed rhs) noexcept { @@ -576,6 +639,7 @@ namespace playrho return lhs; } + /// @brief Modulo operator. template constexpr Fixed operator% (Fixed lhs, Fixed rhs) noexcept { @@ -593,70 +657,82 @@ namespace playrho // Fixed32 free functions. + /// @brief Addition operator. constexpr Fixed32 operator+ (Fixed32 lhs, Fixed32 rhs) noexcept { lhs += rhs; return lhs; } + /// @brief Subtraction operator. constexpr Fixed32 operator- (Fixed32 lhs, Fixed32 rhs) noexcept { lhs -= rhs; return lhs; } + /// @brief Multiplication operator. constexpr Fixed32 operator* (Fixed32 lhs, Fixed32 rhs) noexcept { lhs *= rhs; return lhs; } + /// @brief Division operator. constexpr Fixed32 operator/ (Fixed32 lhs, Fixed32 rhs) noexcept { lhs /= rhs; return lhs; } + /// @brief Modulo operator. constexpr Fixed32 operator% (Fixed32 lhs, Fixed32 rhs) noexcept { lhs %= rhs; return lhs; } + /// @brief Equality operator. constexpr bool operator== (Fixed32 lhs, Fixed32 rhs) noexcept { return lhs.Compare(rhs) == Fixed32::CmpResult::Equal; } + /// @brief Inequality operator. constexpr bool operator!= (Fixed32 lhs, Fixed32 rhs) noexcept { return lhs.Compare(rhs) != Fixed32::CmpResult::Equal; } + /// @brief Less-than or equal-to operator. constexpr bool operator <= (Fixed32 lhs, Fixed32 rhs) noexcept { const auto result = lhs.Compare(rhs); return (result == Fixed32::CmpResult::LessThan) || (result == Fixed32::CmpResult::Equal); } + /// @brief Greater-than or equal-to operator. constexpr bool operator >= (Fixed32 lhs, Fixed32 rhs) noexcept { const auto result = lhs.Compare(rhs); return (result == Fixed32::CmpResult::GreaterThan) || (result == Fixed32::CmpResult::Equal); } + /// @brief Less-than operator. constexpr bool operator < (Fixed32 lhs, Fixed32 rhs) noexcept { const auto result = lhs.Compare(rhs); return result == Fixed32::CmpResult::LessThan; } + /// @brief Greater-than operator. constexpr bool operator > (Fixed32 lhs, Fixed32 rhs) noexcept { const auto result = lhs.Compare(rhs); return result == Fixed32::CmpResult::GreaterThan; } + /// @brief Gets an invalid value. template <> constexpr Fixed32 GetInvalid() noexcept { @@ -676,26 +752,31 @@ namespace playrho #ifndef _WIN32 // Fixed64 free functions. + /// @brief 64-bit fixed precision type. using Fixed64 = Fixed; + /// @brief Addition operator. constexpr Fixed64 operator+ (Fixed64 lhs, Fixed64 rhs) noexcept { lhs += rhs; return lhs; } + /// @brief Subtraction operator. constexpr Fixed64 operator- (Fixed64 lhs, Fixed64 rhs) noexcept { lhs -= rhs; return lhs; } + /// @brief Multiplication operator. constexpr Fixed64 operator* (Fixed64 lhs, Fixed64 rhs) noexcept { lhs *= rhs; return lhs; } + /// @brief Division operator. constexpr Fixed64 operator/ (Fixed64 lhs, Fixed64 rhs) noexcept { lhs /= rhs; @@ -708,11 +789,13 @@ namespace playrho return lhs; } + /// @brief Equality operator. constexpr bool operator== (Fixed64 lhs, Fixed64 rhs) noexcept { return lhs.Compare(rhs) == Fixed64::CmpResult::Equal; } + /// @brief Inequality operator. constexpr bool operator!= (Fixed64 lhs, Fixed64 rhs) noexcept { return lhs.Compare(rhs) != Fixed64::CmpResult::Equal; @@ -743,8 +826,11 @@ namespace playrho } /// @brief Specialization of the Wider trait for Fixed32 type. - template<> struct Wider { using type = Fixed64; }; + template<> struct Wider { + using type = Fixed64; ///< Wider type. + }; + /// @brief Gets an invalid value. template <> constexpr Fixed64 GetInvalid() noexcept { @@ -778,49 +864,81 @@ namespace std // Fixed32 /// @brief Template specialization of numeric limits for Fixed32. + /// @sa http://en.cppreference.com/w/cpp/types/numeric_limits template <> class numeric_limits { public: - static constexpr bool is_specialized = true; + static constexpr bool is_specialized = true; ///< Type is specialized. + /// @brief Gets the min value available for the type. static constexpr playrho::Fixed32 min() noexcept { return playrho::Fixed32::GetMin(); } + + /// @brief Gets the max value available for the type. static constexpr playrho::Fixed32 max() noexcept { return playrho::Fixed32::GetMax(); } + + /// @brief Gets the lowest value available for the type. static constexpr playrho::Fixed32 lowest() noexcept { return playrho::Fixed32::GetLowest(); } + /// @brief Number of radix digits that can be represented. static constexpr int digits = 31 - playrho::Fixed32::FractionBits; + + /// @brief Number of decimal digits that can be represented. static constexpr int digits10 = 31 - playrho::Fixed32::FractionBits; + + /// @brief Number of decimal digits necessary to differentiate all values. static constexpr int max_digits10 = 5; // TODO: check this - static constexpr bool is_signed = true; - static constexpr bool is_integer = false; - static constexpr bool is_exact = true; - static constexpr int radix = 0; + static constexpr bool is_signed = true; ///< Identifies signed types. + static constexpr bool is_integer = false; ///< Identifies integer types. + static constexpr bool is_exact = true; ///< Identifies exact type. + static constexpr int radix = 0; ///< Radix used by the type. + + /// @brief Gets the epsilon value for the type. static constexpr playrho::Fixed32 epsilon() noexcept { return playrho::Fixed32{0}; } // TODO + + /// @brief Gets the round error value for the type. static constexpr playrho::Fixed32 round_error() noexcept { return playrho::Fixed32{0}; } // TODO + /// @brief One more than smallest negative power of the radix that's a valid + /// normalized floating-point value. static constexpr int min_exponent = 0; + + /// @brief Smallest negative power of ten that's a valid normalized floating-point value. static constexpr int min_exponent10 = 0; + + /// @brief One more than largest integer power of radix that's a valid finite + /// floating-point value. static constexpr int max_exponent = 0; + + /// @brief Largest integer power of 10 that's a valid finite floating-point value. static constexpr int max_exponent10 = 0; - static constexpr bool has_infinity = true; - static constexpr bool has_quiet_NaN = true; - static constexpr bool has_signaling_NaN = false; - static constexpr float_denorm_style has_denorm = denorm_absent; - static constexpr bool has_denorm_loss = false; + static constexpr bool has_infinity = true; ///< Whether can represent infinity. + static constexpr bool has_quiet_NaN = true; ///< Whether can represent quiet-NaN. + static constexpr bool has_signaling_NaN = false; ///< Whether can represent signaling-NaN. + static constexpr float_denorm_style has_denorm = denorm_absent; ///< Denorm style used. + static constexpr bool has_denorm_loss = false; ///< Has denorm loss amount. + + /// @brief Gets the infinite value for the type. static constexpr playrho::Fixed32 infinity() noexcept { return playrho::Fixed32::GetInfinity(); } + + /// @brief Gets the quiet NaN value for the type. static constexpr playrho::Fixed32 quiet_NaN() noexcept { return playrho::Fixed32::GetNaN(); } + + /// @brief Gets the signaling NaN value for the type. static constexpr playrho::Fixed32 signaling_NaN() noexcept { return playrho::Fixed32{0}; } + + /// @brief Gets the denorm value for the type. static constexpr playrho::Fixed32 denorm_min() noexcept { return playrho::Fixed32{0}; } - static constexpr bool is_iec559 = false; - static constexpr bool is_bounded = true; - static constexpr bool is_modulo = false; + static constexpr bool is_iec559 = false; ///< @brief Not an IEEE 754 floating-point type. + static constexpr bool is_bounded = true; ///< Type bounded: has limited precision. + static constexpr bool is_modulo = false; ///< Doesn't modulo arithmetic overflows. - static constexpr bool traps = false; - static constexpr bool tinyness_before = false; - static constexpr float_round_style round_style = round_toward_zero; + static constexpr bool traps = false; ///< Doesn't do traps. + static constexpr bool tinyness_before = false; ///< Doesn't detect tinyness before rounding. + static constexpr float_round_style round_style = round_toward_zero; ///< Rounds down. }; inline playrho::Fixed32 abs(playrho::Fixed32 value) noexcept @@ -899,49 +1017,81 @@ namespace std #ifndef _WIN32 /// @brief Template specialization of numeric limits for Fixed64. + /// @sa http://en.cppreference.com/w/cpp/types/numeric_limits template <> class numeric_limits { public: - static constexpr bool is_specialized = true; + static constexpr bool is_specialized = true; ///< Type is specialized. + /// @brief Gets the min value available for the type. static constexpr playrho::Fixed64 min() noexcept { return playrho::Fixed64::GetMin(); } + + /// @brief Gets the max value available for the type. static constexpr playrho::Fixed64 max() noexcept { return playrho::Fixed64::GetMax(); } + + /// @brief Gets the lowest value available for the type. static constexpr playrho::Fixed64 lowest() noexcept { return playrho::Fixed64::GetLowest(); } + /// @brief Number of radix digits that can be represented. static constexpr int digits = 63 - playrho::Fixed64::FractionBits; + + /// @brief Number of decimal digits that can be represented. static constexpr int digits10 = 63 - playrho::Fixed64::FractionBits; + + /// @brief Number of decimal digits necessary to differentiate all values. static constexpr int max_digits10 = 10; // TODO: check this - static constexpr bool is_signed = true; - static constexpr bool is_integer = false; - static constexpr bool is_exact = true; - static constexpr int radix = 0; + static constexpr bool is_signed = true; ///< Identifies signed types. + static constexpr bool is_integer = false; ///< Identifies integer types. + static constexpr bool is_exact = true; ///< Identifies exact type. + static constexpr int radix = 0; ///< Radix used by the type. + + /// @brief Gets the epsilon value for the type. static constexpr playrho::Fixed64 epsilon() noexcept { return playrho::Fixed64{0}; } // TODO + + /// @brief Gets the round error value for the type. static constexpr playrho::Fixed64 round_error() noexcept { return playrho::Fixed64{0}; } // TODO + /// @brief One more than smallest negative power of the radix that's a valid + /// normalized floating-point value. static constexpr int min_exponent = 0; + + /// @brief Smallest negative power of ten that's a valid normalized floating-point value. static constexpr int min_exponent10 = 0; + + /// @brief One more than largest integer power of radix that's a valid finite + /// floating-point value. static constexpr int max_exponent = 0; + + /// @brief Largest integer power of 10 that's a valid finite floating-point value. static constexpr int max_exponent10 = 0; - static constexpr bool has_infinity = true; - static constexpr bool has_quiet_NaN = true; - static constexpr bool has_signaling_NaN = false; - static constexpr float_denorm_style has_denorm = denorm_absent; - static constexpr bool has_denorm_loss = false; + static constexpr bool has_infinity = true; ///< Whether can represent infinity. + static constexpr bool has_quiet_NaN = true; ///< Whether can represent quiet-NaN. + static constexpr bool has_signaling_NaN = false; ///< Whether can represent signaling-NaN. + static constexpr float_denorm_style has_denorm = denorm_absent; ///< Denorm style used. + static constexpr bool has_denorm_loss = false; ///< Has denorm loss amount. + + /// @brief Gets the infinite value for the type. static constexpr playrho::Fixed64 infinity() noexcept { return playrho::Fixed64::GetInfinity(); } + + /// @brief Gets the quiet NaN value for the type. static constexpr playrho::Fixed64 quiet_NaN() noexcept { return playrho::Fixed64::GetNaN(); } + + /// @brief Gets the signaling NaN value for the type. static constexpr playrho::Fixed64 signaling_NaN() noexcept { return playrho::Fixed64{0}; } + + /// @brief Gets the denorm value for the type. static constexpr playrho::Fixed64 denorm_min() noexcept { return playrho::Fixed64{0}; } - static constexpr bool is_iec559 = false; - static constexpr bool is_bounded = true; - static constexpr bool is_modulo = false; + static constexpr bool is_iec559 = false; ///< Not an IEEE 754 floating-point type. + static constexpr bool is_bounded = true; ///< Type bounded: has limited precision. + static constexpr bool is_modulo = false; ///< Doesn't modulo arithmetic overflows. - static constexpr bool traps = false; - static constexpr bool tinyness_before = false; - static constexpr float_round_style round_style = round_toward_zero; + static constexpr bool traps = false; ///< Doesn't do traps. + static constexpr bool tinyness_before = false; ///< Doesn't detect tinyness before rounding. + static constexpr float_round_style round_style = round_toward_zero; ///< Rounds down. }; inline playrho::Fixed64 abs(playrho::Fixed64 value) noexcept diff --git a/PlayRho/Common/GrowableStack.hpp b/PlayRho/Common/GrowableStack.hpp index b4bfe42b33..5fdc41933e 100644 --- a/PlayRho/Common/GrowableStack.hpp +++ b/PlayRho/Common/GrowableStack.hpp @@ -34,14 +34,20 @@ template class GrowableStack { public: + + /// @brief Element type. using ElementType = T; + + /// @brief Count type. using CountType = std::size_t; + /// @brief Gets the initial capacity. static constexpr auto GetInitialCapacity() noexcept { return CountType(N); } + /// @brief Gets the buffer growth rate. static constexpr auto GetBufferGrowthRate() noexcept { return CountType{2}; @@ -58,6 +64,7 @@ class GrowableStack } } + /// @brief Pushes the given elements onto this stack. void push(const ElementType& element) { if (m_count == m_capacity) @@ -76,28 +83,35 @@ class GrowableStack ++m_count; } + /// @brief Accesses the "top" element. + /// @warning Behavior is undefined if this stack doesn't already have at least + /// one value pushed onto it. ElementType top() const { assert(m_count > 0); return m_stack[m_count - 1]; } + /// @brief Pops the "top" element. void pop() noexcept { assert(m_count > 0); --m_count; } + /// @brief Gets the current size in numbers of elements. constexpr CountType size() const noexcept { return m_count; } + /// @brief Gets the capacity in number of elements. constexpr CountType capacity() const noexcept { return m_capacity; } + /// @brief Whether this stack is empty. constexpr bool empty() const noexcept { return m_count == 0; diff --git a/PlayRho/Common/Math.hpp b/PlayRho/Common/Math.hpp index d11603aac6..f7ceb2014f 100644 --- a/PlayRho/Common/Math.hpp +++ b/PlayRho/Common/Math.hpp @@ -41,51 +41,60 @@ namespace playrho { // Other templates. +/// @brief Gets the "X" element of the given value - i.e. the first element. template constexpr auto& GetX(T& value) { return Get<0>(value); } +/// @brief Gets the "Y" element of the given value - i.e. the second element. template constexpr auto& GetY(T& value) { return Get<1>(value); } +/// @brief Gets the "Z" element of the given value - i.e. the third element. template constexpr auto& GetZ(T& value) { return Get<2>(value); } +/// @brief Gets the "X" element of the given value - i.e. the first element. template constexpr inline auto GetX(const T& value) { return Get<0>(value); } +/// @brief Gets the "Y" element of the given value - i.e. the second element. template constexpr inline auto GetY(const T& value) { return Get<1>(value); } +/// @brief Gets the "Z" element of the given value - i.e. the third element. template constexpr inline auto GetZ(const T& value) { return Get<2>(value); } +/// @brief Strips the unit from the given value. template constexpr inline auto StripUnit(const BoundedValue& v) { return StripUnit(v.get()); } +/// @brief Squares the given value. template constexpr inline auto Square(TYPE t) noexcept { return t * t; } +/// @brief Square root's the given value. template inline auto Sqrt(T t) { @@ -100,24 +109,28 @@ inline auto Sqrt(Area t) } #endif +/// @brief Computes the arc-tangent of the given y and x values. template inline auto Atan2(T y, T x) { return Angle{static_cast(std::atan2(StripUnit(y), StripUnit(x))) * Radian}; } +/// @brief Computes the arc-tangent of the given y and x values. template<> inline auto Atan2(double y, double x) { return Angle{static_cast(std::atan2(y, x)) * Radian}; } +/// @brief Computes the absolute value of the given value. template constexpr inline T Abs(T a) { return (a >= T{0}) ? a : -a; } +/// @brief Computes the average of the given values. template inline auto Average(Span span) { @@ -134,9 +147,11 @@ inline auto Average(Span span) return sum / static_cast(count); } +/// @brief Computes the rounded value of the given value. template inline T Round(T value, unsigned precision = 100000); +/// @brief Computes the rounded value of the given value. template <> inline float Round(float value, std::uint32_t precision) { @@ -144,6 +159,7 @@ inline float Round(float value, std::uint32_t precision) return std::round(value * factor) / factor; } +/// @brief Computes the rounded value of the given value. template <> inline double Round(double value, std::uint32_t precision) { @@ -151,6 +167,7 @@ inline double Round(double value, std::uint32_t precision) return std::round(value * factor) / factor; } +/// @brief Computes the rounded value of the given value. template <> inline long double Round(long double value, std::uint32_t precision) { @@ -159,6 +176,7 @@ inline long double Round(long double value, std::uint32_t precision) return std::round(value * factor) / factor; } +/// @brief Computes the rounded value of the given value. template <> inline Fixed32 Round(Fixed32 value, std::uint32_t precision) { @@ -167,6 +185,7 @@ inline Fixed32 Round(Fixed32 value, std::uint32_t precision) } #ifndef _WIN32 +/// @brief Computes the rounded value of the given value. template <> inline Fixed64 Round(Fixed64 value, std::uint32_t precision) { @@ -175,18 +194,20 @@ inline Fixed64 Round(Fixed64 value, std::uint32_t precision) } #endif +/// @brief Computes the rounded value of the given value. template <> inline Vec2 Round(Vec2 value, std::uint32_t precision) { return Vec2{Round(value[0], precision), Round(value[1], precision)}; } +/// @brief Gets a Vec2 representation of the given value. constexpr inline Vec2 GetVec2(const UnitVec2 value) { return Vec2{Get<0>(value), Get<1>(value)}; } -/// Gets whether a given value is almost zero. +/// @brief Gets whether a given value is almost zero. /// @details An almost zero value is "subnormal". Dividing by these values can lead to /// odd results like a divide by zero trap occuring. /// @return true if the given value is almost zero, false otherwise. @@ -195,7 +216,7 @@ constexpr inline bool AlmostZero(float value) return Abs(value) < std::numeric_limits::min(); } -/// Gets whether a given value is almost zero. +/// @brief Gets whether a given value is almost zero. /// @details An almost zero value is "subnormal". Dividing by these values can lead to /// odd results like a divide by zero trap occuring. /// @return true if the given value is almost zero, false otherwise. @@ -204,7 +225,7 @@ constexpr inline bool AlmostZero(double value) return Abs(value) < std::numeric_limits::min(); } -/// Gets whether a given value is almost zero. +/// @brief Gets whether a given value is almost zero. /// @details An almost zero value is "subnormal". Dividing by these values can lead to /// odd results like a divide by zero trap occuring. /// @return true if the given value is almost zero, false otherwise. @@ -213,7 +234,7 @@ constexpr inline bool AlmostZero(long double value) return Abs(value) < std::numeric_limits::min(); } -/// Gets whether a given value is almost zero. +/// @brief Gets whether a given value is almost zero. /// @details An almost zero value is "subnormal". Dividing by these values can lead to /// odd results like a divide by zero trap occuring. /// @return true if the given value is almost zero, false otherwise. @@ -223,7 +244,7 @@ constexpr inline bool AlmostZero(Fixed32 value) } #ifndef _WIN32 -/// Gets whether a given value is almost zero. +/// @brief Gets whether a given value is almost zero. /// @details An almost zero value is "subnormal". Dividing by these values can lead to /// odd results like a divide by zero trap occuring. /// @return true if the given value is almost zero, false otherwise. @@ -233,6 +254,7 @@ constexpr inline bool AlmostZero(Fixed64 value) } #endif +/// @brief Determines whether the given two values are "almost equal". constexpr inline bool AlmostEqual(float x, float y, int ulp = 2) { // From http://en.cppreference.com/w/cpp/types/numeric_limits/epsilon : @@ -244,6 +266,7 @@ constexpr inline bool AlmostEqual(float x, float y, int ulp = 2) return (Abs(x - y) < (std::numeric_limits::epsilon() * Abs(x + y) * ulp)) || AlmostZero(x - y); } +/// @brief Determines whether the given two values are "almost equal". constexpr inline bool AlmostEqual(double x, double y, int ulp = 2) { // From http://en.cppreference.com/w/cpp/types/numeric_limits/epsilon : @@ -255,6 +278,7 @@ constexpr inline bool AlmostEqual(double x, double y, int ulp = 2) return (Abs(x - y) < (std::numeric_limits::epsilon() * Abs(x + y) * ulp)) || AlmostZero(x - y); } +/// @brief Determines whether the given two values are "almost equal". constexpr inline bool AlmostEqual(long double x, long double y, int ulp = 2) { // From http://en.cppreference.com/w/cpp/types/numeric_limits/epsilon : @@ -266,24 +290,27 @@ constexpr inline bool AlmostEqual(long double x, long double y, int ulp = 2) return (Abs(x - y) < (std::numeric_limits::epsilon() * Abs(x + y) * ulp)) || AlmostZero(x - y); } +/// @brief Determines whether the given two values are "almost equal". constexpr inline bool AlmostEqual(Fixed32 x, Fixed32 y, int ulp = 2) { return Abs(x - y) <= Fixed32{0, static_cast(ulp)}; } #ifndef _WIN32 +/// @brief Determines whether the given two values are "almost equal". constexpr inline bool AlmostEqual(Fixed64 x, Fixed64 y, int ulp = 2) { return Abs(x - y) <= Fixed64{0, static_cast(ulp)}; } #endif +/// @brief Gets the angle of the given unit vector. inline Angle GetAngle(const UnitVec2 value) { return Atan2(GetY(value), GetX(value)); } -/// Gets the angle. +/// @brief Gets the angle. /// @return Anglular value in the range of -Pi to +Pi radians. template inline Angle GetAngle(const Vector2D value) @@ -291,8 +318,8 @@ inline Angle GetAngle(const Vector2D value) return Atan2(GetY(value), GetX(value)); } -/// Gets the square of the length/magnitude of the given value. -/// For performance, use this instead of GetLength(T value) (if possible). +/// @brief Gets the square of the length/magnitude of the given value. +/// @note For performance, use this instead of GetLength(T value) (if possible). /// @return Non-negative value. template constexpr inline auto GetLengthSquared(T value) noexcept @@ -300,19 +327,21 @@ constexpr inline auto GetLengthSquared(T value) noexcept return Square(GetX(value)) + Square(GetY(value)); } +/// @brief Gets the square of the length/magnitude of the given value. template <> constexpr inline auto GetLengthSquared(Vec3 value) noexcept { return Square(GetX(value)) + Square(GetY(value)) + Square(GetZ(value)); } +/// @brief Gets the length/magnitude of the given value. template inline auto GetLength(T value) { return Sqrt(GetLengthSquared(value)); } -/// Performs the dot product on two vectors (A and B). +/// @brief Performs the dot product on two vectors (A and B). /// /// @details The dot product of two vectors is defined as: /// the magnitude of vector A, mulitiplied by, the magnitude of vector B, @@ -340,7 +369,7 @@ constexpr inline auto Dot(const T1 a, const T2 b) noexcept return (Get<0>(a) * Get<0>(b)) + (Get<1>(a) * Get<1>(b)); } -/// Perform the dot product on two vectors. +/// @brief Performs the dot product on two vectors. template <> constexpr inline auto Dot(const Vec3 a, const Vec3 b) noexcept { @@ -394,6 +423,7 @@ constexpr inline auto Cross(const T1 a, const T2 b) noexcept return (GetX(a) * GetY(b)) - (GetY(a) * GetX(b)); } +/// @brief Cross-products the given two values. template <> constexpr inline auto Cross(const Vec3 a, const Vec3 b) noexcept { @@ -404,8 +434,8 @@ constexpr inline auto Cross(const Vec3 a, const Vec3 b) noexcept }; } -/// Solve A * x = b, where b is a column vector. This is more efficient -/// than computing the inverse in one-shot cases. +/// @brief Solves A * x = b, where b is a column vector. +/// @note This is more efficient than computing the inverse in one-shot cases. template constexpr auto Solve(const Matrix22 mat, const Vector2D b) noexcept { @@ -418,6 +448,7 @@ constexpr auto Solve(const Matrix22 mat, const Vector2D b) noexcept }: Vector2D{}; } +/// @brief Inverts the given value. template constexpr auto Invert(const Matrix22 value) noexcept { @@ -431,8 +462,8 @@ constexpr auto Invert(const Matrix22 value) noexcept Matrix22{}; } -/// Solve A * x = b, where b is a column vector. This is more efficient -/// than computing the inverse in one-shot cases. +/// @brief Solves A * x = b, where b is a column vector. +/// @note This is more efficient than computing the inverse in one-shot cases. constexpr Vec3 Solve33(const Mat33& mat, const Vec3 b) noexcept { const auto dp = Dot(GetX(mat), Cross(GetY(mat), GetZ(mat))); @@ -443,10 +474,10 @@ constexpr Vec3 Solve33(const Mat33& mat, const Vec3 b) noexcept return Vec3{x, y, z}; } -/// Solve A * x = b, where b is a column vector. This is more efficient -/// than computing the inverse in one-shot cases. Solve only the upper -/// 2-by-2 matrix equation. - template +/// @brief Solves A * x = b, where b is a column vector. +/// @note This is more efficient than computing the inverse in one-shot cases. +/// @note Solves only the upper 2-by-2 matrix equation. +template constexpr T Solve22(const Mat33& mat, const T b) noexcept { const auto cp = GetX(GetX(mat)) * GetY(GetY(mat)) - GetX(GetY(mat)) * GetY(GetX(mat)); @@ -456,8 +487,8 @@ constexpr T Solve22(const Mat33& mat, const T b) noexcept return T{x, y}; } -/// Get the inverse of this matrix as a 2-by-2. -/// Returns the zero matrix if singular. +/// @brief Gets the inverse of the given matrix as a 2-by-2. +/// @return Zero matrix if singular. constexpr inline Mat33 GetInverse22(const Mat33& value) noexcept { const auto a = GetX(GetX(value)), b = GetX(GetY(value)), c = GetY(GetX(value)), d = GetY(GetY(value)); @@ -469,8 +500,8 @@ constexpr inline Mat33 GetInverse22(const Mat33& value) noexcept return Mat33{Vec3{det * d, -det * c, Real{0}}, Vec3{-det * b, det * a, 0}, Vec3{0, 0, 0}}; } -/// Get the symmetric inverse of this matrix as a 3-by-3. -/// Returns the zero matrix if singular. +/// @brief Gets the symmetric inverse of this matrix as a 3-by-3. +/// @return Zero matrix if singular. constexpr inline Mat33 GetSymInverse33(const Mat33& value) noexcept { auto det = Dot(GetX(value), Cross(GetY(value), GetZ(value))); @@ -501,7 +532,7 @@ struct ContactImpulses Momentum m_tangent; ///< Tangent impulse. This is the friction impulse (4-bytes). }; -/// Gets a vector counter-clockwise (reverse-clockwise) perpendicular to the given vector. +/// @brief Gets a vector counter-clockwise (reverse-clockwise) perpendicular to the given vector. /// @details This takes a vector of form (x, y) and returns the vector (-y, x). /// @param vector Vector to return a counter-clockwise perpendicular equivalent for. /// @return A counter-clockwise 90-degree rotation of the given vector. @@ -513,7 +544,7 @@ constexpr inline auto GetRevPerpendicular(const T vector) noexcept return T{-GetY(vector), GetX(vector)}; } -/// Gets a vector clockwise (forward-clockwise) perpendicular to the given vector. +/// @brief Gets a vector clockwise (forward-clockwise) perpendicular to the given vector. /// @details This takes a vector of form (x, y) and returns the vector (y, -x). /// @param vector Vector to return a clockwise perpendicular equivalent for. /// @return A clockwise 90-degree rotation of the given vector. @@ -560,42 +591,47 @@ constexpr inline Vec2 InverseTransform(const Vec2 v, const Mat22& A) noexcept return Vec2{Dot(v, GetX(A)), Dot(v, GetY(A))}; } +/// @brief Multiplication operator. template constexpr inline Vector2D operator* (BoundedValue s, UnitVec2 u) noexcept { return Vector2D{u.GetX() * s, u.GetY() * T{s}}; } +/// @brief Multiplication operator. template constexpr inline Vector2D operator* (const T s, const UnitVec2 u) noexcept { return Vector2D{u.GetX() * s, u.GetY() * s}; } +/// @brief Multiplication operator. template constexpr inline Vector2D operator* (UnitVec2 u, BoundedValue s) noexcept { return Vector2D{u.GetX() * s, u.GetY() * T{s}}; } +/// @brief Multiplication operator. template constexpr inline Vector2D operator* (const UnitVec2 u, const T s) noexcept { return Vector2D{u.GetX() * s, u.GetY() * s}; } +/// @brief Division operator. constexpr inline Vec2 operator/ (const UnitVec2 u, const UnitVec2::value_type s) noexcept { return Vec2{GetX(u) / s, GetY(u) / s}; } -// A * B +/// @brief Computes A * B. constexpr inline Mat22 Mul(const Mat22& A, const Mat22& B) noexcept { return Mat22{Transform(GetX(B), A), Transform(GetY(B), A)}; } -// A^T * B +/// @brief Computes A^T * B. constexpr inline Mat22 MulT(const Mat22& A, const Mat22& B) noexcept { const auto c1 = Vec2{Dot(GetX(A), GetX(B)), Dot(GetY(A), GetX(B))}; @@ -603,13 +639,13 @@ constexpr inline Mat22 MulT(const Mat22& A, const Mat22& B) noexcept return Mat22{c1, c2}; } -/// Multiply a matrix times a vector. +/// @brief Multiplies a matrix by a vector. constexpr inline Vec3 Transform(const Vec3& v, const Mat33& A) noexcept { return (GetX(v) * GetX(A)) + (GetY(v) * GetY(A)) + (GetZ(v) * GetZ(A)); } -/// Multiply a matrix times a vector. +/// @brief Multiplies a matrix by a vector. constexpr inline Vec2 Transform(const Vec2 v, const Mat33& A) noexcept { return Vec2{ @@ -646,7 +682,7 @@ constexpr inline auto InverseRotate(const Vector2D vector, const UnitVec2& an return Vector2D{newX, newY}; } -/// Transforms the given 2-D vector with the given transformation. +/// @brief Transforms the given 2-D vector with the given transformation. /// @details /// Rotate and translate the given 2-D linear position according to the rotation and translation /// defined by the given transformation. @@ -662,7 +698,7 @@ constexpr inline Length2D Transform(const Length2D v, const Transformation T) no return Rotate(v, T.q) + T.p; } -/// Inverse transforms the given 2-D vector with the given transformation. +/// @brief Inverse transforms the given 2-D vector with the given transformation. /// @details /// Inverse translate and rotate the given 2-D vector according to the translation and rotation /// defined by the given transformation. @@ -678,39 +714,44 @@ constexpr inline Length2D InverseTransform(const Length2D v, const Transformatio return InverseRotate(v2, T.q); } -// v2 = A.q.Rot(B.q.Rot(v1) + B.p) + A.p -// = (A.q * B.q).Rot(v1) + A.q.Rot(B.p) + A.p +/// @brief Multiplies a given transformation by another given transformation. +/// @note v2 = A.q.Rot(B.q.Rot(v1) + B.p) + A.p +/// = (A.q * B.q).Rot(v1) + A.q.Rot(B.p) + A.p constexpr inline Transformation Mul(const Transformation& A, const Transformation& B) noexcept { return Transformation{A.p + Rotate(B.p, A.q), A.q.Rotate(B.q)}; } -// v2 = A.q' * (B.q * v1 + B.p - A.p) -// = A.q' * B.q * v1 + A.q' * (B.p - A.p) +/// @brief Inverse multiplies a given transformation by another given transformation. +/// @note v2 = A.q' * (B.q * v1 + B.p - A.p) +/// = A.q' * B.q * v1 + A.q' * (B.p - A.p) constexpr inline Transformation MulT(const Transformation& A, const Transformation& B) noexcept { const auto dp = B.p - A.p; return Transformation{InverseRotate(dp, A.q), B.q.Rotate(A.q.FlipY())}; } +/// @brief Gets the absolute value of the given value. template <> inline Vec2 Abs(Vec2 a) { return Vec2{Abs(a[0]), Abs(a[1])}; } +/// @brief Gets the absolute value of the given value. template <> inline UnitVec2 Abs(UnitVec2 a) { return a.Absolute(); } +/// @brief Gets the absolute value of the given value. inline Mat22 Abs(const Mat22& A) { return Mat22{Abs(GetX(A)), Abs(GetY(A))}; } -/// Clamps the given value within the given range (inclusive). +/// @brief Clamps the given value within the given range (inclusive). /// @param value Value to clamp. /// @param low Lowest value to return or NaN to keep the low-end unbounded. /// @param high Highest value to return or NaN to keep the high-end unbounded. @@ -721,7 +762,8 @@ constexpr inline T Clamp(T value, T low, T high) noexcept return (tmp < low)? low: tmp; // std::isnan(low)? b: Max(b, low); } -/// "Next Largest Power of 2 +/// @brief Gets the next largest power of 2 +/// @details /// Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm /// that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with /// the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next @@ -737,6 +779,7 @@ inline std::uint64_t NextPowerOfTwo(std::uint64_t x) return x + 1; } +/// @brief Gets the transformation for the given values. constexpr inline Transformation GetTransformation(const Length2D ctr, const UnitVec2 rot, const Length2D localCtr) noexcept { @@ -744,6 +787,7 @@ constexpr inline Transformation GetTransformation(const Length2D ctr, const Unit return Transformation{ctr - (Rotate(localCtr, rot)), rot}; } +/// @brief Gets the transformation for the given values. inline Transformation GetTransformation(const Position pos, const Length2D local_ctr) noexcept { assert(IsValid(pos)); @@ -751,7 +795,7 @@ inline Transformation GetTransformation(const Position pos, const Length2D local return GetTransformation(pos.linear, UnitVec2::Get(pos.angular), local_ctr); } -/// Gets the interpolated transform at a specific time. +/// @brief Gets the interpolated transform at a specific time. /// @param sweep Sweep data to get the transform from. /// @param beta Time factor in [0,1], where 0 indicates alpha0. /// @return Transformation of the given sweep at the specified time. @@ -762,7 +806,7 @@ inline Transformation GetTransformation(const Sweep& sweep, const Real beta) noe return GetTransformation(GetPosition(sweep.pos0, sweep.pos1, beta), sweep.GetLocalCenter()); } -/// Gets the transform at "time" zero. +/// @brief Gets the transform at "time" zero. /// @note This is like calling GetTransformation(sweep, 0), except more efficiently. /// @sa GetTransformation(const Sweep& sweep, Real beta). /// @param sweep Sweep data to get the transform from. @@ -772,7 +816,7 @@ inline Transformation GetTransform0(const Sweep& sweep) noexcept return GetTransformation(sweep.pos0, sweep.GetLocalCenter()); } -/// Gets the transform at "time" one. +/// @brief Gets the transform at "time" one. /// @note This is like calling GetTransformation(sweep, 1.0), except more efficiently. /// @sa GetTransformation(const Sweep& sweep, Real beta). /// @param sweep Sweep data to get the transform from. @@ -782,13 +826,14 @@ inline Transformation GetTransform1(const Sweep& sweep) noexcept return GetTransformation(sweep.pos1, sweep.GetLocalCenter()); } +/// @brief Gets the "normalized" value of the given angle. inline Angle GetNormalized(Angle value) { const auto angleInRadians = Real(value / Radian); return Angle{std::fmod(angleInRadians, Real(2 * Pi)) * Radian}; } -/// Gets a sweep with the given sweep's angles normalized. +/// @brief Gets a sweep with the given sweep's angles normalized. /// @param sweep Sweep to return with its angles normalized. /// @return Sweep with its pos0 angle to be between -2 pi and 2 pi /// and its pos1 angle reduced by the amount pos0's angle was reduced by. @@ -801,7 +846,7 @@ inline Sweep GetAnglesNormalized(Sweep sweep) noexcept return sweep; } -/// Converts the given vector into a unit vector and returns its original length. +/// @brief Converts the given vector into a unit vector and returns its original length. inline Real Normalize(Vec2& vector) { const auto length = GetLength(vector); @@ -815,6 +860,7 @@ inline Real Normalize(Vec2& vector) return 0; } +/// @brief Gets whether the given velocity is "under active" based on the given tolerances. inline bool IsUnderActive(Velocity velocity, LinearVelocity linSleepTol, AngularVelocity angSleepTol) noexcept { @@ -824,7 +870,8 @@ inline bool IsUnderActive(Velocity velocity, } /// @brief Gets the contact relative velocity. -/// @note If relA and relB are the zero vectors, the resulting value is simply velB.linear - velA.linear. +/// @note If relA and relB are the zero vectors, the resulting value is simply +/// velB.linear - velA.linear. inline LinearVelocity2D GetContactRelVelocity(const Velocity velA, const Length2D relA, const Velocity velB, const Length2D relB) noexcept @@ -859,11 +906,12 @@ GetContactRelVelocity(const Velocity velA, const Length2D relA, #endif } -/// Computes the centroid of a counter-clockwise array of 3 or more vertices. +/// @brief Computes the centroid of a counter-clockwise array of 3 or more vertices. /// @note Behavior is undefined if there are less than 3 vertices or the vertices don't /// go counter-clockwise. Length2D ComputeCentroid(const Span& vertices); +/// @brief Gets the modulo next value. template constexpr inline T GetModuloNext(T value, T count) noexcept { @@ -871,6 +919,7 @@ constexpr inline T GetModuloNext(T value, T count) noexcept return (value + 1) % count; } +/// @brief Gets the modulo previous value. template constexpr inline T GetModuloPrev(T value, T count) noexcept { @@ -918,6 +967,7 @@ template inline UnitVec2 GetUnitVector(const Vector2D value, T& magnitude, const UnitVec2 fallback = UnitVec2::GetDefaultFallback()); +/// @brief Gets the unit vector of the given value. template <> inline UnitVec2 GetUnitVector(const Vector2D value, Real& magnitude, const UnitVec2 fallback) { @@ -926,6 +976,7 @@ inline UnitVec2 GetUnitVector(const Vector2D value, Real& magnitude, const #ifdef USE_BOOST_UNITS +/// @brief Gets the unit vector of the given value. template <> inline UnitVec2 GetUnitVector(const Vector2D value, Length& magnitude, const UnitVec2 fallback) { @@ -935,6 +986,7 @@ inline UnitVec2 GetUnitVector(const Vector2D value, Length& magnitude, c return uv; } +/// @brief Gets the unit vector of the given value. template <> inline UnitVec2 GetUnitVector(const Vector2D value, LinearVelocity& magnitude, const UnitVec2 fallback) @@ -947,16 +999,21 @@ inline UnitVec2 GetUnitVector(const Vector2D value, LinearVeloci #endif +/// @brief Gets the vertices for a circle described by the given parameters. std::vector GetCircleVertices(const Length radius, unsigned slices, Angle start = Angle{0}, Real turns = Real{1}); +/// @brief Output stream operator. ::std::ostream& operator<<(::std::ostream& os, const Vec2& value); +/// @brief Output stream operator. ::std::ostream& operator<<(::std::ostream& os, const UnitVec2& value); +/// @brief Output stream operator. ::std::ostream& operator<<(::std::ostream& os, const Fixed32& value); #ifndef _WIN32 +/// @brief Output stream operator. ::std::ostream& operator<<(::std::ostream& os, const Fixed64& value); #endif diff --git a/PlayRho/Common/Matrix.hpp b/PlayRho/Common/Matrix.hpp index 752050873a..5d171bc77e 100644 --- a/PlayRho/Common/Matrix.hpp +++ b/PlayRho/Common/Matrix.hpp @@ -29,28 +29,38 @@ namespace playrho { + /// @brief Generic N by M matrix. template using Matrix = Vector>; + /// @brief 2 by 2 matrix. template using Matrix22 = Matrix<2, 2, T>; + /// @brief 3 by 3 matrix. template using Matrix33 = Matrix<3, 3, T>; + /// @brief 2 by 2 matrix of Real elements. using Mat22 = Matrix22; + /// @brief 2 by 2 matrix of Mass elements. using Mass22 = Matrix22; + + /// @brief 2 by 2 matrix of InvMass elements. using InvMass22 = Matrix22; + /// @brief 3 by 3 matrix of Real elements. using Mat33 = Matrix33; + /// @brief Determines if the given value is valid. template <> constexpr inline bool IsValid(const Mat22& value) noexcept { return IsValid(Get<0>(value)) && IsValid(Get<1>(value)); } + /// @brief Gets an invalid value for a Mat22. template <> constexpr inline Mat22 GetInvalid() noexcept { diff --git a/PlayRho/Common/OptionalValue.hpp b/PlayRho/Common/OptionalValue.hpp index 570f22b791..4db6953991 100644 --- a/PlayRho/Common/OptionalValue.hpp +++ b/PlayRho/Common/OptionalValue.hpp @@ -33,26 +33,49 @@ namespace playrho { class OptionalValue { public: + + /// @brief Value type. using value_type = T; constexpr OptionalValue() = default; + + /// @brief Copy constructor. constexpr OptionalValue(const OptionalValue& other) = default; + + /// @brief Initializing constructor. constexpr OptionalValue(const T v); - constexpr const T& operator*() const; - constexpr T& operator*(); - constexpr const T* operator->() const; - constexpr T* operator->(); + /// @brief Indirection operator. + constexpr const T& operator* () const; + /// @brief Indirection operator. + constexpr T& operator* (); + + /// @brief Member of pointer operator. + constexpr const T* operator-> () const; + + /// @brief Member of pointer operator. + constexpr T* operator-> (); + + /// @brief bool operator. constexpr explicit operator bool() const noexcept; + + /// @brief Whether this optional value has a value. constexpr bool has_value() const noexcept; - OptionalValue& operator=(const OptionalValue& other) = default; - OptionalValue& operator=(const T v); + /// @brief Assignment operator. + OptionalValue& operator= (const OptionalValue& other) = default; + /// @brief Assignment operator. + OptionalValue& operator= (const T v); + + /// @brief Accesses the value. constexpr T& value(); + + /// @brief Accesses the value. constexpr const T& value() const; + /// @brief Gets the value or provides the alternate given value instead. constexpr T value_or(const T& alt) const; private: diff --git a/PlayRho/Common/Position.hpp b/PlayRho/Common/Position.hpp index bdf9cbde24..3a20f667a4 100644 --- a/PlayRho/Common/Position.hpp +++ b/PlayRho/Common/Position.hpp @@ -37,32 +37,38 @@ namespace playrho Angle angular; ///< Angular position. }; + /// @brief Determines if the given value is valid. template <> constexpr inline bool IsValid(const Position& value) noexcept { return IsValid(value.linear) && IsValid(value.angular); } + /// @brief Equality operator. constexpr inline bool operator==(const Position& lhs, const Position& rhs) { return (lhs.linear == rhs.linear) && (lhs.angular == rhs.angular); } + /// @brief Inequality operator. constexpr inline bool operator!=(const Position& lhs, const Position& rhs) { return (lhs.linear != rhs.linear) || (lhs.angular != rhs.angular); } + /// @brief Negation operator. constexpr inline Position operator- (const Position& value) { return Position{-value.linear, -value.angular}; } + /// @brief Positive operator. constexpr inline Position operator+ (const Position& value) { return value; } + /// @brief Addition assignment operator. constexpr inline Position& operator+= (Position& lhs, const Position& rhs) { lhs.linear += rhs.linear; @@ -70,11 +76,13 @@ namespace playrho return lhs; } + /// @brief Addition operator. constexpr inline Position operator+ (const Position& lhs, const Position& rhs) { return Position{lhs.linear + rhs.linear, lhs.angular + rhs.angular}; } + /// @brief Subtraction assignment operator. constexpr inline Position& operator-= (Position& lhs, const Position& rhs) { lhs.linear -= rhs.linear; @@ -82,16 +90,19 @@ namespace playrho return lhs; } + /// @brief Subtraction operator. constexpr inline Position operator- (const Position& lhs, const Position& rhs) { return Position{lhs.linear - rhs.linear, lhs.angular - rhs.angular}; } + /// @brief Multiplication operator. constexpr inline Position operator* (const Position& pos, const Real scalar) { return Position{pos.linear * scalar, pos.angular * scalar}; } + /// @brief Multiplication operator. constexpr inline Position operator* (const Real scalar, const Position& pos) { return Position{pos.linear * scalar, pos.angular * scalar}; diff --git a/PlayRho/Common/Range.hpp b/PlayRho/Common/Range.hpp index 9c8c4f05e4..f2b0d8710b 100644 --- a/PlayRho/Common/Range.hpp +++ b/PlayRho/Common/Range.hpp @@ -31,24 +31,30 @@ namespace playrho class Range { public: + + /// @brief Iterator type. using iterator_type = IT; + /// @brief Initializing constructor. constexpr Range(iterator_type iter_begin, iterator_type iter_end) noexcept: m_begin{iter_begin}, m_end{iter_end} { // Intentionally empty. } + /// @brief Gets the "begin" index value. iterator_type begin() const noexcept { return m_begin; } + /// @brief Gets the "end" index value. iterator_type end() const noexcept { return m_end; } + /// @brief Whether this range is empty. bool empty() const noexcept { return m_begin == m_end; @@ -64,8 +70,10 @@ namespace playrho class SizedRange: public Range { public: + /// @brief Size type. using size_type = std::size_t; + /// @brief Initializing constructor. constexpr SizedRange(typename Range::iterator_type iter_begin, typename Range::iterator_type iter_end, size_type size) noexcept: @@ -74,13 +82,14 @@ namespace playrho // Intentionally empty. } + /// @brief Gets the size of this range. size_type size() const noexcept { return m_size; } private: - size_type m_size; + size_type m_size; ///< Size in number of elements in the range. }; } diff --git a/PlayRho/Common/Settings.hpp b/PlayRho/Common/Settings.hpp index 265f655a4a..b2cac36be6 100644 --- a/PlayRho/Common/Settings.hpp +++ b/PlayRho/Common/Settings.hpp @@ -54,12 +54,14 @@ namespace details template struct Defaults { + /// @brief Gets the linear slop. static constexpr auto GetLinearSlop() noexcept { // Return the value used by Box2D 2.3.2 b2_linearSlop define.... return Length{Real(0.005f) * Meter}; } + /// @brief Gets the max vertex radius. static constexpr auto GetMaxVertexRadius() noexcept { // DefaultLinearSlop * Real{2 * 1024 * 1024}; @@ -72,6 +74,8 @@ struct Defaults template struct Defaults> { + + /// @brief Gets the linear slop. static constexpr auto GetLinearSlop() noexcept { // Needs to be big enough that the step tolerance doesn't go to zero. @@ -79,6 +83,7 @@ struct Defaults> return Length{Meter / Real{(1 << (FRACTION_BITS - 2))}}; } + /// @brief Gets the max vertex radius. static constexpr auto GetMaxVertexRadius() noexcept { // linearSlop * 2550000 @@ -104,6 +109,7 @@ using ChildCounter = std::remove_const::type; /// @details A type for countining iterations per time-step. using ts_iters_t = std::uint8_t; +/// @brief Maximum float value. constexpr auto MaxFloat = std::numeric_limits::max(); // FLT_MAX // Collision @@ -127,7 +133,10 @@ constexpr auto MaxShapeVertices = std::uint8_t{254}; /// for bodies to come to rest. constexpr auto DefaultLinearSlop = details::Defaults::GetLinearSlop(); +/// @brief Default minimum vertex radius. constexpr auto DefaultMinVertexRadius = DefaultLinearSlop * Real{2}; + +/// @brief Default maximum vertex radius. constexpr auto DefaultMaxVertexRadius = details::Defaults::GetMaxVertexRadius(); /// @brief Default AABB extension amount. @@ -152,6 +161,7 @@ constexpr auto DefaultMaxLinearCorrection = Real{0.2f} * Meter; /// @note This value should be greater than the angular slop value. constexpr auto DefaultMaxAngularCorrection = Real(8.0f / 180.0f) * Pi * Radian; +/// @brief Default maximum translation amount. constexpr auto DefaultMaxTranslation = Length{Real(2.0f) * Meter}; /// @brief Default maximum rotation per world step. @@ -182,7 +192,10 @@ constexpr auto DefaultMaxSubSteps = std::uint8_t{8}; /// @brief Default velocity threshold. constexpr auto DefaultVelocityThreshold = Real(1) * MeterPerSecond; +/// @brief Default regular-phase minimum momentum. constexpr auto DefaultRegMinMomentum = Momentum{(Real(0) / Real(100)) * NewtonSecond}; + +/// @brief Default TOI-phase minimum momentum. constexpr auto DefaultToiMinMomentum = Momentum{(Real(0) / Real(100)) * NewtonSecond}; /// @brief Maximum number of bodies in a world. @@ -240,7 +253,7 @@ constexpr auto DefaultAngularSleepTolerance = Real{(Pi * 2) / 180} * RadianPerSe /// biased normal collisions. constexpr auto DefaultCirclesRatio = Real{10}; -// Mathematical constants +/// @brief Square root two value. constexpr auto SquareRootTwo = Real(1.414213562373095048801688724209698078569671875376948073176679737990732478462); } diff --git a/PlayRho/Common/Span.hpp b/PlayRho/Common/Span.hpp index 983c2b1a70..8703089a95 100644 --- a/PlayRho/Common/Span.hpp +++ b/PlayRho/Common/Span.hpp @@ -36,60 +36,86 @@ namespace playrho class Span { public: + + /// @brief Data type. using data_type = T; + + /// @brief Pointer type. using pointer = data_type*; + + /// @brief Constant pointer type. using const_pointer = const data_type *; + + /// @brief Size type. using size_type = std::size_t; Span() = default; + /// @brief Copy constructor. Span(const Span& copy) = default; + /// @brief Initializing constructor. constexpr Span(pointer array, size_type size) noexcept: m_array{array}, m_size{size} { } + /// @brief Initializing constructor. constexpr Span(pointer first, pointer last) noexcept: m_array{first}, m_size{static_cast(std::distance(first, last))} { assert(first <= last); } + /// @brief Initializing constructor. template constexpr Span(data_type (&array)[SIZE]) noexcept: m_array{&array[0]}, m_size{SIZE} {} + /// @brief Initializing constructor. template ::value > > constexpr Span(U& value) noexcept: m_array{value.begin()}, m_size{value.size()} {} + /// @brief Initializing constructor. template ::value > > constexpr Span(const U& value) noexcept: m_array{value.begin()}, m_size{value.size()} {} + /// @brief Initializing constructor. constexpr Span(std::vector& value) noexcept: m_array{value.data()}, m_size{value.size()} {} + /// @brief Initializing constructor. constexpr Span(std::initializer_list list) noexcept: m_array{list.begin()}, m_size{list.size()} {} - + + /// @brief Gets the "begin" iterator value. pointer begin() const noexcept { return m_array; } + + /// @brief Gets the "begin" iterator value. const_pointer cbegin() const noexcept { return m_array; } + /// @brief Gets the "end" iterator value. pointer end() const noexcept { return m_array + m_size; } - const_pointer cend() const noexcept { return m_array + m_size; } + /// @brief Gets the "end" iterator value. + const_pointer cend() const noexcept { return m_array + m_size; } + + /// @brief Accesses the indexed element. data_type& operator[](size_type index) noexcept { assert(index < m_size); return m_array[index]; } + /// @brief Accesses the indexed element. const data_type& operator[](size_type index) const noexcept { assert(index < m_size); return m_array[index]; } - + + /// @brief Gets the size of this span. size_type size() const noexcept { return m_size; } + /// @brief Direct access to data. pointer data() const noexcept { return m_array; } private: diff --git a/PlayRho/Common/StackAllocator.hpp b/PlayRho/Common/StackAllocator.hpp index 1bc3e9d6b4..85cf6498ec 100644 --- a/PlayRho/Common/StackAllocator.hpp +++ b/PlayRho/Common/StackAllocator.hpp @@ -34,24 +34,29 @@ namespace playrho { class StackAllocator { public: + + /// @brief Size type. using size_type = std::size_t; /// @brief Stack allocator configuration data. struct Configuration { - size_type preallocation_size = 100 * 1024; - size_type allocation_records = 32; + size_type preallocation_size = 100 * 1024; ///< Preallocation size. + size_type allocation_records = 32; ///< Allocation records. }; + /// @brief Gets the default configuration. static constexpr Configuration GetDefaultConfiguration() { return Configuration{}; } + /// @brief Initializing constructor. StackAllocator(Configuration config = GetDefaultConfiguration()) noexcept; ~StackAllocator() noexcept; + /// @brief Copy constructor. StackAllocator(const StackAllocator& copy) = delete; /// Allocates an aligned block of memory of the given size. @@ -60,8 +65,10 @@ class StackAllocator /// @sa GetEntryCount. void* Allocate(size_type size) noexcept; + /// @brief Frees the given pointer. void Free(void* p) noexcept; + /// @brief Allocates and array of the given size number of elements. template T* AllocateArray(size_type size) noexcept { @@ -76,6 +83,7 @@ class StackAllocator Free(p); } + /// @brief Gets the max allocation. auto GetMaxAllocation() const noexcept { return m_maxAllocation; @@ -105,11 +113,13 @@ class StackAllocator return m_allocation; } + /// @brief Gets the preallocated size. auto GetPreallocatedSize() const noexcept { return m_size; } + /// @brief Gets the max entries. auto GetMaxEntries() const noexcept { return m_max_entries; diff --git a/PlayRho/Common/Templates.hpp b/PlayRho/Common/Templates.hpp index 5ffd3538ce..02db4bb2fa 100644 --- a/PlayRho/Common/Templates.hpp +++ b/PlayRho/Common/Templates.hpp @@ -27,14 +27,17 @@ namespace playrho { + /// @brief "Not used" annotator. template void NOT_USED(T&&...){} + /// @brief Gets an invalid value for the type. template constexpr T GetInvalid() noexcept { static_assert(sizeof(T) == 0, "No available specialization"); } + /// @brief Determines if the given value is valid. template constexpr bool IsValid(const T& value) noexcept { @@ -53,24 +56,28 @@ namespace playrho // GetInvalid template specializations. + /// @brief Gets an invalid value for the float type. template <> constexpr float GetInvalid() noexcept { return std::numeric_limits::signaling_NaN(); } + /// @brief Gets an invalid value for the double type. template <> constexpr double GetInvalid() noexcept { return std::numeric_limits::signaling_NaN(); } + /// @brief Gets an invalid value for the long double type. template <> constexpr long double GetInvalid() noexcept { return std::numeric_limits::signaling_NaN(); } + /// @brief Gets an invalid value for the std::size_t type. template <> constexpr std::size_t GetInvalid() noexcept { @@ -79,6 +86,7 @@ namespace playrho // IsValid template specializations. + /// @brief Determines if the given value is valid. template <> constexpr inline bool IsValid(const std::size_t& x) noexcept { @@ -87,48 +95,56 @@ namespace playrho // Other templates. + /// @brief Gets a pointer for the given variable. template constexpr const T* GetPtr(const T* value) noexcept { return value; } + /// @brief Gets a pointer for the given variable. template constexpr T* GetPtr(T* value) noexcept { return value; } + /// @brief Gets a pointer for the given variable. template constexpr const T* GetPtr(const T& value) noexcept { return &value; } + /// @brief Gets a pointer for the given variable. template constexpr T* GetPtr(T& value) noexcept { return &value; } + /// @brief Gets a reference for the given variable. template constexpr const T& GetRef(const T* value) noexcept { return *value; } + /// @brief Gets a reference for the given variable. template constexpr T& GetRef(T* value) noexcept { return *value; } + /// @brief Gets a reference for the given variable. template constexpr const T& GetRef(const T& value) noexcept { return value; } + /// @brief Gets a reference for the given variable. template constexpr T& GetRef(T& value) noexcept { @@ -147,18 +163,21 @@ namespace playrho return typeid(T).name(); } + /// @brief Gets a human recognizable name for the float type. template <> inline const char* GetTypeName() noexcept { return "float"; } + /// @brief Gets a human recognizable name for the double type. template <> inline const char* GetTypeName() noexcept { return "double"; } + /// @brief Gets a human recognizable name for the long double type. template <> inline const char* GetTypeName() noexcept { diff --git a/PlayRho/Common/Transformation.hpp b/PlayRho/Common/Transformation.hpp index 04c9076a9f..0ebcb75ca2 100644 --- a/PlayRho/Common/Transformation.hpp +++ b/PlayRho/Common/Transformation.hpp @@ -40,22 +40,26 @@ namespace playrho UnitVec2 q; ///< Rotational portion of the transformation. 8-bytes. }; + /// @brief Identity transformation value. constexpr auto Transform_identity = Transformation{ Length2D{Real(0) * Meter, Real(0) * Meter}, UnitVec2::GetRight() }; + /// @brief Determines if the given value is valid. template <> constexpr inline bool IsValid(const Transformation& value) noexcept { return IsValid(value.p) && IsValid(value.q); } - constexpr inline bool operator == (Transformation lhs, Transformation rhs) noexcept + /// @brief Equality operator. + constexpr inline bool operator== (Transformation lhs, Transformation rhs) noexcept { return (lhs.p == rhs.p) && (lhs.q == rhs.q); } - constexpr inline bool operator != (Transformation lhs, Transformation rhs) noexcept + /// @brief Inequality operator. + constexpr inline bool operator!= (Transformation lhs, Transformation rhs) noexcept { return (lhs.p != rhs.p) || (lhs.q != rhs.q); } diff --git a/PlayRho/Common/UnitVec2.hpp b/PlayRho/Common/UnitVec2.hpp index 782e847981..ebeb8184bc 100644 --- a/PlayRho/Common/UnitVec2.hpp +++ b/PlayRho/Common/UnitVec2.hpp @@ -79,8 +79,10 @@ class UnitVec2 return UnitVec2{+SquareRootTwo/Real(2), -SquareRootTwo/Real(2)}; } + /// @brief Gets the default fallback. static constexpr UnitVec2 GetDefaultFallback() noexcept { return UnitVec2{}; } + /// @brief Gets the unit vector from the given parameters. static UnitVec2 Get(const Real x, const Real y, Real& magnitude, const UnitVec2 fallback = GetDefaultFallback()) noexcept { @@ -106,18 +108,25 @@ class UnitVec2 // Intentionally empty. } + /// @brief Gets the "X" value. constexpr auto GetX() const noexcept { return m_elems[0]; } + /// @brief Gets the "Y" value. constexpr auto GetY() const noexcept { return m_elems[1]; } + /// @brief Gets the cosine value. constexpr auto cos() const noexcept { return m_elems[0]; } + /// @brief Gets the sine value. constexpr auto sin() const noexcept { return m_elems[1]; } + /// @brief Flips the X and Y values. constexpr inline UnitVec2 FlipXY() const noexcept { return UnitVec2{-GetX(), -GetY()}; } + /// @brief Flips the X value. constexpr inline UnitVec2 FlipX() const noexcept { return UnitVec2{-GetX(), GetY()}; } + /// @brief Flips the Y value. constexpr inline UnitVec2 FlipY() const noexcept { return UnitVec2{GetX(), -GetY()}; } /// @brief Rotates the unit vector by the given amount. @@ -153,10 +162,13 @@ class UnitVec2 return UnitVec2{GetY(), -GetX()}; } + /// @brief Negation operator. constexpr inline UnitVec2 operator-() const noexcept { return UnitVec2{-GetX(), -GetY()}; } + /// @brief Positive operator. constexpr inline UnitVec2 operator+() const noexcept { return UnitVec2{+GetX(), +GetY()}; } + /// @brief Gets the absolute value. constexpr inline UnitVec2 Absolute() const noexcept { return UnitVec2{std::abs(GetX()), std::abs(GetY())}; @@ -178,11 +190,13 @@ constexpr inline UnitVec2 GetXAxis(UnitVec2 rot) noexcept { return rot; } /// @note This is the reverse perpendicular vector of the given unit vector. constexpr inline UnitVec2 GetYAxis(UnitVec2 rot) noexcept { return rot.GetRevPerpendicular(); } +/// @brief Equality operator. constexpr inline bool operator==(const UnitVec2 a, const UnitVec2 b) noexcept { return (a.GetX() == b.GetX()) && (a.GetY() == b.GetY()); } +/// @brief Inequality operator. constexpr inline bool operator!=(const UnitVec2 a, const UnitVec2 b) noexcept { return (a.GetX() != b.GetX()) || (a.GetY() != b.GetY()); @@ -223,13 +237,16 @@ constexpr inline UnitVec2 InverseRotate(const UnitVec2 vector, const UnitVec2& a return vector.Rotate(angle.FlipY()); } +/// @brief Gets an invalid value for the UnitVec2 type. template <> constexpr UnitVec2 GetInvalid() noexcept { return UnitVec2{}; } +/// @brief Determines if the given value is valid. template <> constexpr inline bool IsValid(const UnitVec2& value) noexcept { return IsValid(value.GetX()) && IsValid(value.GetY()) && (value != UnitVec2::GetZero()); } +/// @brief Gets the I'th element of the given collection. template constexpr UnitVec2::value_type Get(UnitVec2 v) noexcept { @@ -241,12 +258,14 @@ constexpr UnitVec2::value_type Get(UnitVec2 v) noexcept } } +/// @brief Gets the 0'th element of the given collection. template <> constexpr UnitVec2::value_type Get<0>(UnitVec2 v) noexcept { return v.GetX(); } +/// @brief Gets the 1'st element of the given collection. template <> constexpr UnitVec2::value_type Get<1>(UnitVec2 v) noexcept { diff --git a/PlayRho/Common/Units.hpp b/PlayRho/Common/Units.hpp index 73a19c2ae1..272d8539e9 100644 --- a/PlayRho/Common/Units.hpp +++ b/PlayRho/Common/Units.hpp @@ -55,127 +55,129 @@ #include #endif -namespace playrho -{ #ifdef USE_BOOST_UNITS +#define PLAYRHO_QUANTITY(BoostDimension) boost::units::quantity +#define PLAYRHO_UNIT(Quantity, BoostUnit) Quantity{BoostUnit * Real{1}} +#define PLAYRHO_DERIVED_UNIT(Quantity, BoostUnit, Ratio) Quantity{BoostUnit * Real{Ratio}} +#else +#define PLAYRHO_QUANTITY(BoostDimension) Real +#define PLAYRHO_UNIT(Quantity, BoostUnit) Real{1} +#define PLAYRHO_DERIVED_UNIT(Quantity, BoostUnit, Ratio) Real{Ratio}} +#endif + +namespace playrho +{ + /// @brief Time quantity. + using Time = PLAYRHO_QUANTITY(boost::units::si::time); + + /// @brief Second unit of Time. + constexpr auto Second = PLAYRHO_UNIT(Time, boost::units::si::second); + + /// @brief Frequency quantity. + using Frequency = PLAYRHO_QUANTITY(boost::units::si::frequency); + + /// @brief Hertz unit of Frequency. + constexpr auto Hertz = PLAYRHO_UNIT(Frequency, boost::units::si::hertz); + + /// @brief Length type. + using Length = PLAYRHO_QUANTITY(boost::units::si::length); + + /// @brief Meter unit of Length. + constexpr auto Meter = PLAYRHO_UNIT(Length, boost::units::si::meter); + + /// @brief Linear velocity quantity. + using LinearVelocity = PLAYRHO_QUANTITY(boost::units::si::velocity); + + /// @brief Meter per second unit of LinearVelocity. + constexpr auto MeterPerSecond = PLAYRHO_UNIT(LinearVelocity, boost::units::si::meter_per_second); + + /// @brief Linear acceleration quantity. + using LinearAcceleration = PLAYRHO_QUANTITY(boost::units::si::acceleration); + + /// @brief Meter per square second unit of LinearAcceleration. + constexpr auto MeterPerSquareSecond = PLAYRHO_UNIT(LinearAcceleration, boost::units::si::meter_per_second_squared); + + /// @brief Mass quantity. + using Mass = PLAYRHO_QUANTITY(boost::units::si::mass); + + /// @brief Kilogram unit of Mass. + constexpr auto Kilogram = PLAYRHO_UNIT(Mass, boost::units::si::kilogram); + + /// @brief Inverse mass quantity. + using InvMass = PLAYRHO_QUANTITY(boost::units::si::inverse_mass); - using Time = boost::units::quantity; - constexpr auto Second = Time{boost::units::si::second * Real{1}}; - - using Frequency = boost::units::quantity; - constexpr auto Hertz = Frequency{boost::units::si::hertz * Real{1}}; - - using Length = boost::units::quantity; - constexpr auto Meter = Length{boost::units::si::meter * Real{1}}; - - using LinearVelocity = boost::units::quantity; - constexpr auto MeterPerSecond = LinearVelocity{boost::units::si::meter_per_second * Real{1}}; - - using LinearAcceleration = boost::units::quantity; - constexpr auto MeterPerSquareSecond = LinearAcceleration{boost::units::si::meter_per_second_squared * Real{1}}; - - using Mass = boost::units::quantity; - constexpr auto Kilogram = Mass{boost::units::si::kilogram * Real{1}}; + /// @brief Area quantity. + using Area = PLAYRHO_QUANTITY(boost::units::si::area); + + /// @brief Square meter unit of Area. + constexpr auto SquareMeter = PLAYRHO_UNIT(Area, boost::units::si::square_meter); - using InvMass = boost::units::quantity; + /// @brief Aereal/surface density quantity. + using Density = PLAYRHO_QUANTITY(boost::units::si::surface_density); + + /// @brief Kilogram per square meter unit of Density. + constexpr auto KilogramPerSquareMeter = PLAYRHO_UNIT(Density, boost::units::si::kilogram_per_square_meter); - using Area = boost::units::quantity; - constexpr auto SquareMeter = Area{boost::units::si::square_meter * Real{1}}; + /// @brief Angle quantity. + using Angle = PLAYRHO_QUANTITY(boost::units::si::plane_angle); + + /// @brief Radian unit of Angle. + constexpr auto Radian = PLAYRHO_UNIT(Angle, boost::units::si::radian); - using Density = boost::units::quantity; - constexpr auto KilogramPerSquareMeter = Density{boost::units::si::kilogram_per_square_meter * Real{1}}; + /// @brief Degree unit of Angle quantity. + constexpr auto Degree = Angle{Radian * Pi / Real{180}}; - using Angle = boost::units::quantity; - constexpr auto Radian = Angle{boost::units::si::radian * Real{1}}; - constexpr auto Degree = Angle{boost::units::degree::degree * Real{1}}; + /// @brief Square radian unit type. constexpr auto SquareRadian = Radian * Radian; - using AngularVelocity = boost::units::quantity; - constexpr auto RadianPerSecond = AngularVelocity{boost::units::si::radian_per_second * Real{1}}; + /// @brief Angular velocity quantity. + using AngularVelocity = PLAYRHO_QUANTITY(boost::units::si::angular_velocity); + + /// @brief Radian per second unit of AngularVelocity. + constexpr auto RadianPerSecond = PLAYRHO_UNIT(AngularVelocity, boost::units::si::radian_per_second); + + /// @brief Degree per second unit of AngularVelocity. constexpr auto DegreePerSecond = AngularVelocity{RadianPerSecond * Degree / Radian}; - using AngularAcceleration = boost::units::quantity; + /// @brief Angular acceleration quantity. + using AngularAcceleration = PLAYRHO_QUANTITY(boost::units::si::angular_acceleration); + + /// @brief Radian per square second unit of AngularAcceleration. constexpr auto RadianPerSquareSecond = Radian / (Second * Second); - using Force = boost::units::quantity; - constexpr auto Newton = Force{boost::units::si::newton * Real{1}}; + /// @brief Force quantity. + using Force = PLAYRHO_QUANTITY(boost::units::si::force); + + /// @brief Newton unit of Force. + constexpr auto Newton = PLAYRHO_UNIT(Force, boost::units::si::newton); - using Torque = boost::units::quantity; - constexpr auto NewtonMeter = Torque{boost::units::si::newton_meter * Real{1}}; + /// @brief Torque quantity. + using Torque = PLAYRHO_QUANTITY(boost::units::si::torque); + + /// @brief Newton meter unit of Torque. + constexpr auto NewtonMeter = PLAYRHO_UNIT(Torque, boost::units::si::newton_meter); - using SecondMomentOfArea = boost::units::quantity; + /// @brief Second moment of area quantity. + using SecondMomentOfArea = PLAYRHO_QUANTITY(boost::units::si::second_moment_of_area); - using RotInertia = boost::units::quantity; + /// @brief Rotational inertia quantity. + using RotInertia = PLAYRHO_QUANTITY(boost::units::si::moment_of_inertia); - /// @brief Inverse rotational inertia. + /// @brief Inverse rotational inertia quantity. /// @note Units of L^-2 M^-1 QP^2. - using InvRotInertia = boost::units::quantity; + using InvRotInertia = PLAYRHO_QUANTITY(boost::units::si::inverse_moment_of_inertia); - using Momentum = boost::units::quantity; + /// @brief Momentum quantity. + using Momentum = PLAYRHO_QUANTITY(boost::units::si::momentum); + + /// @brief Newton second unit. constexpr auto NewtonSecond = Newton * Second; - /// @brief Angular momentum. + /// @brief Angular momentum quantity. /// @note Units of L^2 M T^-1 QP^-1. - using AngularMomentum = boost::units::quantity; - -#else // USE_BOOST_UNITS - - using Time = Real; - constexpr auto Second = Real{1}; - - using Frequency = Real; - constexpr auto Hertz = Real{1}; - - using Length = Real; - constexpr auto Meter = Real{1}; - - using LinearVelocity = Real; - constexpr auto MeterPerSecond = Real{1}; - - using LinearAcceleration = Real; - constexpr auto MeterPerSquareSecond = Real{1}; - - using Mass = Real; - constexpr auto Kilogram = Real{1}; - - using InvMass = Real; - - using Area = Real; - constexpr auto SquareMeter = Real{1}; - - using Density = Real; - constexpr auto KilogramPerSquareMeter = Real{1}; - - using Angle = Real; - constexpr auto Radian = Real{1}; - constexpr auto Degree = Pi / Real{180}; - constexpr auto SquareRadian = Radian * Radian; - - using AngularVelocity = Real; - constexpr auto RadianPerSecond = Real{1}; - constexpr auto DegreePerSecond = Degree; - - using AngularAcceleration = Real; - constexpr auto RadianPerSquareSecond = Real{1}; - - using Force = Real; - constexpr auto Newton = Real{1}; - - using Torque = Real; - constexpr auto NewtonMeter = Real{1}; - - using SecondMomentOfArea = Real; - - using RotInertia = Real; - using InvRotInertia = Real; - - using Momentum = Real; - constexpr auto NewtonSecond = Real{1}; - - using AngularMomentum = Real; - -#endif // USE_BOOST_UNITS + using AngularMomentum = PLAYRHO_QUANTITY(boost::units::si::angular_momentum); + /// @brief Strips the units off of the given value. constexpr inline Real StripUnit(const Real value) { return value; @@ -183,90 +185,105 @@ namespace playrho #ifdef USE_BOOST_UNITS + /// @brief Strips the units off of the given value. template inline constexpr auto StripUnit(const boost::units::quantity source) { return source.value(); } + /// @brief Gets an invalid value for the Angle type. template <> constexpr Angle GetInvalid() noexcept { return GetInvalid() * Radian; } + /// @brief Gets an invalid value for the Frequency type. template <> constexpr Frequency GetInvalid() noexcept { return GetInvalid() * Hertz; } + /// @brief Gets an invalid value for the AngularVelocity type. template <> constexpr AngularVelocity GetInvalid() noexcept { return GetInvalid() * RadianPerSecond; } + /// @brief Gets an invalid value for the Time type. template <> constexpr Time GetInvalid() noexcept { return GetInvalid() * Second; } + /// @brief Gets an invalid value for the Length type. template <> constexpr Length GetInvalid() noexcept { return GetInvalid() * Meter; } + /// @brief Gets an invalid value for the Mass type. template <> constexpr Mass GetInvalid() noexcept { return GetInvalid() * Kilogram; } + /// @brief Gets an invalid value for the InvMass type. template <> constexpr InvMass GetInvalid() noexcept { return GetInvalid() / Kilogram; } + /// @brief Gets an invalid value for the Momentum type. template <> constexpr Momentum GetInvalid() noexcept { return GetInvalid() * Kilogram * MeterPerSecond; } + /// @brief Gets an invalid value for the Force type. template <> constexpr Force GetInvalid() noexcept { return GetInvalid() * Newton; } + /// @brief Gets an invalid value for the Torque type. template <> constexpr Torque GetInvalid() noexcept { return GetInvalid() * NewtonMeter; } + /// @brief Gets an invalid value for the LinearVelocity type. template <> constexpr LinearVelocity GetInvalid() noexcept { return GetInvalid() * MeterPerSecond; } + /// @brief Gets an invalid value for the LinearAcceleration type. template <> constexpr LinearAcceleration GetInvalid() noexcept { return GetInvalid() * MeterPerSquareSecond; } + /// @brief Gets an invalid value for the AngularAcceleration type. template <> constexpr AngularAcceleration GetInvalid() noexcept { return GetInvalid() * RadianPerSquareSecond; } + /// @brief Gets an invalid value for the RotInertia type. template <> constexpr RotInertia GetInvalid() noexcept { @@ -278,4 +295,7 @@ namespace playrho } // namespace playrho +#undef PLAYRHO_QUANTITY +#undef PLAYRHO_UNIT + #endif /* Units_hpp */ diff --git a/PlayRho/Common/Vector.hpp b/PlayRho/Common/Vector.hpp index 40be3bdde2..da50aa513e 100644 --- a/PlayRho/Common/Vector.hpp +++ b/PlayRho/Common/Vector.hpp @@ -39,14 +39,31 @@ struct Vector { static_assert(N > 0, "Dimension must be greater than 0"); + /// @brief Value type. using value_type = T; + + /// @brief Size type. using size_type = std::size_t; + + /// @brief Difference type. using difference_type = std::ptrdiff_t; + + /// @brief Reference type. using reference = value_type&; + + /// @brief Constant reference type. using const_reference = const value_type&; + + /// @brief Pointer type. using pointer = value_type*; + + /// @brief Constant pointer type. using const_pointer = const value_type*; + + /// @brief Iterator type. using iterator = value_type*; + + /// @brief Constant iterator type. using const_iterator = const value_type*; /// @brief Default constructor. @@ -54,6 +71,7 @@ struct Vector /// @note This constructor performs no action. constexpr Vector() = default; + /// @brief Initializing constructor. template constexpr Vector(typename std::enable_if::type head, Tail... tail) noexcept: elements{head, T(tail)...} @@ -61,15 +79,32 @@ struct Vector //static_assert(sizeof...(args) == N, "Invalid number of arguments"); } + /// @brief Gets the max size. constexpr size_type max_size() const noexcept { return N; } + + /// @brief Gets the size. constexpr size_type size() const noexcept { return N; } + + /// @brief Whether empty. + /// @note Always false for N > 0. constexpr size_type empty() const noexcept { return N == 0; } + /// @brief Gets a "begin" iterator. iterator begin() noexcept { return iterator(elements); } + + /// @brief Gets an "end" iterator. iterator end() noexcept { return iterator(elements + N); } + + /// @brief Gets a "begin" iterator. const_iterator begin() const noexcept { return const_iterator(elements); } + + /// @brief Gets an "end" iterator. const_iterator end() const noexcept { return const_iterator(elements + N); } + + /// @brief Gets a "begin" iterator. const_iterator cbegin() const noexcept { return begin(); } + + /// @brief Gets an "end" iterator. const_iterator cend() const noexcept { return end(); } /// @brief Gets a reference to the requested element. @@ -113,11 +148,13 @@ struct Vector return elements[pos]; } + /// @brief Direct access to data. constexpr pointer data() noexcept { return elements; } + /// @brief Direct access to data. constexpr const_pointer data() const noexcept { return elements; @@ -130,6 +167,7 @@ struct Vector value_type elements[N]; }; +/// @brief Gets the I'th element of the given collection. template constexpr auto& Get(Vector& v) noexcept { @@ -137,6 +175,7 @@ constexpr auto& Get(Vector& v) noexcept return v[I]; } +/// @brief Gets the I'th element of the given collection. template constexpr auto Get(const Vector& v) noexcept { diff --git a/PlayRho/Common/Vector2D.hpp b/PlayRho/Common/Vector2D.hpp index dfe8d9db84..798982cbd4 100644 --- a/PlayRho/Common/Vector2D.hpp +++ b/PlayRho/Common/Vector2D.hpp @@ -69,32 +69,36 @@ namespace playrho Real{-9.8f} * MeterPerSquareSecond }; + /// @brief Gets the given value as a Vec2. constexpr inline Vec2 GetVec2(const Vector2D value) { return Vec2(value); } + /// @brief Gets an invalid value for the Vec2 type. template <> constexpr inline Vec2 GetInvalid() noexcept { return Vec2{GetInvalid(), GetInvalid()}; } - /// Does this vector contain finite coordinates? + /// @brief Determines whether the given vector contains finite coordinates. template constexpr inline bool IsValid(const Vector2D& value) noexcept { return IsValid(Get<0>(value)) && IsValid(Get<1>(value)); } + /// @brief Equality operator. template - constexpr bool operator == (const Vector2D a, const Vector2D b) noexcept + constexpr bool operator== (const Vector2D a, const Vector2D b) noexcept { return (Get<0>(a) == Get<0>(b)) && (Get<1>(a) == Get<1>(b)); } + /// @brief Inequality operator. template - constexpr bool operator != (const Vector2D a, const Vector2D b) noexcept + constexpr bool operator!= (const Vector2D a, const Vector2D b) noexcept { return !(a == b); } @@ -117,28 +121,32 @@ namespace playrho return lhs; } + /// @brief Multiplication assignment operator. template - constexpr Vector2D& operator *= (Vector2D& lhs, const Real rhs) noexcept + constexpr Vector2D& operator*= (Vector2D& lhs, const Real rhs) noexcept { Get<0>(lhs) *= rhs; Get<1>(lhs) *= rhs; return lhs; } + /// @brief Division assignment operator. template - constexpr Vector2D& operator /= (Vector2D& lhs, const Real rhs) noexcept + constexpr Vector2D& operator/= (Vector2D& lhs, const Real rhs) noexcept { Get<0>(lhs) /= rhs; Get<1>(lhs) /= rhs; return lhs; } + /// @brief Positive operator. template constexpr auto operator+ (const Vector2D v) noexcept { return Vector2D{+Get<0>(v), +Get<1>(v)}; } + /// @brief Negation operator. template constexpr auto operator- (const Vector2D v) noexcept { @@ -159,18 +167,21 @@ namespace playrho return lhs -= rhs; } + /// @brief Multiplication operator. template - constexpr inline Vector2D operator * (const TYPE1 s, Vector2D a) noexcept + constexpr inline Vector2D operator* (const TYPE1 s, Vector2D a) noexcept { return Vector2D{Get<0>(a) * s, Get<1>(a) * s}; } + /// @brief Multiplication operator. template - constexpr inline Vector2D operator * (Vector2D a, const TYPE2 s) noexcept + constexpr inline Vector2D operator* (Vector2D a, const TYPE2 s) noexcept { return Vector2D{Get<0>(a) * s, Get<1>(a) * s}; } + /// @brief Division operator. template constexpr Vector2D operator/ (Vector2D a, const TYPE2 s) noexcept { @@ -178,24 +189,28 @@ namespace playrho } #ifdef USE_BOOST_UNITS + /// @brief Gets an invalid value for the Length2D type. template <> constexpr Length2D GetInvalid() noexcept { return Length2D{GetInvalid(), GetInvalid()}; } + /// @brief Gets an invalid value for the LinearVelocity2D type. template <> constexpr LinearVelocity2D GetInvalid() noexcept { return LinearVelocity2D{GetInvalid(), GetInvalid()}; } + /// @brief Gets an invalid value for the Force2D type. template <> constexpr Force2D GetInvalid() noexcept { return Force2D{GetInvalid(), GetInvalid()}; } + /// @brief Gets an invalid value for the Momentum2D type. template <> constexpr Momentum2D GetInvalid() noexcept { diff --git a/PlayRho/Common/Vector3D.hpp b/PlayRho/Common/Vector3D.hpp index 57d13fc9e9..d0bae7079b 100644 --- a/PlayRho/Common/Vector3D.hpp +++ b/PlayRho/Common/Vector3D.hpp @@ -31,15 +31,17 @@ namespace playrho template using Vector3D = Vector<3, T>; + /// @brief Equality operator. template - constexpr inline bool operator == (const Vector3D a, const Vector3D b) noexcept + constexpr inline bool operator== (const Vector3D a, const Vector3D b) noexcept { return (Get<0>(a) == Get<0>(b)) && (Get<1>(a) == Get<1>(b)) && (Get<2>(a) == Get<2>(b)); } + /// @brief Inequality operator. template - constexpr inline bool operator != (const Vector3D a, const Vector3D b) noexcept + constexpr inline bool operator!= (const Vector3D a, const Vector3D b) noexcept { return !(a == b); } @@ -64,8 +66,9 @@ namespace playrho return lhs; } + /// @brief Multiplication assignment operator. template - constexpr Vector3D& operator *= (Vector3D& lhs, const Real rhs) noexcept + constexpr Vector3D& operator*= (Vector3D& lhs, const Real rhs) noexcept { Get<0>(lhs) *= rhs; Get<1>(lhs) *= rhs; @@ -73,8 +76,9 @@ namespace playrho return lhs; } + /// @brief Division assignment operator. template - constexpr Vector3D& operator /= (Vector3D& lhs, const Real rhs) noexcept + constexpr Vector3D& operator/= (Vector3D& lhs, const Real rhs) noexcept { Get<0>(lhs) /= rhs; Get<1>(lhs) /= rhs; @@ -82,12 +86,14 @@ namespace playrho return lhs; } + /// @brief Positive operator. template constexpr auto operator+ (const Vector3D v) noexcept { return Vector3D{+Get<0>(v), +Get<1>(v), +Get<2>(v)}; } + /// @brief Negation operator. template constexpr auto operator- (const Vector3D v) noexcept { @@ -108,18 +114,21 @@ namespace playrho return lhs -= rhs; } + /// @brief Multiplication operator. template - constexpr inline Vector3D operator * (const TYPE1 s, Vector3D a) noexcept + constexpr inline Vector3D operator* (const TYPE1 s, Vector3D a) noexcept { return a *= s; } + /// @brief Multiplication operator. template - constexpr inline Vector3D operator * (Vector3D a, const TYPE2 s) noexcept + constexpr inline Vector3D operator* (Vector3D a, const TYPE2 s) noexcept { return a *= s; } + /// @brief Division operator. template constexpr Vector3D operator/ (Vector3D a, const TYPE2 s) noexcept { @@ -135,13 +144,14 @@ namespace playrho /// @see Vec3. constexpr auto Vec3_zero = Vec3{0, 0, 0}; + /// @brief Gets an invalid value for the Vec3 type. template <> constexpr inline Vec3 GetInvalid() noexcept { return Vec3{GetInvalid(), GetInvalid(), GetInvalid()}; } - /// Does this vector contain finite coordinates? + /// @brief Determines whether the given vector contains finite coordinates. template <> constexpr inline bool IsValid(const Vec3& value) noexcept { diff --git a/PlayRho/Common/Velocity.hpp b/PlayRho/Common/Velocity.hpp index 954beef8e4..60b85015f6 100644 --- a/PlayRho/Common/Velocity.hpp +++ b/PlayRho/Common/Velocity.hpp @@ -35,22 +35,26 @@ namespace playrho AngularVelocity angular; ///< Angular velocity. }; + /// @brief Determines if the given value is valid. template <> constexpr inline bool IsValid(const Velocity& value) noexcept { return IsValid(value.linear) && IsValid(value.angular); } + /// @brief Equality operator. constexpr inline bool operator==(const Velocity& lhs, const Velocity& rhs) { return (lhs.linear == rhs.linear) && (lhs.angular == rhs.angular); } + /// @brief Inequality operator. constexpr inline bool operator!=(const Velocity& lhs, const Velocity& rhs) { return (lhs.linear != rhs.linear) || (lhs.angular != rhs.angular); } + /// @brief Multiplication assignment operator. constexpr inline Velocity& operator*= (Velocity& lhs, const Real rhs) { lhs.linear *= rhs; @@ -58,6 +62,7 @@ namespace playrho return lhs; } + /// @brief Division assignment operator. constexpr inline Velocity& operator/= (Velocity& lhs, const Real rhs) { lhs.linear /= rhs; @@ -65,6 +70,7 @@ namespace playrho return lhs; } + /// @brief Addition assignment operator. constexpr inline Velocity& operator+= (Velocity& lhs, const Velocity& rhs) { lhs.linear += rhs.linear; @@ -72,11 +78,13 @@ namespace playrho return lhs; } + /// @brief Addition operator. constexpr inline Velocity operator+ (const Velocity& lhs, const Velocity& rhs) { return Velocity{lhs.linear + rhs.linear, lhs.angular + rhs.angular}; } + /// @brief Subtraction assignment operator. constexpr inline Velocity& operator-= (Velocity& lhs, const Velocity& rhs) { lhs.linear -= rhs.linear; @@ -84,31 +92,37 @@ namespace playrho return lhs; } + /// @brief Subtraction operator. constexpr inline Velocity operator- (const Velocity& lhs, const Velocity& rhs) { return Velocity{lhs.linear - rhs.linear, lhs.angular - rhs.angular}; } + /// @brief Negation operator. constexpr inline Velocity operator- (const Velocity& value) { return Velocity{-value.linear, -value.angular}; } + /// @brief Positive operator. constexpr inline Velocity operator+ (const Velocity& value) { return value; } + /// @brief Multiplication operator. constexpr inline Velocity operator* (const Velocity& lhs, const Real rhs) { return Velocity{lhs.linear * rhs, lhs.angular * rhs}; } + /// @brief Multiplication operator. constexpr inline Velocity operator* (const Real lhs, const Velocity& rhs) { return Velocity{rhs.linear * lhs, rhs.angular * lhs}; } + /// @brief Division operator. constexpr inline Velocity operator/ (const Velocity& lhs, const Real rhs) { /* diff --git a/PlayRho/Common/Version.hpp b/PlayRho/Common/Version.hpp index 80e4884cff..5ab9e71f54 100644 --- a/PlayRho/Common/Version.hpp +++ b/PlayRho/Common/Version.hpp @@ -31,25 +31,30 @@ namespace playrho { /// See http://en.wikipedia.org/wiki/Software_versioning struct Version { + /// @brief Revision number type. using revnum_type = std::int32_t; - revnum_type major; ///< significant changes - revnum_type minor; ///< incremental changes - revnum_type revision; ///< bug fixes + revnum_type major; ///< significant changes + revnum_type minor; ///< incremental changes + revnum_type revision; ///< bug fixes }; + /// @brief Equality operator. constexpr inline bool operator== (Version lhs, Version rhs) { return lhs.major == rhs.major && lhs.minor == rhs.minor && lhs.revision == rhs.revision; } + /// @brief Inequality operator. constexpr inline bool operator!= (Version lhs, Version rhs) { return !(lhs == rhs); } + /// @brief Gets the version information of the library. Version GetVersion() noexcept; + /// @brief Gets the build details of the library. std::string GetBuildDetails() noexcept; } // namepsace playrho diff --git a/PlayRho/Common/VertexSet.hpp b/PlayRho/Common/VertexSet.hpp index 37e9496861..0ecce3a9fc 100644 --- a/PlayRho/Common/VertexSet.hpp +++ b/PlayRho/Common/VertexSet.hpp @@ -34,21 +34,27 @@ namespace playrho class VertexSet { public: + + /// @brief Constant pointer type. using const_pointer = const Length2D*; + /// @brief Gets the default minimum separation squared value. static Area GetDefaultMinSeparationSquared() { return Sqrt(std::numeric_limits::min()) * SquareMeter; } + /// @brief Initializing constructor. VertexSet(Area minSepSquared = GetDefaultMinSeparationSquared()): m_minSepSquared{minSepSquared} { assert(minSepSquared >= Area{0}); } + /// @brief Gets the min separation squared. Area GetMinSeparationSquared() const noexcept { return m_minSepSquared; } + /// @brief Adds the given vertex into the set if allowed. bool add(Length2D value) { if (find(value) != end()) @@ -59,15 +65,19 @@ namespace playrho return true; } + /// @brief Clear this set. void clear() noexcept { m_elements.clear(); } + /// @brief Gets the current size of this set. std::size_t size() const noexcept { return m_elements.size(); } + /// @brief Gets the "begin" iterator value. const_pointer begin() const { return m_elements.data(); } + /// @brief Gets the "end" iterator value. const_pointer end() const { return m_elements.data() + m_elements.size(); } /// Finds contained point whose delta with the given point has a squared length less @@ -83,6 +93,7 @@ namespace playrho }); } + /// @brief Indexed access. Length2D operator[](std::size_t index) const noexcept { return m_elements[index]; diff --git a/PlayRho/Common/Wider.hpp b/PlayRho/Common/Wider.hpp index f46c61ffaa..76741bdf6d 100644 --- a/PlayRho/Common/Wider.hpp +++ b/PlayRho/Common/Wider.hpp @@ -36,37 +36,57 @@ namespace playrho template struct Wider {}; /// @brief Specialization of the Wider trait for signed 8-bit integers. -template <> struct Wider { using type = std::int16_t; }; +template <> struct Wider { + using type = std::int16_t; ///< Wider type. +}; /// @brief Specialization of the Wider trait for unsigned 8-bit integers. -template <> struct Wider { using type = std::uint16_t; }; +template <> struct Wider { + using type = std::uint16_t; ///< Wider type. +}; /// @brief Specialization of the Wider trait for signed 16-bit integers. -template <> struct Wider { using type = std::int32_t; }; +template <> struct Wider { + using type = std::int32_t; ///< Wider type. +}; /// @brief Specialization of the Wider trait for unsigned 16-bit integers. -template <> struct Wider { using type = std::uint32_t; }; +template <> struct Wider { + using type = std::uint32_t; ///< Wider type. +}; /// @brief Specialization of the Wider trait for signed 32-bit integers. -template <> struct Wider { using type = std::int64_t; }; +template <> struct Wider { + using type = std::int64_t; ///< Wider type. +}; /// @brief Specialization of the Wider trait for unsigned 32-bit integers. -template <> struct Wider { using type = std::uint64_t; }; +template <> struct Wider { + using type = std::uint64_t; ///< Wider type. +}; /// @brief Specialization of the Wider trait for float. -template <> struct Wider { using type = double; }; +template <> struct Wider { + using type = double; ///< Wider type. +}; /// @brief Specialization of the Wider trait for double. -template <> struct Wider { using type = long double; }; +template <> struct Wider { + using type = long double; ///< Wider type. +}; #ifndef _WIN32 // Note: __int128_t not defined for Windows! /// @brief Specialization of the Wider trait for signed 64-bit integers. -template <> struct Wider { using type = __int128_t; }; +template <> struct Wider { + using type = __int128_t; ///< Wider type. +}; /// @brief Specialization of the Wider trait for unsigned 64-bit integers. -template <> struct Wider { using type = __uint128_t; }; +template <> struct Wider { + using type = __uint128_t; ///< Wider type. +}; #endif @@ -79,7 +99,9 @@ namespace std { // define it here explicitly in case it's not. /// @brief Make unsigned specialization for the __int128_t type. -template <> struct make_unsigned<__int128_t> { typedef __uint128_t type; }; +template <> struct make_unsigned<__int128_t> { + typedef __uint128_t type; ///< Wider type. +}; #endif } diff --git a/PlayRho/Dynamics/Body.hpp b/PlayRho/Dynamics/Body.hpp index 80b2683aee..620bbbff1d 100644 --- a/PlayRho/Dynamics/Body.hpp +++ b/PlayRho/Dynamics/Body.hpp @@ -70,6 +70,7 @@ class Body /// @brief Container type for fixtures. using Fixtures = std::vector; + /// @brief Keyed joint pointer. using KeyedJointPtr = std::pair; /// @brief Container type for joints. @@ -78,6 +79,7 @@ class Body /// @brief Container type for contacts. using Contacts = std::vector>; + /// @brief Invalid island index. static constexpr auto InvalidIslandIndex = static_cast(-1); /// @brief Flags type. @@ -122,7 +124,10 @@ class Body e_massDataDirtyFlag = 0x0200, }; + /// @brief Gets the flags for the given value. static FlagsType GetFlags(const BodyType type) noexcept; + + /// @brief Gets the flags for the given value. static FlagsType GetFlags(const BodyDef& bd) noexcept; /// @brief Initializing constructor for unit testing purposes. @@ -167,6 +172,7 @@ class Body /// bool DestroyFixture(Fixture* fixture, bool resetMassData = true); + /// @brief Destory fixtures. void DestroyFixtures(); /// @brief Sets the position of the body's origin and rotation. @@ -194,6 +200,7 @@ class Body /// @return World location of the body's origin. Length2D GetLocation() const noexcept; + /// @brief Gets the body's sweep. const Sweep& GetSweep() const noexcept; /// @brief Get the angle. @@ -206,6 +213,7 @@ class Body /// @brief Gets the local position of the center of mass. Length2D GetLocalCenter() const noexcept; + /// @brief Gets the velocity. Velocity GetVelocity() const noexcept; /// @brief Sets the body's velocity (linear and angular velocity). @@ -841,6 +849,7 @@ inline bool Unawaken(Body& body) noexcept /// @return true if either body is dynamic and no joint prevents collision, false otherwise. bool ShouldCollide(const Body& lhs, const Body& rhs) noexcept; +/// @brief Gets the "position 1" Position information for the given body. inline Position GetPosition1(const Body& body) noexcept { return body.GetSweep().pos1; @@ -856,11 +865,13 @@ inline Mass GetMass(const Body& body) noexcept return (invMass != InvMass{0})? Mass{Real{1} / invMass}: Mass{0}; } +/// @brief Applies the given linear acceleration to the given body. inline void ApplyLinearAcceleration(Body& body, const LinearAcceleration2D amount) { body.SetAcceleration(body.GetLinearAcceleration() + amount, body.GetAngularAcceleration()); } +/// @brief Sets the given amount of force at the given point to the given body. inline void SetForce(Body& body, const Force2D force, const Length2D point) noexcept { const auto linAccel = LinearAcceleration2D{force * body.GetInvMass()}; @@ -902,6 +913,7 @@ inline void ApplyForceToCenter(Body& body, const Force2D force) noexcept body.SetAcceleration(linAccel, angAccel); } +/// @brief Sets the given amount of torque to the given body. inline void SetTorque(Body& body, const Torque torque) noexcept { const auto linAccel = body.GetLinearAcceleration(); @@ -953,6 +965,8 @@ inline void ApplyAngularImpulse(Body& body, AngularMomentum impulse) noexcept body.SetVelocity(velocity); } +/// @brief Gets the centripetal force necessary to put the body into an orbit having +/// the given radius. Force2D GetCentripetalForce(const Body& body, const Length2D axis); /// Gets the rotational inertia of the body. @@ -1021,6 +1035,7 @@ inline Length2D GetWorldVector(const Body& body, const Length2D localVector) noe return Rotate(localVector, body.GetTransformation().q); } +/// @brief Gets the world vector for the given local vector from the given body's transformation. inline UnitVec2 GetWorldVector(const Body& body, const UnitVec2 localVector) noexcept { return Rotate(localVector, body.GetTransformation().q); @@ -1068,11 +1083,13 @@ inline LinearVelocity2D GetLinearVelocityFromLocalPoint(const Body& body, return GetLinearVelocityFromWorldPoint(body, GetWorldPoint(body, localPoint)); } +/// @brief Gets the net force that the given body is currently experiencing. inline Force2D GetForce(const Body& body) noexcept { return body.GetLinearAcceleration() * GetMass(body); } +/// @brief Gets the net torque that the given body is currently experiencing. inline Torque GetTorque(const Body& body) noexcept { return body.GetAngularAcceleration() * GetRotInertia(body); @@ -1086,8 +1103,10 @@ inline Torque GetTorque(const Body& body) noexcept /// @param conf Movement configuration. This defines caps on linear and angular speeds. Velocity GetVelocity(const Body& body, const Time h, MovementConf conf) noexcept; +/// @brief Gets the world index for the given body. BodyCounter GetWorldIndex(const Body* body); +/// @brief Gets the fixture count of the given body. std::size_t GetFixtureCount(const Body& body); /// Rotates a body a given amount around a point in world coordinates. diff --git a/PlayRho/Dynamics/BodyDef.hpp b/PlayRho/Dynamics/BodyDef.hpp index 520442bc8f..f1768a24e7 100644 --- a/PlayRho/Dynamics/BodyDef.hpp +++ b/PlayRho/Dynamics/BodyDef.hpp @@ -47,21 +47,52 @@ namespace playrho { // Builder-styled methods... + /// @brief Use the given type. constexpr BodyDef& UseType(BodyType t) noexcept; + + /// @brief Use the given location. constexpr BodyDef& UseLocation(Length2D l) noexcept; + + /// @brief Use the given angle. constexpr BodyDef& UseAngle(Angle a) noexcept; + + /// @brief Use the given linear velocity. constexpr BodyDef& UseLinearVelocity(LinearVelocity2D v) noexcept; + + /// @brief Use the given angular velocity. constexpr BodyDef& UseAngularVelocity(AngularVelocity v) noexcept; + + /// @brief Use the given linear acceleration. constexpr BodyDef& UseLinearAcceleration(LinearAcceleration2D v) noexcept; + + /// @brief Use the given angular acceleration. constexpr BodyDef& UseAngularAcceleration(AngularAcceleration v) noexcept; + + /// @brief Use the given linear damping. constexpr BodyDef& UseLinearDamping(NonNegative v) noexcept; + + /// @brief Use the given angular damping. constexpr BodyDef& UseAngularDamping(NonNegative v) noexcept; + + /// @brief Use the given under active time. constexpr BodyDef& UseUnderActiveTime(Time v) noexcept; + + /// @brief Use the given allow sleep value. constexpr BodyDef& UseAllowSleep(bool value) noexcept; + + /// @brief Use the given awake value. constexpr BodyDef& UseAwake(bool value) noexcept; + + /// @brief Use the given fixed rotation state. constexpr BodyDef& UseFixedRotation(bool value) noexcept; + + /// @brief Use the given bullet state. constexpr BodyDef& UseBullet(bool value) noexcept; + + /// @brief Use the given enabled state. constexpr BodyDef& UseEnabled(bool value) noexcept; + + /// @brief Use the given user data. constexpr BodyDef& UseUserData(void* value) noexcept; // Public member variables... @@ -224,11 +255,13 @@ namespace playrho return *this; } + /// @brief Gets the default body definition. constexpr BodyDef GetDefaultBodyDef() noexcept { return BodyDef{}; } + /// @brief Gets the body definition for the given body. BodyDef GetBodyDef(const Body& body) noexcept; } // namespace playrho diff --git a/PlayRho/Dynamics/Contacts/BodyConstraint.hpp b/PlayRho/Dynamics/Contacts/BodyConstraint.hpp index 43cb628c6f..a19ecf5062 100644 --- a/PlayRho/Dynamics/Contacts/BodyConstraint.hpp +++ b/PlayRho/Dynamics/Contacts/BodyConstraint.hpp @@ -36,10 +36,12 @@ namespace playrho { public: // Note: Seeing World.TilesComesToRest times of around 5686 ms with this setup. + /// @brief Index type. using index_type = std::remove_const::type; BodyConstraint() = default; + /// @brief Initializing constructor. constexpr BodyConstraint(InvMass invMass, InvRotInertia invRotI, Length2D localCenter, Position position, Velocity velocity) noexcept: m_position{position}, @@ -132,6 +134,7 @@ namespace playrho { return *this; } + /// @brief Gets the BodyConstraint based on the given parameters. inline BodyConstraint GetBodyConstraint(const Body& body, Time time, MovementConf conf) noexcept { diff --git a/PlayRho/Dynamics/Contacts/Contact.hpp b/PlayRho/Dynamics/Contacts/Contact.hpp index b9395e1723..75951572c9 100644 --- a/PlayRho/Dynamics/Contacts/Contact.hpp +++ b/PlayRho/Dynamics/Contacts/Contact.hpp @@ -71,15 +71,18 @@ inline Real MixRestitution(Real restitution1, Real restitution2) noexcept class Contact { public: + + /// @brief Substep type. using substep_type = ts_iters_t; /// @brief Update configuration. struct UpdateConf { - DistanceConf distance; - Manifold::Conf manifold; + DistanceConf distance; ///< Distance configuration data. + Manifold::Conf manifold; ///< Manifold configuration data. }; + /// @brief Gets the update configuration from the given step configuration data. static UpdateConf GetUpdateConf(const StepConf& conf) noexcept; /// @brief Initializing constructor. @@ -100,8 +103,10 @@ class Contact /// Contact(Fixture* fixtureA, ChildCounter indexA, Fixture* fixtureB, ChildCounter indexB); + /// @brief Default construction not allowed. Contact() = delete; + /// @brief Copy constructor. Contact(const Contact& copy) = default; /// @brief Gets the contact manifold. @@ -487,13 +492,17 @@ inline void Contact::UnsetIslanded() noexcept } // Free functions... - + +/// @brief Contact pointer type. using ContactPtr = Contact*; +/// @brief Whether the given contact has a sensor. bool HasSensor(const Contact& contact) noexcept; +/// @brief Whether the given contact is "impenetrable". bool IsImpenetrable(const Contact& contact) noexcept; +/// @brief Sets awake the fixtures of the given contact. void SetAwake(const Contact& c) noexcept; /// Resets the friction mixture to the default value. @@ -502,6 +511,7 @@ void ResetFriction(Contact& contact); /// Reset the restitution to the default value. void ResetRestitution(Contact& contact) noexcept; +/// @brief Calculates the Time Of Impact for the given contact with the given configuration. TOIOutput CalcToi(const Contact& contact, const ToiConf conf); } // namespace playrho diff --git a/PlayRho/Dynamics/Contacts/ContactKey.hpp b/PlayRho/Dynamics/Contacts/ContactKey.hpp index 8b309bef13..a33c7f9b0b 100644 --- a/PlayRho/Dynamics/Contacts/ContactKey.hpp +++ b/PlayRho/Dynamics/Contacts/ContactKey.hpp @@ -40,6 +40,8 @@ namespace playrho class ContactKey { public: + + /// @brief Index type. using Index = ContactCounter; constexpr ContactKey() noexcept @@ -47,17 +49,20 @@ namespace playrho // Intentionally empty } + /// @brief Initializing constructor. constexpr ContactKey(Index fp1, Index fp2) noexcept: m_ids{std::minmax(fp1, fp2)} { // Intentionally empty } + /// @brief Gets the minimum index value. constexpr Index GetMin() const noexcept { return m_ids.first; } + /// @brief Gets the maximum index value. constexpr Index GetMax() const noexcept { return m_ids.second; @@ -67,49 +72,65 @@ namespace playrho std::pair m_ids{static_cast(-1), static_cast(-1)}; }; + /// @brief Equality operator. constexpr bool operator== (const ContactKey lhs, const ContactKey rhs) noexcept { return lhs.GetMin() == rhs.GetMin() && lhs.GetMax() == rhs.GetMax(); } + /// @brief Inequality operator. constexpr bool operator!= (const ContactKey lhs, const ContactKey rhs) noexcept { return !(lhs == rhs); } + /// @brief Less-than operator. constexpr bool operator< (const ContactKey lhs, const ContactKey rhs) noexcept { return (lhs.GetMin() < rhs.GetMin()) || ((lhs.GetMin() == rhs.GetMin()) && (lhs.GetMax() < rhs.GetMax())); } + /// @brief Less-than or equal-to operator. constexpr bool operator<= (const ContactKey lhs, const ContactKey rhs) noexcept { return (lhs.GetMin() < rhs.GetMin()) || ((lhs.GetMin() == rhs.GetMin()) && (lhs.GetMax() <= rhs.GetMax())); } + /// @brief Greater-than operator. constexpr bool operator> (const ContactKey lhs, const ContactKey rhs) noexcept { return (lhs.GetMin() > rhs.GetMin()) || ((lhs.GetMin() == rhs.GetMin()) && (lhs.GetMax() > rhs.GetMax())); } + /// @brief Greater-than or equal-to operator. constexpr bool operator>= (const ContactKey lhs, const ContactKey rhs) noexcept { return (lhs.GetMin() > rhs.GetMin()) || ((lhs.GetMin() == rhs.GetMin()) && (lhs.GetMax() >= rhs.GetMax())); } + /// @brief Keyed contact pointer. using KeyedContactPtr = std::pair; + /// @brief Gets the ContactKey for the given parameters. ContactKey GetContactKey(const FixtureProxy& fpA, const FixtureProxy& fpB) noexcept; + /// @brief Gets the ContactKey for the given parameters. ContactKey GetContactKey(const Fixture* fixtureA, ChildCounter childIndexA, const Fixture* fixtureB, ChildCounter childIndexB) noexcept; + /// @brief Gets the ContactKey for the given contact. ContactKey GetContactKey(const Contact& contact) noexcept; + /// @brief Gets the contact pointer for the given value. + inline Contact* GetContactPtr(KeyedContactPtr value) + { + return value.second; + } + } // namespace playrho namespace std @@ -118,9 +139,13 @@ namespace std template <> struct hash { + /// @brief Argument type. using argument_type = playrho::ContactKey; + + /// @brief Result type. using result_type = std::size_t; + /// @brief Function object operator. constexpr std::size_t operator()(const playrho::ContactKey& key) const { // Use simple and fast Knuth multiplicative hash... @@ -131,12 +156,4 @@ namespace std }; } -namespace playrho -{ - inline Contact* GetContactPtr(KeyedContactPtr value) - { - return value.second; - } -} - #endif /* ContactKey_hpp */ diff --git a/PlayRho/Dynamics/Contacts/ContactSolver.hpp b/PlayRho/Dynamics/Contacts/ContactSolver.hpp index a741bdb427..200fdb350c 100644 --- a/PlayRho/Dynamics/Contacts/ContactSolver.hpp +++ b/PlayRho/Dynamics/Contacts/ContactSolver.hpp @@ -31,11 +31,12 @@ namespace playrho { /// @brief Solution for position constraint. struct PositionSolution { - Position pos_a; - Position pos_b; - Length min_separation; + Position pos_a; ///< Position A. + Position pos_b; ///< Position B. + Length min_separation; ///< Min separation. }; + /// @brief Addition operator. inline PositionSolution operator+ (PositionSolution lhs, PositionSolution rhs) { return PositionSolution{ @@ -45,6 +46,7 @@ namespace playrho { }; } + /// @brief Subtraction operator. inline PositionSolution operator- (PositionSolution lhs, PositionSolution rhs) { return PositionSolution{ @@ -60,14 +62,19 @@ namespace playrho { /// @sa SolvePositionConstraint. struct ConstraintSolverConf { + /// @brief Uses the given resolution rate. ConstraintSolverConf& UseResolutionRate(Real value) noexcept; + /// @brief Uses the given linear slop. ConstraintSolverConf& UseLinearSlop(Length value) noexcept; + /// @brief Uses the given angular slop. ConstraintSolverConf& UseAngularSlop(Angle value) noexcept; + /// @brief Uses the given max linear correction. ConstraintSolverConf& UseMaxLinearCorrection(Length value) noexcept; + /// @brief Uses the given max angular correction. ConstraintSolverConf& UseMaxAngularCorrection(Angle value) noexcept; /// Resolution rate. @@ -132,11 +139,13 @@ namespace playrho { return *this; } + /// @brief Gets the default position solver configuration. inline ConstraintSolverConf GetDefaultPositionSolverConf() { return ConstraintSolverConf{}.UseResolutionRate(Real(0.2)); } + /// @brief Gets the default TOI position solver configuration. inline ConstraintSolverConf GetDefaultToiPositionSolverConf() { // For solving TOI events, use a faster/higher resolution rate than normally used. diff --git a/PlayRho/Dynamics/Contacts/PositionConstraint.hpp b/PlayRho/Dynamics/Contacts/PositionConstraint.hpp index 43a2115a4f..d64c2e4107 100644 --- a/PlayRho/Dynamics/Contacts/PositionConstraint.hpp +++ b/PlayRho/Dynamics/Contacts/PositionConstraint.hpp @@ -30,10 +30,12 @@ namespace playrho { class PositionConstraint { public: + /// @brief Size type. using size_type = std::remove_const::type; PositionConstraint() = default; + /// @brief Initializing constructor. PositionConstraint(const Manifold& m, BodyConstraint& bA, Length rA, BodyConstraint& bB, Length rB): @@ -47,12 +49,16 @@ namespace playrho { Manifold manifold; ///< Copy of contact's manifold with 1 or more contact points (60-bytes). + /// @brief Gets body A. BodyConstraint* GetBodyA() const noexcept { return m_bodyA; } + /// @brief Gets body B. BodyConstraint* GetBodyB() const noexcept { return m_bodyB; } + /// @brief Gets radius A. Length GetRadiusA() const noexcept { return m_radiusA; } + /// @brief Gets radius B. Length GetRadiusB() const noexcept { return m_radiusB; } private: diff --git a/PlayRho/Dynamics/Contacts/VelocityConstraint.hpp b/PlayRho/Dynamics/Contacts/VelocityConstraint.hpp index 28a10aacce..745fde12ed 100644 --- a/PlayRho/Dynamics/Contacts/VelocityConstraint.hpp +++ b/PlayRho/Dynamics/Contacts/VelocityConstraint.hpp @@ -41,17 +41,22 @@ namespace playrho { class VelocityConstraint { public: + + /// @brief Size type. using size_type = std::remove_const::type; + + /// @brief Index type. using index_type = std::size_t; /// @brief Configuration data for velocity constraints. struct Conf { - Real dtRatio = Real(1); - LinearVelocity velocityThreshold = DefaultVelocityThreshold; - bool blockSolve = true; + Real dtRatio = Real(1); ///< Delta time ratio. + LinearVelocity velocityThreshold = DefaultVelocityThreshold; ///< Velocity threshold. + bool blockSolve = true; ///< Whether to block solve. }; + /// @brief Gets the default configuration for a VelocityConstraint. static constexpr Conf GetDefaultConf() noexcept { return Conf{}; @@ -63,10 +68,13 @@ namespace playrho { /// an invalid normal, invalid friction, invalid restitution, an invalid tangent speed. VelocityConstraint() = default; + /// @brief Copy constructor. VelocityConstraint(const VelocityConstraint& copy) = default; + /// @brief Assignment operator. VelocityConstraint& operator= (const VelocityConstraint& copy) = default; + /// @brief Initializing constructor. VelocityConstraint(Real friction, Real restitution, LinearVelocity tangentSpeed, const WorldManifold& worldManifold, BodyConstraint& bA, @@ -79,8 +87,10 @@ namespace playrho { /// otherwise. UnitVec2 GetNormal() const noexcept { return m_normal; } + /// @brief Gets the tangent. UnitVec2 GetTangent() const noexcept { return GetFwdPerpendicular(m_normal); } + /// @brief Gets the inverse mass. InvMass GetInvMass() const noexcept { return m_invMass; } /// Gets the count of points added to this object. @@ -108,8 +118,10 @@ namespace playrho { /// Gets the tangent speed of the associated contact. LinearVelocity GetTangentSpeed() const noexcept { return m_tangentSpeed; } + /// @brief Gets body A. BodyConstraint* GetBodyA() const noexcept { return m_bodyA; } + /// @brief Gets body B. BodyConstraint* GetBodyB() const noexcept { return m_bodyB; } /// Gets the normal impulse at the given point. @@ -159,8 +171,10 @@ namespace playrho { /// @return Previously set value or an invalid value. Length2D GetPointRelPosB(size_type index) const noexcept; + /// @brief Sets the normal impulse at the given point. void SetNormalImpulseAtPoint(size_type index, Momentum value); + /// @brief Sets the tangent impulse at the given point. void SetTangentImpulseAtPoint(size_type index, Momentum value); /// @brief Velocity constraint point. @@ -302,6 +316,43 @@ namespace playrho { return GetPointAt(index).relB; } + inline LinearVelocity VelocityConstraint::GetVelocityBiasAtPoint(size_type index) const noexcept + { + return GetPointAt(index).velocityBias; + } + + inline Mass VelocityConstraint::GetNormalMassAtPoint(VelocityConstraint::size_type index) const noexcept + { + return GetPointAt(index).normalMass; + } + + inline Mass VelocityConstraint::GetTangentMassAtPoint(VelocityConstraint::size_type index) const noexcept + { + return GetPointAt(index).tangentMass; + } + + inline Momentum VelocityConstraint::GetNormalImpulseAtPoint(VelocityConstraint::size_type index) const noexcept + { + return GetPointAt(index).normalImpulse; + } + + inline Momentum VelocityConstraint::GetTangentImpulseAtPoint(VelocityConstraint::size_type index) const noexcept + { + return GetPointAt(index).tangentImpulse; + } + + inline void VelocityConstraint::SetNormalImpulseAtPoint(VelocityConstraint::size_type index, Momentum value) + { + PointAt(index).normalImpulse = value; + } + + inline void VelocityConstraint::SetTangentImpulseAtPoint(VelocityConstraint::size_type index, Momentum value) + { + PointAt(index).tangentImpulse = value; + } + + // Free functions... + /// Gets the normal of the velocity constraint contact in world coordinates. /// @note This value is set via the velocity constraint's SetNormal method. /// @return Contact normal (in world coordinates) if previously set, an invalid value @@ -311,112 +362,98 @@ namespace playrho { return vc.GetNormal(); } + /// @brief Gets the tangent from the given velocity constraint data. inline UnitVec2 GetTangent(const VelocityConstraint& vc) noexcept { return vc.GetTangent(); } + /// @brief Gets the inverse mass from the given velocity constraint data. inline InvMass GetInvMass(const VelocityConstraint& vc) noexcept { return vc.GetBodyA()->GetInvMass() + vc.GetBodyB()->GetInvMass(); } - inline Length2D GetPointRelPosA(const VelocityConstraint& vc, VelocityConstraint::size_type index) + /// @brief Gets the point relative position A data. + inline Length2D GetPointRelPosA(const VelocityConstraint& vc, + VelocityConstraint::size_type index) { return vc.GetPointRelPosA(index); } - inline Length2D GetPointRelPosB(const VelocityConstraint& vc, VelocityConstraint::size_type index) + /// @brief Gets the point relative position B data. + inline Length2D GetPointRelPosB(const VelocityConstraint& vc, + VelocityConstraint::size_type index) { return vc.GetPointRelPosB(index); } - inline LinearVelocity VelocityConstraint::GetVelocityBiasAtPoint(size_type index) const noexcept - { - return GetPointAt(index).velocityBias; - } - + /// @brief Gets the velocity bias at the given point from the given velocity constraint. inline LinearVelocity GetVelocityBiasAtPoint(const VelocityConstraint& vc, VelocityConstraint::size_type index) { return vc.GetVelocityBiasAtPoint(index); } - inline Mass VelocityConstraint::GetNormalMassAtPoint(VelocityConstraint::size_type index) const noexcept - { - return GetPointAt(index).normalMass; - } - - inline Mass VelocityConstraint::GetTangentMassAtPoint(VelocityConstraint::size_type index) const noexcept - { - return GetPointAt(index).tangentMass; - } - - inline Mass GetNormalMassAtPoint(const VelocityConstraint& vc, VelocityConstraint::size_type index) + /// @brief Gets the normal mass at the given point from the given velocity constraint. + inline Mass GetNormalMassAtPoint(const VelocityConstraint& vc, + VelocityConstraint::size_type index) { return vc.GetNormalMassAtPoint(index); } - inline Mass GetTangentMassAtPoint(const VelocityConstraint& vc, VelocityConstraint::size_type index) + /// @brief Gets the tangent mass at the given point from the given velocity constraint. + inline Mass GetTangentMassAtPoint(const VelocityConstraint& vc, + VelocityConstraint::size_type index) { return vc.GetTangentMassAtPoint(index); } - inline Momentum VelocityConstraint::GetNormalImpulseAtPoint(VelocityConstraint::size_type index) const noexcept - { - return GetPointAt(index).normalImpulse; - } - - inline Momentum VelocityConstraint::GetTangentImpulseAtPoint(VelocityConstraint::size_type index) const noexcept - { - return GetPointAt(index).tangentImpulse; - } - - inline Momentum GetNormalImpulseAtPoint(const VelocityConstraint& vc, VelocityConstraint::size_type index) + /// @brief Gets the normal impulse at the given point from the given velocity constraint. + inline Momentum GetNormalImpulseAtPoint(const VelocityConstraint& vc, + VelocityConstraint::size_type index) { return vc.GetNormalImpulseAtPoint(index); } - inline Momentum GetTangentImpulseAtPoint(const VelocityConstraint& vc, VelocityConstraint::size_type index) + /// @brief Gets the tangent impulse at the given point from the given velocity constraint. + inline Momentum GetTangentImpulseAtPoint(const VelocityConstraint& vc, + VelocityConstraint::size_type index) { return vc.GetTangentImpulseAtPoint(index); } + /// @brief Gets the normal impulses of the given velocity constraint. inline Momentum2D GetNormalImpulses(const VelocityConstraint& vc) { return Momentum2D{GetNormalImpulseAtPoint(vc, 0), GetNormalImpulseAtPoint(vc, 1)}; } + /// @brief Gets the tangent impulses of the given velocity constraint. inline Momentum2D GetTangentImpulses(const VelocityConstraint& vc) { return Momentum2D{GetTangentImpulseAtPoint(vc, 0), GetTangentImpulseAtPoint(vc, 1)}; } - inline void VelocityConstraint::SetNormalImpulseAtPoint(VelocityConstraint::size_type index, Momentum value) - { - PointAt(index).normalImpulse = value; - } - - inline void VelocityConstraint::SetTangentImpulseAtPoint(VelocityConstraint::size_type index, Momentum value) - { - PointAt(index).tangentImpulse = value; - } - + /// @brief Sets the normal impulse at the given point of the given velocity constraint. inline void SetNormalImpulseAtPoint(VelocityConstraint& vc, VelocityConstraint::size_type index, Momentum value) { vc.SetNormalImpulseAtPoint(index, value); } + /// @brief Sets the tangent impulse at the given point of the given velocity constraint. inline void SetTangentImpulseAtPoint(VelocityConstraint& vc, VelocityConstraint::size_type index, Momentum value) { vc.SetTangentImpulseAtPoint(index, value); } + /// @brief Sets the normal impulses of the given velocity constraint. inline void SetNormalImpulses(VelocityConstraint& vc, const Momentum2D impulses) { SetNormalImpulseAtPoint(vc, 0, impulses[0]); SetNormalImpulseAtPoint(vc, 1, impulses[1]); } + /// @brief Sets the tangent impulses of the given velocity constraint. inline void SetTangentImpulses(VelocityConstraint& vc, const Momentum2D impulses) { SetTangentImpulseAtPoint(vc, 0, impulses[0]); diff --git a/PlayRho/Dynamics/Filter.hpp b/PlayRho/Dynamics/Filter.hpp index f87a66a38a..6ddd2c5ca7 100644 --- a/PlayRho/Dynamics/Filter.hpp +++ b/PlayRho/Dynamics/Filter.hpp @@ -59,6 +59,7 @@ namespace playrho { index_type groupIndex = 0; }; + /// @brief Determines whether collision processing should be performed. inline bool ShouldCollide(const Filter filterA, const Filter filterB) noexcept { if ((filterA.groupIndex == filterB.groupIndex) && (filterA.groupIndex != 0)) diff --git a/PlayRho/Dynamics/Fixture.hpp b/PlayRho/Dynamics/Fixture.hpp index b8e8ed11e3..1d72dd3d60 100644 --- a/PlayRho/Dynamics/Fixture.hpp +++ b/PlayRho/Dynamics/Fixture.hpp @@ -139,8 +139,10 @@ class Fixture /// @note This will _not_ change the restitution of existing contacts. void SetRestitution(Real restitution) noexcept; + /// @brief Gets the proxy count. ChildCounter GetProxyCount() const noexcept; + /// @brief Gets the proxy for the given index. const FixtureProxy* GetProxy(ChildCounter index) const noexcept; private: diff --git a/PlayRho/Dynamics/FixtureDef.hpp b/PlayRho/Dynamics/FixtureDef.hpp index a74c477846..74415bdb66 100644 --- a/PlayRho/Dynamics/FixtureDef.hpp +++ b/PlayRho/Dynamics/FixtureDef.hpp @@ -38,8 +38,14 @@ namespace playrho { /// struct FixtureDef { + + /// @brief Uses the given user data. constexpr FixtureDef& UseUserData(void* value) noexcept; + + /// @brief Uses the given sensor state value. constexpr FixtureDef& UseIsSensor(bool value) noexcept; + + /// @brief Uses the given filter value. constexpr FixtureDef& UseFilter(Filter value) noexcept; /// Use this to store application specific fixture data. @@ -71,11 +77,13 @@ namespace playrho { return *this; } + /// @brief Gets the default fixture definition. constexpr FixtureDef GetDefaultFixtureDef() noexcept { return FixtureDef{}; } + /// @brief Gets the fixture definition for the given fixture. FixtureDef GetFixtureDef(const Fixture& fixture) noexcept; } // namespace playrho diff --git a/PlayRho/Dynamics/FixtureProxy.hpp b/PlayRho/Dynamics/FixtureProxy.hpp index 666eed5f77..c3788bcb61 100644 --- a/PlayRho/Dynamics/FixtureProxy.hpp +++ b/PlayRho/Dynamics/FixtureProxy.hpp @@ -32,12 +32,16 @@ namespace playrho /// @note This data structure is 32-bytes large (on at least one 64-bit platform). struct FixtureProxy { + + /// @brief Size type. using size_type = std::remove_const::type; FixtureProxy() = default; + /// @brief Copy constructor. FixtureProxy(const FixtureProxy& copy) = default; + /// @brief Initializing constructor. FixtureProxy(const AABB bb, size_type pid, Fixture* f, ChildCounter ci): aabb{bb}, fixture{f}, proxyId{pid}, childIndex{ci} {} diff --git a/PlayRho/Dynamics/Island.hpp b/PlayRho/Dynamics/Island.hpp index a4fadd4e4b..aedd65f438 100644 --- a/PlayRho/Dynamics/Island.hpp +++ b/PlayRho/Dynamics/Island.hpp @@ -29,25 +29,34 @@ class Body; class Contact; class Joint; -/// Island. +/// @brief Island. /// @details A container of bodies contacts and joints relavent to handling world dynamics. /// @note This is an internal class. /// @note This data structure is 72-bytes large (on at least one 64-bit platform). class Island { public: + + /// @brief Body container type. using Bodies = std::vector; + + /// @brief Contact container type. using Contacts = std::vector; + + /// @brief Joint container type. using Joints = std::vector; + /// @brief Initializing constructor. Island(Bodies::size_type bodyCapacity, Contacts::size_type contactCapacity, Joints::size_type jointCapacity); + /// @brief Copy constructor. Island(const Island& copy) noexcept: m_bodies(copy.m_bodies), m_contacts(copy.m_contacts), m_joints(copy.m_joints) {} + /// @brief Move constructor. Island(Island&& other) noexcept: m_bodies{std::move(other.m_bodies)}, m_contacts{std::move(other.m_contacts)}, @@ -57,6 +66,7 @@ class Island /// Destructor. ~Island() = default; + /// @brief Assignment operator. Island& operator= (Island&& other) noexcept { m_bodies = std::move(other.m_bodies); @@ -65,23 +75,30 @@ class Island return *this; } - Bodies m_bodies; - Contacts m_contacts; - Joints m_joints; + Bodies m_bodies; ///< Body container. + Contacts m_contacts; ///< Contact container. + Joints m_joints; ///< Joint container. }; +/// @brief Determines whether the given island is full of bodies. inline bool IsFullOfBodies(const Island& island) { return island.m_bodies.size() == island.m_bodies.max_size(); } +/// @brief Determines whether the given island is full of contacts. inline bool IsFullOfContacts(const Island& island) { return island.m_contacts.size() == island.m_contacts.max_size(); } +/// @brief Counts the number of occurrances of the given entry in the given island. std::size_t Count(const Island& island, const Body* entry); + +/// @brief Counts the number of occurrances of the given entry in the given island. std::size_t Count(const Island& island, const Contact* entry); + +/// @brief Counts the number of occurrances of the given entry in the given island. std::size_t Count(const Island& island, const Joint* entry); } // namespace playrho diff --git a/PlayRho/Dynamics/Joints/DistanceJoint.hpp b/PlayRho/Dynamics/Joints/DistanceJoint.hpp index 3bab87c4a1..191542ee70 100644 --- a/PlayRho/Dynamics/Joints/DistanceJoint.hpp +++ b/PlayRho/Dynamics/Joints/DistanceJoint.hpp @@ -35,11 +35,15 @@ namespace playrho { class DistanceJoint : public Joint { public: + + /// @brief Is the given definition okay. static bool IsOkay(const DistanceJointDef& data) noexcept; + /// @brief Initializing constructor. DistanceJoint(const DistanceJointDef& data); Length2D GetAnchorA() const override; + Length2D GetAnchorB() const override; /// @brief Get the linear reaction. @@ -55,9 +59,11 @@ class DistanceJoint : public Joint /// @brief Gets the local anchor point relative to bodyB's origin. Length2D GetLocalAnchorB() const noexcept { return m_localAnchorB; } - /// Set/get the natural length. - /// Manipulating the length can lead to non-physical behavior when the frequency is zero. + /// @brief Sets the natural length. + /// @note Manipulating the length can lead to non-physical behavior when the frequency is zero. void SetLength(Length length) noexcept; + + /// @brief Gets the length. Length GetLength() const noexcept; /// @brief Sets frequency. @@ -66,8 +72,10 @@ class DistanceJoint : public Joint /// @brief Gets the frequency. NonNegative GetFrequency() const noexcept; - /// Set/get damping ratio. + /// @brief Sets the damping ratio. void SetDampingRatio(Real ratio) noexcept; + + /// @brief Gets damping ratio. Real GetDampingRatio() const noexcept; private: diff --git a/PlayRho/Dynamics/Joints/DistanceJointDef.hpp b/PlayRho/Dynamics/Joints/DistanceJointDef.hpp index 66c52a0cf5..7f0d32bcd5 100644 --- a/PlayRho/Dynamics/Joints/DistanceJointDef.hpp +++ b/PlayRho/Dynamics/Joints/DistanceJointDef.hpp @@ -39,10 +39,13 @@ class DistanceJoint; /// @warning Do not use a zero or short length. struct DistanceJointDef : public JointBuilder { + + /// @brief Super type. using super = JointBuilder; constexpr DistanceJointDef() noexcept: super{JointType::Distance} {} + /// @brief Copy constructor. DistanceJointDef(const DistanceJointDef& copy) = default; /// @brief Initializing constructor. @@ -51,10 +54,13 @@ struct DistanceJointDef : public JointBuilder Length2D anchorA = Length2D{}, Length2D anchorB = Length2D{}) noexcept; + /// @brief Uses the given length. constexpr DistanceJointDef& UseLength(Length v) noexcept; + /// @brief Uses the given frequency. constexpr DistanceJointDef& UseFrequency(NonNegative v) noexcept; + /// @brief Uses the given damping ratio. constexpr DistanceJointDef& UseDampingRatio(Real v) noexcept; /// @brief Local anchor point relative to bodyA's origin. @@ -93,6 +99,7 @@ constexpr DistanceJointDef& DistanceJointDef::UseDampingRatio(Real v) noexcept return *this; } +/// @brief Gets the definition data for the given joint. DistanceJointDef GetDistanceJointDef(const DistanceJoint& joint) noexcept; } // namespace playrho diff --git a/PlayRho/Dynamics/Joints/FrictionJoint.hpp b/PlayRho/Dynamics/Joints/FrictionJoint.hpp index f5aa339980..f6212b96c5 100644 --- a/PlayRho/Dynamics/Joints/FrictionJoint.hpp +++ b/PlayRho/Dynamics/Joints/FrictionJoint.hpp @@ -34,6 +34,8 @@ namespace playrho { class FrictionJoint : public Joint { public: + + /// @brief Initializing constructor. FrictionJoint(const FrictionJointDef& def); Length2D GetAnchorA() const override; diff --git a/PlayRho/Dynamics/Joints/FrictionJointDef.hpp b/PlayRho/Dynamics/Joints/FrictionJointDef.hpp index 6f7b89780a..7f59aae93e 100644 --- a/PlayRho/Dynamics/Joints/FrictionJointDef.hpp +++ b/PlayRho/Dynamics/Joints/FrictionJointDef.hpp @@ -34,6 +34,8 @@ class FrictionJoint; /// @brief Friction joint definition. struct FrictionJointDef : public JointBuilder { + + /// @brief Super type. using super = JointBuilder; constexpr FrictionJointDef() noexcept: super{JointType::Friction} {} @@ -43,8 +45,10 @@ struct FrictionJointDef : public JointBuilder /// anchor and world axis. FrictionJointDef(Body* bodyA, Body* bodyB, const Length2D anchor) noexcept; + /// @brief Uses the given maximum force value. constexpr FrictionJointDef& UseMaxForce(NonNegative v) noexcept; + /// @brief Uses the given maximum torque value. constexpr FrictionJointDef& UseMaxTorque(NonNegative v) noexcept; /// @brief Local anchor point relative to bodyA's origin. @@ -72,6 +76,7 @@ constexpr FrictionJointDef& FrictionJointDef::UseMaxTorque(NonNegative v return *this; } +/// @brief Gets the definition data for the given joint. FrictionJointDef GetFrictionJointDef(const FrictionJoint& joint) noexcept; } // namespace playrho diff --git a/PlayRho/Dynamics/Joints/GearJoint.hpp b/PlayRho/Dynamics/Joints/GearJoint.hpp index 0dd199302e..57ea7146bd 100644 --- a/PlayRho/Dynamics/Joints/GearJoint.hpp +++ b/PlayRho/Dynamics/Joints/GearJoint.hpp @@ -41,6 +41,8 @@ namespace playrho { class GearJoint : public Joint { public: + + /// @brief Initializing constructor. GearJoint(const GearJointDef& data); Length2D GetAnchorA() const override; @@ -61,8 +63,10 @@ class GearJoint : public Joint /// @brief Gets the second joint. NonNull GetJoint2() const noexcept { return m_joint2; } - /// Set/Get the gear ratio. + /// @brief Sets the gear ratio. void SetRatio(Real ratio); + + /// @brief Gets the ratio. Real GetRatio() const noexcept; private: diff --git a/PlayRho/Dynamics/Joints/GearJointDef.hpp b/PlayRho/Dynamics/Joints/GearJointDef.hpp index aa59760e36..e300d296e2 100644 --- a/PlayRho/Dynamics/Joints/GearJointDef.hpp +++ b/PlayRho/Dynamics/Joints/GearJointDef.hpp @@ -36,10 +36,13 @@ class GearJoint; /// revolute or prismatic joints (any combination will work). struct GearJointDef : public JointBuilder { + /// @brief Super type. using super = JointBuilder; + /// @brief Initializing constructor. GearJointDef(NonNull j1, NonNull j2) noexcept; + /// @brief Uses the given ratio value. GearJointDef& UseRatio(Real v) noexcept; /// The first revolute/prismatic joint attached to the gear joint. @@ -59,6 +62,7 @@ inline GearJointDef& GearJointDef::UseRatio(Real v) noexcept return *this; } +/// @brief Gets the definition data for the given joint. GearJointDef GetGearJointDef(const GearJoint& joint) noexcept; } // namespace playrho diff --git a/PlayRho/Dynamics/Joints/Joint.cpp b/PlayRho/Dynamics/Joints/Joint.cpp index 9c460e2440..481d08b035 100644 --- a/PlayRho/Dynamics/Joints/Joint.cpp +++ b/PlayRho/Dynamics/Joints/Joint.cpp @@ -90,6 +90,8 @@ bool Joint::IsOkay(const JointDef& def) noexcept return true; } +// Free functions... + bool IsEnabled(const Joint& j) noexcept { const auto bA = j.GetBodyA(); @@ -111,8 +113,6 @@ void SetAwake(Joint& j) noexcept } } -// Free functions... - JointCounter GetWorldIndex(const Joint* joint) { if (joint) diff --git a/PlayRho/Dynamics/Joints/Joint.hpp b/PlayRho/Dynamics/Joints/Joint.hpp index 7c3e31e811..6f1b20ba5a 100644 --- a/PlayRho/Dynamics/Joints/Joint.hpp +++ b/PlayRho/Dynamics/Joints/Joint.hpp @@ -39,14 +39,20 @@ struct Velocity; struct ConstraintSolverConf; class BodyConstraint; +/// @brief A body constraint pointer alias. using BodyConstraintPtr = BodyConstraint*; + +/// @brief A body pointer and body constraint pointer pair alias. using BodyConstraintPair = std::pair; // #define USE_VECTOR_MAP + +/// @brief A body constraints map alias. +using BodyConstraintsMap = #ifdef USE_VECTOR_MAP -using BodyConstraintsMap = std::vector>; + std::vector>; #else -using BodyConstraintsMap = std::unordered_map; + std::unordered_map; #endif /// @brief Base joint class. @@ -55,6 +61,8 @@ using BodyConstraintsMap = std::unordered_map; class Joint { public: + + /// @brief Limit state. enum LimitState { e_inactiveLimit, @@ -63,6 +71,7 @@ class Joint e_equalLimits }; + /// @brief Is the given definition okay. static bool IsOkay(const JointDef& def) noexcept; /// @brief Gets the type of the concrete joint. @@ -103,6 +112,8 @@ class Joint virtual ~Joint() = default; protected: + + /// @brief Initializing constructor. Joint(const JointDef& def); private: @@ -234,15 +245,18 @@ inline void Joint::UnsetIslanded() noexcept /// @brief Short-cut function to determine if both bodies are enabled. bool IsEnabled(const Joint& j) noexcept; -// @brief Wakes up the joined bodies. +/// @brief Wakes up the joined bodies. void SetAwake(Joint& j) noexcept; +/// @brief Gets the world index of the given joint. JointCounter GetWorldIndex(const Joint* joint); #ifdef PLAYRHO_PROVIDE_VECTOR_AT +/// @brief Provides referenced access to the identified element of the given container. BodyConstraintPtr& At(std::vector& container, const Body* key); #endif +/// @brief Provides referenced access to the identified element of the given container. BodyConstraintPtr& At(std::unordered_map& container, const Body* key); diff --git a/PlayRho/Dynamics/Joints/JointDef.hpp b/PlayRho/Dynamics/Joints/JointDef.hpp index 24db7338d7..955c564b84 100644 --- a/PlayRho/Dynamics/Joints/JointDef.hpp +++ b/PlayRho/Dynamics/Joints/JointDef.hpp @@ -55,6 +55,7 @@ struct JointDef /// Deleted default constructor for abstract base class. JointDef() = delete; // deleted to prevent direct instantiation. + /// @brief Initializing constructor. constexpr JointDef(JointType t) noexcept : type{t} { // Intentionally empty. @@ -88,9 +89,14 @@ struct JointDef template struct JointBuilder : JointDef { + + /// @brief Value type. using value_type = T; + + /// @brief Reference type. using reference = value_type&; + /// @brief Initializing constructor. constexpr JointBuilder(JointType t) noexcept : JointDef{t} { // Intentionally empty. @@ -125,6 +131,7 @@ struct JointBuilder : JointDef } }; +/// @brief Sets the joint definition data for the given joint. void Set(JointDef& def, const Joint& joint) noexcept; } // namespace playrho diff --git a/PlayRho/Dynamics/Joints/JointKey.hpp b/PlayRho/Dynamics/Joints/JointKey.hpp index 2dbdefd5d5..39e3d248eb 100644 --- a/PlayRho/Dynamics/Joints/JointKey.hpp +++ b/PlayRho/Dynamics/Joints/JointKey.hpp @@ -37,16 +37,20 @@ namespace playrho class JointKey { public: + + /// @brief Gets the JointKey for the given bodies. static constexpr JointKey Get(const Body* bodyA, const Body* bodyB) noexcept { return (bodyA < bodyB)? JointKey{bodyA, bodyB}: JointKey{bodyB, bodyA}; } + /// @brief Gets body 1. constexpr const Body* GetBody1() const noexcept { return m_body1; } + /// @brief Gets body 2. constexpr const Body* GetBody2() const { return m_body2; @@ -63,8 +67,10 @@ namespace playrho const Body* m_body2; }; + /// @brief Gets the JointKey for the given joint. JointKey GetJointKey(const Joint& joint) noexcept; + /// @brief Compares the given joint keys. constexpr int Compare(const JointKey& lhs, const JointKey& rhs) noexcept { if (lhs.GetBody1() < rhs.GetBody1()) @@ -86,12 +92,19 @@ namespace playrho return 0; } + /// @brief Determines whether the given key is for the given body. constexpr bool IsFor(const JointKey key, const Body* body) noexcept { return body == key.GetBody1() || body == key.GetBody2(); } -} + /// @brief Gets the joint pointer from the given value. + inline Joint* GetJointPtr(std::pair value) + { + return value.second; + } + +} // namespace playrho namespace std { @@ -99,6 +112,7 @@ namespace std template <> struct less { + /// @brief Function object operator. constexpr bool operator()(const playrho::JointKey& lhs, const playrho::JointKey& rhs) const { @@ -110,6 +124,8 @@ namespace std template <> struct equal_to { + + /// @brief Function object operator. constexpr bool operator()( const playrho::JointKey& lhs, const playrho::JointKey& rhs ) const { return playrho::Compare(lhs, rhs) == 0; @@ -118,12 +134,4 @@ namespace std } -namespace playrho -{ - inline Joint* GetJointPtr(std::pair value) - { - return value.second; - } -} - #endif /* JointKey_hpp */ diff --git a/PlayRho/Dynamics/Joints/MotorJoint.hpp b/PlayRho/Dynamics/Joints/MotorJoint.hpp index 684844a4d4..479345dade 100644 --- a/PlayRho/Dynamics/Joints/MotorJoint.hpp +++ b/PlayRho/Dynamics/Joints/MotorJoint.hpp @@ -34,6 +34,8 @@ namespace playrho { class MotorJoint : public Joint { public: + + /// @brief Initializing constructor. MotorJoint(const MotorJointDef& def); Length2D GetAnchorA() const override; @@ -42,12 +44,16 @@ class MotorJoint : public Joint Momentum2D GetLinearReaction() const override; AngularMomentum GetAngularReaction() const override; - /// Set/get the target linear offset, in frame A. + /// @brief Sets the target linear offset, in frame A. void SetLinearOffset(const Length2D linearOffset); + + /// @brief Gets the target linear offset, in frame A. const Length2D GetLinearOffset() const; - /// Set/get the target angular offset. + /// @brief Sets the target angular offset. void SetAngularOffset(Angle angularOffset); + + /// @brief Gets the target angular offset. Angle GetAngularOffset() const; /// @brief Sets the maximum friction force. diff --git a/PlayRho/Dynamics/Joints/MotorJointDef.hpp b/PlayRho/Dynamics/Joints/MotorJointDef.hpp index f0c57ee8d0..c23bf37738 100644 --- a/PlayRho/Dynamics/Joints/MotorJointDef.hpp +++ b/PlayRho/Dynamics/Joints/MotorJointDef.hpp @@ -34,6 +34,7 @@ class MotorJoint; /// Motor joint definition. struct MotorJointDef : public JointBuilder { + /// @brief Super type. using super = JointBuilder; constexpr MotorJointDef() noexcept: super{JointType::Motor} {} @@ -41,10 +42,13 @@ struct MotorJointDef : public JointBuilder /// Initialize the bodies and offsets using the current transforms. MotorJointDef(NonNull bodyA, NonNull bodyB) noexcept; + /// @brief Uses the given maximum force value. MotorJointDef& UseMaxForce(NonNegative v) noexcept; + /// @brief Uses the given max torque value. MotorJointDef& UseMaxTorque(NonNegative v) noexcept; + /// @brief Uses the given correction factor. MotorJointDef& UseCorrectionFactor(Real v) noexcept; /// Position of bodyB minus the position of bodyA, in bodyA's frame. @@ -81,6 +85,7 @@ inline MotorJointDef& MotorJointDef::UseCorrectionFactor(Real v) noexcept return *this; } +/// @brief Gets the definition data for the given joint. MotorJointDef GetMotorJointDef(const MotorJoint& joint) noexcept; } // namespace playrho diff --git a/PlayRho/Dynamics/Joints/MouseJoint.hpp b/PlayRho/Dynamics/Joints/MouseJoint.hpp index f3c3bca31f..6bc12c0157 100644 --- a/PlayRho/Dynamics/Joints/MouseJoint.hpp +++ b/PlayRho/Dynamics/Joints/MouseJoint.hpp @@ -42,8 +42,11 @@ namespace playrho { class MouseJoint : public Joint { public: + + /// @brief Is the given definition okay. static bool IsOkay(const MouseJointDef& def) noexcept; + /// @brief Initializing constructor. MouseJoint(const MouseJointDef& def); Length2D GetAnchorA() const override; @@ -54,22 +57,31 @@ class MouseJoint : public Joint AngularMomentum GetAngularReaction() const override; + /// @brief Gets the local anchor B. Length2D GetLocalAnchorB() const noexcept; - /// Use this to update the target point. + /// @brief Sets the target point. void SetTarget(const Length2D target) noexcept; + + /// @brief Gets the target point. Length2D GetTarget() const noexcept; - /// Set/get the maximum force in Newtons. + /// @brief Sets the maximum force. void SetMaxForce(NonNegative force) noexcept; + + /// @brief Gets the maximum force. NonNegative GetMaxForce() const noexcept; - /// Set/get the frequency in Hertz. + /// @brief Sets the frequency. void SetFrequency(NonNegative hz) noexcept; + + /// @brief Gets the frequency. NonNegative GetFrequency() const noexcept; - /// Set/get the damping ratio (dimensionless). + /// @brief Sets the damping ratio. void SetDampingRatio(NonNegative ratio) noexcept; + + /// @brief Gets the damping ratio. NonNegative GetDampingRatio() const noexcept; /// Implement Joint::ShiftOrigin diff --git a/PlayRho/Dynamics/Joints/MouseJointDef.hpp b/PlayRho/Dynamics/Joints/MouseJointDef.hpp index 1afc90f31c..8fb51fef44 100644 --- a/PlayRho/Dynamics/Joints/MouseJointDef.hpp +++ b/PlayRho/Dynamics/Joints/MouseJointDef.hpp @@ -35,10 +35,12 @@ class Body; /// @details This requires a world target point, tuning parameters, and the time step. struct MouseJointDef : public JointBuilder { + /// @brief Super type. using super = JointBuilder; constexpr MouseJointDef() noexcept: super{JointType::Mouse} {} + /// @brief Initializing constructor. constexpr MouseJointDef(NonNull b) noexcept: super{super{JointType::Mouse}.UseBodyB(b)} { // Intentionally empty. @@ -101,6 +103,7 @@ constexpr MouseJointDef& MouseJointDef::UseDampingRatio(NonNegative v) noe return *this; } +/// @brief Gets the definition data for the given joint. MouseJointDef GetMouseJointDef(const MouseJoint& joint) noexcept; } // namespace playrho diff --git a/PlayRho/Dynamics/Joints/PrismaticJoint.hpp b/PlayRho/Dynamics/Joints/PrismaticJoint.hpp index 317c2b9a2a..73c8669496 100644 --- a/PlayRho/Dynamics/Joints/PrismaticJoint.hpp +++ b/PlayRho/Dynamics/Joints/PrismaticJoint.hpp @@ -39,6 +39,8 @@ namespace playrho { class PrismaticJoint : public Joint { public: + + /// @brief Copy constructor. PrismaticJoint(const PrismaticJointDef& def); Length2D GetAnchorA() const override; @@ -88,6 +90,8 @@ class PrismaticJoint : public Joint /// @brief Sets the maximum motor force. void SetMaxMotorForce(Force force) noexcept; + + /// @brief Gets the maximum motor force. Force GetMaxMotorForce() const noexcept { return m_maxMotorForce; } /// @brief Gets the current motor force given the inverse time step. diff --git a/PlayRho/Dynamics/Joints/PrismaticJointDef.hpp b/PlayRho/Dynamics/Joints/PrismaticJointDef.hpp index 6d07df54fd..b9ce8c4bc3 100644 --- a/PlayRho/Dynamics/Joints/PrismaticJointDef.hpp +++ b/PlayRho/Dynamics/Joints/PrismaticJointDef.hpp @@ -39,10 +39,12 @@ class PrismaticJoint; /// anchors and a local axis helps when saving and loading a game. struct PrismaticJointDef : public JointBuilder { + /// @brief Super type. using super = JointBuilder; constexpr PrismaticJointDef() noexcept: super{JointType::Prismatic} {} + /// @brief Copy constructor. PrismaticJointDef(const PrismaticJointDef& copy) = default; /// @brief Initializing constructor. @@ -51,12 +53,16 @@ struct PrismaticJointDef : public JointBuilder PrismaticJointDef(NonNull bodyA, NonNull bodyB, const Length2D anchor, const UnitVec2 axis) noexcept; + /// @brief Uses the given enable limit state value. PrismaticJointDef& UseEnableLimit(bool v) noexcept; + /// @brief Uses the given lower translation value. PrismaticJointDef& UseLowerTranslation(Length v) noexcept; + /// @brief Uses the given upper translation value. PrismaticJointDef& UseUpperTranslation(Length v) noexcept; + /// @brief Uses the given enable motor state value. PrismaticJointDef& UseEnableMotor(bool v) noexcept; /// The local anchor point relative to bodyA's origin. @@ -114,6 +120,7 @@ inline PrismaticJointDef& PrismaticJointDef::UseEnableMotor(bool v) noexcept return *this; } +/// @brief Gets the definition data for the given joint. PrismaticJointDef GetPrismaticJointDef(const PrismaticJoint& joint) noexcept; } // namespace playrho diff --git a/PlayRho/Dynamics/Joints/PulleyJoint.hpp b/PlayRho/Dynamics/Joints/PulleyJoint.hpp index fc12fa50a2..12407768c1 100644 --- a/PlayRho/Dynamics/Joints/PulleyJoint.hpp +++ b/PlayRho/Dynamics/Joints/PulleyJoint.hpp @@ -38,9 +38,14 @@ namespace playrho { class PulleyJoint : public Joint { public: + + /// @brief Initializing constructor. PulleyJoint(const PulleyJointDef& data); + /// @brief Gets the local anchor A. Length2D GetLocalAnchorA() const noexcept; + + /// @brief Gets the local anchor B. Length2D GetLocalAnchorB() const noexcept; Length2D GetAnchorA() const override; diff --git a/PlayRho/Dynamics/Joints/PulleyJointDef.hpp b/PlayRho/Dynamics/Joints/PulleyJointDef.hpp index 1bd7445b55..54a5b94a36 100644 --- a/PlayRho/Dynamics/Joints/PulleyJointDef.hpp +++ b/PlayRho/Dynamics/Joints/PulleyJointDef.hpp @@ -34,6 +34,7 @@ class PulleyJoint; /// @details This requires two ground anchors, two dynamic body anchor points, and a pulley ratio. struct PulleyJointDef : public JointBuilder { + /// @brief Super type. using super = JointBuilder; PulleyJointDef() noexcept: super{JointType::Pulley} @@ -46,6 +47,7 @@ struct PulleyJointDef : public JointBuilder const Length2D groundAnchorA, const Length2D groundAnchorB, const Length2D anchorA, const Length2D anchorB); + /// @brief Uses the given ratio value. PulleyJointDef& UseRatio(Real v) noexcept; /// The first ground anchor in world coordinates. This point never moves. @@ -76,6 +78,7 @@ inline PulleyJointDef& PulleyJointDef::UseRatio(Real v) noexcept return *this; } +/// @brief Gets the definition data for the given joint. PulleyJointDef GetPulleyJointDef(const PulleyJoint& joint) noexcept; } // namespace playrho diff --git a/PlayRho/Dynamics/Joints/RevoluteJoint.hpp b/PlayRho/Dynamics/Joints/RevoluteJoint.hpp index 6e6327677a..c02bec4df6 100644 --- a/PlayRho/Dynamics/Joints/RevoluteJoint.hpp +++ b/PlayRho/Dynamics/Joints/RevoluteJoint.hpp @@ -41,6 +41,8 @@ namespace playrho { class RevoluteJoint : public Joint { public: + + /// @brief Initializing constructor. RevoluteJoint(const RevoluteJointDef& def); Length2D GetAnchorA() const override; @@ -85,6 +87,7 @@ class RevoluteJoint : public Joint /// Set the maximum motor torque. void SetMaxMotorTorque(Torque torque); + /// @brief Gets the max motor torque. Torque GetMaxMotorTorque() const noexcept { return m_maxMotorTorque; } /// Get the linear reaction. diff --git a/PlayRho/Dynamics/Joints/RevoluteJointDef.hpp b/PlayRho/Dynamics/Joints/RevoluteJointDef.hpp index ef48b3397b..2ae42080a0 100644 --- a/PlayRho/Dynamics/Joints/RevoluteJointDef.hpp +++ b/PlayRho/Dynamics/Joints/RevoluteJointDef.hpp @@ -44,6 +44,7 @@ class RevoluteJoint; /// the joints will be broken. struct RevoluteJointDef : public JointBuilder { + /// @brief Super type. using super = JointBuilder; constexpr RevoluteJointDef() noexcept: super{JointType::Revolute} {} @@ -51,12 +52,16 @@ struct RevoluteJointDef : public JointBuilder /// @brief Initialize the bodies, anchors, and reference angle using a world anchor point. RevoluteJointDef(NonNull bodyA, NonNull bodyB, const Length2D anchor) noexcept; + /// @brief Uses the given enable limit state value. constexpr RevoluteJointDef& UseEnableLimit(bool v) noexcept; + /// @brief Uses the given lower angle value. constexpr RevoluteJointDef& UseLowerAngle(Angle v) noexcept; + /// @brief Uses the given upper angle value. constexpr RevoluteJointDef& UseUpperAngle(Angle v) noexcept; + /// @brief Uses the given enable motor state value. constexpr RevoluteJointDef& UseEnableMotor(bool v) noexcept; /// @brief Local anchor point relative to bodyA's origin. @@ -112,6 +117,7 @@ constexpr RevoluteJointDef& RevoluteJointDef::UseEnableMotor(bool v) noexcept return *this; } +/// @brief Gets the definition data for the given joint. RevoluteJointDef GetRevoluteJointDef(const RevoluteJoint& joint) noexcept; } // namespace playrho diff --git a/PlayRho/Dynamics/Joints/RopeJoint.hpp b/PlayRho/Dynamics/Joints/RopeJoint.hpp index b6121b3bad..414bf098cf 100644 --- a/PlayRho/Dynamics/Joints/RopeJoint.hpp +++ b/PlayRho/Dynamics/Joints/RopeJoint.hpp @@ -39,6 +39,8 @@ namespace playrho { class RopeJoint : public Joint { public: + + /// @brief Initializing constructor. RopeJoint(const RopeJointDef& data); Length2D GetAnchorA() const override; @@ -53,10 +55,13 @@ class RopeJoint : public Joint /// The local anchor point relative to bodyB's origin. Length2D GetLocalAnchorB() const { return m_localAnchorB; } - /// Set/Get the maximum length of the rope. + /// @brief Sets the maximum length of the rope. void SetMaxLength(Length length) { m_maxLength = length; } + + /// @brief Gets the maximum length of the rope. Length GetMaxLength() const; + /// @brief Gets the limit state. LimitState GetLimitState() const; private: diff --git a/PlayRho/Dynamics/Joints/RopeJointDef.hpp b/PlayRho/Dynamics/Joints/RopeJointDef.hpp index d3794756ca..4fd80e248d 100644 --- a/PlayRho/Dynamics/Joints/RopeJointDef.hpp +++ b/PlayRho/Dynamics/Joints/RopeJointDef.hpp @@ -36,13 +36,19 @@ class RopeJoint; /// @see collideConnected in JointDef. struct RopeJointDef : public JointBuilder { + /// @brief Super type. using super = JointBuilder; constexpr RopeJointDef() noexcept: super{JointType::Rope} {} + /// @brief Initializing constructor. constexpr RopeJointDef(Body* bodyA, Body* bodyB) noexcept: - super{super{JointType::Rope}.UseBodyA(bodyA).UseBodyB(bodyB)} {} + super{super{JointType::Rope}.UseBodyA(bodyA).UseBodyB(bodyB)} + { + // Intentionally empty. + } + /// @brief Uses the given max length value. constexpr RopeJointDef& UseMaxLength(Length v) noexcept; /// The local anchor point relative to bodyA's origin. @@ -61,6 +67,7 @@ constexpr RopeJointDef& RopeJointDef::UseMaxLength(Length v) noexcept return *this; } +/// @brief Gets the definition data for the given joint. RopeJointDef GetRopeJointDef(const RopeJoint& joint) noexcept; } // namespace playrho diff --git a/PlayRho/Dynamics/Joints/WeldJoint.hpp b/PlayRho/Dynamics/Joints/WeldJoint.hpp index dbbcb4d205..f046bb3a8b 100644 --- a/PlayRho/Dynamics/Joints/WeldJoint.hpp +++ b/PlayRho/Dynamics/Joints/WeldJoint.hpp @@ -33,6 +33,8 @@ namespace playrho { class WeldJoint : public Joint { public: + + /// @brief Initializing constructor. WeldJoint(const WeldJointDef& def); Length2D GetAnchorA() const override; @@ -56,8 +58,10 @@ class WeldJoint : public Joint /// @brief Gets the frequency. Frequency GetFrequency() const { return m_frequency; } - /// Set/get damping ratio. + /// @brief Sets damping ratio. void SetDampingRatio(Real ratio) { m_dampingRatio = ratio; } + + /// @brief Gets damping ratio. Real GetDampingRatio() const { return m_dampingRatio; } private: diff --git a/PlayRho/Dynamics/Joints/WeldJointDef.hpp b/PlayRho/Dynamics/Joints/WeldJointDef.hpp index 326c27d6e2..171664eb06 100644 --- a/PlayRho/Dynamics/Joints/WeldJointDef.hpp +++ b/PlayRho/Dynamics/Joints/WeldJointDef.hpp @@ -36,6 +36,7 @@ class WeldJoint; /// of the anchor points is important for computing the reaction torque. struct WeldJointDef : public JointBuilder { + /// @brief Super type. using super = JointBuilder; constexpr WeldJointDef() noexcept: super{JointType::Weld} {} @@ -44,8 +45,10 @@ struct WeldJointDef : public JointBuilder /// anchor point. WeldJointDef(NonNull bodyA, NonNull bodyB, const Length2D anchor) noexcept; + /// @brief Uses the given frequency value. constexpr WeldJointDef& UseFrequency(Frequency v) noexcept; + /// @brief Uses the given damping ratio. constexpr WeldJointDef& UseDampingRatio(Real v) noexcept; /// The local anchor point relative to bodyA's origin. @@ -79,6 +82,7 @@ constexpr WeldJointDef& WeldJointDef::UseDampingRatio(Real v) noexcept return *this; } +/// @brief Gets the definition data for the given joint. WeldJointDef GetWeldJointDef(const WeldJoint& joint) noexcept; } // namespace playrho diff --git a/PlayRho/Dynamics/Joints/WheelJoint.hpp b/PlayRho/Dynamics/Joints/WheelJoint.hpp index d5b2aecabf..4e0c3751ff 100644 --- a/PlayRho/Dynamics/Joints/WheelJoint.hpp +++ b/PlayRho/Dynamics/Joints/WheelJoint.hpp @@ -35,6 +35,8 @@ namespace playrho { class WheelJoint : public Joint { public: + + /// @brief Initializing constructor. WheelJoint(const WheelJointDef& def); Length2D GetAnchorA() const override; @@ -64,8 +66,10 @@ class WheelJoint : public Joint /// Get the angular motor speed. AngularVelocity GetMotorSpeed() const; - /// Set/Get the maximum motor force. + /// @brief Sets the maximum motor torque. void SetMaxMotorTorque(Torque torque); + + /// @brief Gets the maximum motor torque. Torque GetMaxMotorTorque() const; /// Get the current motor torque given the inverse time step. @@ -78,8 +82,10 @@ class WheelJoint : public Joint /// @brief Gets the spring frequency. Frequency GetSpringFrequency() const; - /// Set/Get the spring damping ratio + /// @brief Sets the spring damping ratio void SetSpringDampingRatio(Real ratio); + + /// @brief Gets the spring damping ratio Real GetSpringDampingRatio() const; private: diff --git a/PlayRho/Dynamics/Joints/WheelJointDef.hpp b/PlayRho/Dynamics/Joints/WheelJointDef.hpp index 72f9fa24d4..5f8e6bf75c 100644 --- a/PlayRho/Dynamics/Joints/WheelJointDef.hpp +++ b/PlayRho/Dynamics/Joints/WheelJointDef.hpp @@ -39,6 +39,7 @@ class WheelJoint; /// anchors and a local axis helps when saving and loading a game. struct WheelJointDef : public JointBuilder { + /// @brief Super type. using super = JointBuilder; constexpr WheelJointDef() noexcept: super{JointType::Wheel} {} @@ -48,14 +49,19 @@ struct WheelJointDef : public JointBuilder WheelJointDef(NonNull bodyA, NonNull bodyB, const Length2D anchor, const UnitVec2 axis) noexcept; + /// @brief Uses the given enable motor state value. constexpr WheelJointDef& UseEnableMotor(bool v) noexcept; + /// @brief Uses the given max motor toque value. constexpr WheelJointDef& UseMaxMotorTorque(Torque v) noexcept; + /// @brief Uses the given motor speed value. constexpr WheelJointDef& UseMotorSpeed(AngularVelocity v) noexcept; + /// @brief Uses the given frequency value. constexpr WheelJointDef& UseFrequency(Frequency v) noexcept; + /// @brief Uses the given damping ratio value. constexpr WheelJointDef& UseDampingRatio(Real v) noexcept; /// The local anchor point relative to bodyA's origin. @@ -113,6 +119,7 @@ constexpr WheelJointDef& WheelJointDef::UseDampingRatio(Real v) noexcept return *this; } +/// @brief Gets the definition data for the given joint. WheelJointDef GetWheelJointDef(const WheelJoint& joint) noexcept; } // namespace playrho diff --git a/PlayRho/Dynamics/MovementConf.hpp b/PlayRho/Dynamics/MovementConf.hpp index 1ccc7aed95..f959bf6885 100644 --- a/PlayRho/Dynamics/MovementConf.hpp +++ b/PlayRho/Dynamics/MovementConf.hpp @@ -30,10 +30,11 @@ namespace playrho /// @brief Movement configuration. struct MovementConf { - Length maxTranslation; - Angle maxRotation; + Length maxTranslation; ///< Max translation. + Angle maxRotation; ///< Max rotation. }; + /// @brief Gets the movement configuration from the given value. MovementConf GetMovementConf(const StepConf& conf) noexcept; } // namespace playrho diff --git a/PlayRho/Dynamics/StepConf.hpp b/PlayRho/Dynamics/StepConf.hpp index a89f647b1c..356900edbb 100644 --- a/PlayRho/Dynamics/StepConf.hpp +++ b/PlayRho/Dynamics/StepConf.hpp @@ -126,6 +126,7 @@ class StepConf /// @sa regPositionIterations. Length regMinSeparation = -DefaultLinearSlop * Real{3}; + /// @brief Regular-phase min momentum. Momentum regMinMomentum = DefaultRegMinMomentum; /// @brief Time of impact resolution rate. @@ -146,6 +147,7 @@ class StepConf /// @sa toiPositionIterations. Length toiMinSeparation = -DefaultLinearSlop * Real(1.5f); + /// @brief TOI-phase min momentum. Momentum toiMinMomentum = DefaultToiMinMomentum; /// @brief Target depth. @@ -320,11 +322,13 @@ class StepConf Frequency invTime = DefaultStepFrequency; }; +/// @brief Gets the maximum regular linear correction from the given value. inline Length GetMaxRegLinearCorrection(const StepConf& conf) noexcept { return conf.maxLinearCorrection * static_cast(conf.regPositionIterations); } +/// @brief Determines whether the maximum translation is within tolerance. bool IsMaxTranslationWithinTolerance(const StepConf& conf) noexcept; } // namespace playrho diff --git a/PlayRho/Dynamics/StepStats.hpp b/PlayRho/Dynamics/StepStats.hpp index e972a77eb3..6d12a2bf62 100644 --- a/PlayRho/Dynamics/StepStats.hpp +++ b/PlayRho/Dynamics/StepStats.hpp @@ -27,60 +27,75 @@ namespace playrho { /// @brief Pre-phase per-step statistics. struct PreStepStats { + /// @brief Counter type. using counter_type = std::uint32_t; - counter_type proxiesMoved = 0; - counter_type ignored = 0; - counter_type destroyed = 0; - counter_type updated = 0; - counter_type skipped = 0; - counter_type added = 0; + + counter_type proxiesMoved = 0; ///< Proxies moved count. + counter_type ignored = 0; ///< Ignored count. + counter_type destroyed = 0; ///< Destroyed count. + counter_type updated = 0; ///< Updated count. + counter_type skipped = 0; ///< Skipped count. + counter_type added = 0; ///< Added count. }; /// @brief Regular-phase per-step statistics. struct RegStepStats { + /// @brief Counter type. using counter_type = std::uint32_t; + /// @brief Min separation. Length minSeparation = std::numeric_limits::infinity() * Meter; + + /// @brief Max incremental impulse. Momentum maxIncImpulse = 0; - counter_type islandsFound = 0; - counter_type islandsSolved = 0; - counter_type contactsAdded = 0; - counter_type bodiesSlept = 0; - counter_type proxiesMoved = 0; - counter_type sumPosIters = 0; - counter_type sumVelIters = 0; + counter_type islandsFound = 0; ///< Islands found count. + counter_type islandsSolved = 0; ///< Islands solved count. + counter_type contactsAdded = 0; ///< Contacts added count. + counter_type bodiesSlept = 0; ///< Bodies slept count. + counter_type proxiesMoved = 0; ///< Proxies moved count. + counter_type sumPosIters = 0; ///< Sum of the position iterations. + counter_type sumVelIters = 0; ///< Sum of the velocity iterations. }; /// @brief TOI-phase per-step statistics. struct ToiStepStats { + /// @brief Counter type. using counter_type = std::uint32_t; + /// @brief Min separation. Length minSeparation = std::numeric_limits::infinity() * Meter; + + /// @brief Max incremental impulse. Momentum maxIncImpulse = 0; - counter_type islandsFound = 0; - counter_type islandsSolved = 0; - counter_type contactsFound = 0; - counter_type contactsAtMaxSubSteps = 0; - counter_type contactsUpdatedToi = 0; - counter_type contactsUpdatedTouching = 0; - counter_type contactsSkippedTouching = 0; - counter_type contactsAdded = 0; - counter_type proxiesMoved = 0; - counter_type sumPosIters = 0; - counter_type sumVelIters = 0; + counter_type islandsFound = 0; ///< Islands found count. + counter_type islandsSolved = 0; ///< Islands solved count. + counter_type contactsFound = 0; ///< Contacts found count. + counter_type contactsAtMaxSubSteps = 0; ///< Contacts at max substeps count. + counter_type contactsUpdatedToi = 0; ///< Contacts updated TOI count. + counter_type contactsUpdatedTouching = 0; ///< Contacts updated touching count. + counter_type contactsSkippedTouching = 0; ///< Contacts skipped touching count. + counter_type contactsAdded = 0; ///< Contacts added count. + counter_type proxiesMoved = 0; ///< Proxies moved count. + counter_type sumPosIters = 0; ///< Sum position iterations count. + counter_type sumVelIters = 0; ///< Sum velocity iterations count. counter_type maxSimulContacts = 0; ///< Max contacts occuring simultaneously. + /// @brief Distance iteration type. using dist_iter_type = std::remove_const::type; + + /// @brief TOI iteration type. using toi_iter_type = std::remove_const::type; + + /// @brief Root iteration type. using root_iter_type = std::remove_const::type; - dist_iter_type maxDistIters = 0; - toi_iter_type maxToiIters = 0; - root_iter_type maxRootIters = 0; + dist_iter_type maxDistIters = 0; ///< Max distance iterations. + toi_iter_type maxToiIters = 0; ///< Max TOI iterations. + root_iter_type maxRootIters = 0; ///< Max root iterations. }; /// @brief Per-step statistics. diff --git a/PlayRho/Dynamics/World.cpp b/PlayRho/Dynamics/World.cpp index d4932f1fdc..dbfff3d093 100644 --- a/PlayRho/Dynamics/World.cpp +++ b/PlayRho/Dynamics/World.cpp @@ -82,11 +82,19 @@ using namespace std; namespace playrho { - +/// @brief Body pointer alias. using BodyPtr = Body*; + +/// @brief A body pointer and body constraint pointer pair. using BodyConstraintsPair = pair; + +/// @brief Collection of body constraints. using BodyConstraints = vector; + +/// @brief Collection of position constraints. using PositionConstraints = vector; + +/// @brief Collection of velocity constraints. using VelocityConstraints = vector; namespace { diff --git a/PlayRho/Dynamics/World.hpp b/PlayRho/Dynamics/World.hpp index d23d8edd5b..68128f3a58 100644 --- a/PlayRho/Dynamics/World.hpp +++ b/PlayRho/Dynamics/World.hpp @@ -94,8 +94,10 @@ class World /// @throws InvalidArgument if the given max vertex radius is less than the min. World(const WorldDef& def = GetDefaultWorldDef()); + /// @brief Copy constructor. World(const World& other); + /// @brief Assignment operator. World& operator= (const World& other); /// @brief Destructor. @@ -103,6 +105,7 @@ class World /// All physics entities are destroyed and all dynamically allocated memory is released. ~World(); + /// @brief Clears this world. void Clear() noexcept; /// Register a destruction listener. The listener is owned by you and must @@ -290,9 +293,13 @@ class World /// @note This may alter the body's mass and velocity. void SetType(Body& body, BodyType type); + /// @brief Register for proxies for the given fixture. bool RegisterForProxies(Fixture* fixture); + + /// @brief Register for proxies for the given body. bool RegisterForProxies(Body* body); + /// @brief Creates a fixture with the given parameters. Fixture* CreateFixture(Body& body, std::shared_ptr shape, const FixtureDef& def = GetDefaultFixtureDef(), bool resetMassData = true); @@ -319,6 +326,7 @@ class World /// @note This sets things up so that pairs may be created for potentially new contacts. bool TouchProxies(Fixture& fixture) noexcept; + /// @brief Sets new fixtures flag. void SetNewFixtures() noexcept; private: @@ -669,6 +677,7 @@ class World::LockedError: public std::logic_error using std::logic_error::logic_error; }; +/// @brief World ray cast opcode enumeration. enum class World::RayCastOpcode { /// @brief End the ray-cast search for fixtures. @@ -909,6 +918,7 @@ inline ContactCounter GetContactCount(const World& world) noexcept return static_cast(world.GetContacts().size()); } +/// @brief Gets the touching count for the given world. ContactCounter GetTouchingCount(const World& world) noexcept; /// @brief Steps the world ahead by a given time amount. @@ -962,6 +972,7 @@ BodyCounter Awaken(World& world) noexcept; /// @details Manually clear the force buffer on all bodies. void ClearForces(World& world) noexcept; +/// @brief Determines whether the given contact is "active". bool IsActive(const Contact& contact) noexcept; } // namespace playrho diff --git a/PlayRho/Dynamics/WorldCallbacks.hpp b/PlayRho/Dynamics/WorldCallbacks.hpp index 78812cc166..51b2cf564c 100644 --- a/PlayRho/Dynamics/WorldCallbacks.hpp +++ b/PlayRho/Dynamics/WorldCallbacks.hpp @@ -72,13 +72,20 @@ class ContactFilter class ContactImpulsesList { public: + + /// @brief Count type. using count_t = std::remove_const::type; + /// @brief Gets the count. count_t GetCount() const noexcept { return count; } + /// @brief Gets the given indexed entry normal. Momentum GetEntryNormal(count_t index) const noexcept { return normalImpulses[index]; } + + /// @brief Gets the given indexed entry tangent. Momentum GetEntryTanget(count_t index) const noexcept { return tangentImpulses[index]; } + /// @brief Adds an entry of the given data. void AddEntry(Momentum normal, Momentum tangent) noexcept { assert(count < MaxManifoldPoints); @@ -109,6 +116,8 @@ class ContactImpulsesList class ContactListener { public: + + /// @brief Iteration type. using iteration_type = unsigned; virtual ~ContactListener() = default; diff --git a/PlayRho/Dynamics/WorldDef.hpp b/PlayRho/Dynamics/WorldDef.hpp index dd709f6c20..92da6a14a6 100644 --- a/PlayRho/Dynamics/WorldDef.hpp +++ b/PlayRho/Dynamics/WorldDef.hpp @@ -31,8 +31,13 @@ namespace playrho { /// @brief World construction definitions. struct WorldDef { + /// @brief Uses the given gravity value. constexpr WorldDef& UseGravity(LinearAcceleration2D value) noexcept; + + /// @brief Uses the given min vertex radius value. constexpr WorldDef& UseMinVertexRadius(Positive value) noexcept; + + /// @brief Uses the given max vertex radius value. constexpr WorldDef& UseMaxVertexRadius(Positive value) noexcept; /// @brief Gravity. diff --git a/PlayRho/Rope/Rope.hpp b/PlayRho/Rope/Rope.hpp index 442f512648..6bd7d193f5 100644 --- a/PlayRho/Rope/Rope.hpp +++ b/PlayRho/Rope/Rope.hpp @@ -27,29 +27,20 @@ namespace playrho { /// @brief Rope definition. struct RopeDef { + + /// @brief Size type. using size_type = std::size_t; constexpr RopeDef() = default; - /// - Vec2* vertices = nullptr; - - /// - size_type count = 0; - - /// - Real* masses = nullptr; - - /// - Vec2 gravity = Vec2_zero; + Vec2* vertices = nullptr; ///< Vertices. + size_type count = 0; ///< Count. + Real* masses = nullptr; ///< Masses. + Vec2 gravity = Vec2_zero; ///< Gravity. + Real damping = Real{1} / Real(10); ///< Damping. + Real k2 = Real(9) / Real(10); ///< Stretching stiffness - /// - Real damping = Real{1} / Real(10); - - /// Stretching stiffness - Real k2 = Real(9) / Real(10); - - /// Bending stiffness. Values above 0.5 can make the simulation blow up. + /// @brief Bending stiffness. Values above 0.5 can make the simulation blow up. Real k3 = Real{1} / Real(10); }; @@ -57,36 +48,39 @@ struct RopeDef class Rope { public: + + /// @brief Size type. using size_type = std::size_t; constexpr Rope() = default; ~Rope(); - /// + /// @brief Initializes this object. void Initialize(const RopeDef* def); - /// + /// @brief Steps this object. void Step(Real timeStep, int iterations); - /// + /// @brief Gets the vertex count for this object. size_type GetVertexCount() const noexcept { return m_count; } - /// + /// @brief Gets the vertices for this object. const Vec2* GetVertices() const noexcept { return m_ps; } + /// @brief Gets the vertex for this object that's at the given index. Vec2 GetVertex(size_type index) const noexcept { assert(index < m_count); return m_ps[index]; } - /// + /// @brief Sets the angle. void SetAngle(Angle angle); private: diff --git a/Testbed/Framework/DebugDraw.hpp b/Testbed/Framework/DebugDraw.hpp index 8e0fdc716d..6a78c8824f 100644 --- a/Testbed/Framework/DebugDraw.hpp +++ b/Testbed/Framework/DebugDraw.hpp @@ -42,27 +42,31 @@ struct Coord2D float y; }; +/// @brief Multiplication operator. inline Coord2D operator* (Coord2D coord, float scalar) { return Coord2D{coord.x * scalar, coord.y * scalar}; } +/// @brief Multiplication operator. inline Coord2D operator* (float scalar, Coord2D coord) { return Coord2D{coord.x * scalar, coord.y * scalar}; } +/// @brief Division operator. inline Coord2D operator/ (Coord2D coord, float scalar) { return Coord2D{coord.x / scalar, coord.y / scalar}; } +/// @brief Addition operator. inline Coord2D operator+ (Coord2D a, Coord2D b) { return Coord2D{a.x + b.x, a.y + b.y}; } - +/// @brief Subtraction operator. inline Coord2D operator- (Coord2D a, Coord2D b) { return Coord2D{a.x - b.x, a.y - b.y}; diff --git a/Testbed/Framework/Drawer.hpp b/Testbed/Framework/Drawer.hpp index 8c37a79d69..be81aca5e7 100644 --- a/Testbed/Framework/Drawer.hpp +++ b/Testbed/Framework/Drawer.hpp @@ -56,6 +56,7 @@ Color Brighten(Color color, float factor); class Drawer { public: + /// @brief Size type. using size_type = std::size_t; Drawer() = default; diff --git a/Testbed/Framework/Main.cpp b/Testbed/Framework/Main.cpp index e7643500e8..117bf0acad 100644 --- a/Testbed/Framework/Main.cpp +++ b/Testbed/Framework/Main.cpp @@ -73,6 +73,7 @@ struct UIState class Selection { public: + /// @brief Size type. using size_type = std::size_t; Selection(size_type size, size_type selection = 0): @@ -116,6 +117,7 @@ class Selection class TestSuite { public: + /// @brief Size type. using size_type = std::size_t; TestSuite(Span testEntries, size_type index = 0):