ConvexHullShape.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #pragma once
  4. #include <Jolt/Physics/Collision/Shape/ConvexShape.h>
  5. #include <Jolt/Physics/PhysicsSettings.h>
  6. #include <Jolt/Geometry/Plane.h>
  7. #ifdef JPH_DEBUG_RENDERER
  8. #include <Jolt/Renderer/DebugRenderer.h>
  9. #endif // JPH_DEBUG_RENDERER
  10. JPH_NAMESPACE_BEGIN
  11. /// Class that constructs a ConvexHullShape
  12. class ConvexHullShapeSettings final : public ConvexShapeSettings
  13. {
  14. public:
  15. JPH_DECLARE_SERIALIZABLE_VIRTUAL(ConvexHullShapeSettings)
  16. /// Default constructor for deserialization
  17. ConvexHullShapeSettings() = default;
  18. /// Create a convex hull from inPoints and maximum convex radius inMaxConvexRadius, the radius is automatically lowered if the hull requires it.
  19. /// (internally this will be subtracted so the total size will not grow with the convex radius).
  20. ConvexHullShapeSettings(const Vec3 *inPoints, int inNumPoints, float inMaxConvexRadius = cDefaultConvexRadius, const PhysicsMaterial *inMaterial = nullptr) : ConvexShapeSettings(inMaterial), mPoints(inPoints, inPoints + inNumPoints), mMaxConvexRadius(inMaxConvexRadius) { }
  21. ConvexHullShapeSettings(const vector<Vec3> &inPoints, float inConvexRadius = cDefaultConvexRadius, const PhysicsMaterial *inMaterial = nullptr) : ConvexShapeSettings(inMaterial), mPoints(inPoints), mMaxConvexRadius(inConvexRadius) { }
  22. // See: ShapeSettings
  23. virtual ShapeResult Create() const override;
  24. vector<Vec3> mPoints; ///< Points to create the hull from
  25. float mMaxConvexRadius = 0.0f; ///< Convex radius as supplied by the constructor. Note that during hull creation the convex radius can be made smaller if the value is too big for the hull.
  26. float mMaxErrorConvexRadius = 0.05f; ///< Maximum distance between the shrunk hull + convex radius and the actual hull.
  27. float mHullTolerance = 1.0e-3f; ///< Points are allowed this far outside of the hull (increasing this yields a hull with less vertices). Note that the actual used value can be larger if the points of the hull are far apart.
  28. };
  29. /// A convex hull
  30. class ConvexHullShape final : public ConvexShape
  31. {
  32. public:
  33. /// Maximum amount of points supported in a convex hull. Note that while constructing a hull, interior points are discarded so you can provide more points.
  34. /// The ConvexHullShapeSettings::Create function will return an error when too many points are provided.
  35. static constexpr int cMaxPointsInHull = 256;
  36. /// Constructor
  37. ConvexHullShape() : ConvexShape(EShapeSubType::ConvexHull) { }
  38. ConvexHullShape(const ConvexHullShapeSettings &inSettings, ShapeResult &outResult);
  39. // See Shape::GetCenterOfMass
  40. virtual Vec3 GetCenterOfMass() const override { return mCenterOfMass; }
  41. // See Shape::GetLocalBounds
  42. virtual AABox GetLocalBounds() const override { return mLocalBounds; }
  43. // See Shape::GetInnerRadius
  44. virtual float GetInnerRadius() const override { return mInnerRadius; }
  45. // See Shape::GetMassProperties
  46. virtual MassProperties GetMassProperties() const override;
  47. // See Shape::GetSurfaceNormal
  48. virtual Vec3 GetSurfaceNormal(const SubShapeID &inSubShapeID, Vec3Arg inLocalSurfacePosition) const override;
  49. // See ConvexShape::GetSupportFunction
  50. virtual const Support * GetSupportFunction(ESupportMode inMode, SupportBuffer &inBuffer, Vec3Arg inScale) const override;
  51. // See ConvexShape::GetSupportingFace
  52. virtual void GetSupportingFace(Vec3Arg inDirection, Vec3Arg inScale, SupportingFace &outVertices) const override;
  53. // See Shape::GetSubmergedVolume
  54. virtual void GetSubmergedVolume(Mat44Arg inCenterOfMassTransform, Vec3Arg inScale, const Plane &inSurface, float &outTotalVolume, float &outSubmergedVolume, Vec3 &outCenterOfBuoyancy) const override;
  55. #ifdef JPH_DEBUG_RENDERER
  56. // See Shape::Draw
  57. virtual void Draw(DebugRenderer *inRenderer, Mat44Arg inCenterOfMassTransform, Vec3Arg inScale, ColorArg inColor, bool inUseMaterialColors, bool inDrawWireframe) const override;
  58. /// Debugging helper draw function that draws how all points are moved when a shape is shrunk by the convex radius
  59. void DrawShrunkShape(DebugRenderer *inRenderer, Mat44Arg inCenterOfMassTransform, Vec3Arg inScale) const;
  60. #endif // JPH_DEBUG_RENDERER
  61. // See Shape::CastRay
  62. virtual bool CastRay(const RayCast &inRay, const SubShapeIDCreator &inSubShapeIDCreator, RayCastResult &ioHit) const override;
  63. virtual void CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector, const ShapeFilter &inShapeFilter = { }) const override;
  64. // See: Shape::CollidePoint
  65. virtual void CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector, const ShapeFilter &inShapeFilter = { }) const override;
  66. // See Shape::GetTrianglesStart
  67. virtual void GetTrianglesStart(GetTrianglesContext &ioContext, const AABox &inBox, Vec3Arg inPositionCOM, QuatArg inRotation, Vec3Arg inScale) const override;
  68. // See Shape::GetTrianglesNext
  69. virtual int GetTrianglesNext(GetTrianglesContext &ioContext, int inMaxTrianglesRequested, Float3 *outTriangleVertices, const PhysicsMaterial **outMaterials = nullptr) const override;
  70. // See Shape
  71. virtual void SaveBinaryState(StreamOut &inStream) const override;
  72. // See Shape::GetStats
  73. virtual Stats GetStats() const override;
  74. // See Shape::GetVolume
  75. virtual float GetVolume() const override { return mVolume; }
  76. /// Get the convex radius of this convex hull
  77. float GetConvexRadius() const { return mConvexRadius; }
  78. /// Get the planes of this convex hull
  79. const vector<Plane> & GetPlanes() const { return mPlanes; }
  80. // Register shape functions with the registry
  81. static void sRegister();
  82. protected:
  83. // See: Shape::RestoreBinaryState
  84. virtual void RestoreBinaryState(StreamIn &inStream) override;
  85. private:
  86. /// Helper function that returns the min and max fraction along the ray that hits the convex hull. Returns false if there is no hit.
  87. bool CastRayHelper(const RayCast &inRay, float &outMinFraction, float &outMaxFraction) const;
  88. /// Class for GetTrianglesStart/Next
  89. class CHSGetTrianglesContext;
  90. /// Classes for GetSupportFunction
  91. class HullNoConvex;
  92. class HullWithConvex;
  93. class HullWithConvexScaled;
  94. struct Face
  95. {
  96. uint16 mFirstVertex; ///< First index in mVertexIdx to use
  97. uint16 mNumVertices = 0; ///< Number of vertices in the mVertexIdx to use
  98. };
  99. static_assert(sizeof(Face) == 4, "Unexpected size");
  100. static_assert(alignof(Face) == 2, "Unexpected alignment");
  101. struct Point
  102. {
  103. Vec3 mPosition; ///< Position of vertex
  104. int mNumFaces = 0; ///< Number of faces in the face array below
  105. int mFaces[3] = { -1, -1, -1 }; ///< Indices of 3 neighboring faces with the biggest difference in normal (used to shift vertices for convex radius)
  106. };
  107. static_assert(sizeof(Point) == 32, "Unexpected size");
  108. static_assert(alignof(Point) == 16, "Unexpected alignment");
  109. Vec3 mCenterOfMass; ///< Center of mass of this convex hull
  110. Mat44 mInertia; ///< Inertia matrix assuming density is 1 (needs to be multiplied by density)
  111. AABox mLocalBounds; ///< Local bounding box for the convex hull
  112. vector<Point> mPoints; ///< Points on the convex hull surface
  113. vector<Face> mFaces; ///< Faces of the convex hull surface
  114. vector<Plane> mPlanes; ///< Planes for the faces (1-on-1 with mFaces array, separate because they need to be 16 byte aligned)
  115. vector<uint8> mVertexIdx; ///< A list of vertex indices (indexing in mPoints) for each of the faces
  116. float mConvexRadius = 0.0f; ///< Convex radius
  117. float mVolume; ///< Total volume of the convex hull
  118. float mInnerRadius = FLT_MAX; ///< Radius of the biggest sphere that fits entirely in the convex hull
  119. #ifdef JPH_DEBUG_RENDERER
  120. mutable DebugRenderer::GeometryRef mGeometry;
  121. #endif // JPH_DEBUG_RENDERER
  122. };
  123. JPH_NAMESPACE_END