Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Collision/Shape/ConvexHullShape.h
9917 views
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)1// SPDX-FileCopyrightText: 2021 Jorrit Rouwe2// SPDX-License-Identifier: MIT34#pragma once56#include <Jolt/Physics/Collision/Shape/ConvexShape.h>7#include <Jolt/Physics/PhysicsSettings.h>8#include <Jolt/Geometry/Plane.h>9#ifdef JPH_DEBUG_RENDERER10#include <Jolt/Renderer/DebugRenderer.h>11#endif // JPH_DEBUG_RENDERER1213JPH_NAMESPACE_BEGIN1415/// Class that constructs a ConvexHullShape16class JPH_EXPORT ConvexHullShapeSettings final : public ConvexShapeSettings17{18JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, ConvexHullShapeSettings)1920public:21/// Default constructor for deserialization22ConvexHullShapeSettings() = default;2324/// Create a convex hull from inPoints and maximum convex radius inMaxConvexRadius, the radius is automatically lowered if the hull requires it.25/// (internally this will be subtracted so the total size will not grow with the convex radius).26ConvexHullShapeSettings(const Vec3 *inPoints, int inNumPoints, float inMaxConvexRadius = cDefaultConvexRadius, const PhysicsMaterial *inMaterial = nullptr) : ConvexShapeSettings(inMaterial), mPoints(inPoints, inPoints + inNumPoints), mMaxConvexRadius(inMaxConvexRadius) { }27ConvexHullShapeSettings(const Array<Vec3> &inPoints, float inConvexRadius = cDefaultConvexRadius, const PhysicsMaterial *inMaterial = nullptr) : ConvexShapeSettings(inMaterial), mPoints(inPoints), mMaxConvexRadius(inConvexRadius) { }2829// See: ShapeSettings30virtual ShapeResult Create() const override;3132Array<Vec3> mPoints; ///< Points to create the hull from. Note that these points don't need to be the vertices of the convex hull, they can contain interior points or points on faces/edges.33float 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.34float mMaxErrorConvexRadius = 0.05f; ///< Maximum distance between the shrunk hull + convex radius and the actual hull.35float 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.36};3738/// A convex hull39class JPH_EXPORT ConvexHullShape final : public ConvexShape40{41public:42JPH_OVERRIDE_NEW_DELETE4344/// 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.45/// The ConvexHullShapeSettings::Create function will return an error when too many points are provided.46static constexpr int cMaxPointsInHull = 256;4748/// Constructor49ConvexHullShape() : ConvexShape(EShapeSubType::ConvexHull) { }50ConvexHullShape(const ConvexHullShapeSettings &inSettings, ShapeResult &outResult);5152// See Shape::GetCenterOfMass53virtual Vec3 GetCenterOfMass() const override { return mCenterOfMass; }5455// See Shape::GetLocalBounds56virtual AABox GetLocalBounds() const override { return mLocalBounds; }5758// See Shape::GetInnerRadius59virtual float GetInnerRadius() const override { return mInnerRadius; }6061// See Shape::GetMassProperties62virtual MassProperties GetMassProperties() const override;6364// See Shape::GetSurfaceNormal65virtual Vec3 GetSurfaceNormal(const SubShapeID &inSubShapeID, Vec3Arg inLocalSurfacePosition) const override;6667// See Shape::GetSupportingFace68virtual void GetSupportingFace(const SubShapeID &inSubShapeID, Vec3Arg inDirection, Vec3Arg inScale, Mat44Arg inCenterOfMassTransform, SupportingFace &outVertices) const override;6970// See ConvexShape::GetSupportFunction71virtual const Support * GetSupportFunction(ESupportMode inMode, SupportBuffer &inBuffer, Vec3Arg inScale) const override;7273// See Shape::GetSubmergedVolume74virtual void GetSubmergedVolume(Mat44Arg inCenterOfMassTransform, Vec3Arg inScale, const Plane &inSurface, float &outTotalVolume, float &outSubmergedVolume, Vec3 &outCenterOfBuoyancy JPH_IF_DEBUG_RENDERER(, RVec3Arg inBaseOffset)) const override;7576#ifdef JPH_DEBUG_RENDERER77// See Shape::Draw78virtual void Draw(DebugRenderer *inRenderer, RMat44Arg inCenterOfMassTransform, Vec3Arg inScale, ColorArg inColor, bool inUseMaterialColors, bool inDrawWireframe) const override;7980/// Debugging helper draw function that draws how all points are moved when a shape is shrunk by the convex radius81void DrawShrunkShape(DebugRenderer *inRenderer, RMat44Arg inCenterOfMassTransform, Vec3Arg inScale) const;82#endif // JPH_DEBUG_RENDERER8384// See Shape::CastRay85virtual bool CastRay(const RayCast &inRay, const SubShapeIDCreator &inSubShapeIDCreator, RayCastResult &ioHit) const override;86virtual void CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector, const ShapeFilter &inShapeFilter = { }) const override;8788// See: Shape::CollidePoint89virtual void CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector, const ShapeFilter &inShapeFilter = { }) const override;9091// See: Shape::CollideSoftBodyVertices92virtual void CollideSoftBodyVertices(Mat44Arg inCenterOfMassTransform, Vec3Arg inScale, const CollideSoftBodyVertexIterator &inVertices, uint inNumVertices, int inCollidingShapeIndex) const override;9394// See Shape::GetTrianglesStart95virtual void GetTrianglesStart(GetTrianglesContext &ioContext, const AABox &inBox, Vec3Arg inPositionCOM, QuatArg inRotation, Vec3Arg inScale) const override;9697// See Shape::GetTrianglesNext98virtual int GetTrianglesNext(GetTrianglesContext &ioContext, int inMaxTrianglesRequested, Float3 *outTriangleVertices, const PhysicsMaterial **outMaterials = nullptr) const override;99100// See Shape101virtual void SaveBinaryState(StreamOut &inStream) const override;102103// See Shape::GetStats104virtual Stats GetStats() const override;105106// See Shape::GetVolume107virtual float GetVolume() const override { return mVolume; }108109/// Get the convex radius of this convex hull110float GetConvexRadius() const { return mConvexRadius; }111112/// Get the planes of this convex hull113const Array<Plane> & GetPlanes() const { return mPlanes; }114115/// Get the number of vertices in this convex hull116inline uint GetNumPoints() const { return uint(mPoints.size()); }117118/// Get a vertex of this convex hull relative to the center of mass119inline Vec3 GetPoint(uint inIndex) const { return mPoints[inIndex].mPosition; }120121/// Get the number of faces in this convex hull122inline uint GetNumFaces() const { return uint(mFaces.size()); }123124/// Get the number of vertices in a face125inline uint GetNumVerticesInFace(uint inFaceIndex) const { return mFaces[inFaceIndex].mNumVertices; }126127/// Get the vertices indices of a face128/// @param inFaceIndex Index of the face.129/// @param inMaxVertices Maximum number of vertices to return.130/// @param outVertices Array of vertices indices, must be at least inMaxVertices in size, the vertices are returned in counter clockwise order and the positions can be obtained using GetPoint(index).131/// @return Number of vertices in face, if this is bigger than inMaxVertices, not all vertices were retrieved.132inline uint GetFaceVertices(uint inFaceIndex, uint inMaxVertices, uint *outVertices) const133{134const Face &face = mFaces[inFaceIndex];135const uint8 *first_vertex = mVertexIdx.data() + face.mFirstVertex;136uint num_vertices = min<uint>(face.mNumVertices, inMaxVertices);137for (uint i = 0; i < num_vertices; ++i)138outVertices[i] = first_vertex[i];139return face.mNumVertices;140}141142// Register shape functions with the registry143static void sRegister();144145#ifdef JPH_DEBUG_RENDERER146/// Draw the outlines of the faces of the convex hull when drawing the shape147inline static bool sDrawFaceOutlines = false;148#endif // JPH_DEBUG_RENDERER149150protected:151// See: Shape::RestoreBinaryState152virtual void RestoreBinaryState(StreamIn &inStream) override;153154private:155/// Helper function that returns the min and max fraction along the ray that hits the convex hull. Returns false if there is no hit.156bool CastRayHelper(const RayCast &inRay, float &outMinFraction, float &outMaxFraction) const;157158/// Class for GetTrianglesStart/Next159class CHSGetTrianglesContext;160161/// Classes for GetSupportFunction162class HullNoConvex;163class HullWithConvex;164class HullWithConvexScaled;165166struct Face167{168uint16 mFirstVertex; ///< First index in mVertexIdx to use169uint16 mNumVertices = 0; ///< Number of vertices in the mVertexIdx to use170};171172static_assert(sizeof(Face) == 4, "Unexpected size");173static_assert(alignof(Face) == 2, "Unexpected alignment");174175struct Point176{177Vec3 mPosition; ///< Position of vertex178int mNumFaces = 0; ///< Number of faces in the face array below179int mFaces[3] = { -1, -1, -1 }; ///< Indices of 3 neighboring faces with the biggest difference in normal (used to shift vertices for convex radius)180};181182static_assert(sizeof(Point) == 32, "Unexpected size");183static_assert(alignof(Point) == JPH_VECTOR_ALIGNMENT, "Unexpected alignment");184185Vec3 mCenterOfMass; ///< Center of mass of this convex hull186Mat44 mInertia; ///< Inertia matrix assuming density is 1 (needs to be multiplied by density)187AABox mLocalBounds; ///< Local bounding box for the convex hull188Array<Point> mPoints; ///< Points on the convex hull surface189Array<Face> mFaces; ///< Faces of the convex hull surface190Array<Plane> mPlanes; ///< Planes for the faces (1-on-1 with mFaces array, separate because they need to be 16 byte aligned)191Array<uint8> mVertexIdx; ///< A list of vertex indices (indexing in mPoints) for each of the faces192float mConvexRadius = 0.0f; ///< Convex radius193float mVolume; ///< Total volume of the convex hull194float mInnerRadius = FLT_MAX; ///< Radius of the biggest sphere that fits entirely in the convex hull195196#ifdef JPH_DEBUG_RENDERER197mutable DebugRenderer::GeometryRef mGeometry;198#endif // JPH_DEBUG_RENDERER199};200201JPH_NAMESPACE_END202203204