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:
committed by
GitHub
parent
a8ef23e4ae
commit
b54215552c
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user