LoadSnapshotTest.cpp 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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. #include <commdlg.h>
  13. #include <fstream>
  14. JPH_SUPPRESS_WARNINGS_STD_END
  15. JPH_IMPLEMENT_RTTI_VIRTUAL(LoadSnapshotTest)
  16. {
  17. JPH_ADD_BASE_CLASS(LoadSnapshotTest, Test)
  18. }
  19. void LoadSnapshotTest::Initialize()
  20. {
  21. // Let user browse for a file
  22. char file_name[MAX_PATH] = "";
  23. OPENFILENAMEA ofn;
  24. memset(&ofn, 0, sizeof(ofn));
  25. ofn.lStructSize = sizeof(ofn);
  26. ofn.lpstrFilter = "Snapshots\0*.bin\0";
  27. ofn.lpstrFile = file_name;
  28. ofn.nMaxFile = MAX_PATH;
  29. ofn.lpstrTitle = "Select a Jolt Binary Snapshot";
  30. ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST;
  31. if (!GetOpenFileNameA(&ofn))
  32. return;
  33. ifstream stream(file_name, ifstream::in | ifstream::binary);
  34. if (!stream.is_open())
  35. FatalError("Unable to open file");
  36. StreamInWrapper wrapper(stream);
  37. PhysicsScene::PhysicsSceneResult result = PhysicsScene::sRestoreFromBinaryState(wrapper);
  38. if (result.HasError())
  39. FatalError(result.GetError().c_str());
  40. Ref<PhysicsScene> scene = result.Get();
  41. // Determine quaternion that rotates the world so that up is Y
  42. Quat up_rotation;
  43. switch (sUpAxis)
  44. {
  45. case 0: up_rotation = Quat::sRotation(Vec3::sAxisZ(), 0.5f * JPH_PI); break;
  46. case 2: up_rotation = Quat::sRotation(Vec3::sAxisX(), -0.5f * JPH_PI); break;
  47. default: up_rotation = Quat::sIdentity(); break;
  48. }
  49. // 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
  50. bool override_layers = sOverrideLayers;
  51. if (!override_layers)
  52. for (BodyCreationSettings &settings : scene->GetBodies())
  53. if (settings.mObjectLayer >= Layers::NUM_LAYERS)
  54. {
  55. override_layers = true;
  56. break;
  57. }
  58. for (BodyCreationSettings &settings : scene->GetBodies())
  59. {
  60. if (override_layers)
  61. {
  62. // Override the layer so that all static objects are in the non-moving layer and everything else is in the moving layer
  63. if (settings.mMotionType == EMotionType::Static)
  64. settings.mObjectLayer = Layers::NON_MOVING;
  65. else
  66. settings.mObjectLayer = Layers::MOVING;
  67. }
  68. // Rotate the body so that it matches Y is up
  69. settings.mPosition = RMat44::sRotation(up_rotation) * settings.mPosition;
  70. settings.mRotation = up_rotation * settings.mRotation;
  71. }
  72. scene->CreateBodies(mPhysicsSystem);
  73. }
  74. void LoadSnapshotTest::CreateSettingsMenu(DebugUI *inUI, UIElement *inSubMenu)
  75. {
  76. inUI->CreateComboBox(inSubMenu, "Up Axis", { "X", "Y", "Z" }, sUpAxis, [](int inItem) { sUpAxis = inItem; });
  77. inUI->CreateCheckBox(inSubMenu, "Override Object Layers", sOverrideLayers, [](UICheckBox::EState inState) { sOverrideLayers = inState == UICheckBox::STATE_CHECKED; });
  78. inUI->CreateTextButton(inSubMenu, "Accept Changes", [=]() { RestartTest(); });
  79. }