Merge branch 'development' into Atom/guthadam/atomtools_support_ly_set_gem_variant_to_load

This commit is contained in:
Guthrie Adams
2021-09-22 09:04:38 -05:00
33 changed files with 563 additions and 234 deletions
@@ -116,11 +116,18 @@ namespace AtomToolsFramework
// ModularViewportCameraControllerRequestBus overrides ...
void InterpolateToTransform(const AZ::Transform& worldFromLocal, float lookAtDistance) override;
AZStd::optional<AZ::Vector3> LookAtAfterInterpolation() const override;
AZ::Transform GetReferenceFrame() const override;
void SetReferenceFrame(const AZ::Transform& worldFromLocal) override;
void ClearReferenceFrame() override;
private:
// AzFramework::ViewportDebugDisplayEventBus overrides ...
void DisplayViewport(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override;
//! Update the reference frame after a change has been made to the camera
//! view without updating the internal camera via user input.
void RefreshReferenceFrame();
//! The current mode the camera controller is in.
enum class CameraMode
{
@@ -139,6 +146,8 @@ namespace AtomToolsFramework
AzFramework::Camera m_camera; //!< The current camera state (pitch/yaw/position/look-distance).
AzFramework::Camera m_targetCamera; //!< The target (next) camera state that m_camera is catching up to.
AzFramework::Camera m_previousCamera; //!< The state of the camera from the previous frame.
AZStd::optional<AzFramework::Camera> m_storedCamera; //!< A potentially stored camera for when a custom reference frame is set.
AzFramework::CameraSystem m_cameraSystem; //!< The camera system responsible for managing all CameraInputs.
AzFramework::CameraProps m_cameraProps; //!< Camera properties to control rotate and translate smoothness.
CameraControllerPriorityFn m_priorityFn; //!< Controls at what priority the camera controller should respond to events.
@@ -147,6 +156,7 @@ namespace AtomToolsFramework
CameraMode m_cameraMode = CameraMode::Control; //!< The current mode the camera is operating in.
AZStd::optional<AZ::Vector3> m_lookAtAfterInterpolation; //!< The look at point after an interpolation has finished.
//!< Will be cleared when the view changes (camera looks away).
AZ::Transform m_referenceFrameOverride = AZ::Transform::CreateIdentity(); //!<
//! Flag to prevent circular updates of the camera transform (while the viewport transform is being updated internally).
bool m_updatingTransformInternally = false;
//! Listen for camera view changes outside of the camera controller.
@@ -154,4 +164,17 @@ namespace AtomToolsFramework
//! The current instance of the modular camera viewport context.
AZStd::unique_ptr<ModularCameraViewportContext> m_modularCameraViewportContext;
};
//! Placeholder implementation for ModularCameraViewportContext (useful for verifying the interface).
class PlaceholderModularCameraViewportContextImpl : public AtomToolsFramework::ModularCameraViewportContext
{
public:
AZ::Transform GetCameraTransform() const override;
void SetCameraTransform(const AZ::Transform& transform) override;
void ConnectViewMatrixChangedHandler(AZ::RPI::ViewportContext::MatrixChangedEvent::Handler& handler) override;
private:
AZ::Transform m_cameraTransform = AZ::Transform::CreateIdentity();
AZ::RPI::ViewportContext::MatrixChangedEvent m_viewMatrixChangedEvent;
};
} // namespace AtomToolsFramework
@@ -35,6 +35,16 @@ namespace AtomToolsFramework
//! Look at point after an interpolation has finished and no translation has occurred.
virtual AZStd::optional<AZ::Vector3> LookAtAfterInterpolation() const = 0;
//! Return the current reference frame.
//! @note If a reference frame has not been set or a frame has been cleared, this is just the identity.
virtual AZ::Transform GetReferenceFrame() const = 0;
//! Set a new reference frame other than the identity for the camera controller.
virtual void SetReferenceFrame(const AZ::Transform& worldFromLocal) = 0;
//! Clear the current reference frame to restore the identity.
virtual void ClearReferenceFrame() = 0;
protected:
~ModularViewportCameraControllerRequests() = default;
};
@@ -30,6 +30,18 @@ namespace AtomToolsFramework
"");
AZ_CVAR(float, ed_cameraSystemOrbitPointSize, 0.1f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ::Transform TransformFromMatrix4x4(const AZ::Matrix4x4& matrix)
{
const auto rotation = AZ::Matrix3x3::CreateFromMatrix4x4(matrix);
const auto translation = matrix.GetTranslation();
return AZ::Transform::CreateFromMatrix3x3AndTranslation(rotation, translation);
}
AZ::Matrix4x4 Matrix4x4FromTransform(const AZ::Transform& transform)
{
return AZ::Matrix4x4::CreateFromQuaternionAndTranslation(transform.GetRotation(), transform.GetTranslation());
}
// debug
void DrawPreviewAxis(AzFramework::DebugDisplayRequests& display, const AZ::Transform& transform, const float axisLength)
{
@@ -167,11 +179,19 @@ namespace AtomToolsFramework
controller->SetupCameraControllerPriority(m_priorityFn);
controller->SetupCameraControllerViewportContext(m_modularCameraViewportContext);
auto handleCameraChange = [this](const AZ::Matrix4x4&)
auto handleCameraChange = [this]([[maybe_unused]] const AZ::Matrix4x4& cameraView)
{
// ignore these updates if the camera is being updated internally
if (!m_updatingTransformInternally)
{
if (m_storedCamera.has_value())
{
// if an external change occurs ensure we update the stored reference frame if one is set
RefreshReferenceFrame();
return;
}
m_previousCamera = m_targetCamera;
UpdateCameraFromTransform(m_targetCamera, m_modularCameraViewportContext->GetCameraTransform());
m_camera = m_targetCamera;
}
@@ -231,7 +251,7 @@ namespace AtomToolsFramework
}
}
m_modularCameraViewportContext->SetCameraTransform(m_camera.Transform());
m_modularCameraViewportContext->SetCameraTransform(m_referenceFrameOverride * m_camera.Transform());
}
else if (m_cameraMode == CameraMode::Animation)
{
@@ -240,6 +260,8 @@ namespace AtomToolsFramework
return t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f);
};
m_cameraAnimation.m_time = AZ::GetClamp(m_cameraAnimation.m_time + event.m_deltaTime.count(), 0.0f, 1.0f);
const auto& [transformStart, transformEnd, animationTime] = m_cameraAnimation;
const float transitionTime = smootherStepFn(animationTime);
@@ -253,14 +275,13 @@ namespace AtomToolsFramework
m_camera.m_lookAt = current.GetTranslation();
m_targetCamera = m_camera;
m_modularCameraViewportContext->SetCameraTransform(current);
if (animationTime >= 1.0f)
{
m_cameraMode = CameraMode::Control;
RefreshReferenceFrame();
}
m_cameraAnimation.m_time = AZ::GetClamp(animationTime + event.m_deltaTime.count(), 0.0f, 1.0f);
m_modularCameraViewportContext->SetCameraTransform(current);
}
m_updatingTransformInternally = false;
@@ -280,7 +301,7 @@ namespace AtomToolsFramework
void ModularViewportCameraControllerInstance::InterpolateToTransform(const AZ::Transform& worldFromLocal, const float lookAtDistance)
{
m_cameraMode = CameraMode::Animation;
m_cameraAnimation = CameraAnimation{ m_camera.Transform(), worldFromLocal, 0.0f };
m_cameraAnimation = CameraAnimation{ m_referenceFrameOverride * m_camera.Transform(), worldFromLocal, 0.0f };
m_lookAtAfterInterpolation = worldFromLocal.GetTranslation() + worldFromLocal.GetBasisY() * lookAtDistance;
}
@@ -288,4 +309,59 @@ namespace AtomToolsFramework
{
return m_lookAtAfterInterpolation;
}
AZ::Transform ModularViewportCameraControllerInstance::GetReferenceFrame() const
{
return m_referenceFrameOverride;
}
void ModularViewportCameraControllerInstance::SetReferenceFrame(const AZ::Transform& worldFromLocal)
{
if (!m_storedCamera.has_value())
{
m_storedCamera = m_previousCamera;
}
m_referenceFrameOverride = worldFromLocal;
m_targetCamera.m_pitch = 0.0f;
m_targetCamera.m_yaw = 0.0f;
m_targetCamera.m_lookAt = AZ::Vector3::CreateZero();
m_targetCamera.m_lookDist = 0.0f;
m_camera = m_targetCamera;
}
void ModularViewportCameraControllerInstance::ClearReferenceFrame()
{
m_referenceFrameOverride = AZ::Transform::CreateIdentity();
if (m_storedCamera.has_value())
{
m_targetCamera = m_storedCamera.value();
m_camera = m_targetCamera;
}
m_storedCamera.reset();
}
void ModularViewportCameraControllerInstance::RefreshReferenceFrame()
{
m_referenceFrameOverride = m_modularCameraViewportContext->GetCameraTransform() * m_camera.Transform().GetInverse();
}
AZ::Transform PlaceholderModularCameraViewportContextImpl::GetCameraTransform() const
{
return m_cameraTransform;
}
void PlaceholderModularCameraViewportContextImpl::SetCameraTransform(const AZ::Transform& transform)
{
m_cameraTransform = transform;
m_viewMatrixChangedEvent.Signal(AzFramework::CameraViewFromCameraTransform(Matrix4x4FromTransform(transform)));
}
void PlaceholderModularCameraViewportContextImpl::ConnectViewMatrixChangedHandler(
AZ::RPI::ViewportContext::MatrixChangedEvent::Handler& handler)
{
handler.Connect(m_viewMatrixChangedEvent);
}
} // namespace AtomToolsFramework