test_EditorCamera.cpp 59 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AZTestShared/Math/MathTestHelpers.h>
  9. #include <AtomToolsFramework/Viewport/ModularViewportCameraController.h>
  10. #include <AzCore/UnitTest/TestTypes.h>
  11. #include <AzFramework/Viewport/ViewportControllerList.h>
  12. #include <AzTest/GemTestEnvironment.h>
  13. #include <AzToolsFramework/API/EditorCameraBus.h>
  14. #include <AzToolsFramework/ToolsComponents/TransformComponent.h>
  15. #include <EditorModularViewportCameraComposer.h>
  16. #include <EditorViewportCamera.h>
  17. #include <EditorViewportSettings.h>
  18. #include <Mocks/MockViewportRequests.h>
  19. #include <Tests/Utils/Printers.h>
  20. #include <GotoPositionDlg.h>
  21. namespace UnitTest
  22. {
  23. class EditorCameraFixture : public UnitTest::LeakDetectionFixture
  24. {
  25. public:
  26. AZ::ComponentApplication* m_application = nullptr;
  27. AtomToolsFramework::ModularCameraViewportContext* m_cameraViewportContextView = nullptr;
  28. AZStd::unique_ptr<SandboxEditor::EditorModularViewportCameraComposer> m_editorModularViewportCameraComposer;
  29. AzFramework::ViewportControllerListPtr m_controllerList;
  30. AZ::Entity* m_entity = nullptr;
  31. AZ::ComponentDescriptor* m_transformComponent = nullptr;
  32. AZStd::unique_ptr<AZ::SettingsRegistryInterface> m_settingsRegistry;
  33. ::testing::NiceMock<MockViewportRequests> m_mockViewportRequests;
  34. static inline constexpr AzFramework::ViewportId TestViewportId = 2345;
  35. static inline constexpr float InterpolateToTransformDuration = 1.0f;
  36. static inline constexpr float HalfInterpolateToTransformDuration = InterpolateToTransformDuration * 0.5f;
  37. void SetUp() override
  38. {
  39. m_application = aznew AZ::ComponentApplication;
  40. AZ::ComponentApplication::Descriptor appDesc;
  41. m_entity = m_application->Create(appDesc);
  42. m_transformComponent = AzToolsFramework::Components::TransformComponent::CreateDescriptor();
  43. m_application->RegisterComponentDescriptor(m_transformComponent);
  44. m_entity->Init();
  45. m_entity->CreateComponent<AzToolsFramework::Components::TransformComponent>();
  46. m_entity->Activate();
  47. m_controllerList = AZStd::make_shared<AzFramework::ViewportControllerList>();
  48. m_controllerList->RegisterViewportContext(TestViewportId);
  49. m_editorModularViewportCameraComposer = AZStd::make_unique<SandboxEditor::EditorModularViewportCameraComposer>(TestViewportId);
  50. auto controller = m_editorModularViewportCameraComposer->CreateModularViewportCameraController();
  51. // set some overrides for the test
  52. controller->SetCameraViewportContextBuilderCallback(
  53. [this](AZStd::unique_ptr<AtomToolsFramework::ModularCameraViewportContext>& cameraViewportContext) mutable
  54. {
  55. cameraViewportContext = AZStd::make_unique<AtomToolsFramework::PlaceholderModularCameraViewportContextImpl>();
  56. m_cameraViewportContextView = cameraViewportContext.get();
  57. });
  58. m_controllerList->Add(controller);
  59. m_settingsRegistry = AZStd::make_unique<AZ::SettingsRegistryImpl>();
  60. AZ::SettingsRegistry::Register(m_settingsRegistry.get());
  61. ON_CALL(m_mockViewportRequests, GetCameraTransform)
  62. .WillByDefault(
  63. [this]
  64. {
  65. return m_cameraViewportContextView->GetCameraTransform();
  66. });
  67. ON_CALL(m_mockViewportRequests, SetCameraTransform)
  68. .WillByDefault(
  69. [this](const AZ::Transform& transform)
  70. {
  71. m_cameraViewportContextView->SetCameraTransform(transform);
  72. });
  73. m_mockViewportRequests.Connect(TestViewportId);
  74. }
  75. void TearDown() override
  76. {
  77. m_mockViewportRequests.Disconnect();
  78. AZ::SettingsRegistry::Unregister(m_settingsRegistry.get());
  79. m_settingsRegistry.reset();
  80. m_editorModularViewportCameraComposer.reset();
  81. m_cameraViewportContextView = nullptr;
  82. if (m_application)
  83. {
  84. m_application->UnregisterComponentDescriptor(m_transformComponent);
  85. delete m_transformComponent;
  86. m_transformComponent = nullptr;
  87. m_application->Destroy();
  88. delete m_application;
  89. m_application = nullptr;
  90. }
  91. }
  92. };
  93. TEST_F(EditorCameraFixture, ModularViewportCameraControllerReferenceFrameUpdatedWhenViewportEntityisChanged)
  94. {
  95. // Given
  96. const auto entityTransform = AZ::Transform::CreateFromQuaternionAndTranslation(
  97. AZ::Quaternion::CreateRotationX(AZ::DegToRad(90.0f)), AZ::Vector3(10.0f, 5.0f, -2.0f));
  98. AZ::TransformBus::Event(m_entity->GetId(), &AZ::TransformBus::Events::SetWorldTM, entityTransform);
  99. // When
  100. // imitate viewport entity changing
  101. Camera::EditorCameraNotificationBus::Broadcast(
  102. &Camera::EditorCameraNotificationBus::Events::OnViewportViewEntityChanged, m_entity->GetId());
  103. // ensure the viewport updates after the viewport view entity change
  104. // note: do a large step to ensure smoothing finishes (e.g. not 1.0f/60.0f)
  105. m_controllerList->UpdateViewport({ TestViewportId, AzFramework::FloatSeconds(2.0f), AZ::ScriptTimePoint() });
  106. // retrieve updated camera transform
  107. const AZ::Transform cameraTransform = m_cameraViewportContextView->GetCameraTransform();
  108. // Then
  109. // camera transform matches that of the entity
  110. EXPECT_THAT(cameraTransform, IsClose(entityTransform));
  111. }
  112. TEST_F(EditorCameraFixture, TrackingTransformIsTrueAfterTransformIsTracked)
  113. {
  114. // Given/When
  115. const AZ::Transform referenceFrame = AZ::Transform::CreateFromQuaternionAndTranslation(
  116. AZ::Quaternion::CreateRotationX(AZ::DegToRad(90.0f)), AZ::Vector3(1.0f, 2.0f, 3.0f));
  117. AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
  118. TestViewportId, &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::StartTrackingTransform, referenceFrame);
  119. bool trackingTransform = false;
  120. AtomToolsFramework::ModularViewportCameraControllerRequestBus::EventResult(
  121. trackingTransform, TestViewportId, &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::IsTrackingTransform);
  122. // Then
  123. EXPECT_THAT(trackingTransform, ::testing::IsTrue());
  124. }
  125. TEST_F(EditorCameraFixture, TrackingTransformIsFalseAfterTransformIsStoppedBeingTracked)
  126. {
  127. // Given
  128. const AZ::Transform referenceFrame = AZ::Transform::CreateFromQuaternionAndTranslation(
  129. AZ::Quaternion::CreateRotationX(AZ::DegToRad(90.0f)), AZ::Vector3(1.0f, 2.0f, 3.0f));
  130. AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
  131. TestViewportId, &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::StartTrackingTransform, referenceFrame);
  132. // When
  133. AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
  134. TestViewportId, &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::StopTrackingTransform);
  135. // Then
  136. bool trackingTransform = false;
  137. AtomToolsFramework::ModularViewportCameraControllerRequestBus::EventResult(
  138. trackingTransform, TestViewportId, &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::IsTrackingTransform);
  139. EXPECT_THAT(trackingTransform, ::testing::IsFalse());
  140. }
  141. TEST_F(EditorCameraFixture, InterpolateToTransform)
  142. {
  143. // When
  144. AZ::Transform transformToInterpolateTo = AZ::Transform::CreateFromQuaternionAndTranslation(
  145. AZ::Quaternion::CreateRotationZ(AZ::DegToRad(90.0f)), AZ::Vector3(20.0f, 40.0f, 60.0f));
  146. AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
  147. TestViewportId,
  148. &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform,
  149. transformToInterpolateTo,
  150. InterpolateToTransformDuration);
  151. // simulate interpolation
  152. m_controllerList->UpdateViewport(
  153. { TestViewportId, AzFramework::FloatSeconds(HalfInterpolateToTransformDuration), AZ::ScriptTimePoint() });
  154. m_controllerList->UpdateViewport(
  155. { TestViewportId, AzFramework::FloatSeconds(HalfInterpolateToTransformDuration), AZ::ScriptTimePoint() });
  156. const auto finalTransform = m_cameraViewportContextView->GetCameraTransform();
  157. // Then
  158. EXPECT_THAT(finalTransform, IsClose(transformToInterpolateTo));
  159. }
  160. TEST_F(EditorCameraFixture, InterpolateToTransformWithReferenceSpaceSet)
  161. {
  162. // Given
  163. const AZ::Transform referenceFrame = AZ::Transform::CreateFromQuaternionAndTranslation(
  164. AZ::Quaternion::CreateRotationX(AZ::DegToRad(90.0f)), AZ::Vector3(1.0f, 2.0f, 3.0f));
  165. AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
  166. TestViewportId, &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::StartTrackingTransform, referenceFrame);
  167. AZ::Transform transformToInterpolateTo = AZ::Transform::CreateFromQuaternionAndTranslation(
  168. AZ::Quaternion::CreateRotationZ(AZ::DegToRad(90.0f)), AZ::Vector3(20.0f, 40.0f, 60.0f));
  169. // When
  170. AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
  171. TestViewportId,
  172. &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform,
  173. transformToInterpolateTo,
  174. InterpolateToTransformDuration);
  175. // simulate interpolation
  176. m_controllerList->UpdateViewport(
  177. { TestViewportId, AzFramework::FloatSeconds(HalfInterpolateToTransformDuration), AZ::ScriptTimePoint() });
  178. m_controllerList->UpdateViewport(
  179. { TestViewportId, AzFramework::FloatSeconds(HalfInterpolateToTransformDuration), AZ::ScriptTimePoint() });
  180. const auto finalTransform = m_cameraViewportContextView->GetCameraTransform();
  181. // Then
  182. EXPECT_THAT(finalTransform, IsClose(transformToInterpolateTo));
  183. }
  184. TEST_F(EditorCameraFixture, BeginningCameraInterpolationReturnsTrue)
  185. {
  186. // Given/When
  187. bool interpolationBegan = false;
  188. AtomToolsFramework::ModularViewportCameraControllerRequestBus::EventResult(
  189. interpolationBegan,
  190. TestViewportId,
  191. &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform,
  192. AZ::Transform::CreateTranslation(AZ::Vector3(10.0f, 10.0f, 10.0f)),
  193. InterpolateToTransformDuration);
  194. // Then
  195. EXPECT_THAT(interpolationBegan, ::testing::IsTrue());
  196. }
  197. TEST_F(EditorCameraFixture, CameraInterpolationIsNotInterruptedIfGoingToTheSameTransform)
  198. {
  199. const auto& transformToInterpolateTo = AZ::Transform::CreateTranslation(AZ::Vector3(10.0f, 10.0f, 10.0f));
  200. // Given/When
  201. bool initialInterpolationBegan = false;
  202. AtomToolsFramework::ModularViewportCameraControllerRequestBus::EventResult(
  203. initialInterpolationBegan,
  204. TestViewportId,
  205. &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform,
  206. transformToInterpolateTo,
  207. InterpolateToTransformDuration);
  208. m_controllerList->UpdateViewport(
  209. { TestViewportId, AzFramework::FloatSeconds(HalfInterpolateToTransformDuration), AZ::ScriptTimePoint() });
  210. bool nextInterpolationBegan = true;
  211. AtomToolsFramework::ModularViewportCameraControllerRequestBus::EventResult(
  212. nextInterpolationBegan,
  213. TestViewportId,
  214. &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform,
  215. transformToInterpolateTo,
  216. InterpolateToTransformDuration);
  217. bool interpolating = false;
  218. AtomToolsFramework::ModularViewportCameraControllerRequestBus::EventResult(
  219. interpolating, TestViewportId, &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::IsInterpolating);
  220. // Then
  221. EXPECT_THAT(initialInterpolationBegan, ::testing::IsTrue());
  222. EXPECT_THAT(nextInterpolationBegan, ::testing::IsFalse());
  223. EXPECT_THAT(interpolating, ::testing::IsTrue());
  224. }
  225. TEST_F(EditorCameraFixture, CameraInterpolationCanBeInterruptedIfGoingToDifferentTransform)
  226. {
  227. const auto& firstTransformToInterpolateTo = AZ::Transform::CreateTranslation(AZ::Vector3(10.0f, 10.0f, 10.0f));
  228. const auto& secondTransformToInterpolateTo = AZ::Transform::CreateTranslation(AZ::Vector3(50.0f, 20.0f, 100.0f));
  229. // Given/When
  230. bool initialInterpolationBegan = false;
  231. AtomToolsFramework::ModularViewportCameraControllerRequestBus::EventResult(
  232. initialInterpolationBegan,
  233. TestViewportId,
  234. &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform,
  235. firstTransformToInterpolateTo,
  236. InterpolateToTransformDuration);
  237. m_controllerList->UpdateViewport(
  238. { TestViewportId, AzFramework::FloatSeconds(HalfInterpolateToTransformDuration), AZ::ScriptTimePoint() });
  239. bool nextInterpolationBegan = false;
  240. AtomToolsFramework::ModularViewportCameraControllerRequestBus::EventResult(
  241. nextInterpolationBegan,
  242. TestViewportId,
  243. &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform,
  244. secondTransformToInterpolateTo,
  245. InterpolateToTransformDuration);
  246. bool interpolating = false;
  247. AtomToolsFramework::ModularViewportCameraControllerRequestBus::EventResult(
  248. interpolating, TestViewportId, &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::IsInterpolating);
  249. m_controllerList->UpdateViewport(
  250. { TestViewportId, AzFramework::FloatSeconds(InterpolateToTransformDuration), AZ::ScriptTimePoint() });
  251. const auto actualTransformAfterUpdate = SandboxEditor::GetViewportCameraTransform(TestViewportId);
  252. // Then
  253. EXPECT_THAT(actualTransformAfterUpdate, IsClose(secondTransformToInterpolateTo));
  254. EXPECT_THAT(initialInterpolationBegan, ::testing::IsTrue());
  255. EXPECT_THAT(nextInterpolationBegan, ::testing::IsTrue());
  256. EXPECT_THAT(interpolating, ::testing::IsTrue());
  257. }
  258. TEST_F(EditorCameraFixture, CameraInterpolationCanBeginAfterAnInterpolationCompletes)
  259. {
  260. // Given/When
  261. bool initialInterpolationBegan = false;
  262. AtomToolsFramework::ModularViewportCameraControllerRequestBus::EventResult(
  263. initialInterpolationBegan,
  264. TestViewportId,
  265. &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform,
  266. AZ::Transform::CreateTranslation(AZ::Vector3(10.0f, 10.0f, 10.0f)),
  267. InterpolateToTransformDuration);
  268. m_controllerList->UpdateViewport(
  269. { TestViewportId, AzFramework::FloatSeconds(InterpolateToTransformDuration + 0.5f), AZ::ScriptTimePoint() });
  270. bool interpolating = true;
  271. AtomToolsFramework::ModularViewportCameraControllerRequestBus::EventResult(
  272. interpolating, TestViewportId, &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::IsInterpolating);
  273. bool nextInterpolationBegan = false;
  274. AtomToolsFramework::ModularViewportCameraControllerRequestBus::EventResult(
  275. nextInterpolationBegan,
  276. TestViewportId,
  277. &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform,
  278. AZ::Transform::CreateTranslation(AZ::Vector3(20.0f, 20.0f, 20.0f)),
  279. InterpolateToTransformDuration);
  280. // Then
  281. EXPECT_THAT(initialInterpolationBegan, ::testing::IsTrue());
  282. EXPECT_THAT(interpolating, ::testing::IsFalse());
  283. EXPECT_THAT(nextInterpolationBegan, ::testing::IsTrue());
  284. }
  285. TEST_F(EditorCameraFixture, CameraCannotInterpolateToSamePositionWithoutMovingFromIt)
  286. {
  287. const auto& transformToInterpolateTo = AZ::Transform::CreateTranslation(AZ::Vector3(10.0f, 10.0f, 10.0f));
  288. // Given/When
  289. bool initialInterpolationBegan = false;
  290. AtomToolsFramework::ModularViewportCameraControllerRequestBus::EventResult(
  291. initialInterpolationBegan,
  292. TestViewportId,
  293. &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform,
  294. transformToInterpolateTo,
  295. InterpolateToTransformDuration);
  296. m_controllerList->UpdateViewport(
  297. { TestViewportId, AzFramework::FloatSeconds(InterpolateToTransformDuration), AZ::ScriptTimePoint() });
  298. bool interpolating = true;
  299. AtomToolsFramework::ModularViewportCameraControllerRequestBus::EventResult(
  300. interpolating, TestViewportId, &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::IsInterpolating);
  301. bool nextInterpolationBegan = false;
  302. AtomToolsFramework::ModularViewportCameraControllerRequestBus::EventResult(
  303. nextInterpolationBegan,
  304. TestViewportId,
  305. &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform,
  306. transformToInterpolateTo,
  307. InterpolateToTransformDuration);
  308. // Then
  309. EXPECT_THAT(initialInterpolationBegan, ::testing::IsTrue());
  310. EXPECT_THAT(interpolating, ::testing::IsFalse());
  311. EXPECT_THAT(nextInterpolationBegan, ::testing::IsFalse());
  312. }
  313. TEST_F(EditorCameraFixture, CameraInterpolatesToTransformWhenGoToPositionInstantlyIsOff)
  314. {
  315. // Given
  316. SandboxEditor::SetCameraGoToPositionInstantlyEnabled(false);
  317. SandboxEditor::SetCameraGoToPositionDuration(InterpolateToTransformDuration);
  318. // set initial camera transform
  319. SandboxEditor::SetViewportCameraTransform(TestViewportId, AZ::Transform::CreateIdentity());
  320. const auto startingPosition = AZ::Vector3(10.0f, 20.0f, 30.0f);
  321. const auto pitchRadians = AZ::DegToRad(-45.0f);
  322. const auto yawRadians = AZ::DegToRad(90.0f);
  323. const auto expectedTransform = SandboxEditor::TransformFromPositionPitchYaw(startingPosition, pitchRadians, yawRadians);
  324. // When
  325. // camera transition (interpolation or instant based on setting)
  326. SandboxEditor::HandleViewportCameraTransitionFromSetting(TestViewportId, startingPosition, pitchRadians, yawRadians);
  327. // Then
  328. // ensure camera transform did not change instantly
  329. const auto actualTransformBeforeUpdate = SandboxEditor::GetViewportCameraTransform(TestViewportId);
  330. EXPECT_THAT(actualTransformBeforeUpdate, ::testing::Not(IsClose(expectedTransform)));
  331. EXPECT_THAT(actualTransformBeforeUpdate, IsClose(AZ::Transform::CreateIdentity()));
  332. // simulate viewport update
  333. m_controllerList->UpdateViewport(
  334. { TestViewportId, AzFramework::FloatSeconds(InterpolateToTransformDuration), AZ::ScriptTimePoint() });
  335. // ensure camera transform is at interpolated position/orientation
  336. const auto actualTransformAfterUpdate = SandboxEditor::GetViewportCameraTransform(TestViewportId);
  337. EXPECT_THAT(actualTransformAfterUpdate, IsClose(expectedTransform));
  338. }
  339. TEST_F(EditorCameraFixture, CameraChangesImmediatelyWhenGoToPositionInstantlyIsOn)
  340. {
  341. // Given
  342. SandboxEditor::SetCameraGoToPositionInstantlyEnabled(true);
  343. SandboxEditor::SetCameraGoToPositionDuration(InterpolateToTransformDuration);
  344. // set initial camera transform
  345. SandboxEditor::SetViewportCameraTransform(TestViewportId, AZ::Transform::CreateIdentity());
  346. const auto startingPosition = AZ::Vector3(50.0f, 60.0f, 70.0f);
  347. const auto pitchRadians = AZ::DegToRad(45.0f);
  348. const auto yawRadians = AZ::DegToRad(180.0f);
  349. const auto expectedTransform = SandboxEditor::TransformFromPositionPitchYaw(startingPosition, pitchRadians, yawRadians);
  350. // When
  351. // camera transition (interpolation or instant based on setting)
  352. SandboxEditor::HandleViewportCameraTransitionFromSetting(TestViewportId, expectedTransform);
  353. // Then
  354. // ensure camera transform updated immediately
  355. const auto actualTransformAfterUpdate = SandboxEditor::GetViewportCameraTransform(TestViewportId);
  356. EXPECT_THAT(actualTransformAfterUpdate, IsClose(expectedTransform));
  357. }
  358. TEST_F(EditorCameraFixture, CameraInterpolatesToTransform)
  359. {
  360. // Given
  361. SandboxEditor::SetViewportCameraTransform(TestViewportId, AZ::Transform::CreateIdentity());
  362. const auto startingPosition = AZ::Vector3(1.0f, 2.0f, 3.0f);
  363. const auto pitchRadians = AZ::DegToRad(30.0f);
  364. const auto yawRadians = AZ::DegToRad(20.0f);
  365. const auto expectedTransform = SandboxEditor::TransformFromPositionPitchYaw(startingPosition, pitchRadians, yawRadians);
  366. // When
  367. // interpolate camera to transform
  368. SandboxEditor::InterpolateViewportCameraToTransform(
  369. TestViewportId, startingPosition, pitchRadians, yawRadians, InterpolateToTransformDuration);
  370. // simulate viewport update
  371. m_controllerList->UpdateViewport(
  372. { TestViewportId, AzFramework::FloatSeconds(InterpolateToTransformDuration), AZ::ScriptTimePoint() });
  373. // Then
  374. const auto actualTransform = SandboxEditor::GetViewportCameraTransform(TestViewportId);
  375. EXPECT_THAT(actualTransform, IsClose(expectedTransform));
  376. }
  377. TEST_F(EditorCameraFixture, CameraInterpolatesToTransformWithZeroDurationAfterUpdate)
  378. {
  379. // Given
  380. SandboxEditor::SetViewportCameraTransform(TestViewportId, AZ::Transform::CreateIdentity());
  381. const auto startingPosition = AZ::Vector3(1.0f, 2.0f, 3.0f);
  382. const auto pitchRadians = AZ::DegToRad(30.0f);
  383. const auto yawRadians = AZ::DegToRad(20.0f);
  384. const auto expectedTransform = SandboxEditor::TransformFromPositionPitchYaw(startingPosition, pitchRadians, yawRadians);
  385. // When
  386. // interpolate camera to transform (zero duration)
  387. SandboxEditor::InterpolateViewportCameraToTransform(TestViewportId, startingPosition, pitchRadians, yawRadians, 0.0f);
  388. // simulate viewport update
  389. m_controllerList->UpdateViewport({ TestViewportId, AzFramework::FloatSeconds(0.0166f), AZ::ScriptTimePoint() });
  390. // Then
  391. const auto actualTransform = SandboxEditor::GetViewportCameraTransform(TestViewportId);
  392. EXPECT_THAT(actualTransform, IsClose(expectedTransform));
  393. }
  394. TEST_F(EditorCameraFixture, CameraDoesNotInterpolateToTransformWithZeroDurationAndNoUpdate)
  395. {
  396. // Given
  397. SandboxEditor::SetViewportCameraTransform(TestViewportId, AZ::Transform::CreateIdentity());
  398. const auto startingPosition = AZ::Vector3(1.0f, 2.0f, 3.0f);
  399. const auto pitchRadians = AZ::DegToRad(30.0f);
  400. const auto yawRadians = AZ::DegToRad(20.0f);
  401. // When
  402. // interpolate camera to transform (zero duration)
  403. SandboxEditor::InterpolateViewportCameraToTransform(TestViewportId, startingPosition, pitchRadians, yawRadians, 0.0f);
  404. // no update
  405. // Then
  406. const auto actualTransform = SandboxEditor::GetViewportCameraTransform(TestViewportId);
  407. EXPECT_THAT(actualTransform, IsClose(AZ::Transform::CreateIdentity()));
  408. }
  409. using GotoPositionPitchConstraintsTest = UnitTest::LeakDetectionFixture;
  410. TEST_F(GotoPositionPitchConstraintsTest, GoToPositionPitchIsSetToPlusOrMinusNinetyDegrees)
  411. {
  412. float minPitch = 0.0f;
  413. float maxPitch = 0.0f;
  414. GoToPositionPitchConstraints m_goToPositionContraints;
  415. m_goToPositionContraints.DeterminePitchRange(
  416. [&minPitch, &maxPitch](const float minPitchDegrees, const float maxPitchDegrees)
  417. {
  418. minPitch = minPitchDegrees;
  419. maxPitch = maxPitchDegrees;
  420. });
  421. using ::testing::FloatNear;
  422. EXPECT_THAT(minPitch, FloatNear(-90.0f, AZ::Constants::FloatEpsilon));
  423. EXPECT_THAT(maxPitch, FloatNear(90.0f, AZ::Constants::FloatEpsilon));
  424. }
  425. TEST_F(GotoPositionPitchConstraintsTest, GoToPositionPitchClampsFinalPitchValueWithTolerance)
  426. {
  427. const auto [expectedMinPitchRadians, expectedMaxPitchRadians] = AzFramework::CameraPitchMinMaxRadiansWithTolerance();
  428. GoToPositionPitchConstraints m_goToPositionContraints;
  429. const float minClampedPitchRadians = m_goToPositionContraints.PitchClampedRadians(-90.0f);
  430. const float maxClampedPitchRadians = m_goToPositionContraints.PitchClampedRadians(90.0f);
  431. using ::testing::FloatNear;
  432. EXPECT_THAT(minClampedPitchRadians, FloatNear(expectedMinPitchRadians, AZ::Constants::FloatEpsilon));
  433. EXPECT_THAT(maxClampedPitchRadians, FloatNear(expectedMaxPitchRadians, AZ::Constants::FloatEpsilon));
  434. }
  435. TEST_F(EditorCameraFixture, CameraSettingsRegistryValuesCanBeModified)
  436. {
  437. using ::testing::Eq;
  438. using ::testing::FloatNear;
  439. {
  440. const float existingCameraSpeedScale = SandboxEditor::CameraSpeedScale();
  441. const float expectedCameraSpeedScale = existingCameraSpeedScale + 1.0f;
  442. SandboxEditor::SetCameraSpeedScale(expectedCameraSpeedScale);
  443. const float actualCameraSpeedScale = SandboxEditor::CameraSpeedScale();
  444. EXPECT_THAT(expectedCameraSpeedScale, FloatNear(actualCameraSpeedScale, AZ::Constants::FloatEpsilon));
  445. }
  446. {
  447. const float existingCameraTranslateSpeed = SandboxEditor::CameraTranslateSpeed();
  448. const float expectedCameraTranslateSpeed = existingCameraTranslateSpeed + 1.0f;
  449. SandboxEditor::SetCameraTranslateSpeed(expectedCameraTranslateSpeed);
  450. const float actualCameraTranslateSpeed = SandboxEditor::CameraTranslateSpeed();
  451. EXPECT_THAT(expectedCameraTranslateSpeed, FloatNear(actualCameraTranslateSpeed, AZ::Constants::FloatEpsilon));
  452. }
  453. {
  454. const float existingCameraBoostMultiplier = SandboxEditor::CameraBoostMultiplier();
  455. const float expectedCameraBoostMultiplier = existingCameraBoostMultiplier + 1.0f;
  456. SandboxEditor::SetCameraBoostMultiplier(expectedCameraBoostMultiplier);
  457. const float actualCameraBoostMultiplier = SandboxEditor::CameraBoostMultiplier();
  458. EXPECT_THAT(expectedCameraBoostMultiplier, FloatNear(actualCameraBoostMultiplier, AZ::Constants::FloatEpsilon));
  459. }
  460. {
  461. const float existingCameraRotateSpeed = SandboxEditor::CameraRotateSpeed();
  462. const float expectedCameraRotateSpeed = existingCameraRotateSpeed + 1.0f;
  463. SandboxEditor::SetCameraRotateSpeed(expectedCameraRotateSpeed);
  464. const float actualCameraRotateSpeed = SandboxEditor::CameraRotateSpeed();
  465. EXPECT_THAT(expectedCameraRotateSpeed, FloatNear(actualCameraRotateSpeed, AZ::Constants::FloatEpsilon));
  466. }
  467. {
  468. const float existingCameraScrollSpeed = SandboxEditor::CameraScrollSpeed();
  469. const float expectedCameraScrollSpeed = existingCameraScrollSpeed + 1.0f;
  470. SandboxEditor::SetCameraScrollSpeed(expectedCameraScrollSpeed);
  471. const float actualCameraScrollSpeed = SandboxEditor::CameraScrollSpeed();
  472. EXPECT_THAT(expectedCameraScrollSpeed, FloatNear(actualCameraScrollSpeed, AZ::Constants::FloatEpsilon));
  473. }
  474. {
  475. const float existingCameraDollyMotionSpeed = SandboxEditor::CameraDollyMotionSpeed();
  476. const float expectedCameraDollyMotionSpeed = existingCameraDollyMotionSpeed + 1.0f;
  477. SandboxEditor::SetCameraDollyMotionSpeed(expectedCameraDollyMotionSpeed);
  478. const float actualCameraDollyMotionSpeed = SandboxEditor::CameraDollyMotionSpeed();
  479. EXPECT_THAT(expectedCameraDollyMotionSpeed, FloatNear(actualCameraDollyMotionSpeed, AZ::Constants::FloatEpsilon));
  480. }
  481. {
  482. const float existingCameraPanSpeed = SandboxEditor::CameraPanSpeed();
  483. const float expectedCameraPanSpeed = existingCameraPanSpeed + 1.0f;
  484. SandboxEditor::SetCameraPanSpeed(expectedCameraPanSpeed);
  485. const float actualCameraPanSpeed = SandboxEditor::CameraPanSpeed();
  486. EXPECT_THAT(expectedCameraPanSpeed, FloatNear(actualCameraPanSpeed, AZ::Constants::FloatEpsilon));
  487. }
  488. {
  489. const float existingCameraRotateSmoothness = SandboxEditor::CameraRotateSmoothness();
  490. const float expectedCameraRotateSmoothness = existingCameraRotateSmoothness + 1.0f;
  491. SandboxEditor::SetCameraRotateSmoothness(expectedCameraRotateSmoothness);
  492. const float actualCameraRotateSmoothness = SandboxEditor::CameraRotateSmoothness();
  493. EXPECT_THAT(expectedCameraRotateSmoothness, FloatNear(actualCameraRotateSmoothness, AZ::Constants::FloatEpsilon));
  494. }
  495. {
  496. const float existingCameraTranslateSmoothness = SandboxEditor::CameraTranslateSmoothness();
  497. const float expectedCameraTranslateSmoothness = existingCameraTranslateSmoothness + 1.0f;
  498. SandboxEditor::SetCameraTranslateSmoothness(expectedCameraTranslateSmoothness);
  499. const float actualCameraTranslateSmoothness = SandboxEditor::CameraTranslateSmoothness();
  500. EXPECT_THAT(expectedCameraTranslateSmoothness, FloatNear(actualCameraTranslateSmoothness, AZ::Constants::FloatEpsilon));
  501. }
  502. {
  503. const float existingCameraDefaultOrbitDistance = SandboxEditor::CameraDefaultOrbitDistance();
  504. const float expectedCameraDefaultOrbitDistance = existingCameraDefaultOrbitDistance + 1.0f;
  505. SandboxEditor::SetCameraDefaultOrbitDistance(expectedCameraDefaultOrbitDistance);
  506. const float actualCameraDefaultOrbitDistance = SandboxEditor::CameraDefaultOrbitDistance();
  507. EXPECT_THAT(expectedCameraDefaultOrbitDistance, FloatNear(actualCameraDefaultOrbitDistance, AZ::Constants::FloatEpsilon));
  508. }
  509. {
  510. const float existingCameraDefaultNearPlaneDistance = SandboxEditor::CameraDefaultNearPlaneDistance();
  511. const float expectedCameraDefaultNearPlaneDistance = existingCameraDefaultNearPlaneDistance + 1.0f;
  512. SandboxEditor::SetCameraDefaultNearPlaneDistance(expectedCameraDefaultNearPlaneDistance);
  513. const float actualCameraDefaultNearPlaneDistance = SandboxEditor::CameraDefaultNearPlaneDistance();
  514. EXPECT_THAT(
  515. expectedCameraDefaultNearPlaneDistance, FloatNear(actualCameraDefaultNearPlaneDistance, AZ::Constants::FloatEpsilon));
  516. }
  517. {
  518. const float existingCameraDefaultFarPlaneDistance = SandboxEditor::CameraDefaultFarPlaneDistance();
  519. const float expectedCameraDefaultFarPlaneDistance = existingCameraDefaultFarPlaneDistance + 1.0f;
  520. SandboxEditor::SetCameraDefaultFarPlaneDistance(expectedCameraDefaultFarPlaneDistance);
  521. const float actualCameraDefaultFarPlaneDistance = SandboxEditor::CameraDefaultFarPlaneDistance();
  522. EXPECT_THAT(expectedCameraDefaultFarPlaneDistance, FloatNear(actualCameraDefaultFarPlaneDistance, AZ::Constants::FloatEpsilon));
  523. }
  524. {
  525. const float existingCameraDefaultFovRadians = SandboxEditor::CameraDefaultFovRadians();
  526. const float expectedCameraDefaultFovRadians = existingCameraDefaultFovRadians + 1.0f;
  527. SandboxEditor::SetCameraDefaultFovRadians(expectedCameraDefaultFovRadians);
  528. const float actualCameraDefaultFovRadians = SandboxEditor::CameraDefaultFovRadians();
  529. // precision reduced here due to conversion to/from degrees in underlying code
  530. EXPECT_THAT(expectedCameraDefaultFovRadians, FloatNear(actualCameraDefaultFovRadians, 0.001f));
  531. }
  532. {
  533. const float existingCameraDefaultFovDegrees = SandboxEditor::CameraDefaultFovDegrees();
  534. const float expectedCameraDefaultFovDegrees = existingCameraDefaultFovDegrees + 1.0f;
  535. SandboxEditor::SetCameraDefaultFovDegrees(expectedCameraDefaultFovDegrees);
  536. const float actualCameraDefaultFovDegrees = SandboxEditor::CameraDefaultFovDegrees();
  537. EXPECT_THAT(expectedCameraDefaultFovDegrees, FloatNear(actualCameraDefaultFovDegrees, AZ::Constants::FloatEpsilon));
  538. }
  539. {
  540. const bool existingCameraOrbitYawRotationInverted = SandboxEditor::CameraOrbitYawRotationInverted();
  541. const bool expectedCameraOrbitYawRotationInverted = !existingCameraOrbitYawRotationInverted;
  542. SandboxEditor::SetCameraOrbitYawRotationInverted(expectedCameraOrbitYawRotationInverted);
  543. const bool actualCameraOrbitYawRotationInverted = SandboxEditor::CameraOrbitYawRotationInverted();
  544. EXPECT_THAT(expectedCameraOrbitYawRotationInverted, Eq(actualCameraOrbitYawRotationInverted));
  545. }
  546. {
  547. const bool existingCameraPanInvertedX = SandboxEditor::CameraPanInvertedX();
  548. const bool expectedCameraPanInvertedX = !existingCameraPanInvertedX;
  549. SandboxEditor::SetCameraPanInvertedX(expectedCameraPanInvertedX);
  550. const bool actualCameraPanInvertedX = SandboxEditor::CameraPanInvertedX();
  551. EXPECT_THAT(expectedCameraPanInvertedX, Eq(actualCameraPanInvertedX));
  552. }
  553. {
  554. const bool existingCameraPanInvertedY = SandboxEditor::CameraPanInvertedY();
  555. const bool expectedCameraPanInvertedY = !existingCameraPanInvertedY;
  556. SandboxEditor::SetCameraPanInvertedY(expectedCameraPanInvertedY);
  557. const bool actualCameraPanInvertedY = SandboxEditor::CameraPanInvertedY();
  558. EXPECT_THAT(expectedCameraPanInvertedY, Eq(actualCameraPanInvertedY));
  559. }
  560. {
  561. const bool existingCameraRotateSmoothingEnabled = SandboxEditor::CameraRotateSmoothingEnabled();
  562. const bool expectedCameraRotateSmoothingEnabled = !existingCameraRotateSmoothingEnabled;
  563. SandboxEditor::SetCameraRotateSmoothingEnabled(expectedCameraRotateSmoothingEnabled);
  564. const bool actualCameraRotateSmoothingEnabled = SandboxEditor::CameraRotateSmoothingEnabled();
  565. EXPECT_THAT(expectedCameraRotateSmoothingEnabled, Eq(actualCameraRotateSmoothingEnabled));
  566. }
  567. {
  568. const bool existingCameraTranslateSmoothingEnabled = SandboxEditor::CameraTranslateSmoothingEnabled();
  569. const bool expectedCameraTranslateSmoothingEnabled = !existingCameraTranslateSmoothingEnabled;
  570. SandboxEditor::SetCameraTranslateSmoothingEnabled(expectedCameraTranslateSmoothingEnabled);
  571. const bool actualCameraTranslateSmoothingEnabled = SandboxEditor::CameraTranslateSmoothingEnabled();
  572. EXPECT_THAT(expectedCameraTranslateSmoothingEnabled, Eq(actualCameraTranslateSmoothingEnabled));
  573. }
  574. {
  575. const bool existingCameraCaptureCursorForLook = SandboxEditor::CameraCaptureCursorForLook();
  576. const bool expectedCameraCaptureCursorForLook = !existingCameraCaptureCursorForLook;
  577. SandboxEditor::SetCameraCaptureCursorForLook(expectedCameraCaptureCursorForLook);
  578. const bool actualCameraCaptureCursorForLook = SandboxEditor::CameraCaptureCursorForLook();
  579. EXPECT_THAT(expectedCameraCaptureCursorForLook, Eq(actualCameraCaptureCursorForLook));
  580. }
  581. {
  582. const bool existingCameraGoToPositionInstantly = SandboxEditor::CameraGoToPositionInstantlyEnabled();
  583. const bool expectedCameraGoToPositionInstantly = !existingCameraGoToPositionInstantly;
  584. SandboxEditor::SetCameraGoToPositionInstantlyEnabled(expectedCameraGoToPositionInstantly);
  585. const bool actualCameraGoToPositionInstantly = SandboxEditor::CameraGoToPositionInstantlyEnabled();
  586. EXPECT_THAT(expectedCameraGoToPositionInstantly, Eq(actualCameraGoToPositionInstantly));
  587. }
  588. {
  589. const float existingCameraGoToPositionDuration = SandboxEditor::CameraGoToPositionDuration();
  590. const float expectedCameraGoToPositionDuration = existingCameraGoToPositionDuration + 1.0f;
  591. SandboxEditor::SetCameraGoToPositionDuration(expectedCameraGoToPositionDuration);
  592. const float actualCameraGoToPositionDuration = SandboxEditor::CameraGoToPositionDuration();
  593. EXPECT_THAT(expectedCameraGoToPositionDuration, Eq(actualCameraGoToPositionDuration));
  594. }
  595. }
  596. TEST_F(EditorCameraFixture, CameraSettingsRegistryValuesCanBeReset)
  597. {
  598. using ::testing::Eq;
  599. using ::testing::FloatNear;
  600. using ::testing::IsTrue;
  601. using ::testing::Not;
  602. // reset all relevant settings to defaults
  603. SandboxEditor::ResetCameraSpeedScale();
  604. SandboxEditor::ResetCameraTranslateSpeed();
  605. SandboxEditor::ResetCameraRotateSpeed();
  606. SandboxEditor::ResetCameraBoostMultiplier();
  607. SandboxEditor::ResetCameraScrollSpeed();
  608. SandboxEditor::ResetCameraDollyMotionSpeed();
  609. SandboxEditor::ResetCameraPanSpeed();
  610. SandboxEditor::ResetCameraRotateSmoothness();
  611. SandboxEditor::ResetCameraRotateSmoothingEnabled();
  612. SandboxEditor::ResetCameraTranslateSmoothness();
  613. SandboxEditor::ResetCameraTranslateSmoothingEnabled();
  614. SandboxEditor::ResetCameraCaptureCursorForLook();
  615. SandboxEditor::ResetCameraOrbitYawRotationInverted();
  616. SandboxEditor::ResetCameraPanInvertedX();
  617. SandboxEditor::ResetCameraPanInvertedY();
  618. SandboxEditor::ResetCameraDefaultEditorPosition();
  619. SandboxEditor::ResetCameraDefaultOrbitDistance();
  620. SandboxEditor::ResetCameraDefaultEditorOrientation();
  621. SandboxEditor::ResetCameraGoToPositionInstantlyEnabled();
  622. SandboxEditor::ResetCameraGoToPositionDuration();
  623. // store defaults
  624. const auto initialCameraSpeedScale = SandboxEditor::CameraSpeedScale();
  625. const auto initialCameraTranslateSpeed = SandboxEditor::CameraTranslateSpeed();
  626. const auto initialCameraRotateSpeed = SandboxEditor::CameraRotateSpeed();
  627. const auto initialCameraBoostMultiplier = SandboxEditor::CameraBoostMultiplier();
  628. const auto initialCameraScrollSpeed = SandboxEditor::CameraScrollSpeed();
  629. const auto initialCameraDollyMotionSpeed = SandboxEditor::CameraDollyMotionSpeed();
  630. const auto initialCameraPanSpeed = SandboxEditor::CameraPanSpeed();
  631. const auto initialCameraRotateSmoothness = SandboxEditor::CameraRotateSmoothness();
  632. const auto initialCameraRotateSmoothingEnabled = SandboxEditor::CameraRotateSmoothingEnabled();
  633. const auto initialCameraTranslateSmoothness = SandboxEditor::CameraTranslateSmoothness();
  634. const auto initialCameraTranslateSmoothingEnabled = SandboxEditor::CameraTranslateSmoothingEnabled();
  635. const auto initialCameraCaptureCursorForLook = SandboxEditor::CameraCaptureCursorForLook();
  636. const auto initialCameraOrbitYawRotationInverted = SandboxEditor::CameraOrbitYawRotationInverted();
  637. const auto initialCameraPanInvertedX = SandboxEditor::CameraPanInvertedX();
  638. const auto initialCameraPanInvertedY = SandboxEditor::CameraPanInvertedY();
  639. const auto initialCameraDefaultEditorPosition = SandboxEditor::CameraDefaultEditorPosition();
  640. const auto initialCameraDefaultOrbitDistance = SandboxEditor::CameraDefaultOrbitDistance();
  641. const auto initialCameraDefaultEditorOrientation = SandboxEditor::CameraDefaultEditorOrientation();
  642. const auto initialCameraGoToPositionInstantly = SandboxEditor::CameraGoToPositionInstantlyEnabled();
  643. const auto initialCameraGoToPositionDuration = SandboxEditor::CameraGoToPositionDuration();
  644. // modify all values to be different to default value
  645. SandboxEditor::SetCameraSpeedScale(SandboxEditor::CameraSpeedScale() + 10.0f);
  646. SandboxEditor::SetCameraTranslateSpeed(SandboxEditor::CameraTranslateSpeed() + 10.0f);
  647. SandboxEditor::SetCameraRotateSpeed(SandboxEditor::CameraRotateSpeed() + 10.0f);
  648. SandboxEditor::SetCameraBoostMultiplier(SandboxEditor::CameraBoostMultiplier() + 10.0f);
  649. SandboxEditor::SetCameraScrollSpeed(SandboxEditor::CameraScrollSpeed() + 10.0f);
  650. SandboxEditor::SetCameraDollyMotionSpeed(SandboxEditor::CameraDollyMotionSpeed() + 10.0f);
  651. SandboxEditor::SetCameraPanSpeed(SandboxEditor::CameraPanSpeed() + 10.0f);
  652. SandboxEditor::SetCameraRotateSmoothness(SandboxEditor::CameraRotateSmoothness() + 10.0f);
  653. SandboxEditor::SetCameraRotateSmoothingEnabled(!SandboxEditor::CameraRotateSmoothingEnabled());
  654. SandboxEditor::SetCameraTranslateSmoothness(SandboxEditor::CameraTranslateSmoothness() + 10.0f);
  655. SandboxEditor::SetCameraTranslateSmoothingEnabled(!SandboxEditor::CameraTranslateSmoothingEnabled());
  656. SandboxEditor::SetCameraCaptureCursorForLook(!SandboxEditor::CameraCaptureCursorForLook());
  657. SandboxEditor::SetCameraOrbitYawRotationInverted(!SandboxEditor::CameraOrbitYawRotationInverted());
  658. SandboxEditor::SetCameraPanInvertedX(!SandboxEditor::CameraPanInvertedX());
  659. SandboxEditor::SetCameraPanInvertedY(!SandboxEditor::CameraPanInvertedY());
  660. SandboxEditor::SetCameraDefaultEditorPosition(SandboxEditor::CameraDefaultEditorPosition() + AZ::Vector3(10.0f));
  661. SandboxEditor::SetCameraDefaultOrbitDistance(SandboxEditor::CameraDefaultOrbitDistance() + 10.0f);
  662. SandboxEditor::SetCameraDefaultEditorOrientation(SandboxEditor::CameraDefaultEditorOrientation() + AZ::Vector2(10.0f));
  663. SandboxEditor::SetCameraGoToPositionInstantlyEnabled(!SandboxEditor::CameraGoToPositionInstantlyEnabled());
  664. SandboxEditor::SetCameraGoToPositionDuration(SandboxEditor::CameraGoToPositionDuration() + 10.0f);
  665. // ensure all values have changed vs defaults
  666. EXPECT_THAT(SandboxEditor::CameraSpeedScale(), Not(FloatNear(initialCameraSpeedScale, AZ::Constants::FloatEpsilon)));
  667. EXPECT_THAT(SandboxEditor::CameraTranslateSpeed(), Not(FloatNear(initialCameraTranslateSpeed, AZ::Constants::FloatEpsilon)));
  668. EXPECT_THAT(SandboxEditor::CameraRotateSpeed(), Not(FloatNear(initialCameraRotateSpeed, AZ::Constants::FloatEpsilon)));
  669. EXPECT_THAT(SandboxEditor::CameraBoostMultiplier(), Not(FloatNear(initialCameraBoostMultiplier, AZ::Constants::FloatEpsilon)));
  670. EXPECT_THAT(SandboxEditor::CameraScrollSpeed(), Not(FloatNear(initialCameraScrollSpeed, AZ::Constants::FloatEpsilon)));
  671. EXPECT_THAT(SandboxEditor::CameraDollyMotionSpeed(), Not(FloatNear(initialCameraDollyMotionSpeed, AZ::Constants::FloatEpsilon)));
  672. EXPECT_THAT(SandboxEditor::CameraPanSpeed(), Not(FloatNear(initialCameraPanSpeed, AZ::Constants::FloatEpsilon)));
  673. EXPECT_THAT(SandboxEditor::CameraRotateSmoothness(), Not(FloatNear(initialCameraRotateSmoothness, AZ::Constants::FloatEpsilon)));
  674. EXPECT_THAT(SandboxEditor::CameraRotateSmoothingEnabled(), Not(Eq(initialCameraRotateSmoothingEnabled)));
  675. EXPECT_THAT(
  676. SandboxEditor::CameraTranslateSmoothness(), Not(FloatNear(initialCameraTranslateSmoothness, AZ::Constants::FloatEpsilon)));
  677. EXPECT_THAT(SandboxEditor::CameraTranslateSmoothingEnabled(), Not(Eq(initialCameraTranslateSmoothingEnabled)));
  678. EXPECT_THAT(SandboxEditor::CameraCaptureCursorForLook(), Not(Eq(initialCameraCaptureCursorForLook)));
  679. EXPECT_THAT(SandboxEditor::CameraOrbitYawRotationInverted(), Not(Eq(initialCameraOrbitYawRotationInverted)));
  680. EXPECT_THAT(SandboxEditor::CameraPanInvertedX(), Not(Eq(initialCameraPanInvertedX)));
  681. EXPECT_THAT(SandboxEditor::CameraPanInvertedY(), Not(Eq(initialCameraPanInvertedY)));
  682. EXPECT_THAT(SandboxEditor::CameraDefaultEditorPosition(), Not(IsClose(initialCameraDefaultEditorPosition)));
  683. EXPECT_THAT(
  684. SandboxEditor::CameraDefaultOrbitDistance(), Not(FloatNear(initialCameraDefaultOrbitDistance, AZ::Constants::FloatEpsilon)));
  685. EXPECT_THAT(SandboxEditor::CameraDefaultEditorOrientation(), Not(IsClose(initialCameraDefaultEditorOrientation)));
  686. EXPECT_THAT(SandboxEditor::CameraGoToPositionInstantlyEnabled(), Not(Eq(initialCameraGoToPositionInstantly)));
  687. EXPECT_THAT(SandboxEditor::CameraGoToPositionDuration(), Not(Eq(initialCameraGoToPositionDuration)));
  688. // reset all relevant settings to defaults again
  689. SandboxEditor::ResetCameraSpeedScale();
  690. SandboxEditor::ResetCameraTranslateSpeed();
  691. SandboxEditor::ResetCameraRotateSpeed();
  692. SandboxEditor::ResetCameraBoostMultiplier();
  693. SandboxEditor::ResetCameraScrollSpeed();
  694. SandboxEditor::ResetCameraDollyMotionSpeed();
  695. SandboxEditor::ResetCameraPanSpeed();
  696. SandboxEditor::ResetCameraRotateSmoothness();
  697. SandboxEditor::ResetCameraRotateSmoothingEnabled();
  698. SandboxEditor::ResetCameraTranslateSmoothness();
  699. SandboxEditor::ResetCameraTranslateSmoothingEnabled();
  700. SandboxEditor::ResetCameraCaptureCursorForLook();
  701. SandboxEditor::ResetCameraOrbitYawRotationInverted();
  702. SandboxEditor::ResetCameraPanInvertedX();
  703. SandboxEditor::ResetCameraPanInvertedY();
  704. SandboxEditor::ResetCameraDefaultEditorPosition();
  705. SandboxEditor::ResetCameraDefaultOrbitDistance();
  706. SandboxEditor::ResetCameraDefaultEditorOrientation();
  707. SandboxEditor::ResetCameraGoToPositionInstantlyEnabled();
  708. SandboxEditor::ResetCameraGoToPositionDuration();
  709. // ensure values have been reset to defaults
  710. EXPECT_THAT(SandboxEditor::CameraSpeedScale(), FloatNear(initialCameraSpeedScale, AZ::Constants::FloatEpsilon));
  711. EXPECT_THAT(SandboxEditor::CameraTranslateSpeed(), FloatNear(initialCameraTranslateSpeed, AZ::Constants::FloatEpsilon));
  712. EXPECT_THAT(SandboxEditor::CameraRotateSpeed(), FloatNear(initialCameraRotateSpeed, AZ::Constants::FloatEpsilon));
  713. EXPECT_THAT(SandboxEditor::CameraBoostMultiplier(), FloatNear(initialCameraBoostMultiplier, AZ::Constants::FloatEpsilon));
  714. EXPECT_THAT(SandboxEditor::CameraScrollSpeed(), FloatNear(initialCameraScrollSpeed, AZ::Constants::FloatEpsilon));
  715. EXPECT_THAT(SandboxEditor::CameraDollyMotionSpeed(), FloatNear(initialCameraDollyMotionSpeed, AZ::Constants::FloatEpsilon));
  716. EXPECT_THAT(SandboxEditor::CameraPanSpeed(), FloatNear(initialCameraPanSpeed, AZ::Constants::FloatEpsilon));
  717. EXPECT_THAT(SandboxEditor::CameraRotateSmoothness(), FloatNear(initialCameraRotateSmoothness, AZ::Constants::FloatEpsilon));
  718. EXPECT_THAT(SandboxEditor::CameraRotateSmoothingEnabled(), Eq(initialCameraRotateSmoothingEnabled));
  719. EXPECT_THAT(SandboxEditor::CameraTranslateSmoothness(), FloatNear(initialCameraTranslateSmoothness, AZ::Constants::FloatEpsilon));
  720. EXPECT_THAT(SandboxEditor::CameraTranslateSmoothingEnabled(), Eq(initialCameraTranslateSmoothingEnabled));
  721. EXPECT_THAT(SandboxEditor::CameraCaptureCursorForLook(), Eq(initialCameraCaptureCursorForLook));
  722. EXPECT_THAT(SandboxEditor::CameraOrbitYawRotationInverted(), Eq(initialCameraOrbitYawRotationInverted));
  723. EXPECT_THAT(SandboxEditor::CameraPanInvertedX(), Eq(initialCameraPanInvertedX));
  724. EXPECT_THAT(SandboxEditor::CameraPanInvertedY(), Eq(initialCameraPanInvertedY));
  725. EXPECT_THAT(SandboxEditor::CameraDefaultEditorPosition(), IsClose(initialCameraDefaultEditorPosition));
  726. EXPECT_THAT(SandboxEditor::CameraDefaultOrbitDistance(), FloatNear(initialCameraDefaultOrbitDistance, AZ::Constants::FloatEpsilon));
  727. EXPECT_THAT(SandboxEditor::CameraDefaultEditorOrientation(), IsClose(initialCameraDefaultEditorOrientation));
  728. EXPECT_THAT(SandboxEditor::CameraGoToPositionInstantlyEnabled(), Eq(initialCameraGoToPositionInstantly));
  729. EXPECT_THAT(SandboxEditor::CameraGoToPositionDuration(), FloatNear(initialCameraGoToPositionDuration, AZ::Constants::FloatEpsilon));
  730. }
  731. TEST_F(EditorCameraFixture, CameraSettingsRegistryInputValuesCanBeReset)
  732. {
  733. using ::testing::Eq;
  734. using ::testing::Ne;
  735. // reset all relevant settings to defaults
  736. SandboxEditor::ResetCameraTranslateForwardChannelId();
  737. SandboxEditor::ResetCameraTranslateBackwardChannelId();
  738. SandboxEditor::ResetCameraTranslateLeftChannelId();
  739. SandboxEditor::ResetCameraTranslateRightChannelId();
  740. SandboxEditor::ResetCameraTranslateUpChannelId();
  741. SandboxEditor::ResetCameraTranslateDownChannelId();
  742. SandboxEditor::ResetCameraTranslateBoostChannelId();
  743. SandboxEditor::ResetCameraOrbitChannelId();
  744. SandboxEditor::ResetCameraFreeLookChannelId();
  745. SandboxEditor::ResetCameraFreePanChannelId();
  746. SandboxEditor::ResetCameraOrbitLookChannelId();
  747. SandboxEditor::ResetCameraOrbitDollyChannelId();
  748. SandboxEditor::ResetCameraOrbitPanChannelId();
  749. SandboxEditor::ResetCameraFocusChannelId();
  750. // store defaults
  751. auto initialCameraTranslateForwardChannelId = SandboxEditor::CameraTranslateForwardChannelId();
  752. auto initialCameraTranslateBackwardChannelId = SandboxEditor::CameraTranslateBackwardChannelId();
  753. auto initialCameraTranslateLeftChannelId = SandboxEditor::CameraTranslateLeftChannelId();
  754. auto initialCameraTranslateRightChannelId = SandboxEditor::CameraTranslateRightChannelId();
  755. auto initialCameraTranslateUpChannelId = SandboxEditor::CameraTranslateUpChannelId();
  756. auto initialCameraTranslateDownChannelId = SandboxEditor::CameraTranslateDownChannelId();
  757. auto initialCameraTranslateBoostChannelId = SandboxEditor::CameraTranslateBoostChannelId();
  758. auto initialCameraOrbitChannelId = SandboxEditor::CameraOrbitChannelId();
  759. auto initialCameraFreeLookChannelId = SandboxEditor::CameraFreeLookChannelId();
  760. auto initialCameraFreePanChannelId = SandboxEditor::CameraFreePanChannelId();
  761. auto initialCameraOrbitLookChannelId = SandboxEditor::CameraOrbitLookChannelId();
  762. auto initialCameraOrbitDollyChannelId = SandboxEditor::CameraOrbitDollyChannelId();
  763. auto initialCameraOrbitPanChannelId = SandboxEditor::CameraOrbitPanChannelId();
  764. auto initialCameraFocusChannelId = SandboxEditor::CameraFocusChannelId();
  765. // modify all values to be different to default value
  766. SandboxEditor::SetCameraTranslateForwardChannelId(AZStd::string("keyboard_key_alphanumeric_0"));
  767. SandboxEditor::SetCameraTranslateBackwardChannelId(AZStd::string("keyboard_key_alphanumeric_0"));
  768. SandboxEditor::SetCameraTranslateLeftChannelId(AZStd::string("keyboard_key_alphanumeric_0"));
  769. SandboxEditor::SetCameraTranslateRightChannelId(AZStd::string("keyboard_key_alphanumeric_0"));
  770. SandboxEditor::SetCameraTranslateUpChannelId(AZStd::string("keyboard_key_alphanumeric_0"));
  771. SandboxEditor::SetCameraTranslateDownChannelId(AZStd::string("keyboard_key_alphanumeric_0"));
  772. SandboxEditor::SetCameraTranslateBoostChannelId(AZStd::string("keyboard_key_alphanumeric_0"));
  773. SandboxEditor::SetCameraOrbitChannelId(AZStd::string("keyboard_key_alphanumeric_0"));
  774. SandboxEditor::SetCameraFreeLookChannelId(AZStd::string("keyboard_key_alphanumeric_0"));
  775. SandboxEditor::SetCameraFreePanChannelId(AZStd::string("keyboard_key_alphanumeric_0"));
  776. SandboxEditor::SetCameraOrbitLookChannelId(AZStd::string("keyboard_key_alphanumeric_0"));
  777. SandboxEditor::SetCameraOrbitDollyChannelId(AZStd::string("keyboard_key_alphanumeric_0"));
  778. SandboxEditor::SetCameraOrbitPanChannelId(AZStd::string("keyboard_key_alphanumeric_0"));
  779. SandboxEditor::SetCameraFocusChannelId(AZStd::string("keyboard_key_alphanumeric_0"));
  780. // ensure all values have changed vs defaults
  781. EXPECT_THAT(SandboxEditor::CameraTranslateForwardChannelId(), Ne(initialCameraTranslateForwardChannelId));
  782. EXPECT_THAT(SandboxEditor::CameraTranslateBackwardChannelId(), Ne(initialCameraTranslateBackwardChannelId));
  783. EXPECT_THAT(SandboxEditor::CameraTranslateLeftChannelId(), Ne(initialCameraTranslateLeftChannelId));
  784. EXPECT_THAT(SandboxEditor::CameraTranslateRightChannelId(), Ne(initialCameraTranslateRightChannelId));
  785. EXPECT_THAT(SandboxEditor::CameraTranslateUpChannelId(), Ne(initialCameraTranslateUpChannelId));
  786. EXPECT_THAT(SandboxEditor::CameraTranslateDownChannelId(), Ne(initialCameraTranslateDownChannelId));
  787. EXPECT_THAT(SandboxEditor::CameraTranslateBoostChannelId(), Ne(initialCameraTranslateBoostChannelId));
  788. EXPECT_THAT(SandboxEditor::CameraOrbitChannelId(), Ne(initialCameraOrbitChannelId));
  789. EXPECT_THAT(SandboxEditor::CameraFreeLookChannelId(), Ne(initialCameraFreeLookChannelId));
  790. EXPECT_THAT(SandboxEditor::CameraFreePanChannelId(), Ne(initialCameraFreePanChannelId));
  791. EXPECT_THAT(SandboxEditor::CameraOrbitLookChannelId(), Ne(initialCameraOrbitLookChannelId));
  792. EXPECT_THAT(SandboxEditor::CameraOrbitDollyChannelId(), Ne(initialCameraOrbitDollyChannelId));
  793. EXPECT_THAT(SandboxEditor::CameraOrbitPanChannelId(), Ne(initialCameraOrbitPanChannelId));
  794. EXPECT_THAT(SandboxEditor::CameraFocusChannelId(), Ne(initialCameraFocusChannelId));
  795. // reset all relevant settings to defaults again
  796. SandboxEditor::ResetCameraTranslateForwardChannelId();
  797. SandboxEditor::ResetCameraTranslateBackwardChannelId();
  798. SandboxEditor::ResetCameraTranslateLeftChannelId();
  799. SandboxEditor::ResetCameraTranslateRightChannelId();
  800. SandboxEditor::ResetCameraTranslateUpChannelId();
  801. SandboxEditor::ResetCameraTranslateDownChannelId();
  802. SandboxEditor::ResetCameraTranslateBoostChannelId();
  803. SandboxEditor::ResetCameraOrbitChannelId();
  804. SandboxEditor::ResetCameraFreeLookChannelId();
  805. SandboxEditor::ResetCameraFreePanChannelId();
  806. SandboxEditor::ResetCameraOrbitLookChannelId();
  807. SandboxEditor::ResetCameraOrbitDollyChannelId();
  808. SandboxEditor::ResetCameraOrbitPanChannelId();
  809. SandboxEditor::ResetCameraFocusChannelId();
  810. // ensure values have been reset to defaults
  811. EXPECT_THAT(SandboxEditor::CameraTranslateForwardChannelId(), Eq(initialCameraTranslateForwardChannelId));
  812. EXPECT_THAT(SandboxEditor::CameraTranslateBackwardChannelId(), Eq(initialCameraTranslateBackwardChannelId));
  813. EXPECT_THAT(SandboxEditor::CameraTranslateLeftChannelId(), Eq(initialCameraTranslateLeftChannelId));
  814. EXPECT_THAT(SandboxEditor::CameraTranslateRightChannelId(), Eq(initialCameraTranslateRightChannelId));
  815. EXPECT_THAT(SandboxEditor::CameraTranslateUpChannelId(), Eq(initialCameraTranslateUpChannelId));
  816. EXPECT_THAT(SandboxEditor::CameraTranslateDownChannelId(), Eq(initialCameraTranslateDownChannelId));
  817. EXPECT_THAT(SandboxEditor::CameraTranslateBoostChannelId(), Eq(initialCameraTranslateBoostChannelId));
  818. EXPECT_THAT(SandboxEditor::CameraOrbitChannelId(), Eq(initialCameraOrbitChannelId));
  819. EXPECT_THAT(SandboxEditor::CameraFreeLookChannelId(), Eq(initialCameraFreeLookChannelId));
  820. EXPECT_THAT(SandboxEditor::CameraFreePanChannelId(), Eq(initialCameraFreePanChannelId));
  821. EXPECT_THAT(SandboxEditor::CameraOrbitLookChannelId(), Eq(initialCameraOrbitLookChannelId));
  822. EXPECT_THAT(SandboxEditor::CameraOrbitDollyChannelId(), Eq(initialCameraOrbitDollyChannelId));
  823. EXPECT_THAT(SandboxEditor::CameraOrbitPanChannelId(), Eq(initialCameraOrbitPanChannelId));
  824. EXPECT_THAT(SandboxEditor::CameraFocusChannelId(), Eq(initialCameraFocusChannelId));
  825. }
  826. static constexpr float CameraTransformTolerance = 0.001f;
  827. TEST(EditorViewportCamera, CalculateGoToEntityTransformHandlesNormalCaseLookingForward)
  828. {
  829. const AZStd::optional<AZ::Transform> nextCameraTransform = SandboxEditor::CalculateGoToEntityTransform(
  830. AZ::Transform::CreateTranslation(AZ::Vector3(0.0f, -5.0f, 0.5f)), AZ::DegToRad(60.0f), AZ::Vector3::CreateAxisZ(0.5f), 0.866f);
  831. EXPECT_THAT(
  832. *nextCameraTransform,
  833. IsCloseTolerance(
  834. AZ::Transform::CreateFromQuaternionAndTranslation(AZ::Quaternion::CreateIdentity(), AZ::Vector3(0.0f, -1.87499f, 0.5f)),
  835. CameraTransformTolerance));
  836. }
  837. // camera starts over look down point, looking forwards
  838. TEST(EditorViewportCamera, CalculateGoToEntityTransformHandlesDegenerateCaseLookingDown)
  839. {
  840. const AZStd::optional<AZ::Transform> nextCameraTransform = SandboxEditor::CalculateGoToEntityTransform(
  841. AZ::Transform::CreateTranslation(AZ::Vector3(0.0f, 0.0f, 3.0f)), AZ::DegToRad(60.0f), AZ::Vector3::CreateAxisZ(0.5f), 0.866f);
  842. const auto expectedTransform = AZ::Transform::CreateFromQuaternionAndTranslation(
  843. AZ::Quaternion(-0.675590217f, 0.0f, 0.0f, 0.737277329f), AZ::Vector3(0.0f, -0.163416f, 2.367864f));
  844. EXPECT_THAT(nextCameraTransform->GetTranslation(), IsCloseTolerance(expectedTransform.GetTranslation(), CameraTransformTolerance));
  845. EXPECT_THAT(
  846. nextCameraTransform->GetUniformScale(), ::testing::FloatNear(expectedTransform.GetUniformScale(), CameraTransformTolerance));
  847. // it's possible for either rotation to be valid - both represent the same rotation/orientation
  848. EXPECT_THAT(
  849. nextCameraTransform->GetRotation(),
  850. ::testing::AnyOf(
  851. IsCloseTolerance(expectedTransform.GetRotation(), CameraTransformTolerance),
  852. IsCloseTolerance(-expectedTransform.GetRotation(), CameraTransformTolerance)));
  853. }
  854. // camera starts under look down point, looking up
  855. TEST(EditorViewportCamera, CalculateGoToEntityTransformHandlesDegenerateCaseLookingUp)
  856. {
  857. const AZStd::optional<AZ::Transform> nextCameraTransform = SandboxEditor::CalculateGoToEntityTransform(
  858. AZ::Transform::CreateFromQuaternionAndTranslation(
  859. AZ::Quaternion::CreateRotationZ(AZ::DegToRad(-90.0f)) *
  860. AZ::Quaternion::CreateRotationX(AZ::DegToRad(90.0f) - AzFramework::CameraPitchTolerance),
  861. AZ::Vector3(0.0f, 0.0f, 5.0f)),
  862. AZ::DegToRad(60.0f),
  863. AZ::Vector3::CreateAxisZ(10.0f),
  864. 0.866f);
  865. const auto expectedTransform = AZ::Transform::CreateFromQuaternionAndTranslation(
  866. AZ::Quaternion(-0.477643281f, 0.477785647f, 0.521411479f, -0.521256149f), AZ::Vector3(-0.163416952f, 0.0f, 8.13213539f));
  867. EXPECT_THAT(nextCameraTransform->GetTranslation(), IsCloseTolerance(expectedTransform.GetTranslation(), CameraTransformTolerance));
  868. EXPECT_THAT(
  869. nextCameraTransform->GetUniformScale(), ::testing::FloatNear(expectedTransform.GetUniformScale(), CameraTransformTolerance));
  870. // it's possible for either rotation to be valid - both represent the same rotation/orientation
  871. EXPECT_THAT(
  872. nextCameraTransform->GetRotation(),
  873. ::testing::AnyOf(
  874. IsCloseTolerance(expectedTransform.GetRotation(), CameraTransformTolerance),
  875. IsCloseTolerance(-expectedTransform.GetRotation(), CameraTransformTolerance)));
  876. }
  877. } // namespace UnitTest