PhysicsScene.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #include <Jolt.h>
  4. #include <Physics/PhysicsScene.h>
  5. #include <Physics/PhysicsSystem.h>
  6. #include <ObjectStream/TypeDeclarations.h>
  7. namespace JPH {
  8. JPH_IMPLEMENT_SERIALIZABLE_NON_VIRTUAL(PhysicsScene)
  9. {
  10. JPH_ADD_ATTRIBUTE(PhysicsScene, mBodies)
  11. }
  12. void PhysicsScene::AddBody(const BodyCreationSettings &inBody)
  13. {
  14. mBodies.push_back(inBody);
  15. }
  16. bool PhysicsScene::FixInvalidScales()
  17. {
  18. const Vec3 unit_scale = Vec3::sReplicate(1.0f);
  19. bool success = true;
  20. for (BodyCreationSettings &b : mBodies)
  21. {
  22. // Test if there is an invalid scale in the shape hierarchy
  23. const Shape *shape = b.GetShape();
  24. if (!shape->IsValidScale(unit_scale))
  25. {
  26. // Fix it up
  27. Shape::ShapeResult result = shape->ScaleShape(unit_scale);
  28. if (result.IsValid())
  29. b.SetShape(result.Get());
  30. else
  31. success = false;
  32. }
  33. }
  34. return success;
  35. }
  36. bool PhysicsScene::CreateBodies(PhysicsSystem *inSystem) const
  37. {
  38. BodyInterface &bi = inSystem->GetBodyInterface();
  39. // Create bodies
  40. BodyIDVector body_ids;
  41. body_ids.reserve(mBodies.size());
  42. for (const BodyCreationSettings &b : mBodies)
  43. {
  44. const Body *body = bi.CreateBody(b);
  45. if (body == nullptr)
  46. break; // Out of bodies
  47. body_ids.push_back(body->GetID());
  48. }
  49. // Batch add bodies
  50. BodyInterface::AddState add_state = bi.AddBodiesPrepare(body_ids.data(), (int)body_ids.size());
  51. bi.AddBodiesFinalize(body_ids.data(), (int)body_ids.size(), add_state, EActivation::Activate);
  52. // Return true if all bodies were added
  53. return body_ids.size() == mBodies.size();
  54. }
  55. void PhysicsScene::SaveBinaryState(StreamOut &inStream, bool inSaveShapes, bool inSaveGroupFilter) const
  56. {
  57. BodyCreationSettings::ShapeToIDMap shape_to_id;
  58. BodyCreationSettings::MaterialToIDMap material_to_id;
  59. BodyCreationSettings::GroupFilterToIDMap group_filter_to_id;
  60. // Save bodies
  61. inStream.Write((uint32)mBodies.size());
  62. for (const BodyCreationSettings &b : mBodies)
  63. b.SaveWithChildren(inStream, inSaveShapes? &shape_to_id : nullptr, inSaveShapes? &material_to_id : nullptr, inSaveGroupFilter? &group_filter_to_id : nullptr);
  64. }
  65. PhysicsScene::PhysicsSceneResult PhysicsScene::sRestoreFromBinaryState(StreamIn &inStream)
  66. {
  67. PhysicsSceneResult result;
  68. // Create scene
  69. Ref<PhysicsScene> scene = new PhysicsScene();
  70. BodyCreationSettings::IDToShapeMap id_to_shape;
  71. BodyCreationSettings::IDToMaterialMap id_to_material;
  72. BodyCreationSettings::IDToGroupFilterMap id_to_group_filter;
  73. // Reserve some memory to avoid frequent reallocations
  74. id_to_shape.reserve(1024);
  75. id_to_material.reserve(128);
  76. id_to_group_filter.reserve(128);
  77. // Read bodies
  78. uint32 len = 0;
  79. inStream.Read(len);
  80. scene->mBodies.resize(len);
  81. for (BodyCreationSettings &b : scene->mBodies)
  82. {
  83. // Read creation settings
  84. BodyCreationSettings::BCSResult bcs_result = BodyCreationSettings::sRestoreWithChildren(inStream, id_to_shape, id_to_material, id_to_group_filter);
  85. if (bcs_result.HasError())
  86. {
  87. result.SetError(bcs_result.GetError());
  88. return result;
  89. }
  90. b = bcs_result.Get();
  91. }
  92. result.Set(scene);
  93. return result;
  94. }
  95. } // JPH