Add tests for planar manipulator draw when dealing with scaling (#6164)

* add support to add a custom debug display request interface for manipulator test framework

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

* wip changes to support tests for manipulator view drawing

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

* add test for planar manipulator draw when dealing with scaling

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

* additional comments for added context

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

* small updates/fixes after PR feedback

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

* fix for missing NullDebugDisplayRequests

Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com>
This commit is contained in:
Tom Hulton-Harrop
2021-12-06 14:53:45 +00:00
committed by GitHub
parent 09c9548ba4
commit 969dbf407a
30 changed files with 244 additions and 106 deletions
@@ -191,8 +191,8 @@ namespace AzToolsFramework
{
m_manipulatorView->Draw(
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay, cameraState,
mouseInteraction);
ManipulatorState{ ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay,
cameraState, mouseInteraction);
}
void AngularManipulator::SetAxis(const AZ::Vector3& axis)
@@ -116,8 +116,8 @@ namespace AzToolsFramework
{
m_manipulatorView->Draw(
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ TransformUniformScale(GetSpace()), GetNonUniformScale(), m_localStart, MouseOver() }, debugDisplay, cameraState,
mouseInteraction);
ManipulatorState{ TransformUniformScale(GetSpace()), GetNonUniformScale(), m_localStart, MouseOver() }, debugDisplay,
cameraState, mouseInteraction);
}
}
@@ -239,8 +239,8 @@ namespace AzToolsFramework
view->Draw(
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ ApplySpace(localTransform), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay, cameraState,
mouseInteraction);
ManipulatorState{ ApplySpace(localTransform), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay,
cameraState, mouseInteraction);
}
}
@@ -146,7 +146,7 @@ namespace AzToolsFramework
for (const auto& pair : m_manipulatorIdToPtrMap)
{
pair.second->Draw({ Interacting() }, debugDisplay, cameraState, mouseInteraction);
pair.second->Draw(ManipulatorManagerState{ Interacting() }, debugDisplay, cameraState, mouseInteraction);
}
RefreshMouseOverState(mouseInteraction.m_mousePick);
@@ -10,6 +10,15 @@
namespace AzToolsFramework
{
AZ::Transform ApplySpace(const AZ::Transform& localTransform, const AZ::Transform& space, const AZ::Vector3& nonUniformScale)
{
AZ::Transform result;
result.SetRotation(space.GetRotation() * localTransform.GetRotation());
result.SetTranslation(space.TransformPoint(nonUniformScale * localTransform.GetTranslation()));
result.SetUniformScale(space.GetUniformScale() * localTransform.GetUniformScale());
return result;
}
const AZ::Transform& ManipulatorSpace::GetSpace() const
{
return m_space;
@@ -32,11 +41,7 @@ namespace AzToolsFramework
AZ::Transform ManipulatorSpace::ApplySpace(const AZ::Transform& localTransform) const
{
AZ::Transform result;
result.SetRotation(m_space.GetRotation() * localTransform.GetRotation());
result.SetTranslation(m_space.TransformPoint(m_nonUniformScale * localTransform.GetTranslation()));
result.SetUniformScale(m_space.GetUniformScale() * localTransform.GetUniformScale());
return result;
return AzToolsFramework::ApplySpace(localTransform, m_space, m_nonUniformScale);
}
const AZ::Vector3& ManipulatorSpaceWithLocalPosition::GetLocalPosition() const
@@ -17,6 +17,8 @@ namespace AZ
namespace AzToolsFramework
{
AZ::Transform ApplySpace(const AZ::Transform& localTransform, const AZ::Transform& space, const AZ::Vector3& nonUniformScale);
//! Handles location for manipulators which have a global space but no local transformation.
class ManipulatorSpace
{
@@ -383,8 +383,8 @@ namespace AzToolsFramework
debugDisplay.DrawLine(quadBoundVisual.m_corner1, quadBoundVisual.m_corner2);
debugDisplay.SetColor(ViewColor(manipulatorState.m_mouseOver, m_axis2Color, m_mouseOverColor).GetAsVector4());
debugDisplay.DrawLine(quadBoundVisual.m_corner4, quadBoundVisual.m_corner1);
debugDisplay.DrawLine(quadBoundVisual.m_corner2, quadBoundVisual.m_corner3);
debugDisplay.DrawLine(quadBoundVisual.m_corner1, quadBoundVisual.m_corner4);
if (manipulatorState.m_mouseOver)
{
@@ -738,15 +738,16 @@ namespace AzToolsFramework
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
AZStd::unique_ptr<ManipulatorViewQuad> CreateManipulatorViewQuad(
const PlanarManipulator& planarManipulator,
const AZ::Vector3& axis1,
const AZ::Vector3& axis2,
const AZ::Color& axis1Color,
const AZ::Color& axis2Color,
const AZ::Vector3& offset,
const float size)
{
AZStd::unique_ptr<ManipulatorViewQuad> viewQuad = AZStd::make_unique<ManipulatorViewQuad>();
viewQuad->m_axis1 = planarManipulator.GetAxis1();
viewQuad->m_axis2 = planarManipulator.GetAxis2();
viewQuad->m_axis1 = axis1;
viewQuad->m_axis2 = axis2;
viewQuad->m_size = size;
viewQuad->m_offset = offset;
viewQuad->m_axis1Color = axis1Color;
@@ -382,7 +382,8 @@ namespace AzToolsFramework
// Helpers to create various manipulator views.
AZStd::unique_ptr<ManipulatorViewQuad> CreateManipulatorViewQuad(
const PlanarManipulator& planarManipulator,
const AZ::Vector3& axis1,
const AZ::Vector3& axis2,
const AZ::Color& axis1Color,
const AZ::Color& axis2Color,
const AZ::Vector3& offset,
@@ -145,8 +145,8 @@ namespace AzToolsFramework
{
view->Draw(
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay,
cameraState, mouseInteraction);
ManipulatorState{ ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() },
debugDisplay, cameraState, mouseInteraction);
}
}
@@ -202,8 +202,8 @@ namespace AzToolsFramework
{
view->Draw(
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay,
cameraState, mouseInteraction);
ManipulatorState{ ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() },
debugDisplay, cameraState, mouseInteraction);
}
}
@@ -90,8 +90,8 @@ namespace AzToolsFramework
{
view->Draw(
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalPosition(), MouseOver() }, debugDisplay, cameraState,
mouseInteraction);
ManipulatorState{ TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalPosition(), MouseOver() }, debugDisplay,
cameraState, mouseInteraction);
}
}
@@ -94,8 +94,8 @@ namespace AzToolsFramework
{
m_manipulatorView->Draw(
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ TransformUniformScale(GetSpace()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay,
cameraState, mouseInteraction);
ManipulatorState{ TransformUniformScale(GetSpace()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() },
debugDisplay, cameraState, mouseInteraction);
}
}
@@ -166,8 +166,8 @@ namespace AzToolsFramework
{
m_manipulatorView->Draw(
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalPosition(), MouseOver() }, debugDisplay, cameraState,
mouseInteraction);
ManipulatorState{ TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalPosition(), MouseOver() }, debugDisplay,
cameraState, mouseInteraction);
}
void SurfaceManipulator::InvalidateImpl()
@@ -19,6 +19,21 @@ namespace AzToolsFramework
static const AZ::Color LinearManipulatorZAxisColor = AZ::Color(0.0f, 0.0f, 1.0f, 1.0f);
static const AZ::Color SurfaceManipulatorColor = AZ::Color(1.0f, 1.0f, 0.0f, 0.5f);
static TranslationManipulatorsViewCreateInfo DefaultTranslationManipulatorViewCreateInfo()
{
TranslationManipulatorsViewCreateInfo createInfo;
createInfo.axis1Color = LinearManipulatorXAxisColor;
createInfo.axis2Color = LinearManipulatorYAxisColor;
createInfo.axis3Color = LinearManipulatorZAxisColor;
createInfo.surfaceColor = SurfaceManipulatorColor;
createInfo.linearAxisLength = LinearManipulatorAxisLength();
createInfo.linearConeLength = LinearManipulatorConeLength();
createInfo.linearConeRadius = LinearManipulatorConeRadius();
createInfo.planarAxisLength = PlanarManipulatorAxisLength();
createInfo.surfaceRadius = SurfaceManipulatorRadius();
return createInfo;
}
TranslationManipulators::TranslationManipulators(
const Dimensions dimensions, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale)
: m_dimensions(dimensions)
@@ -231,17 +246,36 @@ namespace AzToolsFramework
}
}
void TranslationManipulators::ConfigureView2d(const TranslationManipulatorsViewCreateInfo& translationManipulatorViewCreateInfo)
{
ConfigureLinearView(
translationManipulatorViewCreateInfo.linearAxisLength, translationManipulatorViewCreateInfo.linearConeLength,
translationManipulatorViewCreateInfo.linearConeRadius, translationManipulatorViewCreateInfo.axis1Color,
translationManipulatorViewCreateInfo.axis2Color, translationManipulatorViewCreateInfo.axis3Color);
ConfigurePlanarView(
translationManipulatorViewCreateInfo.planarAxisLength, translationManipulatorViewCreateInfo.linearAxisLength,
translationManipulatorViewCreateInfo.linearConeLength, translationManipulatorViewCreateInfo.axis1Color,
translationManipulatorViewCreateInfo.axis2Color, translationManipulatorViewCreateInfo.axis3Color);
}
void TranslationManipulators::ConfigureView3d(const TranslationManipulatorsViewCreateInfo& translationManipulatorViewCreateInfo)
{
ConfigureView2d(translationManipulatorViewCreateInfo);
ConfigureSurfaceView(translationManipulatorViewCreateInfo.surfaceRadius, translationManipulatorViewCreateInfo.surfaceColor);
}
void TranslationManipulators::ConfigureLinearView(
const float axisLength,
const float coneLength,
const float coneRadius,
const AZ::Color& axis1Color,
const AZ::Color& axis2Color,
const AZ::Color& axis3Color /*= AZ::Color(0.0f, 0.0f, 1.0f, 0.5f)*/)
{
const AZ::Color axesColor[] = { axis1Color, axis2Color, axis3Color };
const auto configureLinearView =
[lineBoundWidth = m_lineBoundWidth, coneLength = LinearManipulatorConeLength(), axisLength,
coneRadius = LinearManipulatorConeRadius()](LinearManipulator* linearManipulator, const AZ::Color& color)
const auto configureLinearView = [lineBoundWidth = m_lineBoundWidth, coneLength, axisLength,
coneRadius](LinearManipulator* linearManipulator, const AZ::Color& color)
{
const auto lineLength = axisLength - coneLength;
@@ -259,25 +293,21 @@ namespace AzToolsFramework
}
void TranslationManipulators::ConfigurePlanarView(
const float planeSize,
const float planarAxisLength,
const float linearAxisLength,
const float linearConeLength,
const AZ::Color& plane1Color,
const AZ::Color& plane2Color /*= AZ::Color(0.0f, 1.0f, 0.0f, 0.5f)*/,
const AZ::Color& plane3Color /*= AZ::Color(0.0f, 0.0f, 1.0f, 0.5f)*/)
{
const AZ::Color planesColor[] = { plane1Color, plane2Color, plane3Color };
const float linearAxisLength = LinearManipulatorAxisLength();
const float linearConeLength = LinearManipulatorConeLength();
for (size_t manipulatorIndex = 0; manipulatorIndex < m_planarManipulators.size(); ++manipulatorIndex)
{
const auto& planarManipulator = *m_planarManipulators[manipulatorIndex];
const AZStd::shared_ptr<ManipulatorViewQuad> manipulatorView = CreateManipulatorViewQuad(
*m_planarManipulators[manipulatorIndex], planesColor[manipulatorIndex], planesColor[(manipulatorIndex + 1) % 3],
(planarManipulator.GetAxis1() + planarManipulator.GetAxis2()) *
(((linearAxisLength - linearConeLength) * 0.5f) - (planeSize * 0.5f)),
planeSize);
m_planarManipulators[manipulatorIndex]->SetViews(ManipulatorViews{ manipulatorView });
m_planarManipulators[manipulatorIndex]->SetViews(ManipulatorViews{ CreateManipulatorViewQuadForPlanarTranslationManipulator(
planarManipulator.GetAxis1(), planarManipulator.GetAxis2(), planesColor[manipulatorIndex],
planesColor[(manipulatorIndex + 1) % 3], linearAxisLength, linearConeLength, planarAxisLength) });
}
}
@@ -325,19 +355,25 @@ namespace AzToolsFramework
void ConfigureTranslationManipulatorAppearance3d(TranslationManipulators* translationManipulators)
{
translationManipulators->SetAxes(AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY(), AZ::Vector3::CreateAxisZ());
translationManipulators->ConfigurePlanarView(
PlanarManipulatorAxisLength(), LinearManipulatorXAxisColor, LinearManipulatorYAxisColor, LinearManipulatorZAxisColor);
translationManipulators->ConfigureLinearView(
LinearManipulatorAxisLength(), LinearManipulatorXAxisColor, LinearManipulatorYAxisColor, LinearManipulatorZAxisColor);
translationManipulators->ConfigureSurfaceView(SurfaceManipulatorRadius(), SurfaceManipulatorColor);
translationManipulators->ConfigureView3d(DefaultTranslationManipulatorViewCreateInfo());
}
void ConfigureTranslationManipulatorAppearance2d(TranslationManipulators* translationManipulators)
{
translationManipulators->SetAxes(AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY());
translationManipulators->ConfigurePlanarView(
PlanarManipulatorAxisLength(), LinearManipulatorXAxisColor, LinearManipulatorYAxisColor);
translationManipulators->ConfigureLinearView(
LinearManipulatorAxisLength(), LinearManipulatorXAxisColor, LinearManipulatorYAxisColor);
translationManipulators->ConfigureView2d(DefaultTranslationManipulatorViewCreateInfo());
}
AZStd::shared_ptr<ManipulatorViewQuad> CreateManipulatorViewQuadForPlanarTranslationManipulator(
const AZ::Vector3& axis1,
const AZ::Vector3& axis2,
const AZ::Color& axis1Color,
const AZ::Color& axis2Color,
const float linearAxisLength,
const float linearConeLength,
const float planarAxisLength)
{
const AZ::Vector3 offset = (axis1 + axis2) * (((linearAxisLength - linearConeLength) * 0.5f) - (planarAxisLength * 0.5f));
return CreateManipulatorViewQuad(axis1, axis2, axis1Color, axis2Color, offset, planarAxisLength);
}
} // namespace AzToolsFramework
@@ -15,6 +15,20 @@
namespace AzToolsFramework
{
//! Parameters to configure the appearance of the TranslationManipulators view(s).
struct TranslationManipulatorsViewCreateInfo
{
float linearAxisLength;
float linearConeLength;
float linearConeRadius;
float planarAxisLength;
float surfaceRadius;
AZ::Color axis1Color;
AZ::Color axis2Color;
AZ::Color axis3Color;
AZ::Color surfaceColor;
};
//! TranslationManipulators is an aggregation of 3 linear manipulators, 3 planar manipulators
//! and one surface manipulator who share the same transform.
class TranslationManipulators : public Manipulators
@@ -23,6 +37,9 @@ namespace AzToolsFramework
AZ_RTTI(TranslationManipulators, "{D5E49EA2-30E0-42BC-A51D-6A7F87818260}")
AZ_CLASS_ALLOCATOR(TranslationManipulators, AZ::SystemAllocator, 0)
TranslationManipulators(TranslationManipulators&&) = delete;
TranslationManipulators& operator=(TranslationManipulators&&) = delete;
//! How many dimensions does this translation manipulator have.
enum class Dimensions
{
@@ -52,26 +69,31 @@ namespace AzToolsFramework
void SetAxes(const AZ::Vector3& axis1, const AZ::Vector3& axis2, const AZ::Vector3& axis3 = AZ::Vector3::CreateAxisZ());
void ConfigureView2d(const TranslationManipulatorsViewCreateInfo& translationManipulatorViewCreateInfo);
void ConfigureView3d(const TranslationManipulatorsViewCreateInfo& translationManipulatorViewCreateInfo);
//! Sets the bound width to use for the line/axis of a linear manipulator.
void SetLineBoundWidth(float lineBoundWidth);
private:
void ConfigurePlanarView(
float planeSize,
float linearAxisLength,
float linearConeLength,
const AZ::Color& plane1Color,
const AZ::Color& plane2Color = AZ::Color(0.0f, 1.0f, 0.0f, 0.5f),
const AZ::Color& plane3Color = AZ::Color(0.0f, 0.0f, 1.0f, 0.5f));
void ConfigureLinearView(
float axisLength,
float coneLength,
float coneRadius,
const AZ::Color& axis1Color,
const AZ::Color& axis2Color,
const AZ::Color& axis3Color = AZ::Color(0.0f, 0.0f, 1.0f, 0.5f));
void ConfigureSurfaceView(float radius, const AZ::Color& color);
//! Sets the bound width to use for the line/axis of a linear manipulator.
void SetLineBoundWidth(float lineBoundWidth);
private:
AZ_DISABLE_COPY_MOVE(TranslationManipulators)
// Manipulators
void ProcessManipulators(const AZStd::function<void(BaseManipulator*)>&) override;
@@ -131,4 +153,12 @@ namespace AzToolsFramework
void ConfigureTranslationManipulatorAppearance3d(TranslationManipulators* translationManipulators);
void ConfigureTranslationManipulatorAppearance2d(TranslationManipulators* translationManipulators);
AZStd::shared_ptr<ManipulatorViewQuad> CreateManipulatorViewQuadForPlanarTranslationManipulator(
const AZ::Vector3& axis1,
const AZ::Vector3& axis2,
const AZ::Color& axis1Color,
const AZ::Color& axis2Color,
float linearAxisLength,
float linearConeLength,
float planarAxisLength);
} // namespace AzToolsFramework
@@ -15,12 +15,14 @@
#include <AzCore/Slice/SliceComponent.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzCore/std/parallel/binary_semaphore.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/UserSettings/UserSettingsComponent.h>
#include <AzTest/AzTest.h>
#include <AZTestShared/Math/MathTestHelpers.h>
#include <AZTestShared/Utils/Utils.h>
#include <AzFramework/UnitTest/TestDebugDisplayRequests.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzToolsFramework/API/ViewportEditorModeTrackerInterface.h>
#include <AzToolsFramework/API/ViewportEditorModeTrackerNotificationBus.h>
@@ -235,6 +237,13 @@ namespace UnitTest
return toolsApp;
}
//! It is possible to override this in classes deriving from ToolsApplicationFixture to provide alternate
//! implementations of the DebugDisplayRequests interface (e.g. TestDebugDisplayRequests).
virtual AZStd::shared_ptr<AzFramework::DebugDisplayRequests> CreateDebugDisplayRequests()
{
return AZStd::make_shared<NullDebugDisplayRequests>();
}
protected:
TestEditorActions m_editorActions;
ToolsApplicationMessageHandler m_messageHandler; // used to suppress trace messages in test output
@@ -7,12 +7,16 @@
*/
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzManipulatorTestFramework/AzManipulatorTestFramework.h>
#include <AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h>
#include <AzManipulatorTestFramework/ImmediateModeActionDispatcher.h>
#include <AzTest/AzTest.h>
#include <AzToolsFramework/Application/ToolsApplication.h>
#include <AzToolsFramework/Manipulators/RotationManipulators.h>
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
#include <AzToolsFramework/Manipulators/ManipulatorView.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzToolsFramework/Manipulators/RotationManipulators.h>
#include <AzToolsFramework/Manipulators/TranslationManipulators.h>
#include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
#include <AzToolsFramework/UnitTest/ToolsTestApplication.h>
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
@@ -21,8 +25,7 @@ namespace UnitTest
{
using namespace AzToolsFramework;
class ManipulatorViewTest
: public AllocatorsTestFixture
class ManipulatorViewTest : public AllocatorsTestFixture
{
AZStd::unique_ptr<AZ::SerializeContext> m_serializeContext;
@@ -32,7 +35,7 @@ namespace UnitTest
m_serializeContext = AZStd::make_unique<AZ::SerializeContext>();
m_app.Start(AzFramework::Application::Descriptor());
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
// shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash
// shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash
// in the unit tests.
AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize);
}
@@ -51,12 +54,9 @@ namespace UnitTest
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Given
const AZ::Transform orientation =
AZ::Transform::CreateFromQuaternion(
AZ::Quaternion::CreateFromAxisAngle(
AZ::Vector3::CreateAxisX(), AZ::DegToRad(-90.0f)));
AZ::Transform::CreateFromQuaternion(AZ::Quaternion::CreateRotationX(AZ::DegToRad(-90.0f)));
const AZ::Transform translation =
AZ::Transform::CreateTranslation(AZ::Vector3(5.0f, 0.0f, 10.0f));
const AZ::Transform translation = AZ::Transform::CreateTranslation(AZ::Vector3(5.0f, 0.0f, 10.0f));
const AZ::Transform manipulatorSpace = translation * orientation;
// create a rotation manipulator in an arbitrary space
@@ -67,8 +67,7 @@ namespace UnitTest
// When
const AZ::Vector3 worldCameraPosition = AZ::Vector3(5.0f, -10.0f, 10.0f);
// transform the view direction to the space of the manipulator (space + local transform)
const AZ::Vector3 viewDirection =
CalculateViewDirection(rotationManipulators, worldCameraPosition);
const AZ::Vector3 viewDirection = CalculateViewDirection(rotationManipulators, worldCameraPosition);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -84,8 +83,7 @@ namespace UnitTest
cameraState.m_position = AZ::Vector3::CreateAxisY(20.0f);
cameraState.m_forward = -AZ::Vector3::CreateAxisY();
const float scale =
AzToolsFramework::CalculateScreenToWorldMultiplier(AZ::Vector3::CreateZero(), cameraState);
const float scale = AzToolsFramework::CalculateScreenToWorldMultiplier(AZ::Vector3::CreateZero(), cameraState);
EXPECT_NEAR(scale, 2.0f, std::numeric_limits<float>::epsilon());
}
@@ -96,9 +94,57 @@ namespace UnitTest
cameraState.m_position = AZ::Vector3::CreateAxisY(20.0f);
cameraState.m_forward = -AZ::Vector3::CreateAxisY();
const float scale =
AzToolsFramework::CalculateScreenToWorldMultiplier(AZ::Vector3::CreateAxisX(-10.0f), cameraState);
const float scale = AzToolsFramework::CalculateScreenToWorldMultiplier(AZ::Vector3::CreateAxisX(-10.0f), cameraState);
EXPECT_NEAR(scale, 2.0f, std::numeric_limits<float>::epsilon());
}
TEST_F(ManipulatorViewTest, ManipulatorViewQuadDrawsAtCorrectPositionWhenManipulatorSpaceIsScaledUniformlyAndNonUniformly)
{
// Given
// simulate a custom manipulator space (e.g. entity transform) and a local offset within that space (e.g. spline vertex position)
const AZ::Transform space =
AZ::Transform::CreateTranslation(AZ::Vector3(2.0f, -3.0f, -4.0f)) * AZ::Transform::CreateUniformScale(2.0f);
const AZ::Vector3 localPosition = AZ::Vector3(2.0f, -2.0f, 0.0f);
const AZ::Vector3 nonUniformScale = AZ::Vector3(2.0f, 3.0f, 4.0f);
const AZ::Transform combinedTransform =
AzToolsFramework::ApplySpace(AZ::Transform::CreateTranslation(localPosition), space, nonUniformScale);
// create a manipulator state based on the space and local position
AzToolsFramework::ManipulatorState manipulatorState{};
manipulatorState.m_worldFromLocal = combinedTransform;
manipulatorState.m_nonUniformScale = nonUniformScale;
// note: This is zero as the localPosition is already encoded in the combinedTransform
manipulatorState.m_localPosition = AZ::Vector3::CreateZero();
// camera (go to position format) - 10.00, -15.00, 6.00, -90.00, 0.00
const AzFramework::CameraState cameraState = AzFramework::CreateDefaultCamera(
AZ::Transform::CreateFromMatrix3x3AndTranslation(
AZ::Matrix3x3::CreateRotationX(AZ::DegToRad(-90.0f)), AZ::Vector3(10.0f, -15.0f, 6.0f)),
AZ::Vector2(1280, 720));
// test debug display instance to record vertices that were output
auto testDebugDisplayRequests = AZStd::make_shared<TestDebugDisplayRequests>();
auto planarTranslationViewQuad = CreateManipulatorViewQuadForPlanarTranslationManipulator(
AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY(), AZ::Color::CreateZero(), AZ::Color::CreateZero(), 2.2f, 0.2f, 1.0f);
// When
// draw the quad as it would be for a manipulator
planarTranslationViewQuad->Draw(
AzToolsFramework::ManipulatorManagerId(1), AzToolsFramework::ManipulatorManagerState{ false },
AzToolsFramework::ManipulatorId(1), manipulatorState, *testDebugDisplayRequests, cameraState,
AzToolsFramework::ViewportInteraction::MouseInteraction{});
const AZStd::vector<AZ::Vector3> expectedDisplayPositions = {
AZ::Vector3(10.5f, -13.5f, -4.0f), AZ::Vector3(11.5f, -13.5f, -4.0f), AZ::Vector3(10.5f, -14.5f, -4.0f),
AZ::Vector3(11.5f, -14.5f, -4.0f), AZ::Vector3(10.5f, -13.5f, -4.0f), AZ::Vector3(10.5f, -14.5f, -4.0f),
AZ::Vector3(11.5f, -14.5f, -4.0f), AZ::Vector3(11.5f, -13.5f, -4.0f)
};
// Then
const auto points = testDebugDisplayRequests->GetPoints();
// quad vertices appear in the expected position (not offset or scaled incorrectly by space scale)
using ::testing::UnorderedPointwise;
EXPECT_THAT(points, UnorderedPointwise(ContainerIsClose(), expectedDisplayPositions));
}
} // namespace UnitTest