BodyCreationSettings.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #include <Jolt/Jolt.h>
  5. #include <Jolt/Physics/Body/BodyCreationSettings.h>
  6. #include <Jolt/ObjectStream/TypeDeclarations.h>
  7. #include <Jolt/Core/StreamIn.h>
  8. #include <Jolt/Core/StreamOut.h>
  9. #include <Jolt/Core/StreamUtils.h>
  10. JPH_NAMESPACE_BEGIN
  11. JPH_IMPLEMENT_SERIALIZABLE_NON_VIRTUAL(BodyCreationSettings)
  12. {
  13. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mPosition)
  14. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mRotation)
  15. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mLinearVelocity)
  16. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mAngularVelocity)
  17. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mUserData)
  18. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mShape)
  19. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mCollisionGroup)
  20. JPH_ADD_ENUM_ATTRIBUTE(BodyCreationSettings, mObjectLayer)
  21. JPH_ADD_ENUM_ATTRIBUTE(BodyCreationSettings, mMotionType)
  22. JPH_ADD_ENUM_ATTRIBUTE(BodyCreationSettings, mAllowedDOFs)
  23. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mAllowDynamicOrKinematic)
  24. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mIsSensor)
  25. JPH_ADD_ATTRIBUTE_WITH_ALIAS(BodyCreationSettings, mCollideKinematicVsNonDynamic, "mSensorDetectsStatic") // This is the old name to keep backwards compatibility
  26. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mUseManifoldReduction)
  27. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mApplyGyroscopicForce)
  28. JPH_ADD_ENUM_ATTRIBUTE(BodyCreationSettings, mMotionQuality)
  29. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mEnhancedInternalEdgeRemoval)
  30. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mAllowSleeping)
  31. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mFriction)
  32. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mRestitution)
  33. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mLinearDamping)
  34. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mAngularDamping)
  35. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mMaxLinearVelocity)
  36. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mMaxAngularVelocity)
  37. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mGravityFactor)
  38. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mNumVelocityStepsOverride)
  39. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mNumPositionStepsOverride)
  40. JPH_ADD_ENUM_ATTRIBUTE(BodyCreationSettings, mOverrideMassProperties)
  41. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mInertiaMultiplier)
  42. JPH_ADD_ATTRIBUTE(BodyCreationSettings, mMassPropertiesOverride)
  43. }
  44. void BodyCreationSettings::SaveBinaryState(StreamOut &inStream) const
  45. {
  46. inStream.Write(mPosition);
  47. inStream.Write(mRotation);
  48. inStream.Write(mLinearVelocity);
  49. inStream.Write(mAngularVelocity);
  50. mCollisionGroup.SaveBinaryState(inStream);
  51. inStream.Write(mObjectLayer);
  52. inStream.Write(mMotionType);
  53. inStream.Write(mAllowedDOFs);
  54. inStream.Write(mAllowDynamicOrKinematic);
  55. inStream.Write(mIsSensor);
  56. inStream.Write(mCollideKinematicVsNonDynamic);
  57. inStream.Write(mUseManifoldReduction);
  58. inStream.Write(mApplyGyroscopicForce);
  59. inStream.Write(mMotionQuality);
  60. inStream.Write(mEnhancedInternalEdgeRemoval);
  61. inStream.Write(mAllowSleeping);
  62. inStream.Write(mFriction);
  63. inStream.Write(mRestitution);
  64. inStream.Write(mLinearDamping);
  65. inStream.Write(mAngularDamping);
  66. inStream.Write(mMaxLinearVelocity);
  67. inStream.Write(mMaxAngularVelocity);
  68. inStream.Write(mGravityFactor);
  69. inStream.Write(mNumVelocityStepsOverride);
  70. inStream.Write(mNumPositionStepsOverride);
  71. inStream.Write(mOverrideMassProperties);
  72. inStream.Write(mInertiaMultiplier);
  73. mMassPropertiesOverride.SaveBinaryState(inStream);
  74. }
  75. void BodyCreationSettings::RestoreBinaryState(StreamIn &inStream)
  76. {
  77. inStream.Read(mPosition);
  78. inStream.Read(mRotation);
  79. inStream.Read(mLinearVelocity);
  80. inStream.Read(mAngularVelocity);
  81. mCollisionGroup.RestoreBinaryState(inStream);
  82. inStream.Read(mObjectLayer);
  83. inStream.Read(mMotionType);
  84. inStream.Read(mAllowedDOFs);
  85. inStream.Read(mAllowDynamicOrKinematic);
  86. inStream.Read(mIsSensor);
  87. inStream.Read(mCollideKinematicVsNonDynamic);
  88. inStream.Read(mUseManifoldReduction);
  89. inStream.Read(mApplyGyroscopicForce);
  90. inStream.Read(mMotionQuality);
  91. inStream.Read(mEnhancedInternalEdgeRemoval);
  92. inStream.Read(mAllowSleeping);
  93. inStream.Read(mFriction);
  94. inStream.Read(mRestitution);
  95. inStream.Read(mLinearDamping);
  96. inStream.Read(mAngularDamping);
  97. inStream.Read(mMaxLinearVelocity);
  98. inStream.Read(mMaxAngularVelocity);
  99. inStream.Read(mGravityFactor);
  100. inStream.Read(mNumVelocityStepsOverride);
  101. inStream.Read(mNumPositionStepsOverride);
  102. inStream.Read(mOverrideMassProperties);
  103. inStream.Read(mInertiaMultiplier);
  104. mMassPropertiesOverride.RestoreBinaryState(inStream);
  105. }
  106. Shape::ShapeResult BodyCreationSettings::ConvertShapeSettings()
  107. {
  108. // If we already have a shape, return it
  109. if (mShapePtr != nullptr)
  110. {
  111. mShape = nullptr;
  112. Shape::ShapeResult result;
  113. result.Set(const_cast<Shape *>(mShapePtr.GetPtr()));
  114. return result;
  115. }
  116. // Check if we have shape settings
  117. if (mShape == nullptr)
  118. {
  119. Shape::ShapeResult result;
  120. result.SetError("No shape present!");
  121. return result;
  122. }
  123. // Create the shape
  124. Shape::ShapeResult result = mShape->Create();
  125. if (result.IsValid())
  126. mShapePtr = result.Get();
  127. mShape = nullptr;
  128. return result;
  129. }
  130. const Shape *BodyCreationSettings::GetShape() const
  131. {
  132. // If we already have a shape, return it
  133. if (mShapePtr != nullptr)
  134. return mShapePtr;
  135. // Check if we have shape settings
  136. if (mShape == nullptr)
  137. return nullptr;
  138. // Create the shape
  139. Shape::ShapeResult result = mShape->Create();
  140. if (result.IsValid())
  141. return result.Get();
  142. Trace("Error: %s", result.GetError().c_str());
  143. JPH_ASSERT(false, "An error occurred during shape creation. Use ConvertShapeSettings() to convert the shape and get the error!");
  144. return nullptr;
  145. }
  146. MassProperties BodyCreationSettings::GetMassProperties() const
  147. {
  148. // Calculate mass properties
  149. MassProperties mass_properties;
  150. switch (mOverrideMassProperties)
  151. {
  152. case EOverrideMassProperties::CalculateMassAndInertia:
  153. mass_properties = GetShape()->GetMassProperties();
  154. mass_properties.mInertia *= mInertiaMultiplier;
  155. mass_properties.mInertia(3, 3) = 1.0f;
  156. break;
  157. case EOverrideMassProperties::CalculateInertia:
  158. mass_properties = GetShape()->GetMassProperties();
  159. mass_properties.ScaleToMass(mMassPropertiesOverride.mMass);
  160. mass_properties.mInertia *= mInertiaMultiplier;
  161. mass_properties.mInertia(3, 3) = 1.0f;
  162. break;
  163. case EOverrideMassProperties::MassAndInertiaProvided:
  164. mass_properties = mMassPropertiesOverride;
  165. break;
  166. }
  167. return mass_properties;
  168. }
  169. void BodyCreationSettings::SaveWithChildren(StreamOut &inStream, ShapeToIDMap *ioShapeMap, MaterialToIDMap *ioMaterialMap, GroupFilterToIDMap *ioGroupFilterMap) const
  170. {
  171. // Save creation settings
  172. SaveBinaryState(inStream);
  173. // Save shape
  174. if (ioShapeMap != nullptr && ioMaterialMap != nullptr)
  175. GetShape()->SaveWithChildren(inStream, *ioShapeMap, *ioMaterialMap);
  176. else
  177. inStream.Write(~uint32(0));
  178. // Save group filter
  179. StreamUtils::SaveObjectReference(inStream, mCollisionGroup.GetGroupFilter(), ioGroupFilterMap);
  180. }
  181. BodyCreationSettings::BCSResult BodyCreationSettings::sRestoreWithChildren(StreamIn &inStream, IDToShapeMap &ioShapeMap, IDToMaterialMap &ioMaterialMap, IDToGroupFilterMap &ioGroupFilterMap)
  182. {
  183. BCSResult result;
  184. // Read creation settings
  185. BodyCreationSettings settings;
  186. settings.RestoreBinaryState(inStream);
  187. if (inStream.IsEOF() || inStream.IsFailed())
  188. {
  189. result.SetError("Error reading body creation settings");
  190. return result;
  191. }
  192. // Read shape
  193. Shape::ShapeResult shape_result = Shape::sRestoreWithChildren(inStream, ioShapeMap, ioMaterialMap);
  194. if (shape_result.HasError())
  195. {
  196. result.SetError(shape_result.GetError());
  197. return result;
  198. }
  199. settings.SetShape(shape_result.Get());
  200. // Read group filter
  201. Result gfresult = StreamUtils::RestoreObjectReference(inStream, ioGroupFilterMap);
  202. if (gfresult.HasError())
  203. {
  204. result.SetError(gfresult.GetError());
  205. return result;
  206. }
  207. settings.mCollisionGroup.SetGroupFilter(gfresult.Get());
  208. result.Set(settings);
  209. return result;
  210. }
  211. JPH_NAMESPACE_END