MeshShape.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #pragma once
  4. #include <Physics/Collision/Shape/Shape.h>
  5. #include <Physics/Collision/PhysicsMaterial.h>
  6. #include <Core/ByteBuffer.h>
  7. #include <Geometry/Triangle.h>
  8. #include <Geometry/IndexedTriangle.h>
  9. #ifdef JPH_DEBUG_RENDERER
  10. #include <Renderer/DebugRenderer.h>
  11. #endif // JPH_DEBUG_RENDERER
  12. namespace JPH {
  13. class ConvexShape;
  14. class CollideShapeSettings;
  15. /// Class that constructs a MeshShape
  16. class MeshShapeSettings final : public ShapeSettings
  17. {
  18. public:
  19. JPH_DECLARE_SERIALIZABLE_VIRTUAL(MeshShapeSettings)
  20. /// Default constructor for deserialization
  21. MeshShapeSettings() = default;
  22. /// Create a mesh shape.
  23. MeshShapeSettings(const TriangleList &inTriangles, const PhysicsMaterialList &inMaterials = PhysicsMaterialList());
  24. MeshShapeSettings(const VertexList &inVertices, const IndexedTriangleList &inTriangles, const PhysicsMaterialList &inMaterials = PhysicsMaterialList());
  25. /// Sanitize the mesh data. Remove duplicate and degenerate triangles.
  26. void Sanitize();
  27. // See: ShapeSettings
  28. virtual ShapeResult Create() const override;
  29. /// Mesh data.
  30. VertexList mTriangleVertices; ///< Vertices belonging to mIndexedTriangles
  31. IndexedTriangleList mIndexedTriangles; ///< Original list of indexed triangles
  32. /// Materials assigned to the triangles. Each triangle specifies which material it uses through its mMaterialIndex
  33. PhysicsMaterialList mMaterials;
  34. /// Maximum number of triangles in each leaf of the axis aligned box tree. This is a balance between memory and performance. Can be in the range [1, MeshShape::MaxTrianglesPerLeaf].
  35. /// Sensible values are between 4 (for better performance) and 8 (for less memory usage).
  36. uint mMaxTrianglesPerLeaf = 8;
  37. };
  38. /// A mesh shape, consisting of triangles. Cannot be used as a dynamic object.
  39. class MeshShape final : public Shape
  40. {
  41. public:
  42. /// Constructor
  43. MeshShape() : Shape(EShapeType::Mesh, EShapeSubType::Mesh) { }
  44. MeshShape(const MeshShapeSettings &inSettings, ShapeResult &outResult);
  45. // See Shape::MustBeStatic
  46. virtual bool MustBeStatic() const override { return true; }
  47. // See Shape::GetLocalBounds
  48. virtual AABox GetLocalBounds() const override;
  49. // See Shape::GetSubShapeIDBitsRecursive
  50. virtual uint GetSubShapeIDBitsRecursive() const override;
  51. // See Shape::GetInnerRadius
  52. virtual float GetInnerRadius() const override { return 0.0f; }
  53. // See Shape::GetMassProperties
  54. virtual MassProperties GetMassProperties() const override;
  55. // See Shape::GetMaterial
  56. virtual const PhysicsMaterial * GetMaterial(const SubShapeID &inSubShapeID) const override;
  57. // See Shape::GetSurfaceNormal
  58. virtual Vec3 GetSurfaceNormal(const SubShapeID &inSubShapeID, Vec3Arg inLocalSurfacePosition) const override;
  59. #ifdef JPH_DEBUG_RENDERER
  60. // See Shape::Draw
  61. virtual void Draw(DebugRenderer *inRenderer, Mat44Arg inCenterOfMassTransform, Vec3Arg inScale, ColorArg inColor, bool inUseMaterialColors, bool inDrawWireframe) const override;
  62. #endif // JPH_DEBUG_RENDERER
  63. // See Shape::CastRay
  64. virtual bool CastRay(const RayCast &inRay, const SubShapeIDCreator &inSubShapeIDCreator, RayCastResult &ioHit) const override;
  65. virtual void CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector) const override;
  66. /// See: Shape::CollidePoint
  67. /// Note that for CollidePoint to work for a mesh shape, the mesh needs to be closed (a manifold) or multiple non-intersecting manifolds. Triangles may be facing the interior of the manifold.
  68. /// Insideness is tested by counting the amount of triangles encountered when casting an infinite ray from inPoint. If the number of hits is odd we're inside, if it's even we're outside.
  69. virtual void CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector) const override;
  70. // See Shape::GetTrianglesStart
  71. virtual void GetTrianglesStart(GetTrianglesContext &ioContext, const AABox &inBox, Vec3Arg inPositionCOM, QuatArg inRotation, Vec3Arg inScale) const override;
  72. // See Shape::GetTrianglesNext
  73. virtual int GetTrianglesNext(GetTrianglesContext &ioContext, int inMaxTrianglesRequested, Float3 *outTriangleVertices, const PhysicsMaterial **outMaterials = nullptr) const override;
  74. // See Shape::GetSubmergedVolume
  75. virtual void GetSubmergedVolume(Mat44Arg inCenterOfMassTransform, Vec3Arg inScale, const Plane &inSurface, float &outTotalVolume, float &outSubmergedVolume, Vec3 &outCenterOfBuoyancy) const override { JPH_ASSERT(false, "Not supported"); }
  76. // See Shape
  77. virtual void SaveBinaryState(StreamOut &inStream) const override;
  78. virtual void SaveMaterialState(PhysicsMaterialList &outMaterials) const override;
  79. virtual void RestoreMaterialState(const PhysicsMaterialRefC *inMaterials, uint inNumMaterials) override;
  80. // See Shape::GetStats
  81. virtual Stats GetStats() const override;
  82. // See Shape::GetVolume
  83. virtual float GetVolume() const override { return 0; }
  84. #ifdef JPH_DEBUG_RENDERER
  85. // Settings
  86. static bool sDrawTriangleGroups;
  87. static bool sDrawTriangleOutlines;
  88. #endif // JPH_DEBUG_RENDERER
  89. // Register shape functions with the registry
  90. static void sRegister();
  91. protected:
  92. // See: Shape::RestoreBinaryState
  93. virtual void RestoreBinaryState(StreamIn &inStream) override;
  94. private:
  95. struct MSGetTrianglesContext; ///< Context class for GetTrianglesStart/Next
  96. static constexpr int NumTriangleBits = 3; ///< How many bits to reserve to encode the triangle index
  97. static constexpr int MaxTrianglesPerLeaf = 1 << NumTriangleBits; ///< Number of triangles that are stored max per leaf aabb node
  98. /// Find and flag active edges
  99. void FindActiveEdges(const VertexList &inVertices, IndexedTriangleList &ioIndices);
  100. /// Visit the entire tree using a visitor pattern
  101. template <class Visitor>
  102. void WalkTree(Visitor &ioVisitor) const;
  103. /// Same as above but with a callback per triangle instead of per block of triangles
  104. template <class Visitor>
  105. void WalkTreePerTriangle(const SubShapeIDCreator &inSubShapeIDCreator2, Visitor &ioVisitor) const;
  106. /// Decode a sub shape ID
  107. inline void DecodeSubShapeID(const SubShapeID &inSubShapeID, const void *&outTriangleBlock, uint32 &outTriangleIndex) const;
  108. // Helper functions called by CollisionDispatch
  109. static void sCollideConvexVsMesh(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);
  110. static void sCollideSphereVsMesh(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);
  111. static void sCastConvexVsMesh(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector);
  112. static void sCastSphereVsMesh(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector);
  113. /// Materials assigned to the triangles. Each triangle specifies which material it uses through its mMaterialIndex
  114. PhysicsMaterialList mMaterials;
  115. ByteBuffer mTree; ///< Resulting packed data structure
  116. /// 8 bit flags stored per triangle
  117. enum ETriangleFlags
  118. {
  119. /// Material index
  120. FLAGS_MATERIAL_BITS = 5,
  121. FLAGS_MATERIAL_MASK = (1 << FLAGS_MATERIAL_BITS) - 1,
  122. /// Active edge bits
  123. FLAGS_ACTIVE_EGDE_SHIFT = FLAGS_MATERIAL_BITS,
  124. FLAGS_ACTIVE_EDGE_BITS = 3,
  125. FLAGS_ACTIVE_EDGE_MASK = (1 << FLAGS_ACTIVE_EDGE_BITS) - 1
  126. };
  127. #ifdef JPH_DEBUG_RENDERER
  128. mutable DebugRenderer::GeometryRef mGeometry; ///< Debug rendering data
  129. mutable bool mCachedTrianglesColoredPerGroup = false; ///< This is used to regenerate the triangle batch if the drawing settings change
  130. mutable bool mCachedUseMaterialColors = false; ///< This is used to regenerate the triangle batch if the drawing settings change
  131. #endif // JPH_DEBUG_RENDERER
  132. };
  133. } // JPH