EditorViewportCamera.cpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  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 <EditorViewportCamera.h>
  9. #include <Atom/RPI.Public/ViewportContext.h>
  10. #include <Atom/RPI.Public/ViewportContextBus.h>
  11. #include <AtomToolsFramework/Viewport/ModularViewportCameraControllerRequestBus.h>
  12. #include <EditorViewportSettings.h>
  13. namespace SandboxEditor
  14. {
  15. void SetViewportCameraPosition(const AzFramework::ViewportId viewportId, const AZ::Vector3& position)
  16. {
  17. const auto& currentCameraTransform = GetViewportCameraTransform(viewportId);
  18. SetViewportCameraTransform(
  19. viewportId, AZ::Transform::CreateFromQuaternionAndTranslation(currentCameraTransform.GetRotation(), position));
  20. }
  21. void SetDefaultViewportCameraPosition(const AZ::Vector3& position)
  22. {
  23. auto viewportContextManager = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get();
  24. if (auto viewportContext = viewportContextManager->GetDefaultViewportContext())
  25. {
  26. SetViewportCameraPosition(viewportContext->GetId(), position);
  27. }
  28. }
  29. void SetViewportCameraRotation(const AzFramework::ViewportId viewportId, const float pitch, const float yaw)
  30. {
  31. const auto& currentCameraTransform = GetViewportCameraTransform(viewportId);
  32. SetViewportCameraTransform(viewportId, TransformFromPositionPitchYaw(currentCameraTransform.GetTranslation(), pitch, yaw));
  33. }
  34. void SetDefaultViewportCameraRotation(const float pitch, const float yaw)
  35. {
  36. auto viewportContextManager = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get();
  37. if (auto viewportContext = viewportContextManager->GetDefaultViewportContext())
  38. {
  39. SetViewportCameraRotation(viewportContext->GetId(), pitch, yaw);
  40. }
  41. }
  42. void SetViewportCameraTransform(const AzFramework::ViewportId viewportId, const AZ::Transform& transform)
  43. {
  44. AzFramework::ViewportRequestBus::Event(viewportId, &AzFramework::ViewportRequestBus::Events::SetCameraTransform, transform);
  45. }
  46. void SetViewportCameraTransform(
  47. const AzFramework::ViewportId viewportId, const AZ::Vector3& position, const float pitch, const float yaw)
  48. {
  49. SetViewportCameraTransform(viewportId, TransformFromPositionPitchYaw(position, pitch, yaw));
  50. }
  51. void SetDefaultViewportCameraTransform(const AZ::Transform& transform)
  52. {
  53. auto viewportContextManager = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get();
  54. if (auto viewportContext = viewportContextManager->GetDefaultViewportContext())
  55. {
  56. SetViewportCameraTransform(viewportContext->GetId(), transform);
  57. }
  58. }
  59. void SetDefaultViewportCameraTransform(const AZ::Vector3& position, const float pitch, const float yaw)
  60. {
  61. SetDefaultViewportCameraTransform(TransformFromPositionPitchYaw(position, pitch, yaw));
  62. }
  63. void InterpolateViewportCameraToTransform(
  64. const AzFramework::ViewportId viewportId, const AZ::Vector3& position, const float pitch, const float yaw, const float duration)
  65. {
  66. InterpolateViewportCameraToTransform(viewportId, TransformFromPositionPitchYaw(position, pitch, yaw), duration);
  67. }
  68. void InterpolateDefaultViewportCameraToTransform(const AZ::Vector3& position, const float pitch, const float yaw, const float duration)
  69. {
  70. InterpolateDefaultViewportCameraToTransform(TransformFromPositionPitchYaw(position, pitch, yaw), duration);
  71. }
  72. void InterpolateViewportCameraToTransform(
  73. const AzFramework::ViewportId viewportId, const AZ::Transform& transform, const float duration)
  74. {
  75. AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
  76. viewportId,
  77. &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform,
  78. transform,
  79. duration);
  80. }
  81. void InterpolateDefaultViewportCameraToTransform(const AZ::Transform& transform, const float duration)
  82. {
  83. auto viewportContextManager = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get();
  84. if (auto viewportContext = viewportContextManager->GetDefaultViewportContext())
  85. {
  86. InterpolateViewportCameraToTransform(viewportContext->GetId(), transform, duration);
  87. }
  88. }
  89. void HandleViewportCameraTransitionFromSetting(
  90. const AzFramework::ViewportId viewportId, const AZ::Vector3& position, const float pitch, const float yaw)
  91. {
  92. HandleViewportCameraTransitionFromSetting(viewportId, TransformFromPositionPitchYaw(position, pitch, yaw));
  93. }
  94. void HandleDefaultViewportCameraTransitionFromSetting(
  95. const AZ::Vector3& position, const float pitch, const float yaw)
  96. {
  97. HandleDefaultViewportCameraTransitionFromSetting(TransformFromPositionPitchYaw(position, pitch, yaw));
  98. }
  99. void HandleViewportCameraTransitionFromSetting(
  100. const AzFramework::ViewportId viewportId, const AZ::Transform& transform)
  101. {
  102. if (CameraGoToPositionInstantlyEnabled())
  103. {
  104. SetViewportCameraTransform(viewportId, transform);
  105. }
  106. else
  107. {
  108. InterpolateViewportCameraToTransform(viewportId, transform, CameraGoToPositionDuration());
  109. }
  110. }
  111. void HandleDefaultViewportCameraTransitionFromSetting(const AZ::Transform& transform)
  112. {
  113. auto viewportContextManager = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get();
  114. if (auto viewportContext = viewportContextManager->GetDefaultViewportContext())
  115. {
  116. HandleViewportCameraTransitionFromSetting(viewportContext->GetId(), transform);
  117. }
  118. }
  119. AZStd::optional<AZ::Transform> CalculateGoToEntityTransform(
  120. const AZ::Transform& cameraTransform, const float fovRadians, const AZ::Vector3& center, const float radius)
  121. {
  122. // do not attempt to interpolate to where we currently are
  123. if (cameraTransform.GetTranslation().IsClose(center))
  124. {
  125. return AZStd::nullopt;
  126. }
  127. const AZ::Vector3 forward = [&center, &cameraTransform]
  128. {
  129. const AZ::Vector3 forward = (center - cameraTransform.GetTranslation()).GetNormalized();
  130. // if the camera is looking directly up or down, pitch the camera down or up respectively to avoid
  131. // a singularity when creating the lookat transformation below
  132. if (const float forwardDot = forward.Dot(AZ::Vector3::CreateAxisZ()); AZ::IsCloseMag(AZ::Abs(forwardDot), 1.0f, 0.001f))
  133. {
  134. return AZ::Transform::CreateFromQuaternion(
  135. AZ::Quaternion::CreateFromAxisAngle(cameraTransform.GetBasisX(), AZ::DegToRad(5.0f) * -AZ::GetSign(forwardDot)))
  136. .TransformVector(AZ::Vector3::CreateAxisZ() * AZ::GetSign(forwardDot));
  137. }
  138. return forward;
  139. }();
  140. // minimum center size is 40cm, maxium center size is 25m
  141. const float MinSelectionRadius = 0.4f;
  142. const float MaxSelectionRadius = 25.0f;
  143. const float selectionSize = AZ::GetClamp(radius, MinSelectionRadius, MaxSelectionRadius);
  144. // move camera 25% further back than required
  145. const float centerScale = 1.25f;
  146. // compute new camera transform
  147. const float fovScale = 1.0f / AZStd::tan(fovRadians * 0.5f);
  148. const float distanceToLookAt = selectionSize * fovScale * centerScale;
  149. return AZ::Transform::CreateLookAt(center - (forward * distanceToLookAt), center);
  150. }
  151. AZ::Transform GetViewportCameraTransform(const AzFramework::ViewportId viewportId)
  152. {
  153. AZ::Transform cameraTransform = AZ::Transform::CreateIdentity();
  154. AzFramework::ViewportRequestBus::EventResult(
  155. cameraTransform, viewportId, &AzFramework::ViewportRequestBus::Events::GetCameraTransform);
  156. return cameraTransform;
  157. }
  158. AZ::Transform GetDefaultViewportCameraTransform()
  159. {
  160. auto viewportContextManager = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get();
  161. if (auto viewportContext = viewportContextManager->GetDefaultViewportContext())
  162. {
  163. return GetViewportCameraTransform(viewportContext->GetId());
  164. }
  165. AZ_WarningOnce("EditorViewport", false, "Default viewport camera not found");
  166. return AZ::Transform::CreateIdentity();
  167. }
  168. } // namespace SandboxEditor