Prevent the camera from easily being set to an invalid orientation (#6203)

* add temporary debug logging

Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com>

* improvement for box select sometimes getting stuck on

Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com>

* add temporary debug logging

Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com>

* improvement for box select sometimes getting stuck on

Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com>

* remove temporary logging

Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com>

* fixes for camera pitch issues

Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com>

* missed file with camera pitch fixes

Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com>

* remove debug logs

Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com>

* add some tests for new pitch constraint updates

Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com>
This commit is contained in:
Tom Hulton-Harrop
2021-12-08 09:42:40 +00:00
committed by GitHub
parent a8ef23e4ae
commit b54215552c
8 changed files with 121 additions and 25 deletions
@@ -356,7 +356,8 @@ namespace SandboxEditor
AZ::TransformBus::EventResult(worldFromLocal, viewEntityId, &AZ::TransformBus::Events::GetWorldTM);
AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
m_viewportId, &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::StartTrackingTransform, worldFromLocal);
m_viewportId, &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::StartTrackingTransform,
worldFromLocal);
}
else
{
@@ -367,8 +368,10 @@ namespace SandboxEditor
void EditorModularViewportCameraComposer::OnTick(const float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time)
{
const float delta = [duration = &ed_cameraDefaultOrbitFadeDuration, deltaTime] {
if (*duration == 0.0f) {
const float delta = [duration = &ed_cameraDefaultOrbitFadeDuration, deltaTime]
{
if (*duration == 0.0f)
{
return 1.0f;
}
return deltaTime / *duration;
+28 -14
View File
@@ -6,7 +6,6 @@
*
*/
#include "GotoPositionDlg.h"
#include "EditorDefs.h"
@@ -25,6 +24,17 @@ AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
#include <ui_GotoPositionDlg.h>
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
void GotoPositionPitchConstraints::DeterminePitchRange(const AngleRangeConfigureFn& configurePitchRangeFn) const
{
const auto [pitchMinRadians, pitchMaxRadians] = AzFramework::CameraPitchMinMaxRadians();
configurePitchRangeFn(AZ::RadToDeg(pitchMinRadians), AZ::RadToDeg(pitchMaxRadians));
}
float GotoPositionPitchConstraints::PitchClampedRadians(float pitchDegrees) const
{
return AzFramework::ClampPitchRotation(AZ::DegToRad(pitchDegrees));
}
GotoPositionDialog::GotoPositionDialog(QWidget* parent)
: QDialog(parent)
, m_ui(new Ui::GotoPositionDialog)
@@ -55,20 +65,23 @@ void GotoPositionDialog::OnInitDialog()
const auto yawDegrees = AZ::RadToDeg(cameraRotation.GetZ());
// position
m_ui->m_dymX->setRange(-64000.0, 64000.0);
const double CameraPositionExtent = 64000.0;
m_ui->m_dymX->setRange(-CameraPositionExtent, CameraPositionExtent);
m_ui->m_dymX->setValue(cameraTranslation.GetX());
m_ui->m_dymY->setRange(-64000.0, 64000.0);
m_ui->m_dymY->setRange(-CameraPositionExtent, CameraPositionExtent);
m_ui->m_dymY->setValue(cameraTranslation.GetY());
m_ui->m_dymZ->setRange(-64000.0, 64000.0);
m_ui->m_dymZ->setRange(-CameraPositionExtent, CameraPositionExtent);
m_ui->m_dymZ->setValue(cameraTranslation.GetZ());
// rotation
m_ui->m_dymAnglePitch->setRange(-180.0, 180.0);
m_gotoPositionPitchConstraints.DeterminePitchRange(
[this](const float minPitchDegrees, const float maxPitchDegrees)
{
m_ui->m_dymAnglePitch->setRange(minPitchDegrees, maxPitchDegrees);
});
m_ui->m_dymAnglePitch->setValue(pitchDegrees);
m_ui->m_dymAngleYaw->setRange(-180.0, 180.0);
m_ui->m_dymAngleYaw->setRange(-360, 360);
m_ui->m_dymAngleYaw->setValue(yawDegrees);
// ensure the goto button is highlighted correctly.
@@ -108,12 +121,13 @@ void GotoPositionDialog::OnUpdateNumbers()
void GotoPositionDialog::accept()
{
SandboxEditor::InterpolateDefaultViewportCameraToTransform(
AZ::Vector3(
aznumeric_cast<float>(m_ui->m_dymX->value()), aznumeric_cast<float>(m_ui->m_dymY->value()),
aznumeric_cast<float>(m_ui->m_dymZ->value())),
AZ::DegToRad(aznumeric_cast<float>(m_ui->m_dymAnglePitch->value())),
AZ::DegToRad(aznumeric_cast<float>(m_ui->m_dymAngleYaw->value())));
const auto position = AZ::Vector3(
aznumeric_cast<float>(m_ui->m_dymX->value()), aznumeric_cast<float>(m_ui->m_dymY->value()),
aznumeric_cast<float>(m_ui->m_dymZ->value()));
const auto pitchRadians = m_gotoPositionPitchConstraints.PitchClampedRadians(aznumeric_cast<float>(m_ui->m_dymAnglePitch->value()));
const auto yawRadians = AZ::DegToRad(aznumeric_cast<float>(m_ui->m_dymAngleYaw->value()));
SandboxEditor::InterpolateDefaultViewportCameraToTransform(position, pitchRadians, yawRadians);
QDialog::accept();
}
+16 -3
View File
@@ -6,21 +6,33 @@
*
*/
#pragma once
#if !defined(Q_MOC_RUN)
#include <QDialog>
#endif
#include <SandboxAPI.h>
#include <AzCore/std/functional.h>
namespace Ui
{
class GotoPositionDialog;
}
//! Utility to deal with ensuring camera pitch values are in the expected range.
struct GotoPositionPitchConstraints
{
using AngleRangeConfigureFn = AZStd::function<void(float, float)>;
//! Notify a callback with the min and max camera pitch constraints (no tolerance included).
SANDBOX_API void DeterminePitchRange(const AngleRangeConfigureFn& configurePitchRangeFn) const;
//! Returns the clamped pitch value (including tolerance with range extents).
SANDBOX_API float PitchClampedRadians(float pitchDegrees) const;
};
//! GotoPositionDialog for setting camera position and rotation.
class GotoPositionDialog
: public QDialog
class GotoPositionDialog : public QDialog
{
Q_OBJECT
@@ -39,5 +51,6 @@ public:
QString m_transform;
private:
GotoPositionPitchConstraints m_gotoPositionPitchConstraints;
QScopedPointer<Ui::GotoPositionDialog> m_ui;
};
@@ -15,6 +15,8 @@
#include <AzToolsFramework/ToolsComponents/TransformComponent.h>
#include <EditorModularViewportCameraComposer.h>
#include <GotoPositionDlg.h>
namespace UnitTest
{
class EditorCameraFixture : public ::testing::Test
@@ -257,4 +259,35 @@ namespace UnitTest
EXPECT_THAT(interpolating, ::testing::IsFalse());
EXPECT_THAT(nextInterpolationBegan, ::testing::IsTrue());
}
TEST(GotoPositionPitchConstraints, GoToPositionPitchIsSetToPlusOrMinusNinetyDegrees)
{
float minPitch = 0.0f;
float maxPitch = 0.0f;
GotoPositionPitchConstraints m_gotoPositionContraints;
m_gotoPositionContraints.DeterminePitchRange(
[&minPitch, &maxPitch](const float minPitchDegrees, const float maxPitchDegrees)
{
minPitch = minPitchDegrees;
maxPitch = maxPitchDegrees;
});
using ::testing::FloatNear;
EXPECT_THAT(minPitch, FloatNear(-90.0f, AZ::Constants::FloatEpsilon));
EXPECT_THAT(maxPitch, FloatNear(90.0f, AZ::Constants::FloatEpsilon));
}
TEST(GotoPositionPitchConstraints, GoToPositionPitchClampsFinalPitchValueWithTolerance)
{
const auto [expectedMinPitchRadians, expectedMaxPitchRadians] = AzFramework::CameraPitchMinMaxRadiansWithTolerance();
GotoPositionPitchConstraints m_gotoPositionContraints;
const float minClampedPitchRadians = m_gotoPositionContraints.PitchClampedRadians(-90.0f);
const float maxClampedPitchRadians = m_gotoPositionContraints.PitchClampedRadians(90.0f);
using ::testing::FloatNear;
EXPECT_THAT(minClampedPitchRadians, FloatNear(expectedMinPitchRadians, AZ::Constants::FloatEpsilon));
EXPECT_THAT(maxClampedPitchRadians, FloatNear(expectedMaxPitchRadians, AZ::Constants::FloatEpsilon));
}
} // namespace UnitTest