ConvexShape.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #pragma once
  4. #include <Core/StaticArray.h>
  5. #include <Physics/Collision/Shape/Shape.h>
  6. #include <Physics/Collision/Shape/SubShapeID.h>
  7. #include <Physics/Collision/PhysicsMaterial.h>
  8. #include <unordered_map>
  9. #ifdef JPH_DEBUG_RENDERER
  10. #include <Renderer/DebugRenderer.h>
  11. #endif // JPH_DEBUG_RENDERER
  12. namespace JPH {
  13. class CollideShapeSettings;
  14. /// Class that constructs a ConvexShape (abstract)
  15. class ConvexShapeSettings : public ShapeSettings
  16. {
  17. public:
  18. JPH_DECLARE_SERIALIZABLE_ABSTRACT(ConvexShapeSettings)
  19. /// Constructor
  20. ConvexShapeSettings() = default;
  21. explicit ConvexShapeSettings(const PhysicsMaterial *inMaterial) : mMaterial(inMaterial) { }
  22. /// Set the density of the object in kg / m^3
  23. void SetDensity(float inDensity) { mDensity = inDensity; }
  24. // Properties
  25. RefConst<PhysicsMaterial> mMaterial; ///< Material assigned to this shape
  26. float mDensity = 1000.0f; ///< Uniform density of the interior of the convex object (kg / m^3)
  27. };
  28. /// Base class for all convex shapes. Defines a virtual interface.
  29. class ConvexShape : public Shape
  30. {
  31. public:
  32. /// Constructor
  33. explicit ConvexShape(EShapeSubType inSubType) : Shape(EShapeType::Convex, inSubType) { }
  34. ConvexShape(EShapeSubType inSubType, const ConvexShapeSettings &inSettings, ShapeResult &outResult) : Shape(EShapeType::Convex, inSubType, inSettings, outResult), mMaterial(inSettings.mMaterial), mDensity(inSettings.mDensity) { }
  35. ConvexShape(EShapeSubType inSubType, const PhysicsMaterial *inMaterial) : Shape(EShapeType::Convex, inSubType), mMaterial(inMaterial) { }
  36. // See Shape::GetSubShapeIDBitsRecursive
  37. virtual uint GetSubShapeIDBitsRecursive() const override { return 0; } // Convex shapes don't have sub shapes
  38. // See Shape::GetMaterial
  39. virtual const PhysicsMaterial * GetMaterial(const SubShapeID &inSubShapeID) const override { JPH_ASSERT(inSubShapeID.IsEmpty(), "Invalid subshape ID"); return GetMaterial(); }
  40. // See Shape::CastRay
  41. virtual bool CastRay(const RayCast &inRay, const SubShapeIDCreator &inSubShapeIDCreator, RayCastResult &ioHit) const override;
  42. virtual void CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector) const override;
  43. // See: Shape::CollidePoint
  44. virtual void CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector) const override;
  45. // See Shape::GetTrianglesStart
  46. virtual void GetTrianglesStart(GetTrianglesContext &ioContext, const AABox &inBox, Vec3Arg inPositionCOM, QuatArg inRotation, Vec3Arg inScale) const override;
  47. // See Shape::GetTrianglesNext
  48. virtual int GetTrianglesNext(GetTrianglesContext &ioContext, int inMaxTrianglesRequested, Float3 *outTriangleVertices, const PhysicsMaterial **outMaterials = nullptr) const override;
  49. // See Shape::GetSubmergedVolume
  50. virtual void GetSubmergedVolume(Mat44Arg inCenterOfMassTransform, Vec3Arg inScale, const Plane &inSurface, float &outTotalVolume, float &outSubmergedVolume, Vec3 &outCenterOfBuoyancy) const override;
  51. /// Function that provides an interface for GJK
  52. class Support
  53. {
  54. public:
  55. /// Warning: Virtual destructor will not be called on this object!
  56. virtual ~Support() = default;
  57. /// Calculate the support vector for this convex shape (includes / excludes the convex radius depending on how this was obtained).
  58. /// Support vector is relative to the center of mass of the shape.
  59. virtual Vec3 GetSupport(Vec3Arg inDirection) const = 0;
  60. /// Convex radius of shape. Collision detection on penetrating shapes is much more expensive,
  61. /// so you can add a radius around objects to increase the shape. This makes it far less likely that they will actually penetrate.
  62. virtual float GetConvexRadius() const = 0;
  63. };
  64. /// Buffer to hold a Support object, used to avoid dynamic memory allocations
  65. class alignas(16) SupportBuffer
  66. {
  67. public:
  68. uint8 mData[4160];
  69. };
  70. /// How the GetSupport function should behave
  71. enum class ESupportMode
  72. {
  73. ExcludeConvexRadius, ///< Return the shape excluding the convex radius
  74. IncludeConvexRadius, ///< Return the shape including the convex radius
  75. };
  76. /// Returns an object that provides the GetSupport function for this shape.
  77. /// inMode determines if this support function includes or excludes the convex radius.
  78. /// of the values returned by the GetSupport function. This improves numerical accuracy of the results.
  79. /// inScale scales this shape in local space.
  80. virtual const Support * GetSupportFunction(ESupportMode inMode, SupportBuffer &inBuffer, Vec3Arg inScale) const = 0;
  81. /// Type definition for a supporting face
  82. using SupportingFace = StaticArray<Vec3, 32>;
  83. /// Get the vertices of the face that faces inDirection the most (includes convex radius).
  84. /// Face is relative to the center of mass of the shape.
  85. virtual void GetSupportingFace(Vec3Arg inDirection, Vec3Arg inScale, SupportingFace &outVertices) const = 0;
  86. /// Material of the shape
  87. void SetMaterial(const PhysicsMaterial *inMaterial) { mMaterial = inMaterial; }
  88. const PhysicsMaterial * GetMaterial() const { return mMaterial != nullptr? mMaterial : PhysicsMaterial::sDefault; }
  89. /// Set density of the shape (kg / m^3)
  90. void SetDensity(float inDensity) { mDensity = inDensity; }
  91. /// Get density of the shape (kg / m^3)
  92. float GetDensity() const { return mDensity; }
  93. #ifdef JPH_DEBUG_RENDERER
  94. // See Shape::DrawGetSupportFunction
  95. virtual void DrawGetSupportFunction(DebugRenderer *inRenderer, Mat44Arg inCenterOfMassTransform, Vec3Arg inScale, ColorArg inColor, bool inDrawSupportDirection) const override;
  96. // See Shape::DrawGetSupportingFace
  97. virtual void DrawGetSupportingFace(DebugRenderer *inRenderer, Mat44Arg inCenterOfMassTransform, Vec3Arg inScale) const override;
  98. #endif // JPH_DEBUG_RENDERER
  99. // See Shape
  100. virtual void SaveBinaryState(StreamOut &inStream) const override;
  101. virtual void SaveMaterialState(PhysicsMaterialList &outMaterials) const override;
  102. virtual void RestoreMaterialState(const PhysicsMaterialRefC *inMaterials, uint inNumMaterials) override;
  103. // Register shape functions with the registry
  104. static void sRegister();
  105. protected:
  106. // See: Shape::RestoreBinaryState
  107. virtual void RestoreBinaryState(StreamIn &inStream) override;
  108. /// Vertex list that forms a unit sphere
  109. static const vector<Vec3> sUnitSphereTriangles;
  110. private:
  111. // Class for GetTrianglesStart/Next
  112. class CSGetTrianglesContext;
  113. // Helper functions called by CollisionDispatch
  114. static void sCollideConvexVsConvex(const Shape *inShape1, const Shape *inShape2, Vec3Arg inScale1, Vec3Arg inScale2, Mat44Arg inCenterOfMassTransform1, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, const CollideShapeSettings &inCollideShapeSettings, CollideShapeCollector &ioCollector);
  115. static void sCastConvexVsConvex(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector);
  116. // Properties
  117. RefConst<PhysicsMaterial> mMaterial; ///< Material assigned to this shape
  118. float mDensity = 1000.0f; ///< Uniform density of the interior of the convex object (kg / m^3)
  119. #ifdef JPH_DEBUG_RENDERER
  120. mutable unordered_map<Vec3, DebugRenderer::GeometryRef> mGetSupportFunctionGeometry;
  121. #endif // JPH_DEBUG_RENDERER
  122. };
  123. } // JPH