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
@@ -335,10 +335,13 @@ namespace AzFramework
|
||||
Camera nextCamera = targetCamera;
|
||||
|
||||
const float rotateSpeed = m_rotateSpeedFn();
|
||||
nextCamera.m_pitch -= float(cursorDelta.m_y) * rotateSpeed * Invert(m_invertPitchFn());
|
||||
nextCamera.m_yaw -= float(cursorDelta.m_x) * rotateSpeed * Invert(m_invertYawFn());
|
||||
const float deltaPitch = aznumeric_cast<float>(cursorDelta.m_y) * rotateSpeed * Invert(m_invertPitchFn());
|
||||
const float deltaYaw = aznumeric_cast<float>(cursorDelta.m_x) * rotateSpeed * Invert(m_invertYawFn());
|
||||
|
||||
nextCamera.m_pitch -= deltaPitch;
|
||||
nextCamera.m_yaw -= deltaYaw;
|
||||
nextCamera.m_yaw = WrapYawRotation(nextCamera.m_yaw);
|
||||
|
||||
if (m_constrainPitch())
|
||||
{
|
||||
nextCamera.m_pitch = ClampPitchRotation(nextCamera.m_pitch);
|
||||
|
||||
@@ -25,6 +25,9 @@ namespace AzFramework
|
||||
|
||||
struct WindowSize;
|
||||
|
||||
//! Tolerance to use when limiting pitch to avoid reaching +/-Pi/2 exactly.
|
||||
constexpr float CameraPitchTolerance = 1.0e-4f;
|
||||
|
||||
//! Returns Euler angles (pitch, roll, yaw) for the incoming orientation.
|
||||
//! @note Order of rotation is Z, Y, X.
|
||||
AZ::Vector3 EulerAngles(const AZ::Matrix3x3& orientation);
|
||||
@@ -318,11 +321,26 @@ namespace AzFramework
|
||||
return m_handlingEvents;
|
||||
}
|
||||
|
||||
//! Clamps pitch to be +/-90 degrees (-Pi/2, Pi/2).
|
||||
//! Returns min/max values for camera pitch (in radians).
|
||||
inline AZStd::tuple<float, float> CameraPitchMinMaxRadians()
|
||||
{
|
||||
return { -AZ::Constants::HalfPi, AZ::Constants::HalfPi };
|
||||
}
|
||||
|
||||
//! Returns min/max values for camera pitch (in radians) including a small tolerance at each
|
||||
//! extreme (looking directly up or down) to avoid floating point accuracy issues.
|
||||
inline AZStd::tuple<float, float> CameraPitchMinMaxRadiansWithTolerance()
|
||||
{
|
||||
const auto [pitchMinRadians, pitchMaxRadians] = CameraPitchMinMaxRadians();
|
||||
return { pitchMinRadians + CameraPitchTolerance, pitchMaxRadians - CameraPitchTolerance };
|
||||
}
|
||||
|
||||
//! Clamps pitch to be +/-90 degrees (-Pi/2, Pi/2) with a minor tolerance at each extreme.
|
||||
//! @param pitch Pitch angle in radians.
|
||||
inline float ClampPitchRotation(const float pitch)
|
||||
{
|
||||
return AZ::GetClamp(pitch, -AZ::Constants::HalfPi, AZ::Constants::HalfPi);
|
||||
const auto [pitchMin, pitchMax] = CameraPitchMinMaxRadiansWithTolerance();
|
||||
return AZ::GetClamp(pitch, pitchMin, pitchMax);
|
||||
}
|
||||
|
||||
//! Ensures yaw wraps between 0 and 360 degrees (0, 2Pi).
|
||||
|
||||
@@ -322,6 +322,17 @@ namespace UnitTest
|
||||
EXPECT_THAT(m_camera.m_offset, IsClose(AZ::Vector3::CreateZero()));
|
||||
}
|
||||
|
||||
TEST(CameraInput, CameraPitchIsClampedWithExpectedTolerance)
|
||||
{
|
||||
const auto [expectedMinPitch, expectedMaxPitch] = AzFramework::CameraPitchMinMaxRadiansWithTolerance();
|
||||
const float minPitch = AzFramework::ClampPitchRotation(-AZ::Constants::HalfPi);
|
||||
const float maxPitch = AzFramework::ClampPitchRotation(AZ::Constants::HalfPi);
|
||||
|
||||
using ::testing::FloatNear;
|
||||
EXPECT_THAT(minPitch, FloatNear(expectedMinPitch, AzFramework::CameraPitchTolerance));
|
||||
EXPECT_THAT(maxPitch, FloatNear(expectedMaxPitch, AzFramework::CameraPitchTolerance));
|
||||
}
|
||||
|
||||
TEST_F(CameraInputFixture, OrbitRotateCameraInputRotatesPitchOffsetByNinetyDegreesWithRequiredPixelDelta)
|
||||
{
|
||||
const auto cameraStartingPosition = AZ::Vector3::CreateAxisY(-20.0f);
|
||||
|
||||
+2
-1
@@ -64,7 +64,8 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
if (clickOutcome == AzFramework::ClickDetector::ClickOutcome::Release)
|
||||
if (clickOutcome == AzFramework::ClickDetector::ClickOutcome::Release ||
|
||||
clickOutcome == AzFramework::ClickDetector::ClickOutcome::Click)
|
||||
{
|
||||
if (m_leftMouseUp)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user