LoadSnapshotTest.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #include <TestFramework.h>
  5. #include <Tests/Tools/LoadSnapshotTest.h>
  6. #include <Jolt/Physics/PhysicsScene.h>
  7. #include <Jolt/Core/StreamWrapper.h>
  8. #include <Application/DebugUI.h>
  9. #include <Utils/Log.h>
  10. #include <Layers.h>
  11. JPH_SUPPRESS_WARNINGS_STD_BEGIN
  12. #ifdef JPH_PLATFORM_WINDOWS
  13. #include <commdlg.h>
  14. #endif
  15. #include <fstream>
  16. JPH_SUPPRESS_WARNINGS_STD_END
  17. JPH_IMPLEMENT_RTTI_VIRTUAL(LoadSnapshotTest)
  18. {
  19. JPH_ADD_BASE_CLASS(LoadSnapshotTest, Test)
  20. }
  21. void LoadSnapshotTest::Initialize()
  22. {
  23. #ifdef JPH_PLATFORM_WINDOWS
  24. // Let user browse for a file
  25. char file_name[MAX_PATH] = "";
  26. OPENFILENAMEA ofn;
  27. memset(&ofn, 0, sizeof(ofn));
  28. ofn.lStructSize = sizeof(ofn);
  29. ofn.lpstrFilter = "Snapshots\0*.bin\0";
  30. ofn.lpstrFile = file_name;
  31. ofn.nMaxFile = MAX_PATH;
  32. ofn.lpstrTitle = "Select a Jolt Binary Snapshot";
  33. ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST;
  34. if (!GetOpenFileNameA(&ofn))
  35. return;
  36. #else
  37. // Can't browse for a file, use the default name
  38. char file_name[] = "snapshot.bin";
  39. #endif
  40. ifstream stream(file_name, ifstream::in | ifstream::binary);
  41. if (!stream.is_open())
  42. FatalError("Unable to open file");
  43. StreamInWrapper wrapper(stream);
  44. PhysicsScene::PhysicsSceneResult result = PhysicsScene::sRestoreFromBinaryState(wrapper);
  45. if (result.HasError())
  46. FatalError(result.GetError().c_str());
  47. Ref<PhysicsScene> scene = result.Get();
  48. // Determine quaternion that rotates the world so that up is Y
  49. Quat up_rotation;
  50. switch (sUpAxis)
  51. {
  52. case 0: up_rotation = Quat::sRotation(Vec3::sAxisZ(), 0.5f * JPH_PI); break;
  53. case 2: up_rotation = Quat::sRotation(Vec3::sAxisX(), -0.5f * JPH_PI); break;
  54. default: up_rotation = Quat::sIdentity(); break;
  55. }
  56. // Determine if we are forced to override the object layers because one of the bodies has a layer number that is invalid in the context of this application
  57. bool override_layers = sOverrideLayers;
  58. if (!override_layers)
  59. for (BodyCreationSettings &settings : scene->GetBodies())
  60. if (settings.mObjectLayer >= Layers::NUM_LAYERS)
  61. {
  62. override_layers = true;
  63. break;
  64. }
  65. for (BodyCreationSettings &settings : scene->GetBodies())
  66. {
  67. if (override_layers)
  68. {
  69. // Override the layer so that all static objects are in the non-moving layer and everything else is in the moving layer
  70. if (settings.mMotionType == EMotionType::Static)
  71. settings.mObjectLayer = Layers::NON_MOVING;
  72. else
  73. settings.mObjectLayer = Layers::MOVING;
  74. }
  75. // Rotate the body so that it matches Y is up
  76. settings.mPosition = RMat44::sRotation(up_rotation) * settings.mPosition;
  77. settings.mRotation = up_rotation * settings.mRotation;
  78. }
  79. scene->CreateBodies(mPhysicsSystem);
  80. }
  81. void LoadSnapshotTest::CreateSettingsMenu(DebugUI *inUI, UIElement *inSubMenu)
  82. {
  83. inUI->CreateComboBox(inSubMenu, "Up Axis", { "X", "Y", "Z" }, sUpAxis, [](int inItem) { sUpAxis = inItem; });
  84. inUI->CreateCheckBox(inSubMenu, "Override Object Layers", sOverrideLayers, [](UICheckBox::EState inState) { sOverrideLayers = inState == UICheckBox::STATE_CHECKED; });
  85. inUI->CreateTextButton(inSubMenu, "Accept Changes", [this]() { RestartTest(); });
  86. }