ConvexHullShape.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #pragma once
  4. #include <Physics/Collision/Shape/ConvexShape.h>
  5. #include <Physics/PhysicsSettings.h>
  6. #include <Geometry/Plane.h>
  7. #ifdef JPH_DEBUG_RENDERER
  8. #include <Renderer/DebugRenderer.h>
  9. #endif // JPH_DEBUG_RENDERER
  10. namespace JPH {
  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. /// Constructor
  34. ConvexHullShape() : ConvexShape(EShapeSubType::ConvexHull) { }
  35. ConvexHullShape(const ConvexHullShapeSettings &inSettings, ShapeResult &outResult);
  36. // See Shape::GetCenterOfMass
  37. virtual Vec3 GetCenterOfMass() const override { return mCenterOfMass; }
  38. // See Shape::GetLocalBounds
  39. virtual AABox GetLocalBounds() const override { return mLocalBounds; }
  40. // See Shape::GetInnerRadius
  41. virtual float GetInnerRadius() const override { return mInnerRadius; }
  42. // See Shape::GetMassProperties
  43. virtual MassProperties GetMassProperties() const override;
  44. // See Shape::GetSurfaceNormal
  45. virtual Vec3 GetSurfaceNormal(const SubShapeID &inSubShapeID, Vec3Arg inLocalSurfacePosition) const override;
  46. // See ConvexShape::GetSupportFunction
  47. virtual const Support * GetSupportFunction(ESupportMode inMode, SupportBuffer &inBuffer, Vec3Arg inScale) const override;
  48. // See ConvexShape::GetSupportingFace
  49. virtual void GetSupportingFace(Vec3Arg inDirection, Vec3Arg inScale, SupportingFace &outVertices) const override;
  50. // See Shape::GetSubmergedVolume
  51. virtual void GetSubmergedVolume(Mat44Arg inCenterOfMassTransform, Vec3Arg inScale, const Plane &inSurface, float &outTotalVolume, float &outSubmergedVolume, Vec3 &outCenterOfBuoyancy) const override;
  52. #ifdef JPH_DEBUG_RENDERER
  53. // See Shape::Draw
  54. virtual void Draw(DebugRenderer *inRenderer, Mat44Arg inCenterOfMassTransform, Vec3Arg inScale, ColorArg inColor, bool inUseMaterialColors, bool inDrawWireframe) const override;
  55. /// Debugging helper draw function that draws how all points are moved when a shape is shrunk by the convex radius
  56. void DrawShrunkShape(DebugRenderer *inRenderer, Mat44Arg inCenterOfMassTransform, Vec3Arg inScale) const;
  57. #endif // JPH_DEBUG_RENDERER
  58. // See Shape::CastRay
  59. virtual bool CastRay(const RayCast &inRay, const SubShapeIDCreator &inSubShapeIDCreator, RayCastResult &ioHit) const override;
  60. virtual void CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector) const override;
  61. // See: Shape::CollidePoint
  62. virtual void CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector) const override;
  63. // See Shape::GetTrianglesStart
  64. virtual void GetTrianglesStart(GetTrianglesContext &ioContext, const AABox &inBox, Vec3Arg inPositionCOM, QuatArg inRotation, Vec3Arg inScale) const override;
  65. // See Shape::GetTrianglesNext
  66. virtual int GetTrianglesNext(GetTrianglesContext &ioContext, int inMaxTrianglesRequested, Float3 *outTriangleVertices, const PhysicsMaterial **outMaterials = nullptr) const override;
  67. // See Shape
  68. virtual void SaveBinaryState(StreamOut &inStream) const override;
  69. // See Shape::GetStats
  70. virtual Stats GetStats() const override;
  71. // See Shape::GetVolume
  72. virtual float GetVolume() const override { return mVolume; }
  73. /// Get the convex radius of this convex hull
  74. float GetConvexRadius() const { return mConvexRadius; }
  75. /// Get the planes of this convex hull
  76. const vector<Plane> & GetPlanes() const { return mPlanes; }
  77. // Register shape functions with the registry
  78. static void sRegister();
  79. protected:
  80. // See: Shape::RestoreBinaryState
  81. virtual void RestoreBinaryState(StreamIn &inStream) override;
  82. private:
  83. /// Helper function that returns the min and max fraction along the ray that hits the convex hull. Returns false if there is no hit.
  84. bool CastRayHelper(const RayCast &inRay, float &outMinFraction, float &outMaxFraction) const;
  85. /// Class for GetTrianglesStart/Next
  86. class CHSGetTrianglesContext;
  87. /// Classes for GetSupportFunction
  88. class HullNoConvex;
  89. class HullWithConvex;
  90. class HullWithConvexScaled;
  91. struct Face
  92. {
  93. uint16 mFirstVertex; ///< First index in mVertexIdx to use
  94. uint16 mNumVertices = 0; ///< Number of vertices in the mVertexIdx to use
  95. };
  96. static_assert(sizeof(Face) == 4, "Unexpected size");
  97. static_assert(alignof(Face) == 2, "Unexpected alignment");
  98. struct Point
  99. {
  100. Vec3 mPosition; ///< Position of vertex
  101. int mNumFaces = 0; ///< Number of faces in the face array below
  102. int mFaces[3] = { -1, -1, -1 }; ///< Indices of 3 neighboring faces with the biggest difference in normal (used to shift vertices for convex radius)
  103. };
  104. static_assert(sizeof(Point) == 32, "Unexpected size");
  105. static_assert(alignof(Point) == 16, "Unexpected alignment");
  106. Vec3 mCenterOfMass; ///< Center of mass of this convex hull
  107. Mat44 mInertia; ///< Inertia matrix assuming density is 1 (needs to be multiplied by density)
  108. AABox mLocalBounds; ///< Local bounding box for the convex hull
  109. vector<Point> mPoints; ///< Points on the convex hull surface
  110. vector<Face> mFaces; ///< Faces of the convex hull surface
  111. vector<Plane> mPlanes; ///< Planes for the faces (1-on-1 with mFaces array, separate because they need to be 16 byte aligned)
  112. vector<uint8> mVertexIdx; ///< A list of vertex indices (indexing in mPoints) for each of the faces
  113. float mConvexRadius = 0.0f; ///< Convex radius
  114. float mVolume; ///< Total volume of the convex hull
  115. float mInnerRadius = FLT_MAX; ///< Radius of the biggest sphere that fits entirely in the convex hull
  116. #ifdef JPH_DEBUG_RENDERER
  117. mutable DebugRenderer::GeometryRef mGeometry;
  118. #endif // JPH_DEBUG_RENDERER
  119. };
  120. } // JPH