SoftBodySharedSettings.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2023 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #pragma once
  5. #include <Jolt/Core/Reference.h>
  6. #include <Jolt/Physics/Collision/PhysicsMaterial.h>
  7. #include <Jolt/Core/StreamUtils.h>
  8. JPH_NAMESPACE_BEGIN
  9. /// This class defines the setup of all particles and their constraints.
  10. /// It is used during the simulation and can be shared between multiple soft bodies.
  11. class JPH_EXPORT SoftBodySharedSettings : public RefTarget<SoftBodySharedSettings>
  12. {
  13. public:
  14. JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(JPH_EXPORT, SoftBodySharedSettings)
  15. /// Calculate the initial lengths of all springs of the edges of this soft body
  16. void CalculateEdgeLengths();
  17. /// Calculates the initial volume of all tetrahedra of this soft body
  18. void CalculateVolumeConstraintVolumes();
  19. /// Information about the optimization of the soft body, the indices of certain elements may have changed.
  20. class OptimizationResults
  21. {
  22. public:
  23. Array<uint> mEdgeRemap; ///< Maps old edge index to new edge index
  24. };
  25. /// Optimize the soft body settings for simulation. This will reorder constraints so they can be executed in parallel.
  26. void Optimize(OptimizationResults &outResults);
  27. /// Optimize the soft body settings without results
  28. void Optimize() { OptimizationResults results; Optimize(results); }
  29. /// Saves the state of this object in binary form to inStream. Doesn't store the material list.
  30. void SaveBinaryState(StreamOut &inStream) const;
  31. /// Restore the state of this object from inStream. Doesn't restore the material list.
  32. void RestoreBinaryState(StreamIn &inStream);
  33. using SharedSettingsToIDMap = StreamUtils::ObjectToIDMap<SoftBodySharedSettings>;
  34. using IDToSharedSettingsMap = StreamUtils::IDToObjectMap<SoftBodySharedSettings>;
  35. using MaterialToIDMap = StreamUtils::ObjectToIDMap<PhysicsMaterial>;
  36. using IDToMaterialMap = StreamUtils::IDToObjectMap<PhysicsMaterial>;
  37. /// Save this shared settings and its materials. Pass in an empty map ioSettingsMap / ioMaterialMap or reuse the same map while saving multiple settings objects to the same stream in order to avoid writing duplicates.
  38. void SaveWithMaterials(StreamOut &inStream, SharedSettingsToIDMap &ioSettingsMap, MaterialToIDMap &ioMaterialMap) const;
  39. using SettingsResult = Result<Ref<SoftBodySharedSettings>>;
  40. /// Restore a shape and materials. Pass in an empty map in ioSettingsMap / ioMaterialMap or reuse the same map while reading multiple settings objects from the same stream in order to restore duplicates.
  41. static SettingsResult sRestoreWithMaterials(StreamIn &inStream, IDToSharedSettingsMap &ioSettingsMap, IDToMaterialMap &ioMaterialMap);
  42. /// A vertex is a particle, the data in this structure is only used during creation of the soft body and not during simulation
  43. struct JPH_EXPORT Vertex
  44. {
  45. JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(JPH_EXPORT, Vertex)
  46. /// Constructor
  47. Vertex() = default;
  48. Vertex(const Float3 &inPosition, const Float3 &inVelocity = Float3(0, 0, 0), float inInvMass = 1.0f) : mPosition(inPosition), mVelocity(inVelocity), mInvMass(inInvMass) { }
  49. Float3 mPosition { 0, 0, 0 }; ///< Initial position of the vertex
  50. Float3 mVelocity { 0, 0, 0 }; ///< Initial velocity of the vertex
  51. float mInvMass = 1.0f; ///< Initial inverse of the mass of the vertex
  52. };
  53. /// A face defines the surface of the body
  54. struct JPH_EXPORT Face
  55. {
  56. JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(JPH_EXPORT, Face)
  57. /// Constructor
  58. Face() = default;
  59. Face(uint32 inVertex1, uint32 inVertex2, uint32 inVertex3, uint32 inMaterialIndex = 0) : mVertex { inVertex1, inVertex2, inVertex3 }, mMaterialIndex(inMaterialIndex) { }
  60. /// Check if this is a degenerate face (a face which points to the same vertex twice)
  61. bool IsDegenerate() const { return mVertex[0] == mVertex[1] || mVertex[0] == mVertex[2] || mVertex[1] == mVertex[2]; }
  62. uint32 mVertex[3]; ///< Indices of the vertices that form the face
  63. uint32 mMaterialIndex = 0; ///< Index of the material of the face in SoftBodySharedSettings::mMaterials
  64. };
  65. /// An edge keeps two vertices at a constant distance using a spring: |x1 - x2| = rest length
  66. struct JPH_EXPORT Edge
  67. {
  68. JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(JPH_EXPORT, Edge)
  69. /// Constructor
  70. Edge() = default;
  71. Edge(uint32 inVertex1, uint32 inVertex2, float inCompliance = 0.0f) : mVertex { inVertex1, inVertex2 }, mCompliance(inCompliance) { }
  72. uint32 mVertex[2]; ///< Indices of the vertices that form the edge
  73. float mRestLength = 1.0f; ///< Rest length of the spring
  74. float mCompliance = 0.0f; ///< Inverse of the stiffness of the spring
  75. };
  76. /// Volume constraint, keeps the volume of a tetrahedron constant
  77. struct JPH_EXPORT Volume
  78. {
  79. JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(JPH_EXPORT, Volume)
  80. /// Constructor
  81. Volume() = default;
  82. Volume(uint32 inVertex1, uint32 inVertex2, uint32 inVertex3, uint32 inVertex4, float inCompliance = 0.0f) : mVertex { inVertex1, inVertex2, inVertex3, inVertex4 }, mCompliance(inCompliance) { }
  83. uint32 mVertex[4]; ///< Indices of the vertices that form the tetrhedron
  84. float mSixRestVolume = 1.0f; ///< 6 times the rest volume of the tetrahedron
  85. float mCompliance = 0.0f; ///< Inverse of the stiffness of the constraint
  86. };
  87. /// Add a face to this soft body
  88. void AddFace(const Face &inFace) { JPH_ASSERT(!inFace.IsDegenerate()); mFaces.push_back(inFace); }
  89. /// Get the size of an edge group (edge groups can run in parallel)
  90. uint GetEdgeGroupSize(uint inGroupIdx) const { return inGroupIdx == 0? mEdgeGroupEndIndices[0] : mEdgeGroupEndIndices[inGroupIdx] - mEdgeGroupEndIndices[inGroupIdx - 1]; }
  91. Array<Vertex> mVertices; ///< The list of vertices or particles of the body
  92. Array<Face> mFaces; ///< The list of faces of the body
  93. Array<Edge> mEdgeConstraints; ///< The list of edges or springs of the body
  94. Array<uint> mEdgeGroupEndIndices; ///< The start index of each group of edges that can be solved in parallel
  95. Array<Volume> mVolumeConstraints; ///< The list of volume constraints of the body that keep the volume of tetrahedra in the soft body constant
  96. PhysicsMaterialList mMaterials { PhysicsMaterial::sDefault }; ///< The materials of the faces of the body, referenced by Face::mMaterialIndex
  97. };
  98. JPH_NAMESPACE_END