Merge branch 'develop' into LYN-1767-AB

This commit is contained in:
igarri
2021-06-09 11:42:31 +01:00
316 changed files with 6288 additions and 7245 deletions
@@ -0,0 +1,5 @@
This is the UUID for libs / particles / milestone2particles . xml.
6BDE282B49C957F7B0714B26579BCA9A
This isn an invalid UUID
33bdee92F3225688ABEE534F6058593F
This is another invalid UUID B076CDDC-14DK-50F4-A5E9-7518ABB3E851
@@ -1,14 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// If you make changes in ICryPak.h, make changes here, to dirty the PCH.
#include "CrySystem_precompiled.h"
@@ -75,6 +75,5 @@ set(FILES
ViewSystem/View.h
ViewSystem/ViewSystem.cpp
ViewSystem/ViewSystem.h
CrySystem_precompiled.cpp
WindowsErrorReporting.cpp
)
+13 -8
View File
@@ -150,8 +150,13 @@ namespace AZ
// also needs to be an overload for every version because they all represent overloads for different non-types.
namespace AzGenericTypeInfo
{
template<typename...>
constexpr bool false_v = false;
/// Needs to match declared parameter type.
template <template <typename...> class> constexpr bool false_v1 = false;
template <template <AZStd::size_t...> class> constexpr bool false_v2 = false;
template <template <typename, AZStd::size_t> class> constexpr bool false_v3 = false;
template <template <typename, typename, AZStd::size_t> class> constexpr bool false_v4 = false;
template <template <typename, typename, typename, AZStd::size_t> class> constexpr bool false_v5 = false;
template <template <typename, AZStd::size_t, typename> class> constexpr bool false_v6 = false;
template<typename T>
inline const AZ::TypeId& Uuid()
@@ -162,7 +167,7 @@ namespace AZ
template<template<typename...> class T>
inline const AZ::TypeId& Uuid()
{
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
static_assert(false_v1<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
return s_uuid;
}
@@ -170,7 +175,7 @@ namespace AZ
template<template<AZStd::size_t...> class T>
inline const AZ::TypeId& Uuid()
{
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
static_assert(false_v2<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
return s_uuid;
}
@@ -178,7 +183,7 @@ namespace AZ
template<template<typename, AZStd::size_t> class T>
inline const AZ::TypeId& Uuid()
{
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
static_assert(false_v3<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
return s_uuid;
}
@@ -186,7 +191,7 @@ namespace AZ
template<template<typename, typename, AZStd::size_t> class T>
inline const AZ::TypeId& Uuid()
{
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
static_assert(false_v4<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
return s_uuid;
}
@@ -194,7 +199,7 @@ namespace AZ
template<template<typename, typename, typename, AZStd::size_t> class T>
inline const AZ::TypeId& Uuid()
{
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
static_assert(false_v5<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
return s_uuid;
}
@@ -202,7 +207,7 @@ namespace AZ
template<template<typename, AZStd::size_t, typename> class T>
inline const AZ::TypeId& Uuid()
{
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
static_assert(false_v6<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
return s_uuid;
}
+3
View File
@@ -21,11 +21,14 @@ namespace AZStd
using std::asin;
using std::atan;
using std::atan2;
using std::ceil;
using std::cos;
using std::exp2;
using std::floor;
using std::fmod;
using std::round;
using std::sin;
using std::sqrt;
using std::tan;
using std::trunc;
} // namespace AZStd
@@ -1681,13 +1681,11 @@ namespace AZ::IO
AZStd::vector<AZStd::string> files;
do
{
if (AZStd::wildcard_match(pWildcardIn, fileIterator.m_filename))
{
AZStd::string foundFilename{ fileIterator.m_filename };
AZStd::to_lower(foundFilename.begin(), foundFilename.end());
files.emplace_back(AZStd::move(foundFilename));
}
} while (fileIterator = FindNext(fileIterator));
AZStd::string foundFilename{ fileIterator.m_filename };
AZStd::to_lower(foundFilename.begin(), foundFilename.end());
files.emplace_back(AZStd::move(foundFilename));
}
while (fileIterator = FindNext(fileIterator));
// Open files in alphabet order.
AZStd::sort(files.begin(), files.end());
@@ -37,9 +37,10 @@ namespace AzPhysics
if (auto* behaviorContext = azdynamic_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->Class<TriggerEvent>()
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Method("GetTriggerEntityId", &TriggerEvent::GetTriggerEntityId)
->Method("GetOtherEntityId", &TriggerEvent::GetOtherEntityId)
->Attribute(AZ::Script::Attributes::Module, "physics")
->Attribute(AZ::Script::Attributes::Category, "Physics")
->Method("Get Trigger EntityId", &TriggerEvent::GetTriggerEntityId)
->Method("Get Other EntityId", &TriggerEvent::GetOtherEntityId)
;
}
}
@@ -104,10 +105,11 @@ namespace AzPhysics
if (auto* behaviorContext = azdynamic_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->Class<CollisionEvent>()
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Property("Contacts", BehaviorValueProperty(&CollisionEvent::m_contacts))
->Method("GetBody1EntityId", &CollisionEvent::GetBody1EntityId)
->Method("GetBody2EntityId", &CollisionEvent::GetBody2EntityId)
->Attribute(AZ::Script::Attributes::Module, "physics")
->Attribute(AZ::Script::Attributes::Category, "Physics")
->Property("Contacts", BehaviorValueGetter(&CollisionEvent::m_contacts), nullptr)
->Method("Get Body 1 EntityId", &CollisionEvent::GetBody1EntityId)
->Method("Get Body 2 EntityId", &CollisionEvent::GetBody2EntityId)
;
}
}
@@ -22,7 +22,11 @@
namespace AzFramework
{
AZ_CVAR(
float, ed_cameraSystemDefaultPlaneHeight, 34.0f, nullptr, AZ::ConsoleFunctorFlags::Null,
float,
ed_cameraSystemDefaultPlaneHeight,
34.0f,
nullptr,
AZ::ConsoleFunctorFlags::Null,
"The default height of the ground plane to do intersection tests against when orbiting");
AZ_CVAR(float, ed_cameraSystemBoostMultiplier, 3.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(float, ed_cameraSystemTranslateSpeed, 10.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
@@ -41,7 +45,11 @@ namespace AzFramework
AZ_CVAR(
AZ::CVarFixedString, ed_cameraSystemTranslateForwardKey, "keyboard_key_alphanumeric_W", nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(
AZ::CVarFixedString, ed_cameraSystemTranslateBackwardKey, "keyboard_key_alphanumeric_S", nullptr, AZ::ConsoleFunctorFlags::Null,
AZ::CVarFixedString,
ed_cameraSystemTranslateBackwardKey,
"keyboard_key_alphanumeric_S",
nullptr,
AZ::ConsoleFunctorFlags::Null,
"");
AZ_CVAR(
AZ::CVarFixedString, ed_cameraSystemTranslateLeftKey, "keyboard_key_alphanumeric_A", nullptr, AZ::ConsoleFunctorFlags::Null, "");
@@ -326,7 +334,9 @@ namespace AzFramework
}
Camera RotateCameraInput::StepCamera(
const Camera& targetCamera, const ScreenVector& cursorDelta, [[maybe_unused]] const float scrollDelta,
const Camera& targetCamera,
const ScreenVector& cursorDelta,
[[maybe_unused]] const float scrollDelta,
[[maybe_unused]] const float deltaTime)
{
Camera nextCamera = targetCamera;
@@ -374,7 +384,9 @@ namespace AzFramework
}
Camera PanCameraInput::StepCamera(
const Camera& targetCamera, const ScreenVector& cursorDelta, [[maybe_unused]] const float scrollDelta,
const Camera& targetCamera,
const ScreenVector& cursorDelta,
[[maybe_unused]] const float scrollDelta,
[[maybe_unused]] const float deltaTime)
{
Camera nextCamera = targetCamera;
@@ -473,7 +485,9 @@ namespace AzFramework
}
Camera TranslateCameraInput::StepCamera(
const Camera& targetCamera, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] const float scrollDelta,
const Camera& targetCamera,
[[maybe_unused]] const ScreenVector& cursorDelta,
[[maybe_unused]] const float scrollDelta,
const float deltaTime)
{
Camera nextCamera = targetCamera;
@@ -630,7 +644,9 @@ namespace AzFramework
}
Camera OrbitDollyScrollCameraInput::StepCamera(
const Camera& targetCamera, [[maybe_unused]] const ScreenVector& cursorDelta, const float scrollDelta,
const Camera& targetCamera,
[[maybe_unused]] const ScreenVector& cursorDelta,
const float scrollDelta,
[[maybe_unused]] const float deltaTime)
{
Camera nextCamera = targetCamera;
@@ -666,7 +682,9 @@ namespace AzFramework
}
Camera OrbitDollyCursorMoveCameraInput::StepCamera(
const Camera& targetCamera, const ScreenVector& cursorDelta, [[maybe_unused]] const float scrollDelta,
const Camera& targetCamera,
const ScreenVector& cursorDelta,
[[maybe_unused]] const float scrollDelta,
[[maybe_unused]] const float deltaTime)
{
Camera nextCamera = targetCamera;
@@ -686,7 +704,9 @@ namespace AzFramework
}
Camera ScrollTranslationCameraInput::StepCamera(
const Camera& targetCamera, [[maybe_unused]] const ScreenVector& cursorDelta, const float scrollDelta,
const Camera& targetCamera,
[[maybe_unused]] const ScreenVector& cursorDelta,
const float scrollDelta,
[[maybe_unused]] const float deltaTime)
{
Camera nextCamera = targetCamera;
@@ -97,7 +97,7 @@ namespace AzManipulatorTestFramework
if (m_logging)
{
AZStd::string message = AZStd::string::format(format, args...);
std::cout << "[ActionDispatcher] " << message.c_str() << "\n";
AZ_Printf("[ActionDispatcher] %s", message.c_str());
}
}
@@ -21,12 +21,14 @@ namespace AzManipulatorTestFramework
{
//! Create a linear manipulator with a unit sphere bound.
AZStd::shared_ptr<AzToolsFramework::LinearManipulator> CreateLinearManipulator(
const AzToolsFramework::ManipulatorManagerId manipulatorManagerId, const AZ::Vector3& position = AZ::Vector3::CreateZero(),
const AzToolsFramework::ManipulatorManagerId manipulatorManagerId,
const AZ::Vector3& position = AZ::Vector3::CreateZero(),
float radius = 1.0f);
//! Create a planar manipulator with a unit sphere bound.
AZStd::shared_ptr<AzToolsFramework::PlanarManipulator> CreatePlanarManipulator(
const AzToolsFramework::ManipulatorManagerId manipulatorManagerId, const AZ::Vector3& position = AZ::Vector3::CreateZero(),
const AzToolsFramework::ManipulatorManagerId manipulatorManagerId,
const AZ::Vector3& position = AZ::Vector3::CreateZero(),
float radius = 1.0f);
//! Create a mouse pick from the specified ray and screen point.
@@ -39,7 +41,8 @@ namespace AzManipulatorTestFramework
//! Create a mouse interaction from the specified pick, buttons, interaction id and keyboard modifiers.
AzToolsFramework::ViewportInteraction::MouseInteraction CreateMouseInteraction(
const AzToolsFramework::ViewportInteraction::MousePick& mousePick, AzToolsFramework::ViewportInteraction::MouseButtons buttons,
const AzToolsFramework::ViewportInteraction::MousePick& mousePick,
AzToolsFramework::ViewportInteraction::MouseButtons buttons,
AzToolsFramework::ViewportInteraction::InteractionId interactionId,
AzToolsFramework::ViewportInteraction::KeyboardModifiers modifiers);
@@ -12,14 +12,13 @@
#pragma once
#include <AzManipulatorTestFramework/AzManipulatorTestFramework.h>
#include <AzManipulatorTestFramework/ActionDispatcher.h>
#include <AzManipulatorTestFramework/AzManipulatorTestFramework.h>
namespace AzManipulatorTestFramework
{
//! Dispatches actions immediately to the manipulators.
class ImmediateModeActionDispatcher
: public ActionDispatcher<ImmediateModeActionDispatcher>
class ImmediateModeActionDispatcher : public ActionDispatcher<ImmediateModeActionDispatcher>
{
using KeyboardModifier = AzToolsFramework::ViewportInteraction::KeyboardModifier;
using KeyboardModifiers = AzToolsFramework::ViewportInteraction::KeyboardModifiers;
@@ -62,7 +61,7 @@ namespace AzManipulatorTestFramework
void MouseLButtonUpImpl() override;
void MousePositionImpl(const AzFramework::ScreenPoint& position) override;
void KeyboardModifierDownImpl(const KeyboardModifier& keyModifier) override;
void KeyboardModifierUpImpl(const KeyboardModifier& keyModifier) override;
void KeyboardModifierUpImpl(const KeyboardModifier& keyModifier) override;
void ExpectManipulatorBeingInteractedImpl() override;
void ExpectManipulatorNotBeingInteractedImpl() override;
void SetEntityWorldTransformImpl(AZ::EntityId entityId, const AZ::Transform& transform) override;
@@ -97,8 +96,7 @@ namespace AzManipulatorTestFramework
return this;
}
inline ImmediateModeActionDispatcher* ImmediateModeActionDispatcher::GetKeyboardModifiers(
KeyboardModifiers& keyboardModifiers)
inline ImmediateModeActionDispatcher* ImmediateModeActionDispatcher::GetKeyboardModifiers(KeyboardModifiers& keyboardModifiers)
{
keyboardModifiers = GetKeyboardModifiers();
return this;
@@ -30,8 +30,10 @@ namespace AzManipulatorTestFramework
// create a default sphere view for a manipulator for simple intersection
template<typename Manipulator>
void SetupManipulatorView(
AZStd::shared_ptr<Manipulator> manipulator, const AzToolsFramework::ManipulatorManagerId manipulatorManagerId,
const AZ::Vector3& position, const float radius)
AZStd::shared_ptr<Manipulator> manipulator,
const AzToolsFramework::ManipulatorManagerId manipulatorManagerId,
const AZ::Vector3& position,
const float radius)
{
// unit sphere view
auto sphereView = AzToolsFramework::CreateManipulatorViewSphere(
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h>
#include <AzManipulatorTestFramework/ViewportInteraction.h>
@@ -19,10 +19,10 @@ namespace AzManipulatorTestFramework
using MouseInteraction = AzToolsFramework::ViewportInteraction::MouseInteraction;
using MouseInteractionEvent = AzToolsFramework::ViewportInteraction::MouseInteractionEvent;
class CustomManipulatorManager
: public AzToolsFramework::ManipulatorManager
class CustomManipulatorManager : public AzToolsFramework::ManipulatorManager
{
using ManagerBase = AzToolsFramework::ManipulatorManager;
public:
using ManagerBase::ManagerBase;
@@ -31,18 +31,17 @@ namespace AzManipulatorTestFramework
};
//! Implementation of the manipulator interface using direct access to the manipulator manager.
class DirectCallManipulatorManager
: public ManipulatorManagerInterface
class DirectCallManipulatorManager : public ManipulatorManagerInterface
{
public:
DirectCallManipulatorManager(
ViewportInteractionInterface* viewportInteraction,
AZStd::shared_ptr<CustomManipulatorManager> manipulatorManager);
ViewportInteractionInterface* viewportInteraction, AZStd::shared_ptr<CustomManipulatorManager> manipulatorManager);
// ManipulatorManagerInterface ...
void ConsumeMouseInteractionEvent(const MouseInteractionEvent& event);
AzToolsFramework::ManipulatorManagerId GetId() const override;
bool ManipulatorBeingInteracted() const override;
private:
// Trigger the updating of manipulator bounds.
void DrawManipulators(const MouseInteraction& mouseInteraction);
@@ -61,8 +60,7 @@ namespace AzManipulatorTestFramework
}
DirectCallManipulatorManager::DirectCallManipulatorManager(
ViewportInteractionInterface* viewportInteraction,
AZStd::shared_ptr<CustomManipulatorManager> manipulatorManager)
ViewportInteractionInterface* viewportInteraction, AZStd::shared_ptr<CustomManipulatorManager> manipulatorManager)
: m_viewportInteraction(viewportInteraction)
, m_manipulatorManager(AZStd::move(manipulatorManager))
{
@@ -126,11 +124,9 @@ namespace AzManipulatorTestFramework
DirectCallManipulatorViewportInteraction::DirectCallManipulatorViewportInteraction()
: m_customManager(
AZStd::make_unique<CustomManipulatorManager>(
AzToolsFramework::ManipulatorManagerId(AZ::Crc32("TestManipulatorManagerId"))))
AZStd::make_unique<CustomManipulatorManager>(AzToolsFramework::ManipulatorManagerId(AZ::Crc32("TestManipulatorManagerId"))))
, m_viewportInteraction(AZStd::make_unique<ViewportInteraction>())
, m_manipulatorManager(
AZStd::make_unique<DirectCallManipulatorManager>(m_viewportInteraction.get(), m_customManager))
, m_manipulatorManager(AZStd::make_unique<DirectCallManipulatorManager>(m_viewportInteraction.get(), m_customManager))
{
}
@@ -10,8 +10,8 @@
*
*/
#include <AzManipulatorTestFramework/ImmediateModeActionDispatcher.h>
#include <AzManipulatorTestFramework/AzManipulatorTestFrameworkUtils.h>
#include <AzManipulatorTestFramework/ImmediateModeActionDispatcher.h>
#include <AzToolsFramework/ComponentMode/EditorComponentModeBus.h>
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
@@ -33,8 +33,7 @@ namespace AzManipulatorTestFramework
using KeyboardModifier = AzToolsFramework::ViewportInteraction::KeyboardModifier;
using MouseInteractionEvent = AzToolsFramework::ViewportInteraction::MouseInteractionEvent;
ImmediateModeActionDispatcher::ImmediateModeActionDispatcher(
ManipulatorViewportInteraction& viewportManipulatorInteraction)
ImmediateModeActionDispatcher::ImmediateModeActionDispatcher(ManipulatorViewportInteraction& viewportManipulatorInteraction)
: m_viewportManipulatorInteraction(viewportManipulatorInteraction)
{
}
@@ -126,8 +125,7 @@ namespace AzManipulatorTestFramework
void ImmediateModeActionDispatcher::EnterComponentModeImpl(const AZ::Uuid& uuid)
{
using AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequestBus;
ComponentModeSystemRequestBus::Broadcast(
&ComponentModeSystemRequestBus::Events::AddSelectedComponentModesOfType, uuid);
ComponentModeSystemRequestBus::Broadcast(&ComponentModeSystemRequestBus::Events::AddSelectedComponentModesOfType, uuid);
}
const AzToolsFramework::ViewportInteraction::MouseInteractionEvent* ImmediateModeActionDispatcher::GetMouseInteractionEvent() const
@@ -144,8 +142,7 @@ namespace AzManipulatorTestFramework
AzToolsFramework::ViewportInteraction::MouseInteractionEvent* ImmediateModeActionDispatcher::GetMouseInteractionEvent()
{
return const_cast<MouseInteractionEvent*>(
static_cast<const ImmediateModeActionDispatcher*>(this)->GetMouseInteractionEvent());
return const_cast<MouseInteractionEvent*>(static_cast<const ImmediateModeActionDispatcher*>(this)->GetMouseInteractionEvent());
}
ImmediateModeActionDispatcher* ImmediateModeActionDispatcher::ExpectTrue(bool result)
@@ -162,8 +159,7 @@ namespace AzManipulatorTestFramework
return this;
}
ImmediateModeActionDispatcher* ImmediateModeActionDispatcher::GetEntityWorldTransform(
AZ::EntityId entityId, AZ::Transform& transform)
ImmediateModeActionDispatcher* ImmediateModeActionDispatcher::GetEntityWorldTransform(AZ::EntityId entityId, AZ::Transform& transform)
{
Log("Getting entity world transform");
transform = AzToolsFramework::GetWorldTransform(entityId);
@@ -11,17 +11,18 @@
*/
#include "AzManipulatorTestFrameworkTestFixtures.h"
#include <AzToolsFramework/ViewportSelection/EditorInteractionSystemViewportSelectionRequestBus.h>
#include <AzToolsFramework/ViewportSelection/EditorDefaultSelection.h>
#include <AzToolsFramework/ViewportSelection/EditorInteractionSystemViewportSelectionRequestBus.h>
namespace UnitTest
{
class AzManipulatorTestFrameworkBusCallTestFixture
: public LinearManipulatorTestFixture
class AzManipulatorTestFrameworkBusCallTestFixture : public LinearManipulatorTestFixture
{
protected:
AzManipulatorTestFrameworkBusCallTestFixture()
: LinearManipulatorTestFixture(AzToolsFramework::g_mainManipulatorManagerId) {}
: LinearManipulatorTestFixture(AzToolsFramework::g_mainManipulatorManagerId)
{
}
bool IsManipulatorInteractingBusCall() const
{
@@ -37,8 +38,8 @@ namespace UnitTest
TEST_F(AzManipulatorTestFrameworkBusCallTestFixture, ConsumeViewportLeftMouseClick)
{
// given a left mouse down ray in world space
auto event = AzManipulatorTestFramework::CreateMouseInteractionEvent(
m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Down);
auto event =
AzManipulatorTestFramework::CreateMouseInteractionEvent(m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Down);
// consume the mouse down and up events
AzManipulatorTestFramework::DispatchMouseInteractionEvent(event);
@@ -56,8 +57,8 @@ namespace UnitTest
TEST_F(AzManipulatorTestFrameworkBusCallTestFixture, ConsumeViewportMouseMoveHover)
{
// given a left mouse down ray in world space
const auto event = AzManipulatorTestFramework::CreateMouseInteractionEvent(
m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Move);
const auto event =
AzManipulatorTestFramework::CreateMouseInteractionEvent(m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Move);
// consume the mouse move event
AzManipulatorTestFramework::DispatchMouseInteractionEvent(event);
@@ -75,8 +76,8 @@ namespace UnitTest
TEST_F(AzManipulatorTestFrameworkBusCallTestFixture, ConsumeViewportMouseMoveActive)
{
// given a left mouse down ray in world space
auto event = AzManipulatorTestFramework::CreateMouseInteractionEvent(
m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Down);
auto event =
AzManipulatorTestFramework::CreateMouseInteractionEvent(m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Down);
// consume the mouse down event
AzManipulatorTestFramework::DispatchMouseInteractionEvent(event);
@@ -110,14 +111,14 @@ namespace UnitTest
const AZ::Vector3 initialManipulatorPosition = m_linearManipulator->GetLocalPosition();
m_linearManipulator->InstallMouseMoveCallback(
[&movementAlongAxis, this](const AzToolsFramework::LinearManipulator::Action& action)
{
movementAlongAxis = action.LocalPositionOffset();
m_linearManipulator->SetLocalPosition(action.LocalPosition());
});
{
movementAlongAxis = action.LocalPositionOffset();
m_linearManipulator->SetLocalPosition(action.LocalPosition());
});
// given a left mouse down ray in world space
auto event = AzManipulatorTestFramework::CreateMouseInteractionEvent(
m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Down);
auto event =
AzManipulatorTestFramework::CreateMouseInteractionEvent(m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Down);
// consume the mouse down event
AzManipulatorTestFramework::DispatchMouseInteractionEvent(event);
@@ -134,7 +135,7 @@ namespace UnitTest
// consume the mouse up event
event.m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Up;
AzManipulatorTestFramework::DispatchMouseInteractionEvent(event);
// expect the left mouse down/up sanity flags to be set
EXPECT_TRUE(m_receivedLeftMouseDown);
EXPECT_TRUE(m_receivedLeftMouseUp);
@@ -14,10 +14,10 @@
namespace UnitTest
{
class CustomManipulatorManager
: public AzToolsFramework::ManipulatorManager
class CustomManipulatorManager : public AzToolsFramework::ManipulatorManager
{
using ManagerBase = AzToolsFramework::ManipulatorManager;
public:
using ManagerBase::ManagerBase;
@@ -27,17 +27,17 @@ namespace UnitTest
}
};
class AzManipulatorTestFrameworkCustomManagerTestFixture
: public LinearManipulatorTestFixture
class AzManipulatorTestFrameworkCustomManagerTestFixture : public LinearManipulatorTestFixture
{
protected:
AzManipulatorTestFrameworkCustomManagerTestFixture()
: LinearManipulatorTestFixture(AzToolsFramework::ManipulatorManagerId(AZ::Crc32("TestManipulatorManagerId"))) {}
: LinearManipulatorTestFixture(AzToolsFramework::ManipulatorManagerId(AZ::Crc32("TestManipulatorManagerId")))
{
}
void SetUpEditorFixtureImpl() override
{
m_manipulatorManager =
AZStd::make_shared<CustomManipulatorManager>(m_manipulatorManagerId);
m_manipulatorManager = AZStd::make_shared<CustomManipulatorManager>(m_manipulatorManagerId);
LinearManipulatorTestFixture::SetUpEditorFixtureImpl();
}
@@ -115,9 +115,9 @@ namespace UnitTest
m_linearManipulator->InstallMouseMoveCallback(
[&movementAlongAxis](const AzToolsFramework::LinearManipulator::Action& action)
{
movementAlongAxis = action.m_current.m_localPositionOffset;
});
{
movementAlongAxis = action.m_current.m_localPositionOffset;
});
// consume the mouse down event
m_manipulatorManager->ConsumeViewportMousePress(m_interaction);
@@ -141,4 +141,3 @@ namespace UnitTest
EXPECT_EQ(movementAlongAxis, expectedPositionAfterMovementAlongAxis);
}
} // namespace UnitTest
@@ -12,6 +12,7 @@
#include "AzManipulatorTestFrameworkTestFixtures.h"
#include <AZTestShared/Math/MathTestHelpers.h>
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <AzFramework/Viewport/ViewportScreen.h>
#include <AzManipulatorTestFramework/AzManipulatorTestFramework.h>
@@ -22,7 +23,6 @@
#include <AzToolsFramework/Manipulators/LinearManipulator.h>
#include <AzToolsFramework/Manipulators/PlanarManipulator.h>
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
#include <AZTestShared/Math/MathTestHelpers.h>
namespace UnitTest
{
@@ -94,7 +94,8 @@ namespace UnitTest
template<typename Manipulator>
void ValidateManipulatorSnappingBehavior(
AZStd::shared_ptr<Manipulator> manipulator, AzManipulatorTestFramework::ImmediateModeActionDispatcher* actionDispatcher,
AZStd::shared_ptr<Manipulator> manipulator,
AzManipulatorTestFramework::ImmediateModeActionDispatcher* actionDispatcher,
const AzFramework::CameraState& cameraState)
{
manipulator->SetLocalOrientation(AZ::Quaternion::CreateFromEulerAnglesDegrees(AZ::Vector3(180.0f, 0.0f, 135.0f)));
@@ -15,8 +15,7 @@
namespace UnitTest
{
class AValidViewportInteraction
: public ToolsApplicationFixture
class AValidViewportInteraction : public ToolsApplicationFixture
{
public:
AValidViewportInteraction()
@@ -27,8 +26,7 @@ namespace UnitTest
protected:
void SetUpEditorFixtureImpl() override
{
m_cameraState =
AzFramework::CreateIdentityDefaultCamera(AZ::Vector3::CreateZero(), AZ::Vector2(800.0f, 600.0f));
m_cameraState = AzFramework::CreateIdentityDefaultCamera(AZ::Vector3::CreateZero(), AZ::Vector2(800.0f, 600.0f));
}
public:
@@ -11,49 +11,48 @@
*/
#include <AzFramework/Viewport/ViewportScreen.h>
#include <AzManipulatorTestFramework/AzManipulatorTestFrameworkUtils.h>
#include <AzManipulatorTestFramework/AzManipulatorTestFramework.h>
#include <AzManipulatorTestFramework/AzManipulatorTestFrameworkUtils.h>
#include <AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h>
#include <AzManipulatorTestFramework/IndirectManipulatorViewportInteraction.h>
#include <AzManipulatorTestFramework/ImmediateModeActionDispatcher.h>
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
#include <AzManipulatorTestFramework/IndirectManipulatorViewportInteraction.h>
#include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
namespace UnitTest
{
class AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture
: public ToolsApplicationFixture
class AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture : public ToolsApplicationFixture
{
protected:
struct State
{
State(AZStd::unique_ptr<AzManipulatorTestFramework::ManipulatorViewportInteraction> viewportManipulatorInteraction)
: m_viewportManipulatorInteraction(viewportManipulatorInteraction.release())
, m_actionDispatcher(AZStd::make_unique<AzManipulatorTestFramework::ImmediateModeActionDispatcher>(*m_viewportManipulatorInteraction))
, m_linearManipulator(
AzManipulatorTestFramework::CreateLinearManipulator(
m_viewportManipulatorInteraction->GetManipulatorManager().GetId(),
/*position=*/AZ::Vector3(0.0f, 50.0f, 0.0f),
/*radius=*/m_boundsRadius))
, m_actionDispatcher(
AZStd::make_unique<AzManipulatorTestFramework::ImmediateModeActionDispatcher>(*m_viewportManipulatorInteraction))
, m_linearManipulator(AzManipulatorTestFramework::CreateLinearManipulator(
m_viewportManipulatorInteraction->GetManipulatorManager().GetId(),
/*position=*/AZ::Vector3(0.0f, 50.0f, 0.0f),
/*radius=*/m_boundsRadius))
{
// default sanity check call backs
m_linearManipulator->InstallLeftMouseDownCallback(
[this]([[maybe_unused]] const AzToolsFramework::LinearManipulator::Action& action)
{
m_receivedLeftMouseDown = true;
});
{
m_receivedLeftMouseDown = true;
});
m_linearManipulator->InstallMouseMoveCallback(
[this]([[maybe_unused]] const AzToolsFramework::LinearManipulator::Action& action)
{
m_receivedMouseMove = true;
});
{
m_receivedMouseMove = true;
});
m_linearManipulator->InstallLeftMouseUpCallback(
[this]([[maybe_unused]] const AzToolsFramework::LinearManipulator::Action& action)
{
m_receivedLeftMouseUp = true;
});
{
m_receivedLeftMouseUp = true;
});
}
~State() = default;
@@ -79,13 +78,12 @@ namespace UnitTest
protected:
void SetUpEditorFixtureImpl() override
{
m_directState = AZStd::make_unique<State>(
AZStd::make_unique<AzManipulatorTestFramework::DirectCallManipulatorViewportInteraction>());
m_busState = AZStd::make_unique<State>(
AZStd::make_unique<AzManipulatorTestFramework::IndirectCallManipulatorViewportInteraction>());
m_directState =
AZStd::make_unique<State>(AZStd::make_unique<AzManipulatorTestFramework::DirectCallManipulatorViewportInteraction>());
m_busState =
AZStd::make_unique<State>(AZStd::make_unique<AzManipulatorTestFramework::IndirectCallManipulatorViewportInteraction>());
m_cameraState =
AzFramework::CreateIdentityDefaultCamera(
AZ::Vector3::CreateZero(), AzManipulatorTestFramework::DefaultViewportSize);
AzFramework::CreateIdentityDefaultCamera(AZ::Vector3::CreateZero(), AzManipulatorTestFramework::DefaultViewportSize);
}
void TearDownEditorFixtureImpl() override
@@ -105,8 +103,7 @@ namespace UnitTest
{
// given a left mouse down ray in world space
// consume the mouse down and up events
state.m_actionDispatcher
->CameraState(m_cameraState)
state.m_actionDispatcher->CameraState(m_cameraState)
->MousePosition(AzManipulatorTestFramework::GetCameraStateViewportCenter(m_cameraState))
->MouseLButtonDown()
->Trace("Expecting left mouse button down")
@@ -126,31 +123,27 @@ namespace UnitTest
->ExpectTrue(state.m_receivedLeftMouseUp)
->ExpectTrue(state.m_receivedMouseMove)
->ExpectFalse(state.m_linearManipulator->PerformingAction())
->ExpectManipulatorNotBeingInteracted()
;
->ExpectManipulatorNotBeingInteracted();
}
void AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture::ConsumeViewportMouseMoveHover(State& state)
{
// given a left mouse down ray in world space
// consume the mouse move event
state.m_actionDispatcher
->CameraState(m_cameraState)
state.m_actionDispatcher->CameraState(m_cameraState)
->MousePosition(AzManipulatorTestFramework::GetCameraStateViewportCenter(m_cameraState))
->ExpectFalse(state.m_linearManipulator->PerformingAction())
->ExpectManipulatorNotBeingInteracted()
->ExpectFalse(state.m_receivedLeftMouseDown)
->ExpectFalse(state.m_receivedMouseMove)
->ExpectFalse(state.m_receivedLeftMouseUp)
;
->ExpectFalse(state.m_receivedLeftMouseUp);
}
void AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture::ConsumeViewportMouseMoveActive(State& state)
{
// given a left mouse down ray in world space
// consume the mouse move event
state.m_actionDispatcher
->CameraState(m_cameraState)
state.m_actionDispatcher->CameraState(m_cameraState)
->MouseLButtonDown()
->MousePosition(AzManipulatorTestFramework::GetCameraStateViewportCenter(m_cameraState))
->ExpectTrue(state.m_linearManipulator->PerformingAction())
@@ -158,8 +151,7 @@ namespace UnitTest
->MouseLButtonUp()
->ExpectTrue(state.m_receivedLeftMouseDown)
->ExpectTrue(state.m_receivedMouseMove)
->ExpectTrue(state.m_receivedLeftMouseUp)
;
->ExpectTrue(state.m_receivedLeftMouseUp);
}
void AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture::MoveManipulatorAlongAxis(State& state)
@@ -176,8 +168,7 @@ namespace UnitTest
// adjusted final world position taking into account the manipulator position relative to the camera
const auto finalPositionWorldAdjusted = finalPositionWorld - (vectorToInitialPositionWorld * scaledRadiusBound);
// calculate the position in screen space of the initial position of the manipulator
const auto initialPositionScreen =
AzFramework::WorldToScreen(initialPositionWorld, m_cameraState);
const auto initialPositionScreen = AzFramework::WorldToScreen(initialPositionWorld, m_cameraState);
// calculate the position in screen space of the final position of the manipulator
const auto finalPositionScreen = AzFramework::WorldToScreen(finalPositionWorldAdjusted, m_cameraState);
@@ -185,12 +176,11 @@ namespace UnitTest
state.m_linearManipulator->InstallMouseMoveCallback(
[&movementAlongAxis](const AzToolsFramework::LinearManipulator::Action& action)
{
movementAlongAxis = action.LocalPosition();
});
{
movementAlongAxis = action.LocalPosition();
});
state.m_actionDispatcher
->CameraState(m_cameraState)
state.m_actionDispatcher->CameraState(m_cameraState)
->MousePosition(initialPositionScreen)
->MouseLButtonDown()
->ExpectTrue(state.m_linearManipulator->PerformingAction())
@@ -199,8 +189,7 @@ namespace UnitTest
->MouseLButtonUp()
->ExpectTrue(state.m_receivedLeftMouseDown)
->ExpectTrue(state.m_receivedLeftMouseUp)
->ExpectTrue(movementAlongAxis.IsClose(finalPositionWorld, 0.01f))
;
->ExpectTrue(movementAlongAxis.IsClose(finalPositionWorld, 0.01f));
}
TEST_F(AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture, ConsumeViewportLeftMouseClick)
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Icon / Locked Status</title>
<g id="Icon-/-Locked-Status" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group-9">
<g id="Icons-/-Icon-Grid" transform="translate(17.000000, 15.000000)" fill="#FFFFFF">
<path d="M3,0 C4.03553391,-1.90224492e-16 4.875,0.839466094 4.875,1.875 L4.875,3.6 L6,3.6 L6,8 L0,8 L0,3.6 L1.125,3.6 L1.125,1.875 C1.125,0.839466094 1.96446609,1.90224492e-16 3,0 Z M3.375,5.2 L2.625,5.2 L2.625,6.4 L3.375,6.4 L3.375,5.2 Z M3,0.8 C2.37867966,0.8 1.875,1.30367966 1.875,1.925 L1.875,1.925 L1.875,3.6 L4.125,3.6 L4.125,1.925 C4.125,1.30367966 3.62132034,0.8 3,0.8 Z" id="Combined-Shape"></path>
</g>
<rect id="Rectangle" fill="#F9F9F9" opacity="0" x="0" y="0" width="24" height="24"></rect>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1017 B

@@ -356,7 +356,8 @@
<file>img/UI20/toolbar/Load.svg</file>
<file>img/UI20/toolbar/Local.svg</file>
<file>img/UI20/toolbar/Locked.svg</file>
<file>img/UI20/toolbar/LUA.svg</file>
<file>img/UI20/toolbar/Locked_Status.svg</file>
<file>img/UI20/toolbar/LUA.svg</file>
<file>img/UI20/toolbar/Material.svg</file>
<file>img/UI20/toolbar/Measure.svg</file>
<file>img/UI20/toolbar/Move.svg</file>
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Camera </title>
<g id="Camera-" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Icon-2" fill="#FFFFFF" transform="translate(1.666667, 4.166667)">
<path d="M11.5739175,9.2927927 C11.5739175,9.54639717 11.3384276,9.99926232 10.8312187,9.99926232 C10.3240097,9.99926232 2.37169783,10.0264342 2.13620796,10.0264342 C1.74674394,10.0264342 1.33916531,9.69131402 1.33916531,9.09353203 C1.33916531,8.76746913 1.35126587,5.13853395 1.35126587,4.84870026 C1.35126587,4.37772052 1.35727992,4.13013009 1.81014506,4.13013009 C2.2630102,4.13013009 10.840276,4.11201548 10.840276,4.11201548 C11.4199434,4.11201548 11.5829748,4.51959411 11.5829748,4.86377162 C11.5829748,5.20794912 11.5739175,9.03918822 11.5739175,9.2927927 L11.5739175,9.2927927 Z M2.65247422,1.24990779 C2.65247422,1.09593364 2.65247422,0.941959493 2.77927646,0.941959493 L9.83491536,0.941959493 C10.0070041,0.941959493 10.2062648,0.978188705 10.2062648,1.16839206 C10.2062648,1.35859542 10.1972075,2.73530545 10.1972075,2.73530545 L2.64943097,2.7111768 L2.65247422,1.24990779 Z M16.9539554,4.02144245 L16.374288,4.03049976 L14.6896297,5.50684012 L14.2548791,5.50684012 C14.2548791,5.50684012 13.1317736,3.56857731 13.0049713,3.31497283 C12.8781691,3.06136835 12.4615332,2.77153466 12.2622725,2.77153466 L11.139167,2.77153466 C11.139167,2.77153466 11.1210524,0.905730282 11.1210524,0.579667381 C11.1210524,0.253604479 10.8131041,2.81996648e-13 10.4145827,2.81996648e-13 L2.22678099,2.81996648e-13 C1.86144562,2.81996648e-13 1.66522821,0.208317965 1.66522821,0.45887919 L1.66522821,2.69907624 C1.3325716,2.7055975 1.26148988,2.70509029 1.06744623,2.70509029 C0.626681643,2.70509029 0.43343503,2.86812174 0.43343503,3.51423349 L0.43343503,9.83623086 C0.43343503,10.5698724 0.804784446,10.8778207 1.36633722,10.8778207 C1.72862933,10.8778207 11.5920321,10.8687634 12.0992411,10.8687634 C12.60645,10.8687634 12.8238253,10.4340129 13.0049713,10.198523 C13.1861174,9.9630331 14.309223,8.11534333 14.309223,8.11534333 L14.8164319,8.09722872 L16.4558037,9.60074099 L16.97207,9.60074099 L16.9539554,4.02144245 Z" id="Icon"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>debug</title>
<g id="debug" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M11.3615865,7.917238 L15.2274672,9.63843901 L16.4675037,9.16172668 C16.6979214,9.07292417 16.9553551,9.18924382 17.0442998,9.41972476 C17.1330234,9.64993705 17.0253844,9.89284574 16.7952509,9.98177479 L16.7952509,9.98177479 L15.3951151,10.4956726 C15.2842902,10.5384499 15.1889358,10.4726675 15.0806503,10.4244557 L15.0806503,10.4244557 L14.1703124,10.0191471 C14.3857263,10.9664393 14.4599954,12.0211666 14.2565873,12.952264 L14.2565873,12.952264 L15.6721159,13.5824979 C15.8976398,13.6829076 15.9908466,13.9650071 15.8904369,14.190531 C15.7900905,14.4159128 15.5180189,14.5355501 15.292495,14.4351404 L15.292495,14.4351404 L13.9556938,13.8399581 C13.6322377,14.54733 13.1335636,15.1766897 12.5630158,15.6037725 L12.5630158,15.6037725 L12.8756514,15.7429668 C12.983937,15.7911787 13.0605157,15.8995144 13.1027401,16.0104336 L13.1027401,16.0104336 L13.6353002,17.4447605 C13.7234077,17.6752093 13.6080984,17.9334334 13.3776496,18.021541 C13.2626228,18.0653422 13.1408059,18.058613 13.0364993,18.0121727 C12.9319085,17.9656059 12.8452864,17.8786807 12.8011855,17.7631798 L12.8011855,17.7631798 L12.3264968,16.520128 L11.644667,16.2165578 C10.4621412,16.7117239 8.87932984,16.9345084 7.56328989,16.4483518 L7.56328989,16.4483518 L11.3615865,7.917238 Z M5.52878415,4.3232224 C5.75937506,4.23517812 6.01946614,4.34552927 6.10779463,4.57624672 L6.10779463,4.57624672 L6.58675456,5.80894035 L10.4526353,7.53014136 L6.6529468,16.0643815 C5.4063142,15.4223335 4.43289769,14.215203 4.07288375,12.8629772 L4.07288375,12.8629772 L3.41379116,12.5695302 L2.17275891,13.0473317 C2.05755786,13.0919067 1.93523585,13.0847824 1.83064504,13.0382156 C1.72633845,12.9917753 1.64104404,12.9033978 1.59654788,12.7884022 C1.5078242,12.5581899 1.62471629,12.294881 1.85492858,12.2061574 L1.85492858,12.2061574 L3.27301757,11.6515537 C3.38384243,11.6087763 3.51545059,11.5931314 3.62387829,11.6414065 L3.62387829,11.6414065 L3.91988732,11.7731982 C3.85933759,11.0651327 3.99592287,10.2745607 4.30516824,9.5608618 L4.30516824,9.5608618 L2.97859873,8.970235 C2.7530748,8.86982528 2.6599312,8.58758374 2.76027765,8.36220193 C2.86068737,8.13667801 3.13269567,8.01718285 3.35821959,8.11759257 L3.35821959,8.11759257 L4.7450425,8.73504591 C5.26222301,7.94364898 6.01359598,7.25652125 6.89624338,6.79811742 L6.89624338,6.79811742 L6.10101221,6.4440577 C5.99258451,6.39578258 5.88032145,6.36759526 5.83803372,6.25681811 L5.83803372,6.25681811 L5.26971048,4.90243425 C5.18174504,4.67204872 5.29833534,4.41132994 5.52878415,4.3232224 Z M10.8942352,2.34455584 C11.1427316,2.24942103 11.4210854,2.3733521 11.5165098,2.62161032 L11.5165098,2.62161032 L11.9777045,3.8224019 C12.2035494,3.86678469 12.4283918,3.93403345 12.6476126,4.03163684 C12.8668334,4.12924023 13.0677354,4.25026013 13.2518379,4.38839772 L13.2518379,4.38839772 L14.4533966,3.92589245 C14.7019612,3.83060445 14.9816108,3.95162483 15.0770352,4.19988305 C15.1723915,4.44829447 15.0509158,4.72113321 14.8025726,4.81633622 L14.8025726,4.81633622 L13.9775725,5.12324418 C14.5520125,5.98310253 14.7248639,7.02632912 14.247419,8.09868801 L14.247419,8.09868801 L8.55503156,5.56427385 C9.03247651,4.49191495 9.9234901,3.92253515 10.946252,3.77379694 L10.946252,3.77379694 L10.6171125,2.96698358 C10.5217563,2.71857217 10.6457388,2.43969065 10.8942352,2.34455584 Z" id="Combined-Shape" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>resolution</title>
<g id="resolution" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M17.7222222,2.5 L17.7222222,17.7222222 L2.5,17.7222222 L2.5,2.5 L17.7222222,2.5 Z M16.721,4.45 L3.499,4.45 L3.499,10.111 L10.1293705,10.1111111 L10.129,16.722 L16.722,16.722 L16.721,4.45 Z M9.128,11.722 L3.999,11.722 L4,16.222 L9.129,16.222 L9.128,11.722 Z" id="Combined-Shape" fill="#FFFFFF" fill-rule="nonzero"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 654 B

@@ -15,4 +15,9 @@
<file alias="download.svg">Notifications/download.svg</file>
<file alias="link.svg">Notifications/link.svg</file>
</qresource>
<qresource prefix="/Menu">
<file alias="resolution.svg">Menu/resolution.svg</file>
<file alias="debug.svg">Menu/debug.svg</file>
<file alias="camera.svg">Menu/camera.svg</file>
</qresource>
</RCC>
@@ -42,6 +42,9 @@ namespace AzToolsFramework
bool detachedWindow = false; ///< set to true if the view pane should use a detached, non-dockable widget. This is to workaround a problem with QOpenGLWidget on macOS. Currently this has no effect on other platforms.
bool isDisabledInSimMode = false; ///< set to true if the view pane should not be openable from level editor menu when editor is in simulation mode.
bool showOnToolsToolbar = false; ///< set to true if the view pane should create a button on the tools toolbar to open/close the pane
QString toolbarIcon; ///< path to the icon to use for the toolbar button - only used if showOnToolsToolbar is set to true
};
} // namespace AzToolsFramework
@@ -1,13 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "AzToolsFramework_precompiled.h"
@@ -197,7 +197,7 @@ namespace AzToolsFramework
AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder) override;
Prefab::InstanceOptionalReference GetRootPrefabInstance() override;
const AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& GetPlayInEditorAssetData() override;
//////////////////////////////////////////////////////////////////////////
@@ -1,28 +1,32 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "AngularManipulator.h"
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
#include <AzToolsFramework/Manipulators/ManipulatorView.h>
#include <AzToolsFramework/Manipulators/ManipulatorSnapping.h>
#include <AzToolsFramework/Manipulators/ManipulatorView.h>
namespace AzToolsFramework
{
static const float s_circularRotateThresholdDegrees = 80.0f;
static const float CircularRotateThresholdDegrees = 80.0f;
AngularManipulator::ActionInternal AngularManipulator::CalculateManipulationDataStart(
const Fixed& fixed, const AZ::Transform& worldFromLocal, const AZ::Transform& localTransform,
const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection, const float rayDistance)
const Fixed& fixed,
const AZ::Transform& worldFromLocal,
const AZ::Transform& localTransform,
const AZ::Vector3& rayOrigin,
const AZ::Vector3& rayDirection,
const float rayDistance)
{
const AZ::Transform worldFromLocalWithTransform = worldFromLocal * localTransform;
const AZ::Vector3 worldAxis = TransformDirectionNoScaling(worldFromLocalWithTransform, fixed.m_axis);
@@ -35,7 +39,7 @@ namespace AzToolsFramework
// if angular manipulator axis is at right angles to us, use initial ray direction
// as plane normal and use hit position on manipulator as plane point
const float pickAngle = AZ::RadToDeg(AZ::Acos(AZ::Abs(rayDirection.Dot(worldAxis))));
if (pickAngle > s_circularRotateThresholdDegrees)
if (pickAngle > CircularRotateThresholdDegrees)
{
actionInternal.m_start.m_planeNormal = -rayDirection;
actionInternal.m_start.m_planePoint = rayOrigin + rayDirection * rayDistance;
@@ -43,8 +47,8 @@ namespace AzToolsFramework
// store initial world hit position
Internal::CalculateRayPlaneIntersectingPoint(
rayOrigin, rayDirection, actionInternal.m_start.m_planePoint,
actionInternal.m_start.m_planeNormal, actionInternal.m_current.m_worldHitPosition);
rayOrigin, rayDirection, actionInternal.m_start.m_planePoint, actionInternal.m_start.m_planeNormal,
actionInternal.m_current.m_worldHitPosition);
// store entity transform (to go from local to world space)
// and store our own starting local transform
@@ -56,31 +60,33 @@ namespace AzToolsFramework
}
AngularManipulator::Action AngularManipulator::CalculateManipulationDataAction(
const Fixed& fixed, ActionInternal& actionInternal, const AZ::Transform& worldFromLocal,
const AZ::Transform& localTransform, const bool snapping, const float angleStepDegrees,
const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection,
const Fixed& fixed,
ActionInternal& actionInternal,
const AZ::Transform& worldFromLocal,
const AZ::Transform& localTransform,
const bool snapping,
const float angleStepDegrees,
const AZ::Vector3& rayOrigin,
const AZ::Vector3& rayDirection,
const ViewportInteraction::KeyboardModifiers keyboardModifiers)
{
const AZ::Transform worldFromLocalWithTransform = worldFromLocal * localTransform;
const AZ::Vector3 worldAxis = TransformDirectionNoScaling(worldFromLocalWithTransform, fixed.m_axis);
AZ::Vector3 worldHitPosition = AZ::Vector3::CreateZero();
Internal::CalculateRayPlaneIntersectingPoint(rayOrigin, rayDirection,
actionInternal.m_start.m_planePoint, actionInternal.m_start.m_planeNormal,
worldHitPosition);
Internal::CalculateRayPlaneIntersectingPoint(
rayOrigin, rayDirection, actionInternal.m_start.m_planePoint, actionInternal.m_start.m_planeNormal, worldHitPosition);
// get vector from center of rotation for current and previous frame
const AZ::Vector3 center = worldFromLocalWithTransform.GetTranslation();
const AZ::Vector3 currentWorldHitVector = (worldHitPosition - center).GetNormalizedSafe();
const AZ::Vector3 previousWorldHitVector =
(actionInternal.m_current.m_worldHitPosition - center).GetNormalizedSafe();
const AZ::Vector3 previousWorldHitVector = (actionInternal.m_current.m_worldHitPosition - center).GetNormalizedSafe();
// calculate which direction we rotated
const AZ::Vector3 worldAxisRight = worldAxis.Cross(previousWorldHitVector);
const float rotateSign = Sign(currentWorldHitVector.Dot(worldAxisRight));
// how far did we rotate this frame
const float rotationAngleRad = AZ::Acos(AZ::GetMin<float>(
1.0f, currentWorldHitVector.Dot(previousWorldHitVector)));
const float rotationAngleRad = AZ::Acos(AZ::GetMin<float>(1.0f, currentWorldHitVector.Dot(previousWorldHitVector)));
actionInternal.m_current.m_worldHitPosition = worldHitPosition;
// if we're snapping, only increment current radians when we know
@@ -148,16 +154,13 @@ namespace AzToolsFramework
// calculate initial state when mouse press first happens
m_actionInternal = CalculateManipulationDataStart(
m_fixed, TransformNormalizedScale(GetSpace()), TransformNormalizedScale(GetLocalTransform()),
interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection,
rayIntersectionDistance);
interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection, rayIntersectionDistance);
if (m_onLeftMouseDownCallback)
{
m_onLeftMouseDownCallback(CalculateManipulationDataAction(
m_fixed, m_actionInternal, m_actionInternal.m_start.m_worldFromLocal,
m_actionInternal.m_start.m_localTransform, snapping, angleStep,
interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection,
interaction.m_keyboardModifiers));
m_fixed, m_actionInternal, m_actionInternal.m_start.m_worldFromLocal, m_actionInternal.m_start.m_localTransform, snapping,
angleStep, interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection, interaction.m_keyboardModifiers));
}
}
@@ -167,12 +170,9 @@ namespace AzToolsFramework
{
// calculate delta rotation
m_onMouseMoveCallback(CalculateManipulationDataAction(
m_fixed, m_actionInternal, m_actionInternal.m_start.m_worldFromLocal,
m_actionInternal.m_start.m_localTransform,
AngleSnapping(interaction.m_interactionId.m_viewportId),
AngleStep(interaction.m_interactionId.m_viewportId),
interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection,
interaction.m_keyboardModifiers));
m_fixed, m_actionInternal, m_actionInternal.m_start.m_worldFromLocal, m_actionInternal.m_start.m_localTransform,
AngleSnapping(interaction.m_interactionId.m_viewportId), AngleStep(interaction.m_interactionId.m_viewportId),
interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection, interaction.m_keyboardModifiers));
}
}
@@ -181,12 +181,9 @@ namespace AzToolsFramework
if (m_onLeftMouseUpCallback)
{
m_onLeftMouseUpCallback(CalculateManipulationDataAction(
m_fixed, m_actionInternal, m_actionInternal.m_start.m_worldFromLocal,
m_actionInternal.m_start.m_localTransform,
AngleSnapping(interaction.m_interactionId.m_viewportId),
AngleStep(interaction.m_interactionId.m_viewportId),
interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection,
interaction.m_keyboardModifiers));
m_fixed, m_actionInternal, m_actionInternal.m_start.m_worldFromLocal, m_actionInternal.m_start.m_localTransform,
AngleSnapping(interaction.m_interactionId.m_viewportId), AngleStep(interaction.m_interactionId.m_viewportId),
interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection, interaction.m_keyboardModifiers));
}
}
@@ -197,12 +194,9 @@ namespace AzToolsFramework
const ViewportInteraction::MouseInteraction& mouseInteraction)
{
m_manipulatorView->Draw(
GetManipulatorManagerId(), managerState,
GetManipulatorId(), {
ApplySpace(GetLocalTransform()), GetNonUniformScale(),
AZ::Vector3::CreateZero(), MouseOver()
},
debugDisplay, cameraState, mouseInteraction);
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay, cameraState,
mouseInteraction);
}
void AngularManipulator::SetAxis(const AZ::Vector3& axis)
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -22,14 +22,14 @@ namespace AzToolsFramework
{
class ManipulatorView;
/// AngularManipulator serves as a visual tool for users to change a component's property based on rotation
/// around an axis. The rotation angle increases if the rotation goes counter clock-wise when looking
/// in the opposite direction the rotation axis points to.
//! AngularManipulator serves as a visual tool for users to change a component's property based on rotation
//! around an axis. The rotation angle increases if the rotation goes counter clock-wise when looking
//! in the opposite direction the rotation axis points to.
class AngularManipulator
: public BaseManipulator
, public ManipulatorSpaceWithLocalTransform
{
/// Private constructor.
//! Private constructor.
explicit AngularManipulator(const AZ::Transform& worldFromLocal);
public:
@@ -42,33 +42,36 @@ namespace AzToolsFramework
~AngularManipulator() = default;
/// A Manipulator must only be created and managed through a shared_ptr.
//! A Manipulator must only be created and managed through a shared_ptr.
static AZStd::shared_ptr<AngularManipulator> MakeShared(const AZ::Transform& worldFromLocal);
/// The state of the manipulator at the start of an interaction.
//! The state of the manipulator at the start of an interaction.
struct Start
{
AZ::Quaternion m_space; ///< Starting orientation space of manipulator.
AZ::Quaternion m_rotation; ///< Starting local rotation of the manipulator.
AZ::Quaternion m_space; //!< Starting orientation space of manipulator.
AZ::Quaternion m_rotation; //!< Starting local rotation of the manipulator.
};
/// The state of the manipulator during an interaction.
//! The state of the manipulator during an interaction.
struct Current
{
AZ::Quaternion m_delta; ///< Amount of rotation to apply to manipulator during action.
AZ::Quaternion m_delta; //!< Amount of rotation to apply to manipulator during action.
};
/// Mouse action data used by MouseActionCallback (wraps Start and Current manipulator state).
//! Mouse action data used by MouseActionCallback (wraps Start and Current manipulator state).
struct Action
{
Start m_start;
Current m_current;
ViewportInteraction::KeyboardModifiers m_modifiers;
AZ::Quaternion LocalOrientation() const { return m_start.m_rotation * m_current.m_delta; }
AZ::Quaternion LocalOrientation() const
{
return m_start.m_rotation * m_current.m_delta;
}
};
/// This is the function signature of callbacks that will be invoked whenever a manipulator
/// is clicked on or dragged.
//! This is the function signature of callbacks that will be invoked whenever a manipulator
//! is clicked on or dragged.
using MouseActionCallback = AZStd::function<void(const Action&)>;
void InstallLeftMouseDownCallback(const MouseActionCallback& onMouseDownCallback);
@@ -82,46 +85,49 @@ namespace AzToolsFramework
const ViewportInteraction::MouseInteraction& mouseInteraction) override;
void SetAxis(const AZ::Vector3& axis);
const AZ::Vector3& GetAxis() const { return m_fixed.m_axis; }
const AZ::Vector3& GetAxis() const
{
return m_fixed.m_axis;
}
void SetView(AZStd::unique_ptr<ManipulatorView>&& view);
ManipulatorView* GetView() const { return m_manipulatorView.get(); }
ManipulatorView* GetView() const
{
return m_manipulatorView.get();
}
private:
void OnLeftMouseDownImpl(
const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override;
void OnLeftMouseUpImpl(
const ViewportInteraction::MouseInteraction& interaction) override;
void OnMouseMoveImpl(
const ViewportInteraction::MouseInteraction& interaction) override;
void OnLeftMouseDownImpl(const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override;
void OnLeftMouseUpImpl(const ViewportInteraction::MouseInteraction& interaction) override;
void OnMouseMoveImpl(const ViewportInteraction::MouseInteraction& interaction) override;
void SetBoundsDirtyImpl() override;
void InvalidateImpl() override;
/// Unchanging data set once for the angular manipulator.
//! Unchanging data set once for the angular manipulator.
struct Fixed
{
AZ::Vector3 m_axis = AZ::Vector3::CreateAxisX(); ///< Axis for this angular manipulator to rotate around.
AZ::Vector3 m_axis = AZ::Vector3::CreateAxisX(); //!< Axis for this angular manipulator to rotate around.
};
/// Initial data recorded when a press first happens with an angular manipulator.
//! Initial data recorded when a press first happens with an angular manipulator.
struct StartInternal
{
AZ::Transform m_worldFromLocal; ///< Initial transform when pressed.
AZ::Transform m_localTransform; ///< Additional transform (offset) to apply to manipulator.
AZ::Vector3 m_planePoint; ///< Position on plane to use for ray intersection.
AZ::Vector3 m_planeNormal; ///< Normal of plane to use for ray intersection.
AZ::Transform m_worldFromLocal; //!< Initial transform when pressed.
AZ::Transform m_localTransform; //!< Additional transform (offset) to apply to manipulator.
AZ::Vector3 m_planePoint; //!< Position on plane to use for ray intersection.
AZ::Vector3 m_planeNormal; //!< Normal of plane to use for ray intersection.
};
/// Current data recorded each frame during an interaction with an angular manipulator.
//! Current data recorded each frame during an interaction with an angular manipulator.
struct CurrentInternal
{
float m_preSnapRadians = 0.0f; ///< Amount of rotation before a snap (snap increment accumulator).
float m_radians = 0.0f; ///< Amount of rotation about the axis for this action.
AZ::Vector3 m_worldHitPosition; ///< Initial world space hit position.
float m_preSnapRadians = 0.0f; //!< Amount of rotation before a snap (snap increment accumulator).
float m_radians = 0.0f; //!< Amount of rotation about the axis for this action.
AZ::Vector3 m_worldHitPosition; //!< Initial world space hit position.
};
/// Wrap start and current internal data during an interaction with an angular manipulator.
//! Wrap start and current internal data during an interaction with an angular manipulator.
struct ActionInternal
{
StartInternal m_start;
@@ -135,16 +141,25 @@ namespace AzToolsFramework
MouseActionCallback m_onLeftMouseUpCallback = nullptr;
MouseActionCallback m_onMouseMoveCallback = nullptr;
AZStd::unique_ptr<ManipulatorView> m_manipulatorView; ///< Look of manipulator.
AZStd::unique_ptr<ManipulatorView> m_manipulatorView; //!< Look of manipulator.
static ActionInternal CalculateManipulationDataStart(
const Fixed& fixed, const AZ::Transform& worldFromLocal, const AZ::Transform& localTransform,
const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection, float rayDistance);
const Fixed& fixed,
const AZ::Transform& worldFromLocal,
const AZ::Transform& localTransform,
const AZ::Vector3& rayOrigin,
const AZ::Vector3& rayDirection,
float rayDistance);
static Action CalculateManipulationDataAction(
const Fixed& fixed, ActionInternal& actionInternal, const AZ::Transform& worldFromLocal,
const AZ::Transform& localTransform, bool snapping, float angleStepDegrees,
const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection,
const Fixed& fixed,
ActionInternal& actionInternal,
const AZ::Transform& worldFromLocal,
const AZ::Transform& localTransform,
bool snapping,
float angleStepDegrees,
const AZ::Vector3& rayOrigin,
const AZ::Vector3& rayDirection,
ViewportInteraction::KeyboardModifiers keyboardModifiers);
};
} // namespace AzToolsFramework
@@ -1,33 +1,30 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "BaseManipulator.h"
#include <AzCore/Math/IntersectSegment.h>
#include <AzToolsFramework/Viewport/ViewportMessages.h>
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
#include <AzToolsFramework/Viewport/ViewportMessages.h>
namespace AzToolsFramework
{
AZ_CVAR(
bool, cl_manipulatorDrawDebug, false, nullptr, AZ::ConsoleFunctorFlags::Null,
"Enable debug drawing for Manipulators");
AZ_CVAR(bool, cl_manipulatorDrawDebug, false, nullptr, AZ::ConsoleFunctorFlags::Null, "Enable debug drawing for Manipulators");
const AZ::Color BaseManipulator::s_defaultMouseOverColor = AZ::Color(1.0f, 1.0f, 0.0f, 1.0f); // yellow
AZ_CLASS_ALLOCATOR_IMPL(BaseManipulator, AZ::SystemAllocator, 0)
static bool EntityIdAndEntityComponentIdComparison(
const AZ::EntityId entityId, const AZ::EntityComponentIdPair& entityComponentId)
static bool EntityIdAndEntityComponentIdComparison(const AZ::EntityId entityId, const AZ::EntityComponentIdPair& entityComponentId)
{
return entityId == entityComponentId.GetEntityId();
}
@@ -38,8 +35,7 @@ namespace AzToolsFramework
EndUndoBatch();
}
bool BaseManipulator::OnLeftMouseDown(
const ViewportInteraction::MouseInteraction& interaction, const float rayIntersectionDistance)
bool BaseManipulator::OnLeftMouseDown(const ViewportInteraction::MouseInteraction& interaction, const float rayIntersectionDistance)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
@@ -57,8 +53,7 @@ namespace AzToolsFramework
(*this.*m_onLeftMouseDownImpl)(interaction, rayIntersectionDistance);
ToolsApplicationNotificationBus::Broadcast(
&ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_Values);
ToolsApplicationNotificationBus::Broadcast(&ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_Values);
return true;
}
@@ -66,8 +61,7 @@ namespace AzToolsFramework
return false;
}
bool BaseManipulator::OnRightMouseDown(
const ViewportInteraction::MouseInteraction& interaction, const float rayIntersectionDistance)
bool BaseManipulator::OnRightMouseDown(const ViewportInteraction::MouseInteraction& interaction, const float rayIntersectionDistance)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
@@ -85,8 +79,7 @@ namespace AzToolsFramework
(*this.*m_onRightMouseDownImpl)(interaction, rayIntersectionDistance);
ToolsApplicationNotificationBus::Broadcast(
&ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_Values);
ToolsApplicationNotificationBus::Broadcast(&ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_Values);
return true;
}
@@ -118,8 +111,7 @@ namespace AzToolsFramework
EndUndoBatch();
}
bool BaseManipulator::OnMouseOver(
const ManipulatorId manipulatorId, const ViewportInteraction::MouseInteraction& interaction)
bool BaseManipulator::OnMouseOver(const ManipulatorId manipulatorId, const ViewportInteraction::MouseInteraction& interaction)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
@@ -132,8 +124,7 @@ namespace AzToolsFramework
{
OnMouseWheelImpl(interaction);
ToolsApplicationNotificationBus::Broadcast(
&ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_Values);
ToolsApplicationNotificationBus::Broadcast(&ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_Values);
}
void BaseManipulator::OnMouseMove(const ViewportInteraction::MouseInteraction& interaction)
@@ -142,16 +133,13 @@ namespace AzToolsFramework
if (!m_performingAction)
{
AZ_Warning(
"Manipulators", false,
"MouseMove action received, but this manipulator is not performing an action");
AZ_Warning("Manipulators", false, "MouseMove action received, but this manipulator is not performing an action");
return;
}
// ensure property grid (entity inspector) values are refreshed
ToolsApplicationNotificationBus::Broadcast(
&ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_Values);
ToolsApplicationNotificationBus::Broadcast(&ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_Values);
OnMouseMoveImpl(interaction);
}
@@ -170,16 +158,14 @@ namespace AzToolsFramework
Unregister();
}
ManipulatorManagerRequestBus::Event(managerId,
&ManipulatorManagerRequestBus::Events::RegisterManipulator, shared_from_this());
ManipulatorManagerRequestBus::Event(managerId, &ManipulatorManagerRequestBus::Events::RegisterManipulator, shared_from_this());
}
void BaseManipulator::Unregister()
{
// if the manipulator has already been unregistered, the m_manipulatorManagerId
// should be invalid which makes the call below a no-op.
ManipulatorManagerRequestBus::Event(m_manipulatorManagerId,
&ManipulatorManagerRequestBus::Events::UnregisterManipulator, this);
ManipulatorManagerRequestBus::Event(m_manipulatorManagerId, &ManipulatorManagerRequestBus::Events::UnregisterManipulator, this);
}
void BaseManipulator::Invalidate()
@@ -197,8 +183,7 @@ namespace AzToolsFramework
if (m_performingAction)
{
AZ_Warning(
"Manipulators", false,
"MouseDown action received, but the manipulator (id: %d) is still performing an action",
"Manipulators", false, "MouseDown action received, but the manipulator (id: %d) is still performing an action",
GetManipulatorId());
return;
@@ -214,8 +199,7 @@ namespace AzToolsFramework
if (!m_performingAction)
{
AZ_Warning(
"Manipulators", false,
"MouseUp action received, but this manipulator (id: %d) didn't receive MouseDown action before",
"Manipulators", false, "MouseUp action received, but this manipulator (id: %d) didn't receive MouseDown action before",
GetManipulatorId());
return;
}
@@ -263,13 +247,13 @@ namespace AzToolsFramework
if (entityComponentIdPair.GetComponentId() != AZ::InvalidComponentId)
{
PropertyEditorEntityChangeNotificationBus::Event(
entityComponentIdPair.GetEntityId(),
&PropertyEditorEntityChangeNotifications::OnEntityComponentPropertyChanged,
entityComponentIdPair.GetEntityId(), &PropertyEditorEntityChangeNotifications::OnEntityComponentPropertyChanged,
entityComponentIdPair.GetComponentId());
}
else
{
AZ_Warning("Manipulators", false,
AZ_Warning(
"Manipulators", false,
"This Manipulator was only registered with an EntityId and not an EntityComponentIdPair. "
"Please use AddEntityComponentIdPair() instead of AddEntityId() when registering what this "
"Manipulator is changing.");
@@ -280,8 +264,7 @@ namespace AzToolsFramework
for (const AZ::Component* component : entity->GetComponents())
{
PropertyEditorEntityChangeNotificationBus::Event(
entity->GetId(), &PropertyEditorEntityChangeNotifications::OnEntityComponentPropertyChanged,
component->GetId());
entity->GetId(), &PropertyEditorEntityChangeNotifications::OnEntityComponentPropertyChanged, component->GetId());
}
}
}
@@ -298,9 +281,7 @@ namespace AzToolsFramework
{
// look for a match (keep looking in case we have several entity ids with different component ids)
const auto entityComponentPairId =
m_entityComponentIdPairs.find_as(
entityId, AZStd::hash<AZ::EntityId>(),
&EntityIdAndEntityComponentIdComparison);
m_entityComponentIdPairs.find_as(entityId, AZStd::hash<AZ::EntityId>(), &EntityIdAndEntityComponentIdComparison);
// update the afterErased variable so we can return an iterator
// to the correct position in the container.
@@ -334,9 +315,8 @@ namespace AzToolsFramework
bool BaseManipulator::HasEntityId(const AZ::EntityId entityId) const
{
return m_entityComponentIdPairs.find_as(
entityId, AZStd::hash<AZ::EntityId>(),
&EntityIdAndEntityComponentIdComparison) != m_entityComponentIdPairs.end();
return m_entityComponentIdPairs.find_as(entityId, AZStd::hash<AZ::EntityId>(), &EntityIdAndEntityComponentIdComparison) !=
m_entityComponentIdPairs.end();
}
bool BaseManipulator::HasEntityComponentIdPair(const AZ::EntityComponentIdPair& entityComponentIdPair) const
@@ -346,7 +326,8 @@ namespace AzToolsFramework
void Manipulators::Register(const ManipulatorManagerId manipulatorManagerId)
{
ProcessManipulators([manipulatorManagerId](BaseManipulator* manipulator)
ProcessManipulators(
[manipulatorManagerId](BaseManipulator* manipulator)
{
manipulator->Register(manipulatorManagerId);
});
@@ -354,7 +335,8 @@ namespace AzToolsFramework
void Manipulators::Unregister()
{
ProcessManipulators([](BaseManipulator* manipulator)
ProcessManipulators(
[](BaseManipulator* manipulator)
{
if (manipulator->Registered())
{
@@ -365,7 +347,8 @@ namespace AzToolsFramework
void Manipulators::SetBoundsDirty()
{
ProcessManipulators([](BaseManipulator* manipulator)
ProcessManipulators(
[](BaseManipulator* manipulator)
{
manipulator->SetBoundsDirty();
});
@@ -373,7 +356,8 @@ namespace AzToolsFramework
void Manipulators::AddEntityComponentIdPair(const AZ::EntityComponentIdPair& entityComponentIdPair)
{
ProcessManipulators([&entityComponentIdPair](BaseManipulator* manipulator)
ProcessManipulators(
[&entityComponentIdPair](BaseManipulator* manipulator)
{
manipulator->AddEntityComponentIdPair(entityComponentIdPair);
});
@@ -381,7 +365,8 @@ namespace AzToolsFramework
void Manipulators::RemoveEntityComponentIdPair(const AZ::EntityComponentIdPair& entityComponentIdPair)
{
ProcessManipulators([&entityComponentIdPair](BaseManipulator* manipulator)
ProcessManipulators(
[&entityComponentIdPair](BaseManipulator* manipulator)
{
manipulator->RemoveEntityComponentIdPair(entityComponentIdPair);
});
@@ -389,7 +374,8 @@ namespace AzToolsFramework
void Manipulators::RemoveEntityId(const AZ::EntityId entityId)
{
ProcessManipulators([entityId](BaseManipulator* manipulator)
ProcessManipulators(
[entityId](BaseManipulator* manipulator)
{
manipulator->RemoveEntityId(entityId);
});
@@ -398,7 +384,8 @@ namespace AzToolsFramework
bool Manipulators::PerformingAction()
{
bool performingAction = false;
ProcessManipulators([&performingAction](BaseManipulator* manipulator)
ProcessManipulators(
[&performingAction](BaseManipulator* manipulator)
{
if (manipulator->PerformingAction())
{
@@ -412,7 +399,8 @@ namespace AzToolsFramework
bool Manipulators::Registered()
{
bool registered = false;
ProcessManipulators([&registered](BaseManipulator* manipulator)
ProcessManipulators(
[&registered](BaseManipulator* manipulator)
{
if (manipulator->Registered())
{
@@ -470,8 +458,12 @@ namespace AzToolsFramework
namespace Internal
{
bool CalculateRayPlaneIntersectingPoint(const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection,
const AZ::Vector3& pointOnPlane, const AZ::Vector3& planeNormal, AZ::Vector3& resultIntersectingPoint)
bool CalculateRayPlaneIntersectingPoint(
const AZ::Vector3& rayOrigin,
const AZ::Vector3& rayDirection,
const AZ::Vector3& pointOnPlane,
const AZ::Vector3& planeNormal,
AZ::Vector3& resultIntersectingPoint)
{
float t = 0.0f;
if (AZ::Intersect::IntersectRayPlane(rayOrigin, rayDirection, pointOnPlane, planeNormal, t) > 0)
@@ -484,11 +476,12 @@ namespace AzToolsFramework
}
AZ::Vector3 TryConstrainHitPositionToView(
const AZ::Vector3& currentLocalHitPosition, const AZ::Vector3& startLocalHitPosition,
const AZ::Transform& localFromWorld, const AzFramework::CameraState& cameraState)
const AZ::Vector3& currentLocalHitPosition,
const AZ::Vector3& startLocalHitPosition,
const AZ::Transform& localFromWorld,
const AzFramework::CameraState& cameraState)
{
if (currentLocalHitPosition.GetDistance(localFromWorld.TransformPoint(cameraState.m_position))
> cameraState.m_farClip)
if (currentLocalHitPosition.GetDistance(localFromWorld.TransformPoint(cameraState.m_position)) > cameraState.m_farClip)
{
return startLocalHitPosition;
}
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -22,13 +22,13 @@
#include <AzCore/std/containers/set.h>
#include <AzCore/std/smart_ptr/enable_shared_from_this.h>
#include <AzToolsFramework/Manipulators/ManipulatorBus.h>
#include "ManipulatorSpace.h"
#include <AzToolsFramework/Manipulators/ManipulatorSpace.h>
namespace AzFramework
{
struct CameraState;
class DebugDisplayRequests;
}
} // namespace AzFramework
namespace AzToolsFramework
{
@@ -46,9 +46,8 @@ namespace AzToolsFramework
struct ManipulatorManagerState;
/// The base class for manipulators, providing interfaces for users of manipulators to talk to.
class BaseManipulator
: public AZStd::enable_shared_from_this<BaseManipulator>
//! The base class for manipulators, providing interfaces for users of manipulators to talk to.
class BaseManipulator : public AZStd::enable_shared_from_this<BaseManipulator>
{
public:
AZ_CLASS_ALLOCATOR_DECL
@@ -61,139 +60,181 @@ namespace AzToolsFramework
using EntityComponentIds = AZStd::unordered_set<AZ::EntityComponentIdPair>;
/// Callback for the event when the mouse pointer is over this manipulator and the left mouse button is pressed.
/// @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera through the mouse pointer.
/// @param rayIntersectionDistance The parameter value in the ray's explicit equation that represents the intersecting point on the target manipulator in world space.
/// @return Return true if OnLeftMouseDownImpl was attached and will be used.
//! Callback for the event when the mouse pointer is over this manipulator and the left mouse button is pressed.
//! @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera
//! through the mouse pointer.
//! @param rayIntersectionDistance The parameter value in the ray's explicit equation that represents the intersecting point on the
//! target manipulator in world space.
//! @return Return true if OnLeftMouseDownImpl was attached and will be used.
bool OnLeftMouseDown(const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance);
/// Callback for the event when this manipulator is active and the left mouse button is released.
/// @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera through the mouse pointer.
//! Callback for the event when this manipulator is active and the left mouse button is released.
//! @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera
//! through the mouse pointer.
void OnLeftMouseUp(const ViewportInteraction::MouseInteraction& interaction);
/// Callback for the event when the mouse pointer is over this manipulator and the right mouse button is pressed .
/// @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera through the mouse pointer.
/// @param rayIntersectionDistance The parameter value in the ray's explicit equation that represents the intersecting point on the target manipulator in world space.
/// @return Return true if OnRightMouseDownImpl was attached and will be used.
//! Callback for the event when the mouse pointer is over this manipulator and the right mouse button is pressed .
//! @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera
//! through the mouse pointer.
//! @param rayIntersectionDistance The parameter value in the ray's explicit equation that represents the intersecting point on the
//! target manipulator in world space.
//! @return Return true if OnRightMouseDownImpl was attached and will be used.
bool OnRightMouseDown(const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance);
/// Callback for the event when this manipulator is active and the right mouse button is released.
/// @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera through the mouse pointer.
//! Callback for the event when this manipulator is active and the right mouse button is released.
//! @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera
//! through the mouse pointer.
void OnRightMouseUp(const ViewportInteraction::MouseInteraction& interaction);
/// Callback for the event when this manipulator is active and the mouse is moved.
/// @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera through the mouse pointer.
//! Callback for the event when this manipulator is active and the mouse is moved.
//! @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera
//! through the mouse pointer.
void OnMouseMove(const ViewportInteraction::MouseInteraction& interaction);
/// Callback for the event when this manipulator is active and the mouse wheel is scrolled.
/// @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera through the mouse pointer.
//! Callback for the event when this manipulator is active and the mouse wheel is scrolled.
//! @param interaction It contains various mouse states when the event happens, as well as a ray shooting from the viewing camera
//! through the mouse pointer.
void OnMouseWheel(const ViewportInteraction::MouseInteraction& interaction);
/// This function changes the state indicating whether the manipulator is under the mouse pointer.
/// It is called in the event of OnMouseMove and OnMouseWheel only when there is no manipulator currently performing actions.
//! This function changes the state indicating whether the manipulator is under the mouse pointer.
//! It is called in the event of OnMouseMove and OnMouseWheel only when there is no manipulator currently performing actions.
bool OnMouseOver(ManipulatorId manipulatorId, const ViewportInteraction::MouseInteraction& interaction);
/// Register itself to a manipulator manager so that it can receive various mouse events and perform manipulations.
/// @param managerId The id identifying a unique manipulator manager.
//! Register itself to a manipulator manager so that it can receive various mouse events and perform manipulations.
//! @param managerId The id identifying a unique manipulator manager.
void Register(ManipulatorManagerId managerId);
/// Unregister itself from the manipulator manager it was registered with.
//! Unregister itself from the manipulator manager it was registered with.
void Unregister();
/// Bounds will need to be recalculated next time we render.
//! Bounds will need to be recalculated next time we render.
void SetBoundsDirty();
/// Is this manipulator currently registered with a manipulator manager.
//! Is this manipulator currently registered with a manipulator manager.
bool Registered() const
{
return m_manipulatorId != InvalidManipulatorId &&
m_manipulatorManagerId != InvalidManipulatorManagerId;
return m_manipulatorId != InvalidManipulatorId && m_manipulatorManagerId != InvalidManipulatorManagerId;
}
/// Is the manipulator in the middle of an action (between mouse down and mouse up).
bool PerformingAction() const { return m_performingAction; }
//! Is the manipulator in the middle of an action (between mouse down and mouse up).
bool PerformingAction() const
{
return m_performingAction;
}
/// Is the mouse currently over the manipulator (intersecting manipulator bound).
bool MouseOver() const { return m_mouseOver; }
//! Is the mouse currently over the manipulator (intersecting manipulator bound).
bool MouseOver() const
{
return m_mouseOver;
}
/// The unique id of this manipulator.
ManipulatorId GetManipulatorId() const { return m_manipulatorId; }
//! The unique id of this manipulator.
ManipulatorId GetManipulatorId() const
{
return m_manipulatorId;
}
/// The unique id of the manager this manipulator was registered with.
ManipulatorManagerId GetManipulatorManagerId() const { return m_manipulatorManagerId; }
//! The unique id of the manager this manipulator was registered with.
ManipulatorManagerId GetManipulatorManagerId() const
{
return m_manipulatorManagerId;
}
/// Returns all EntityComponentIdPairs associated with this manipulator.
//! Returns all EntityComponentIdPairs associated with this manipulator.
const EntityComponentIds& EntityComponentIdPairs() const
{
return m_entityComponentIdPairs;
}
/// Add an entity and component the manipulator is responsible for.
//! Add an entity and component the manipulator is responsible for.
void AddEntityComponentIdPair(const AZ::EntityComponentIdPair& entityComponentIdPair);
/// Remove an entity from being affected by this manipulator.
/// @note All components on this entity registered with the manipulator will be removed.
//! Remove an entity from being affected by this manipulator.
//! @note All components on this entity registered with the manipulator will be removed.
EntityComponentIds::iterator RemoveEntityId(AZ::EntityId entityId);
/// Remove a specific component (via a EntityComponentIdPair) being affected by this manipulator.
//! Remove a specific component (via a EntityComponentIdPair) being affected by this manipulator.
EntityComponentIds::iterator RemoveEntityComponentIdPair(const AZ::EntityComponentIdPair& entityComponentIdPair);
/// Is this entity currently being tracked by this manipulator.
//! Is this entity currently being tracked by this manipulator.
bool HasEntityId(AZ::EntityId entityId) const;
/// Is this entity component pair currently being tracked by this manipulator.
//! Is this entity component pair currently being tracked by this manipulator.
bool HasEntityComponentIdPair(const AZ::EntityComponentIdPair& entityComponentIdPair) const;
/// Forward a mouse over event in a case where we need the manipulator to immediately refresh.
/// @note Only call this when a mouse over event has just happened.
//! Forward a mouse over event in a case where we need the manipulator to immediately refresh.
//! @note Only call this when a mouse over event has just happened.
void ForwardMouseOverEvent(const ViewportInteraction::MouseInteraction& interaction);
static const AZ::Color s_defaultMouseOverColor;
protected:
/// Protected constructor.
//! Protected constructor.
BaseManipulator() = default;
/// Called when unregistering - users of manipulators should not call it directly.
//! Called when unregistering - users of manipulators should not call it directly.
void Invalidate();
/// The implementation to override in a derived class for Invalidate.
virtual void InvalidateImpl() {}
//! The implementation to override in a derived class for Invalidate.
virtual void InvalidateImpl()
{
}
/// The implementation to override in a derived class for OnLeftMouseDown.
/// Note: When implementing this function you must also call AttachLeftMouseDownImpl to ensure
/// m_onLeftMouseDownImpl is set to OnLeftMouseDownImpl, otherwise it will not be called
virtual void OnLeftMouseDownImpl(
const ViewportInteraction::MouseInteraction& /*interaction*/, float /*rayIntersectionDistance*/) {}
void AttachLeftMouseDownImpl() { m_onLeftMouseDownImpl = &BaseManipulator::OnLeftMouseDownImpl; }
//! The implementation to override in a derived class for OnLeftMouseDown.
//! Note: When implementing this function you must also call AttachLeftMouseDownImpl to ensure
//! m_onLeftMouseDownImpl is set to OnLeftMouseDownImpl, otherwise it will not be called
virtual void OnLeftMouseDownImpl(const ViewportInteraction::MouseInteraction& /*interaction*/, float /*rayIntersectionDistance*/)
{
}
/// The implementation to override in a derived class for OnRightMouseDown.
/// Note: When implementing this function you must also call AttachRightMouseDownImpl to ensure
/// m_onRightMouseDownImpl is set to OnRightMouseDownImpl, otherwise it will not be called
virtual void OnRightMouseDownImpl(
const ViewportInteraction::MouseInteraction& /*interaction*/, float /*rayIntersectionDistance*/) {}
void AttachRightMouseDownImpl() { m_onRightMouseDownImpl = &BaseManipulator::OnRightMouseDownImpl; }
void AttachLeftMouseDownImpl()
{
m_onLeftMouseDownImpl = &BaseManipulator::OnLeftMouseDownImpl;
}
/// The implementation to override in a derived class for OnLeftMouseUp.
virtual void OnLeftMouseUpImpl(const ViewportInteraction::MouseInteraction& /*interaction*/) {}
//! The implementation to override in a derived class for OnRightMouseDown.
//! Note: When implementing this function you must also call AttachRightMouseDownImpl to ensure
//! m_onRightMouseDownImpl is set to OnRightMouseDownImpl, otherwise it will not be called
virtual void OnRightMouseDownImpl(const ViewportInteraction::MouseInteraction& /*interaction*/, float /*rayIntersectionDistance*/)
{
}
/// The implementation to override in a derived class for OnRightMouseUp.
virtual void OnRightMouseUpImpl(const ViewportInteraction::MouseInteraction& /*interaction*/) {}
void AttachRightMouseDownImpl()
{
m_onRightMouseDownImpl = &BaseManipulator::OnRightMouseDownImpl;
}
/// The implementation to override in a derived class for OnMouseMove.
virtual void OnMouseMoveImpl(const ViewportInteraction::MouseInteraction& /*interaction*/) {}
//! The implementation to override in a derived class for OnLeftMouseUp.
virtual void OnLeftMouseUpImpl(const ViewportInteraction::MouseInteraction& /*interaction*/)
{
}
/// The implementation to override in a derived class for OnMouseOver.
virtual void OnMouseOverImpl(
ManipulatorId /*manipulatorId*/, const ViewportInteraction::MouseInteraction& /*interaction*/) {}
//! The implementation to override in a derived class for OnRightMouseUp.
virtual void OnRightMouseUpImpl(const ViewportInteraction::MouseInteraction& /*interaction*/)
{
}
/// The implementation to override in a derived class for OnMouseWheel.
virtual void OnMouseWheelImpl(const ViewportInteraction::MouseInteraction& /*interaction*/) {}
//! The implementation to override in a derived class for OnMouseMove.
virtual void OnMouseMoveImpl(const ViewportInteraction::MouseInteraction& /*interaction*/)
{
}
/// The implementation to override in a derived class for SetBoundsDirty.
virtual void SetBoundsDirtyImpl() {}
//! The implementation to override in a derived class for OnMouseOver.
virtual void OnMouseOverImpl(ManipulatorId /*manipulatorId*/, const ViewportInteraction::MouseInteraction& /*interaction*/)
{
}
/// Rendering for the manipulator - it is recommended drawing be delegated to a ManipulatorView.
//! The implementation to override in a derived class for OnMouseWheel.
virtual void OnMouseWheelImpl(const ViewportInteraction::MouseInteraction& /*interaction*/)
{
}
//! The implementation to override in a derived class for SetBoundsDirty.
virtual void SetBoundsDirtyImpl()
{
}
//! Rendering for the manipulator - it is recommended drawing be delegated to a ManipulatorView.
virtual void Draw(
const ManipulatorManagerState& managerState,
AzFramework::DebugDisplayRequests& debugDisplay,
@@ -202,39 +243,39 @@ namespace AzToolsFramework
private:
friend class ManipulatorManager;
AZStd::unordered_set<AZ::EntityComponentIdPair> m_entityComponentIdPairs; ///< The entities this manipulator is associated with.
AZStd::unordered_set<AZ::EntityComponentIdPair> m_entityComponentIdPairs; //!< The entities this manipulator is associated with.
ManipulatorId m_manipulatorId = InvalidManipulatorId; ///< The unique id of this manipulator.
ManipulatorManagerId m_manipulatorManagerId = InvalidManipulatorManagerId; ///< The manager this manipulator was registered with.
UndoSystem::URSequencePoint* m_undoBatch = nullptr; ///< Undo active while mouse is pressed.
bool m_performingAction = false; ///< After mouse down and before mouse up.
bool m_mouseOver = false; ///< Is the mouse pointer over the manipulator bound.
ManipulatorId m_manipulatorId = InvalidManipulatorId; //!< The unique id of this manipulator.
ManipulatorManagerId m_manipulatorManagerId = InvalidManipulatorManagerId; //!< The manager this manipulator was registered with.
UndoSystem::URSequencePoint* m_undoBatch = nullptr; //!< Undo active while mouse is pressed.
bool m_performingAction = false; //!< After mouse down and before mouse up.
bool m_mouseOver = false; //!< Is the mouse pointer over the manipulator bound.
/// Member function pointers to OnLeftMouseDownImpl and OnRightMouseDownImpl.
/// Set in AttachLeft/RightMouseDownImpl.
//! Member function pointers to OnLeftMouseDownImpl and OnRightMouseDownImpl.
//! Set in AttachLeft/RightMouseDownImpl.
void (BaseManipulator::*m_onLeftMouseDownImpl)(
const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) = nullptr;
void (BaseManipulator::*m_onRightMouseDownImpl)(
const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) = nullptr;
/// Update the mouseOver state for this manipulator.
//! Update the mouseOver state for this manipulator.
void UpdateMouseOver(ManipulatorId manipulatorId);
/// Manage correctly ending the undo batch.
//! Manage correctly ending the undo batch.
void EndUndoBatch();
/// Record an action as having started.
//! Record an action as having started.
void BeginAction();
/// Record an action as having stopped.
//! Record an action as having stopped.
void EndAction();
/// Let other systems (UI) know that a component property has been modified by a manipulator.
//! Let other systems (UI) know that a component property has been modified by a manipulator.
void NotifyEntityComponentPropertyChanged();
};
/// Base class to be used when composing aggregate manipulator types - wraps some
/// common functionality all manipulators need.
//! Base class to be used when composing aggregate manipulator types - wraps some
//! common functionality all manipulators need.
class Manipulators
{
public:
@@ -249,8 +290,10 @@ namespace AzToolsFramework
bool PerformingAction();
bool Registered();
/// Refresh the Manipulator and/or View based on the current view position.
virtual void RefreshView(const AZ::Vector3& /*worldViewPosition*/) {}
//! Refresh the Manipulator and/or View based on the current view position.
virtual void RefreshView(const AZ::Vector3& /*worldViewPosition*/)
{
}
const AZ::Transform& GetLocalTransform() const;
const AZ::Transform& GetSpace() const;
@@ -262,39 +305,59 @@ namespace AzToolsFramework
void SetNonUniformScale(const AZ::Vector3& nonUniformScale);
protected:
/// Common processing for base manipulator type - Implement for all
/// individual manipulators used in an aggregate manipulator.
//! Common processing for base manipulator type - Implement for all
//! individual manipulators used in an aggregate manipulator.
virtual void ProcessManipulators(const AZStd::function<void(BaseManipulator*)>&) = 0;
///@{
/// Allows implementers to perform additional logic when updating the location of the manipulator group.
virtual void SetSpaceImpl([[maybe_unused]] const AZ::Transform& worldFromLocal) {}
virtual void SetLocalTransformImpl([[maybe_unused]] const AZ::Transform& localTransform) {}
virtual void SetLocalPositionImpl([[maybe_unused]] const AZ::Vector3& localPosition) {}
virtual void SetLocalOrientationImpl([[maybe_unused]] const AZ::Quaternion& localOrientation) {}
virtual void SetNonUniformScaleImpl([[maybe_unused]] const AZ::Vector3& nonUniformScale) {}
///@}
//!@{
//! Allows implementers to perform additional logic when updating the location of the manipulator group.
virtual void SetSpaceImpl([[maybe_unused]] const AZ::Transform& worldFromLocal)
{
}
ManipulatorSpaceWithLocalTransform m_manipulatorSpaceWithLocalTransform; ///< The space and local transform for the manipulators.
virtual void SetLocalTransformImpl([[maybe_unused]] const AZ::Transform& localTransform)
{
}
virtual void SetLocalPositionImpl([[maybe_unused]] const AZ::Vector3& localPosition)
{
}
virtual void SetLocalOrientationImpl([[maybe_unused]] const AZ::Quaternion& localOrientation)
{
}
virtual void SetNonUniformScaleImpl([[maybe_unused]] const AZ::Vector3& nonUniformScale)
{
}
//!@}
ManipulatorSpaceWithLocalTransform m_manipulatorSpaceWithLocalTransform; //!< The space and local transform for the manipulators.
};
namespace Internal
{
/// This helper function calculates the intersecting point between a ray and a plane.
/// @param rayOrigin The origin of the ray to test.
/// @param rayDirection The direction of the ray to test.
/// @param maxRayLength
/// @param pointOnPlane A point on the plane.
/// @param planeNormal The normal vector of the plane.
/// @param[out] resultIntersectingPoint This stores the result intersecting point. It will be left unchanged
/// if there is no intersection between the ray and the plane.
/// @return Was there an intersection
bool CalculateRayPlaneIntersectingPoint(const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection,
const AZ::Vector3& pointOnPlane, const AZ::Vector3& planeNormal, AZ::Vector3& resultIntersectingPoint);
//! This helper function calculates the intersecting point between a ray and a plane.
//! @param rayOrigin The origin of the ray to test.
//! @param rayDirection The direction of the ray to test.
//! @param maxRayLength The maximum length of the ray to test.
//! @param pointOnPlane A point on the plane.
//! @param planeNormal The normal vector of the plane.
//! @param[out] resultIntersectingPoint This stores the result intersecting point. It will be left unchanged
//! if there is no intersection between the ray and the plane.
//! @return Was there an intersection
bool CalculateRayPlaneIntersectingPoint(
const AZ::Vector3& rayOrigin,
const AZ::Vector3& rayDirection,
const AZ::Vector3& pointOnPlane,
const AZ::Vector3& planeNormal,
AZ::Vector3& resultIntersectingPoint);
/// Returns startLocalHitPosition if currentLocalHitPosition is further away than the camera's far clip plane.
//! Returns startLocalHitPosition if currentLocalHitPosition is further away than the camera's far clip plane.
AZ::Vector3 TryConstrainHitPositionToView(
const AZ::Vector3& currentLocalHitPosition, const AZ::Vector3& startLocalHitPosition,
const AZ::Transform& localFromWorld, const AzFramework::CameraState& cameraState);
}
const AZ::Vector3& currentLocalHitPosition,
const AZ::Vector3& startLocalHitPosition,
const AZ::Transform& localFromWorld,
const AzFramework::CameraState& cameraState);
} // namespace Internal
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -21,31 +21,30 @@ namespace AZ
namespace AzToolsFramework
{
/// Interface for handling box manipulator requests.
/// Used by \ref BoxComponentMode.
class BoxManipulatorRequests
: public AZ::EntityComponentBus
//! Interface for handling box manipulator requests.
//! Used by \ref BoxComponentMode.
class BoxManipulatorRequests : public AZ::EntityComponentBus
{
public:
/// Get the X/Y/Z dimensions of the box shape/collider.
//! Get the X/Y/Z dimensions of the box shape/collider.
virtual AZ::Vector3 GetDimensions() = 0;
/// Set the X/Y/Z dimensions of the box shape/collider.
//! Set the X/Y/Z dimensions of the box shape/collider.
virtual void SetDimensions(const AZ::Vector3& dimensions) = 0;
/// Get the transform of the box shape/collider.
/// This is used by \ref BoxComponentMode instead of the \ref \AZ::TransformBus
/// because a collider may have an additional translation/orientation offset from
/// the Entity transform.
//! Get the transform of the box shape/collider.
//! This is used by \ref BoxComponentMode instead of the \ref \AZ::TransformBus
//! because a collider may have an additional translation/orientation offset from
//! the Entity transform.
virtual AZ::Transform GetCurrentTransform() = 0;
/// Get the scale currently applied to the box.
/// With the Box Shape, the largest x/y/z component is taken
/// so scale is always uniform, with colliders the scale may
/// be different per component.
//! Get the scale currently applied to the box.
//! With the Box Shape, the largest x/y/z component is taken
//! so scale is always uniform, with colliders the scale may
//! be different per component.
virtual AZ::Vector3 GetBoxScale() = 0;
protected:
~BoxManipulatorRequests() = default;
};
/// Type to inherit to implement BoxManipulatorRequests
//! Type to inherit to implement BoxManipulatorRequests
using BoxManipulatorRequestBus = AZ::EBus<BoxManipulatorRequests>;
} // namespace AzToolsFramework
@@ -1,22 +1,22 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Math/VertexContainer.h>
#include <AzCore/Math/VertexContainerInterface.h>
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
#include <AzToolsFramework/Manipulators/ManipulatorBus.h>
#include <AzToolsFramework/Manipulators/HoverSelection.h>
#include <AzToolsFramework/Manipulators/ManipulatorBus.h>
#include <AzToolsFramework/Manipulators/SelectionManipulator.h>
#include <AzToolsFramework/Manipulators/TranslationManipulators.h>
#include <AzToolsFramework/Viewport/ActionBus.h>
@@ -24,37 +24,74 @@
namespace AzToolsFramework
{
/// Concrete implementation of AZ::VariableVertices backed by an AZ::VertexContainer.
//! Concrete implementation of AZ::VariableVertices backed by an AZ::VertexContainer.
template<typename Vertex>
class VariableVerticesVertexContainer
: public AZ::VariableVertices<Vertex>
class VariableVerticesVertexContainer : public AZ::VariableVertices<Vertex>
{
public:
explicit VariableVerticesVertexContainer(AZ::VertexContainer<Vertex>& vertexContainer)
: m_vertexContainer(vertexContainer) {}
: m_vertexContainer(vertexContainer)
{
}
bool GetVertex(size_t index, Vertex& vertex) const override { return m_vertexContainer.GetVertex(index, vertex); }
bool UpdateVertex(size_t index, const Vertex& vertex) override { return m_vertexContainer.UpdateVertex(index, vertex); };
void AddVertex(const Vertex& vertex) override { m_vertexContainer.AddVertex(vertex); }
bool InsertVertex(size_t index, const Vertex& vertex) override { return m_vertexContainer.InsertVertex(index, vertex); }
bool RemoveVertex(size_t index) override { return m_vertexContainer.RemoveVertex(index); }
void SetVertices(const AZStd::vector<Vertex>& vertices) override { m_vertexContainer.SetVertices(vertices); };
void ClearVertices() override { m_vertexContainer.Clear(); }
size_t Size() const override { return m_vertexContainer.Size(); }
bool Empty() const override { return m_vertexContainer.Empty(); }
bool GetVertex(size_t index, Vertex& vertex) const override
{
return m_vertexContainer.GetVertex(index, vertex);
}
bool UpdateVertex(size_t index, const Vertex& vertex) override
{
return m_vertexContainer.UpdateVertex(index, vertex);
};
void AddVertex(const Vertex& vertex) override
{
m_vertexContainer.AddVertex(vertex);
}
bool InsertVertex(size_t index, const Vertex& vertex) override
{
return m_vertexContainer.InsertVertex(index, vertex);
}
bool RemoveVertex(size_t index) override
{
return m_vertexContainer.RemoveVertex(index);
}
void SetVertices(const AZStd::vector<Vertex>& vertices) override
{
m_vertexContainer.SetVertices(vertices);
};
void ClearVertices() override
{
m_vertexContainer.Clear();
}
size_t Size() const override
{
return m_vertexContainer.Size();
}
bool Empty() const override
{
return m_vertexContainer.Empty();
}
private:
AZ::VertexContainer<Vertex>& m_vertexContainer;
};
/// Concrete implementation of AZ::FixedVertices backed by an AZStd::array.
//! Concrete implementation of AZ::FixedVertices backed by an AZStd::array.
template<typename Vertex, size_t Count>
class FixedVerticesArray
: public AZ::FixedVertices<Vertex>
class FixedVerticesArray : public AZ::FixedVertices<Vertex>
{
public:
explicit FixedVerticesArray(AZStd::array<Vertex, Count>& array)
: m_array(array) {}
: m_array(array)
{
}
bool GetVertex(size_t index, Vertex& vertex) const override
{
@@ -72,22 +109,26 @@ namespace AzToolsFramework
if (index < m_array.size())
{
m_array[index] = vertex;
return true;;
return true;
;
}
return false;
}
size_t Size() const override { return m_array.size(); }
size_t Size() const override
{
return m_array.size();
}
private:
AZStd::array<Vertex, Count>& m_array;
};
/// EditorVertexSelection provides an interface for a collection of manipulators to expose
/// editing of vertices in a container/collection. EditorVertexSelection is templated on the
/// type of Vertex (Vector2/Vector3) stored in the container.
/// EditorVertexSelectionBase provides common behavior shared across Fixed and Variable selections.
//! EditorVertexSelection provides an interface for a collection of manipulators to expose
//! editing of vertices in a container/collection. EditorVertexSelection is templated on the
//! type of Vertex (Vector2/Vector3) stored in the container.
//! EditorVertexSelectionBase provides common behavior shared across Fixed and Variable selections.
template<typename Vertex>
class EditorVertexSelectionBase
: private AzFramework::EntityDebugDisplayEventBus::Handler
@@ -99,89 +140,110 @@ namespace AzToolsFramework
EditorVertexSelectionBase& operator=(EditorVertexSelectionBase&&) = default;
virtual ~EditorVertexSelectionBase() = default;
/// Setup and configure the EditorVertexSelection for operation.
//! Setup and configure the EditorVertexSelection for operation.
void Create(
const AZ::EntityComponentIdPair& entityComponentIdPair, ManipulatorManagerId managerId,
const AZ::EntityComponentIdPair& entityComponentIdPair,
ManipulatorManagerId managerId,
AZStd::unique_ptr<HoverSelection> hoverSelection,
TranslationManipulators::Dimensions dimensions,
TranslationManipulatorConfiguratorFn translationManipulatorConfigurator);
/// Create a translation manipulator for a given vertex.
//! Create a translation manipulator for a given vertex.
void CreateTranslationManipulator(
const AZ::EntityComponentIdPair& entityComponentIdPair,
ManipulatorManagerId managerId, const Vertex& vertex, size_t index);
const AZ::EntityComponentIdPair& entityComponentIdPair, ManipulatorManagerId managerId, const Vertex& vertex, size_t index);
/// Destroy all manipulators associated with the vertex selection.
//! Destroy all manipulators associated with the vertex selection.
void Destroy();
/// Set custom callback for when vertex positions are updated.
//! Set custom callback for when vertex positions are updated.
void SetVertexPositionsUpdatedCallback(const AZStd::function<void()>& callback);
/// Update manipulators based on local changes to vertex positions.
//! Update manipulators based on local changes to vertex positions.
void RefreshLocal();
/// Update the translation manipulator to be correctly positioned based
/// on the current selection (recenter it).
//! Update the translation manipulator to be correctly positioned based
//! on the current selection (recenter it).
void RefreshTranslationManipulator();
/// Update manipulators based on changes to the entity's transform and non-uniform scale.
//! Update manipulators based on changes to the entity's transform and non-uniform scale.
void RefreshSpace(const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale = AZ::Vector3::CreateOne());
/// Set bounds dirty (need recalculating) for all owned manipulators (selection, translation, hover).
//! Set bounds dirty (need recalculating) for all owned manipulators (selection, translation, hover).
void SetBoundsDirty();
/// How should the EditorVertexSelection respond to mouse input.
virtual bool HandleMouse(
const ViewportInteraction::MouseInteractionEvent& mouseInteraction);
//! How should the EditorVertexSelection respond to mouse input.
virtual bool HandleMouse(const ViewportInteraction::MouseInteractionEvent& mouseInteraction);
/// Snap the selected vertices to the terrain.
/// Note: With a multi-selection the manipulator will be translated to the picked
/// terrain position with all verts moved relative to it.
void SnapVerticesToTerrain(
const ViewportInteraction::MouseInteractionEvent& mouseInteraction);
//! Snap the selected vertices to the terrain.
//! Note: With a multi-selection the manipulator will be translated to the picked
//! terrain position with all vertices moved relative to it.
void SnapVerticesToTerrain(const ViewportInteraction::MouseInteractionEvent& mouseInteraction);
/// The Actions provided by the EditorVertexSelection while it is active.
/// e.g. Vertex deletion, duplication etc.
//! The Actions provided by the EditorVertexSelection while it is active.
//! e.g. Vertex deletion, duplication etc.
AZStd::vector<ActionOverride> ActionOverrides() const;
/// Let the EditorVertexSelection know a batch movement is about to begin so it
/// can avoid certain unnecessary updates.
//! Let the EditorVertexSelection know a batch movement is about to begin so it
//! can avoid certain unnecessary updates.
void BeginBatchMovement();
/// Let the EditorVertexSelection know a batch movement has ended so it can return
/// to its normal state.
//! Let the EditorVertexSelection know a batch movement has ended so it can return
//! to its normal state.
void EndBatchMovement();
/// Set the position of the TranslationManipulators (if active).
//! Set the position of the TranslationManipulators (if active).
void SetSelectedPosition(const AZ::Vector3& localPosition);
AZ::EntityId GetEntityId() const { return m_entityComponentIdPair.GetEntityId(); }
AZ::EntityId GetEntityId() const
{
return m_entityComponentIdPair.GetEntityId();
}
protected:
/// Internal interface for EditorVertexSelection.
//! Internal interface for EditorVertexSelection.
virtual void SetupSelectionManipulator(
const AZStd::shared_ptr<SelectionManipulator>& selectionManipulator,
const AZ::EntityComponentIdPair& entityComponentIdPair,
ManipulatorManagerId managerId, size_t index) = 0;
ManipulatorManagerId managerId,
size_t index) = 0;
virtual void PrepareActions() = 0;
/// Default behavior when clicking on a selection manipulator (representing a vertex).
//! Default behavior when clicking on a selection manipulator (representing a vertex).
void SelectionManipulatorSelectCallback(
size_t index, const ViewportInteraction::MouseInteraction& interaction,
const AZ::EntityComponentIdPair& entityComponentIdPair, ManipulatorManagerId managerId);
size_t index,
const ViewportInteraction::MouseInteraction& interaction,
const AZ::EntityComponentIdPair& entityComponentIdPair,
ManipulatorManagerId managerId);
/// Destroy the translation manipulator and deselect all vertices.
//! Destroy the translation manipulator and deselect all vertices.
void ClearSelected();
AZ::ComponentId GetComponentId() const { return m_entityComponentIdPair.GetComponentId(); }
const AZ::EntityComponentIdPair& GetEntityComponentIdPair() const { return m_entityComponentIdPair; }
ManipulatorManagerId GetManipulatorManagerId() const { return m_manipulatorManagerId; }
AZ::ComponentId GetComponentId() const
{
return m_entityComponentIdPair.GetComponentId();
}
/// Is the translation vertex manipulator in 2D or 3D.
TranslationManipulators::Dimensions Dimensions() const { return m_dimensions; }
const AZ::EntityComponentIdPair& GetEntityComponentIdPair() const
{
return m_entityComponentIdPair;
}
/// How to configure the translation manipulator (view and axes).
TranslationManipulatorConfiguratorFn ConfiguratorFn() const { return m_manipulatorConfiguratorFn; }
ManipulatorManagerId GetManipulatorManagerId() const
{
return m_manipulatorManagerId;
}
/// The state we are in when editing vertices.
//! Is the translation vertex manipulator in 2D or 3D.
TranslationManipulators::Dimensions Dimensions() const
{
return m_dimensions;
}
//! How to configure the translation manipulator (view and axes).
TranslationManipulatorConfiguratorFn ConfiguratorFn() const
{
return m_manipulatorConfiguratorFn;
}
//! The state we are in when editing vertices.
enum class State
{
Selecting,
@@ -190,23 +252,22 @@ namespace AzToolsFramework
void SetState(State state);
AZStd::unique_ptr<HoverSelection> m_hoverSelection = nullptr; ///< Interface to hover selection, representing bounds that can be selected.
AZStd::shared_ptr<IndexedTranslationManipulator<Vertex>> m_translationManipulator = nullptr; ///< Manipulator when vertex is selected to translate it.
AZStd::vector<AZStd::shared_ptr<SelectionManipulator>> m_selectionManipulators; ///< Manipulators for each vertex when entity is selected.
AZStd::array<AZStd::vector<ActionOverride>, 2> m_actionOverrides; ///< Available actions corresponding to each mode.
AZStd::unique_ptr<HoverSelection> m_hoverSelection =
nullptr; //!< Interface to hover selection, representing bounds that can be selected.
AZStd::shared_ptr<IndexedTranslationManipulator<Vertex>> m_translationManipulator =
nullptr; //!< Manipulator when vertex is selected to translate it.
AZStd::vector<AZStd::shared_ptr<SelectionManipulator>>
m_selectionManipulators; //!< Manipulators for each vertex when entity is selected.
AZStd::array<AZStd::vector<ActionOverride>, 2> m_actionOverrides; //!< Available actions corresponding to each mode.
private:
// AzFramework::EntityDebugDisplayEventBus
void DisplayEntityViewport(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay) override;
void DisplayEntityViewport(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override;
// AzFramework::ViewportDebugDisplayEventBus
void DisplayViewport2d(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay) override;
void DisplayViewport2d(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override;
/// Set selected manipulator and vertices position from offset from starting position when pressed.
//! Set selected manipulator and vertices position from offset from starting position when pressed.
void UpdateManipulatorsAndVerticesFromOffset(
IndexedTranslationManipulator<Vertex>& translationManipulator,
const AZ::Vector3& localManipulatorStartPosition,
@@ -217,23 +278,24 @@ namespace AzToolsFramework
template<typename V, typename AZStd::enable_if<AZStd::is_same<V, AZ::Vector2>::value>::type* = nullptr>
void UpdateManipulatorSpace(const AzFramework::ViewportInfo& viewportInfo) const;
EditorBoxSelect m_editorBoxSelect; ///< Provide box select support for vertex selection.
AZ::EntityComponentIdPair m_entityComponentIdPair; ///< Id of the Entity and Component this editor vertex selection was created on.
ManipulatorManagerId m_manipulatorManagerId; ///< Id of the manager manipulators created from this type will be associated with.
TranslationManipulators::Dimensions m_dimensions = TranslationManipulators::Dimensions::Three; ///< The dimensions this vertex selection was created with.
TranslationManipulatorConfiguratorFn m_manipulatorConfiguratorFn = nullptr; ///< Function pointer set on Create to decide look and functionality of translation manipulator.
AZStd::function<void()> m_onVertexPositionsUpdated = nullptr; ///< Callback for when vertex positions are changed.
State m_state = State::Selecting; ///< Different states VertexSelection can be in.
bool m_worldSpace = false; ///< Are the manipulators being used in local or world space.
bool m_batchMovementInProgress = false; ///< If a batch movement operation is in progress we do not want to
///< refresh the VertexSelection during it for performance reasons.
EditorBoxSelect m_editorBoxSelect; //!< Provide box select support for vertex selection.
AZ::EntityComponentIdPair m_entityComponentIdPair; //!< Id of the Entity and Component this editor vertex selection was created on.
ManipulatorManagerId m_manipulatorManagerId; //!< Id of the manager manipulators created from this type will be associated with.
TranslationManipulators::Dimensions m_dimensions =
TranslationManipulators::Dimensions::Three; //!< The dimensions this vertex selection was created with.
TranslationManipulatorConfiguratorFn m_manipulatorConfiguratorFn =
nullptr; //!< Function pointer set on Create to decide look and functionality of translation manipulator.
AZStd::function<void()> m_onVertexPositionsUpdated = nullptr; //!< Callback for when vertex positions are changed.
State m_state = State::Selecting; //!< Different states VertexSelection can be in.
bool m_worldSpace = false; //!< Are the manipulators being used in local or world space.
bool m_batchMovementInProgress = false; //!< If a batch movement operation is in progress we do not want to
//!< refresh the VertexSelection during it for performance reasons.
};
/// EditorVertexSelectionFixed provides selection and editing for a fixed length number of
/// vertices. New vertices cannot be inserted/added or removed.
//! EditorVertexSelectionFixed provides selection and editing for a fixed length number of
//! vertices. New vertices cannot be inserted/added or removed.
template<typename Vertex>
class EditorVertexSelectionFixed
: public EditorVertexSelectionBase<Vertex>
class EditorVertexSelectionFixed : public EditorVertexSelectionBase<Vertex>
{
public:
AZ_CLASS_ALLOCATOR_DECL
@@ -247,15 +309,15 @@ namespace AzToolsFramework
void SetupSelectionManipulator(
const AZStd::shared_ptr<SelectionManipulator>& selectionManipulator,
const AZ::EntityComponentIdPair& entityComponentIdPair,
ManipulatorManagerId managerId, size_t index) override;
ManipulatorManagerId managerId,
size_t index) override;
void PrepareActions() override;
};
/// EditorVertexSelectionVariable provides selection and editing for a variable length number of
/// vertices. New vertices can be inserted/added or removed from the collection.
//! EditorVertexSelectionVariable provides selection and editing for a variable length number of
//! vertices. New vertices can be inserted/added or removed from the collection.
template<typename Vertex>
class EditorVertexSelectionVariable
: public EditorVertexSelectionBase<Vertex>
class EditorVertexSelectionVariable : public EditorVertexSelectionBase<Vertex>
{
public:
AZ_CLASS_ALLOCATOR_DECL
@@ -272,7 +334,8 @@ namespace AzToolsFramework
void SetupSelectionManipulator(
const AZStd::shared_ptr<SelectionManipulator>& selectionManipulator,
const AZ::EntityComponentIdPair& entityComponentIdPair,
ManipulatorManagerId managerId, size_t vertIndex) override;
ManipulatorManagerId managerId,
size_t vertIndex) override;
//! Presents a warning to the user that vertices will not be deleted.
//! @note Allow overriding by derived classes to make this a noop if required.
@@ -281,21 +344,18 @@ namespace AzToolsFramework
private:
void PrepareActions() override;
/// @return The center point of the selected vertices.
Vertex InsertSelectedInPlace(
AZStd::vector<typename IndexedTranslationManipulator<Vertex>::VertexLookup>& manipulators);
//! @return The center point of the selected vertices.
Vertex InsertSelectedInPlace(AZStd::vector<typename IndexedTranslationManipulator<Vertex>::VertexLookup>& manipulators);
};
/// Helper for inserting a vertex in a variable vertices container.
//! Helper for inserting a vertex in a variable vertices container.
template<typename Vertex>
void InsertVertexAfter(
const AZ::EntityComponentIdPair& entityComponentIdPair, size_t vertIndex, const Vertex& localPosition);
void InsertVertexAfter(const AZ::EntityComponentIdPair& entityComponentIdPair, size_t vertIndex, const Vertex& localPosition);
/// Helper for removing a vertex in a variable vertices container.
/// Remove a vertex from the container and ensure the associated manipulator is unset and
/// property display values are refreshed.
//! Helper for removing a vertex in a variable vertices container.
//! Remove a vertex from the container and ensure the associated manipulator is unset and
//! property display values are refreshed.
template<typename Vertex>
void SafeRemoveVertex(
const AZ::EntityComponentIdPair& entityComponentIdPair, size_t vertexIndex);
void SafeRemoveVertex(const AZ::EntityComponentIdPair& entityComponentIdPair, size_t vertexIndex);
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -16,10 +16,10 @@
namespace AzToolsFramework
{
/// HoverSelection provides an interface for manipulator/s offering selection when
/// the mouse is hovered over a particular bound. This interface is used to represent
/// a Spline manipulator bound, and a series of LineSegment manipulator bounds.
/// This generic interface allows EditorVertexSelection to use either Spline or LineSegment selection.
//! HoverSelection provides an interface for manipulator/s offering selection when
//! the mouse is hovered over a particular bound. This interface is used to represent
//! a Spline manipulator bound, and a series of LineSegment manipulator bounds.
//! This generic interface allows EditorVertexSelection to use either Spline or LineSegment selection.
class HoverSelection
{
public:
@@ -33,21 +33,37 @@ namespace AzToolsFramework
virtual void SetNonUniformScale(const AZ::Vector3& nonUniformScale) = 0;
};
/// NullHoverSelection is used when vertices cannot be inserted. This serves as a no-op
/// and is used to prevent the need for additional null checks in EditorVertexSelection.
class NullHoverSelection
: public HoverSelection
//! NullHoverSelection is used when vertices cannot be inserted. This serves as a no-op
//! and is used to prevent the need for additional null checks in EditorVertexSelection.
class NullHoverSelection : public HoverSelection
{
public:
NullHoverSelection() = default;
NullHoverSelection(const NullHoverSelection&) = delete;
NullHoverSelection& operator=(const NullHoverSelection&) = delete;
void Register(ManipulatorManagerId /*managerId*/) override {}
void Unregister() override {}
void SetBoundsDirty() override {}
void Refresh() override {}
void SetSpace(const AZ::Transform& /*worldFromLocal*/) override {}
void SetNonUniformScale([[maybe_unused]] const AZ::Vector3& nonUniformScale) override {}
void Register([[maybe_unused]] ManipulatorManagerId managerId) override
{
}
void Unregister() override
{
}
void SetBoundsDirty() override
{
}
void Refresh() override
{
}
void SetSpace([[maybe_unused]] const AZ::Transform& worldFromLocal) override
{
}
void SetNonUniformScale([[maybe_unused]] const AZ::Vector3& nonUniformScale) override
{
}
};
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "LineHoverSelection.h"
@@ -22,17 +22,15 @@
namespace AzToolsFramework
{
static const AZ::Color s_lineSelectManipulatorColor = AZ::Color(0.0f, 1.0f, 0.0f, 1.0f);
static const AZ::Color LineSelectManipulatorColor = AZ::Color(0.0f, 1.0f, 0.0f, 1.0f);
template<typename Vertex>
static void UpdateLineSegmentPosition(
const size_t vertIndex, const AZ::EntityId entityId, LineSegmentSelectionManipulator& lineSegment)
static void UpdateLineSegmentPosition(const size_t vertIndex, const AZ::EntityId entityId, LineSegmentSelectionManipulator& lineSegment)
{
Vertex start;
bool foundStart = false;
AZ::FixedVerticesRequestBus<Vertex>::EventResult(
foundStart, entityId, &AZ::FixedVerticesRequestBus<Vertex>::Handler::GetVertex,
vertIndex, start);
foundStart, entityId, &AZ::FixedVerticesRequestBus<Vertex>::Handler::GetVertex, vertIndex, start);
if (foundStart)
{
@@ -40,14 +38,12 @@ namespace AzToolsFramework
}
size_t size = 0;
AZ::FixedVerticesRequestBus<Vertex>::EventResult(
size, entityId, &AZ::FixedVerticesRequestBus<Vertex>::Handler::Size);
AZ::FixedVerticesRequestBus<Vertex>::EventResult(size, entityId, &AZ::FixedVerticesRequestBus<Vertex>::Handler::Size);
Vertex end;
bool foundEnd = false;
AZ::FixedVerticesRequestBus<Vertex>::EventResult(
foundEnd, entityId, &AZ::FixedVerticesRequestBus<Vertex>::Handler::GetVertex,
(vertIndex + 1) % size, end);
foundEnd, entityId, &AZ::FixedVerticesRequestBus<Vertex>::Handler::GetVertex, (vertIndex + 1) % size, end);
if (foundEnd)
{
@@ -56,8 +52,7 @@ namespace AzToolsFramework
// update the view
const float lineWidth = 0.05f;
lineSegment.SetView(
CreateManipulatorViewLineSelect(lineSegment, s_lineSelectManipulatorColor, lineWidth));
lineSegment.SetView(CreateManipulatorViewLineSelect(lineSegment, LineSelectManipulatorColor, lineWidth));
}
template<typename Vertex>
@@ -66,9 +61,8 @@ namespace AzToolsFramework
: m_entityId(entityComponentIdPair.GetEntityId())
{
// create a line segment manipulator from vertex positions and setup its callback
auto setupLineSegment = [this] (
const AZ::EntityComponentIdPair& entityComponentIdPair,
const ManipulatorManagerId managerId, const size_t vertIndex)
auto setupLineSegment =
[this](const AZ::EntityComponentIdPair& entityComponentIdPair, const ManipulatorManagerId managerId, const size_t vertIndex)
{
m_lineSegmentManipulators.push_back(LineSegmentSelectionManipulator::MakeShared());
AZStd::shared_ptr<LineSegmentSelectionManipulator>& lineSegmentManipulator = m_lineSegmentManipulators.back();
@@ -81,11 +75,9 @@ namespace AzToolsFramework
lineSegmentManipulator->InstallLeftMouseUpCallback(
[vertIndex, entityComponentIdPair](const LineSegmentSelectionManipulator::Action& action)
{
InsertVertexAfter<Vertex>(
entityComponentIdPair, vertIndex,
AZ::AdaptVertexIn<Vertex>(action.m_localLineHitPosition));
});
{
InsertVertexAfter<Vertex>(entityComponentIdPair, vertIndex, AZ::AdaptVertexIn<Vertex>(action.m_localLineHitPosition));
});
};
// create all line segment manipulators for the polygon prism (used for selection bounds)
@@ -150,8 +142,7 @@ namespace AzToolsFramework
void LineSegmentHoverSelection<Vertex>::Refresh()
{
size_t vertexCount = 0;
AZ::FixedVerticesRequestBus<Vertex>::EventResult(
vertexCount, m_entityId, &AZ::FixedVerticesRequestBus<Vertex>::Handler::Size);
AZ::FixedVerticesRequestBus<Vertex>::EventResult(vertexCount, m_entityId, &AZ::FixedVerticesRequestBus<Vertex>::Handler::Size);
// update the start/end positions of all the line segment manipulators to ensure
// they stay consistent with the polygon prism shape
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -25,17 +25,14 @@ namespace AzToolsFramework
{
class LineSegmentSelectionManipulator;
/// LineSegmentHoverSelection is a concrete implementation of HoverSelection wrapping a collection/container
/// of vertices and a list of LineSegmentManipulators. The underlying manipulators are used to control selection
/// by highlighting where on the line a new vertex will be inserted.
//! LineSegmentHoverSelection is a concrete implementation of HoverSelection wrapping a collection/container
//! of vertices and a list of LineSegmentManipulators. The underlying manipulators are used to control selection
//! by highlighting where on the line a new vertex will be inserted.
template<typename Vertex>
class LineSegmentHoverSelection
: public HoverSelection
class LineSegmentHoverSelection : public HoverSelection
{
public:
explicit LineSegmentHoverSelection(
const AZ::EntityComponentIdPair& entityComponentIdPair,
ManipulatorManagerId managerId);
explicit LineSegmentHoverSelection(const AZ::EntityComponentIdPair& entityComponentIdPair, ManipulatorManagerId managerId);
LineSegmentHoverSelection(const LineSegmentHoverSelection&) = delete;
LineSegmentHoverSelection& operator=(const LineSegmentHoverSelection&) = delete;
~LineSegmentHoverSelection();
@@ -49,6 +46,6 @@ namespace AzToolsFramework
private:
AZ::EntityId m_entityId;
AZStd::vector<AZStd::shared_ptr<LineSegmentSelectionManipulator>> m_lineSegmentManipulators; ///< Manipulators for each line.
AZStd::vector<AZStd::shared_ptr<LineSegmentSelectionManipulator>> m_lineSegmentManipulators; //!< Manipulators for each line.
};
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "LineSegmentSelectionManipulator.h"
@@ -20,15 +20,20 @@
namespace AzToolsFramework
{
LineSegmentSelectionManipulator::Action CalculateManipulationDataAction(
const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale, const AZ::Vector3& rayOrigin,
const AZ::Vector3& rayDirection, const float rayLength, const AZ::Vector3& localStart, const AZ::Vector3& localEnd)
const AZ::Transform& worldFromLocal,
const AZ::Vector3& nonUniformScale,
const AZ::Vector3& rayOrigin,
const AZ::Vector3& rayDirection,
const float rayLength,
const AZ::Vector3& localStart,
const AZ::Vector3& localEnd)
{
AZ::Vector3 worldClosestPositionRay, worldClosestPositionLineSegment;
float rayProportion, lineSegmentProportion;
AZ::Intersect::ClosestSegmentSegment(
rayOrigin, rayOrigin + rayDirection * rayLength,
worldFromLocal.TransformPoint(nonUniformScale * localStart), worldFromLocal.TransformPoint(nonUniformScale * localEnd),
rayProportion, lineSegmentProportion, worldClosestPositionRay, worldClosestPositionLineSegment);
rayOrigin, rayOrigin + rayDirection * rayLength, worldFromLocal.TransformPoint(nonUniformScale * localStart),
worldFromLocal.TransformPoint(nonUniformScale * localEnd), rayProportion, lineSegmentProportion, worldClosestPositionRay,
worldClosestPositionLineSegment);
AZ::Transform worldFromLocalNormalized = worldFromLocal;
const AZ::Vector3 scale = worldFromLocalNormalized.ExtractUniformScale() * nonUniformScale;
@@ -47,7 +52,9 @@ namespace AzToolsFramework
AttachLeftMouseDownImpl();
}
LineSegmentSelectionManipulator::~LineSegmentSelectionManipulator() {}
LineSegmentSelectionManipulator::~LineSegmentSelectionManipulator()
{
}
void LineSegmentSelectionManipulator::InstallLeftMouseDownCallback(const MouseActionCallback& onMouseDownCallback)
{
@@ -112,12 +119,9 @@ namespace AzToolsFramework
if (mouseInteraction.m_keyboardModifiers.Ctrl() && !mouseInteraction.m_keyboardModifiers.Shift())
{
m_manipulatorView->Draw(
GetManipulatorManagerId(), managerState,
GetManipulatorId(), {
TransformUniformScale(GetSpace()), GetNonUniformScale(),
m_localStart, MouseOver()
},
debugDisplay, cameraState, mouseInteraction);
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ TransformUniformScale(GetSpace()), GetNonUniformScale(), m_localStart, MouseOver() }, debugDisplay, cameraState,
mouseInteraction);
}
}
@@ -135,4 +139,4 @@ namespace AzToolsFramework
{
m_manipulatorView->Invalidate(GetManipulatorManagerId());
}
}
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -20,12 +20,12 @@ namespace AzToolsFramework
{
class ManipulatorView;
/// A manipulator to expose where on a line a user is moving their mouse.
//! A manipulator to expose where on a line a user is moving their mouse.
class LineSegmentSelectionManipulator
: public BaseManipulator
, public ManipulatorSpace
{
/// Private constructor.
//! Private constructor.
LineSegmentSelectionManipulator();
public:
@@ -37,10 +37,10 @@ namespace AzToolsFramework
~LineSegmentSelectionManipulator();
/// A Manipulator must only be created and managed through a shared_ptr.
//! A Manipulator must only be created and managed through a shared_ptr.
static AZStd::shared_ptr<LineSegmentSelectionManipulator> MakeShared();
/// Mouse action data used by MouseActionCallback.
//! Mouse action data used by MouseActionCallback.
struct Action
{
AZ::Vector3 m_localLineHitPosition;
@@ -57,18 +57,31 @@ namespace AzToolsFramework
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction) override;
void SetStart(const AZ::Vector3& startLocal) { m_localStart = startLocal; }
void SetEnd(const AZ::Vector3& endLocal) { m_localEnd = endLocal; }
const AZ::Vector3& GetStart() const { return m_localStart; }
const AZ::Vector3& GetEnd() const { return m_localEnd; }
void SetStart(const AZ::Vector3& startLocal)
{
m_localStart = startLocal;
}
void SetEnd(const AZ::Vector3& endLocal)
{
m_localEnd = endLocal;
}
const AZ::Vector3& GetStart() const
{
return m_localStart;
}
const AZ::Vector3& GetEnd() const
{
return m_localEnd;
}
void SetView(AZStd::unique_ptr<ManipulatorView>&& view);
private:
void OnLeftMouseDownImpl(
const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override;
void OnLeftMouseUpImpl(
const ViewportInteraction::MouseInteraction& interaction) override;
void OnLeftMouseDownImpl(const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override;
void OnLeftMouseUpImpl(const ViewportInteraction::MouseInteraction& interaction) override;
void InvalidateImpl() override;
void SetBoundsDirtyImpl() override;
@@ -79,12 +92,18 @@ namespace AzToolsFramework
MouseActionCallback m_onLeftMouseDownCallback = nullptr;
MouseActionCallback m_onLeftMouseUpCallback = nullptr;
ViewportInteraction::KeyboardModifiers m_keyboardModifiers; ///< What modifier keys are pressed when interacting with this manipulator.
ViewportInteraction::KeyboardModifiers
m_keyboardModifiers; //!< What modifier keys are pressed when interacting with this manipulator.
AZStd::unique_ptr<ManipulatorView> m_manipulatorView = nullptr; ///< Look of manipulator.
AZStd::unique_ptr<ManipulatorView> m_manipulatorView = nullptr; //!< Look of manipulator.
};
LineSegmentSelectionManipulator::Action CalculateManipulationDataAction(
const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale, const AZ::Vector3& rayOrigin,
const AZ::Vector3& rayDirection, float rayLength, const AZ::Vector3& localStart, const AZ::Vector3& localEnd);
const AZ::Transform& worldFromLocal,
const AZ::Vector3& nonUniformScale,
const AZ::Vector3& rayOrigin,
const AZ::Vector3& rayDirection,
float rayLength,
const AZ::Vector3& localStart,
const AZ::Vector3& localEnd);
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "LinearManipulator.h"
@@ -22,13 +22,16 @@
namespace AzToolsFramework
{
LinearManipulator::Starter CalculateLinearManipulationDataStart(
const LinearManipulator::Fixed& fixed, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale,
const AZ::Transform& localTransform, const ViewportInteraction::MouseInteraction& interaction, const float intersectionDistance,
const LinearManipulator::Fixed& fixed,
const AZ::Transform& worldFromLocal,
const AZ::Vector3& nonUniformScale,
const AZ::Transform& localTransform,
const ViewportInteraction::MouseInteraction& interaction,
const float intersectionDistance,
const AzFramework::CameraState& cameraState)
{
const ManipulatorInteraction manipulatorInteraction =
BuildManipulatorInteraction(
worldFromLocal, nonUniformScale, interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection);
const ManipulatorInteraction manipulatorInteraction = BuildManipulatorInteraction(
worldFromLocal, nonUniformScale, interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection);
const AZ::Vector3 axis = TransformDirectionNoScaling(localTransform, fixed.m_axis);
const AZ::Vector3 rayCrossAxis = manipulatorInteraction.m_localRayDirection.Cross(axis);
@@ -47,32 +50,35 @@ namespace AzToolsFramework
manipulatorInteraction.m_localRayOrigin + manipulatorInteraction.m_localRayDirection * intersectionDistance;
Internal::CalculateRayPlaneIntersectingPoint(
manipulatorInteraction.m_localRayOrigin, manipulatorInteraction.m_localRayDirection,
localIntersectionPoint, startTransition.m_localNormal, start.m_localHitPosition);
manipulatorInteraction.m_localRayOrigin, manipulatorInteraction.m_localRayDirection, localIntersectionPoint,
startTransition.m_localNormal, start.m_localHitPosition);
start.m_screenPosition = interaction.m_mousePick.m_screenCoordinates;
start.m_localPosition = localTransform.GetTranslation();
start.m_localScale = AZ::Vector3(localTransform.GetUniformScale());;
start.m_localScale = AZ::Vector3(localTransform.GetUniformScale());
;
start.m_localAxis = axis;
// sign to determine which side of the linear axis we pressed
// (useful to know when the visual axis flips to face the camera)
start.m_sign =
AZ::GetSign((start.m_localHitPosition - localTransform.GetTranslation()).Dot(axis));
start.m_sign = AZ::GetSign((start.m_localHitPosition - localTransform.GetTranslation()).Dot(axis));
startTransition.m_screenToWorldScale =
1.0f / CalculateScreenToWorldMultiplier((worldFromLocal * localTransform).GetTranslation(), cameraState);
return {startTransition, start};
return { startTransition, start };
}
LinearManipulator::Action CalculateLinearManipulationDataAction(
const LinearManipulator::Fixed& fixed, const LinearManipulator::Starter& starter,
const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale, const AZ::Transform& localTransform,
const GridSnapParameters& gridSnapParams, const ViewportInteraction::MouseInteraction& interaction)
const LinearManipulator::Fixed& fixed,
const LinearManipulator::Starter& starter,
const AZ::Transform& worldFromLocal,
const AZ::Vector3& nonUniformScale,
const AZ::Transform& localTransform,
const GridSnapParameters& gridSnapParams,
const ViewportInteraction::MouseInteraction& interaction)
{
const ManipulatorInteraction manipulatorInteraction =
BuildManipulatorInteraction(
worldFromLocal, nonUniformScale, interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection);
const ManipulatorInteraction manipulatorInteraction = BuildManipulatorInteraction(
worldFromLocal, nonUniformScale, interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection);
const auto& [startTransition, start] = starter;
@@ -81,8 +87,8 @@ namespace AzToolsFramework
// if an invalid ray intersection is attempted
AZ::Vector3 localHitPosition = start.m_localHitPosition;
Internal::CalculateRayPlaneIntersectingPoint(
manipulatorInteraction.m_localRayOrigin, manipulatorInteraction.m_localRayDirection,
start.m_localHitPosition, startTransition.m_localNormal, localHitPosition);
manipulatorInteraction.m_localRayOrigin, manipulatorInteraction.m_localRayDirection, start.m_localHitPosition,
startTransition.m_localNormal, localHitPosition);
localHitPosition = Internal::TryConstrainHitPositionToView(
localHitPosition, start.m_localHitPosition, worldFromLocal.GetInverse(),
@@ -103,9 +109,8 @@ namespace AzToolsFramework
LinearManipulator::Action action;
action.m_fixed = fixed;
action.m_start = start;
action.m_current.m_localPositionOffset = snapping
? CalculateSnappedAmount(unsnappedOffset, axis, gridSize * scaleRecip)
: unsnappedOffset;
action.m_current.m_localPositionOffset =
snapping ? CalculateSnappedAmount(unsnappedOffset, axis, gridSize * scaleRecip) : unsnappedOffset;
action.m_current.m_screenPosition = interaction.m_mousePick.m_screenCoordinates;
action.m_viewportId = interaction.m_interactionId.m_viewportId;
@@ -191,7 +196,8 @@ namespace AzToolsFramework
// note: m_localTransform must not be made uniform as it may contain a local scale we want to snap
m_onLeftMouseUpCallback(CalculateLinearManipulationDataAction(
m_fixed, m_starter, TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalTransform(), gridSnapParams, interaction));
m_fixed, m_starter, TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalTransform(), gridSnapParams,
interaction));
}
}
@@ -202,16 +208,14 @@ namespace AzToolsFramework
const ViewportInteraction::MouseInteraction& mouseInteraction)
{
const AZ::Transform localTransform = m_useVisualsOverride
? AZ::Transform::CreateFromQuaternionAndTranslation(
m_visualOrientationOverride, GetLocalPosition())
? AZ::Transform::CreateFromQuaternionAndTranslation(m_visualOrientationOverride, GetLocalPosition())
: GetLocalTransform();
if (cl_manipulatorDrawDebug)
{
if (PerformingAction())
{
const GridSnapParameters gridSnapParams =
GridSnapSettings(mouseInteraction.m_interactionId.m_viewportId);
const GridSnapParameters gridSnapParams = GridSnapSettings(mouseInteraction.m_interactionId.m_viewportId);
const auto action = CalculateLinearManipulationDataAction(
m_fixed, m_starter, TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalTransform(), gridSnapParams,
@@ -219,9 +223,10 @@ namespace AzToolsFramework
// display the exact hit (ray intersection) of the mouse pick on the manipulator
DrawTransformAxes(
debugDisplay, TransformUniformScale(GetSpace()) *
AZ::Transform::CreateTranslation(
action.m_start.m_localHitPosition + GetNonUniformScale() * action.m_current.m_localPositionOffset));
debugDisplay,
TransformUniformScale(GetSpace()) *
AZ::Transform::CreateTranslation(
action.m_start.m_localHitPosition + GetNonUniformScale() * action.m_current.m_localPositionOffset));
}
AZ::Transform combined = GetLocalTransform();
@@ -229,8 +234,7 @@ namespace AzToolsFramework
combined = GetSpace() * combined;
DrawTransformAxes(debugDisplay, combined);
DrawAxis(
debugDisplay, combined.GetTranslation(), TransformDirectionNoScaling(combined, m_fixed.m_axis));
DrawAxis(debugDisplay, combined.GetTranslation(), TransformDirectionNoScaling(combined, m_fixed.m_axis));
}
for (auto& view : m_manipulatorViews)
@@ -238,12 +242,9 @@ namespace AzToolsFramework
auto nonUniformScale = GetNonUniformScale();
view->Draw(
GetManipulatorManagerId(), managerState,
GetManipulatorId(), {
ApplySpace(localTransform), GetNonUniformScale(),
AZ::Vector3::CreateZero(), MouseOver()
},
debugDisplay, cameraState, mouseInteraction);
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ ApplySpace(localTransform), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay, cameraState,
mouseInteraction);
}
}
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -22,13 +22,13 @@ namespace AzToolsFramework
{
struct GridSnapParameters;
/// LinearManipulator serves as a visual tool for users to modify values
/// in one dimension on an axis defined in 3D space.
//! LinearManipulator serves as a visual tool for users to modify values
//! in one dimension on an axis defined in 3D space.
class LinearManipulator
: public BaseManipulator
, public ManipulatorSpaceWithLocalTransform
{
/// Private constructor.
//! Private constructor.
explicit LinearManipulator(const AZ::Transform& worldFromLocal);
public:
@@ -41,68 +41,80 @@ namespace AzToolsFramework
~LinearManipulator() = default;
/// A Manipulator must only be created and managed through a shared_ptr.
/// @note worldFromLocal should not contain scale.
//! A Manipulator must only be created and managed through a shared_ptr.
//! @note worldFromLocal should not contain scale.
static AZStd::shared_ptr<LinearManipulator> MakeShared(const AZ::Transform& worldFromLocal);
/// Unchanging data set once for the linear manipulator.
//! Unchanging data set once for the linear manipulator.
struct Fixed
{
AZ::Vector3 m_axis = AZ::Vector3::CreateAxisX(); ///< The axis the manipulator will move along.
AZ::Vector3 m_axis = AZ::Vector3::CreateAxisX(); //!< The axis the manipulator will move along.
};
/// Data passed between the initial press and first movement of the linear manipulator.
//! Data passed between the initial press and first movement of the linear manipulator.
struct StartTransition
{
/// The normal in local space of the manipulator when the mouse down event happens.
//! The normal in local space of the manipulator when the mouse down event happens.
AZ::Vector3 m_localNormal;
/// Used to scale movement based on camera distance if we want screen space instead
/// of world space displacement.
//! Used to scale movement based on camera distance if we want screen space instead
//! of world space displacement.
float m_screenToWorldScale;
};
/// The state of the manipulator at the start of an interaction.
//! The state of the manipulator at the start of an interaction.
struct Start
{
AZ::Vector3 m_localPosition; ///< The current position of the manipulator in local space.
AZ::Vector3 m_localScale; ///< The current scale of the manipulator in local space.
AZ::Vector3 m_localHitPosition; ///< The intersection point in local space between the ray and the manipulator when the mouse down event happens.
AZ::Vector3 m_localAxis; ///< The axis in the local space of the manipulator itself.
float m_sign; ///< Used to determine which side of the axis we clicked on in case it's flipped to face the camera.
AzFramework::ScreenPoint m_screenPosition; ///< The initial position in screen space of the manipulator.
AZ::Vector3 m_localPosition; //!< The current position of the manipulator in local space.
AZ::Vector3 m_localScale; //!< The current scale of the manipulator in local space.
AZ::Vector3 m_localHitPosition; //!< The intersection point in local space between the ray and the manipulator when the mouse
//!< down event happens.
AZ::Vector3 m_localAxis; //!< The axis in the local space of the manipulator itself.
float m_sign; //!< Used to determine which side of the axis we clicked on in case it's flipped to face the camera.
AzFramework::ScreenPoint m_screenPosition; //!< The initial position in screen space of the manipulator.
};
/// The state of the manipulator during an interaction.
//! The state of the manipulator during an interaction.
struct Current
{
AZ::Vector3 m_localPositionOffset; ///< The current offset of the manipulator from its starting position in local space.
AZ::Vector3 m_localScaleOffset; ///< The current offset of the manipulator from its starting scale in local space.
AzFramework::ScreenPoint m_screenPosition; ///< The current position in screen space of the manipulator.
AZ::Vector3 m_localPositionOffset; //!< The current offset of the manipulator from its starting position in local space.
AZ::Vector3 m_localScaleOffset; //!< The current offset of the manipulator from its starting scale in local space.
AzFramework::ScreenPoint m_screenPosition; //!< The current position in screen space of the manipulator.
};
/// Mouse action data used by MouseActionCallback (wraps Fixed, Start and Current manipulator state).
//! Mouse action data used by MouseActionCallback (wraps Fixed, Start and Current manipulator state).
struct Action
{
Fixed m_fixed;
Start m_start;
Current m_current;
ViewportInteraction::KeyboardModifiers m_modifiers;
int m_viewportId; ///< The id of the viewport this manipulator is being used in.
AZ::Vector3 LocalScale() const { return m_start.m_localScale + m_current.m_localScaleOffset; }
AZ::Vector3 LocalScaleOffset() const { return m_current.m_localScaleOffset; }
AZ::Vector3 LocalPosition() const { return m_start.m_localPosition + m_current.m_localPositionOffset; }
AZ::Vector3 LocalPositionOffset() const { return m_current.m_localPositionOffset; }
int m_viewportId; //!< The id of the viewport this manipulator is being used in.
AZ::Vector3 LocalScale() const
{
return m_start.m_localScale + m_current.m_localScaleOffset;
}
AZ::Vector3 LocalScaleOffset() const
{
return m_current.m_localScaleOffset;
}
AZ::Vector3 LocalPosition() const
{
return m_start.m_localPosition + m_current.m_localPositionOffset;
}
AZ::Vector3 LocalPositionOffset() const
{
return m_current.m_localPositionOffset;
}
AZ::Vector2 ScreenOffset() const
{
return AzFramework::Vector2FromScreenVector(
m_current.m_screenPosition - m_start.m_screenPosition);
return AzFramework::Vector2FromScreenVector(m_current.m_screenPosition - m_start.m_screenPosition);
}
};
/// This is the function signature of callbacks that will be invoked whenever a manipulator
/// is clicked on or dragged.
//! This is the function signature of callbacks that will be invoked whenever a manipulator
//! is clicked on or dragged.
using MouseActionCallback = AZStd::function<void(const Action&)>;
/// Tuple of StartTransition (initial mouse down to mouse move) and Start state.
//! Tuple of StartTransition (initial mouse down to mouse move) and Start state.
using Starter = AZStd::tuple<StartTransition, Start>;
void InstallLeftMouseDownCallback(const MouseActionCallback& onMouseDownCallback);
@@ -116,7 +128,10 @@ namespace AzToolsFramework
const ViewportInteraction::MouseInteraction& mouseInteraction) override;
void SetAxis(const AZ::Vector3& axis);
const AZ::Vector3& GetAxis() const { return m_fixed.m_axis; }
const AZ::Vector3& GetAxis() const
{
return m_fixed.m_axis;
}
template<typename Views>
void SetViews(Views&& views)
@@ -135,12 +150,9 @@ namespace AzToolsFramework
}
private:
void OnLeftMouseDownImpl(
const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override;
void OnLeftMouseUpImpl(
const ViewportInteraction::MouseInteraction& interaction) override;
void OnMouseMoveImpl(
const ViewportInteraction::MouseInteraction& interaction) override;
void OnLeftMouseDownImpl(const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override;
void OnLeftMouseUpImpl(const ViewportInteraction::MouseInteraction& interaction) override;
void OnMouseMoveImpl(const ViewportInteraction::MouseInteraction& interaction) override;
void InvalidateImpl() override;
void SetBoundsDirtyImpl() override;
@@ -155,16 +167,24 @@ namespace AzToolsFramework
MouseActionCallback m_onLeftMouseUpCallback = nullptr;
MouseActionCallback m_onMouseMoveCallback = nullptr;
ManipulatorViews m_manipulatorViews; ///< Look of manipulator.
ManipulatorViews m_manipulatorViews; //!< Look of manipulator.
};
LinearManipulator::Starter CalculateLinearManipulationDataStart(
const LinearManipulator::Fixed& fixed, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale,
const AZ::Transform& localTransform, const ViewportInteraction::MouseInteraction& interaction, float intersectionDistance,
const LinearManipulator::Fixed& fixed,
const AZ::Transform& worldFromLocal,
const AZ::Vector3& nonUniformScale,
const AZ::Transform& localTransform,
const ViewportInteraction::MouseInteraction& interaction,
float intersectionDistance,
const AzFramework::CameraState& cameraState);
LinearManipulator::Action CalculateLinearManipulationDataAction(
const LinearManipulator::Fixed& fixed, const LinearManipulator::Starter& starter,
const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale, const AZ::Transform& localTransform,
const GridSnapParameters& gridSnapParams, const ViewportInteraction::MouseInteraction& interaction);
const LinearManipulator::Fixed& fixed,
const LinearManipulator::Starter& starter,
const AZ::Transform& worldFromLocal,
const AZ::Vector3& nonUniformScale,
const AZ::Transform& localTransform,
const GridSnapParameters& gridSnapParams,
const ViewportInteraction::MouseInteraction& interaction);
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -26,56 +26,55 @@ namespace AzToolsFramework
using ManipulatorManagerId = IdType<struct ManipulatorManagerType>;
static const ManipulatorManagerId InvalidManipulatorManagerId = ManipulatorManagerId(0);
/// EBus interface used to send requests to ManipulatorManager.
class ManipulatorManagerRequests
: public AZ::EBusTraits
//! EBus interface used to send requests to ManipulatorManager.
class ManipulatorManagerRequests : public AZ::EBusTraits
{
public:
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById; /**< We can have multiple manipulator managers.
In the case where there are multiple viewports, each displaying
a different set of entities, a different manipulator manager is required
to provide a different collision space for each viewport so that mouse
hit detection can be handled properly. */
//! We can have multiple manipulator managers.
//! In the case where there are multiple viewports, each displaying
//! a different set of entities, a different manipulator manager is required
//! to provide a different collision space for each viewport so that mouse
//! hit detection can be handled properly.
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
using BusIdType = ManipulatorManagerId;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
virtual ~ManipulatorManagerRequests() = default;
/// Register a manipulator with the Manipulator Manager.
/// @param manipulator The manipulator parameter is passed as a shared_ptr so
/// that the system responsible for managing manipulators can maintain ownership
/// of the manipulator even if is destroyed while in use.
//! Register a manipulator with the Manipulator Manager.
//! @param manipulator The manipulator parameter is passed as a shared_ptr so
//! that the system responsible for managing manipulators can maintain ownership
//! of the manipulator even if is destroyed while in use.
virtual void RegisterManipulator(AZStd::shared_ptr<BaseManipulator> manipulator) = 0;
/// Unregister a manipulator from the Manipulator Manager.
/// After unregistering the manipulator, it will be excluded from mouse hit detection
/// and will not receive any mouse action events. The Manipulator Manager will also
/// relinquish ownership of the manipulator.
//! Unregister a manipulator from the Manipulator Manager.
//! After unregistering the manipulator, it will be excluded from mouse hit detection
//! and will not receive any mouse action events. The Manipulator Manager will also
//! relinquish ownership of the manipulator.
virtual void UnregisterManipulator(BaseManipulator* manipulator) = 0;
/// Delete a manipulator bound.
//! Delete a manipulator bound.
virtual void DeleteManipulatorBound(Picking::RegisteredBoundId boundId) = 0;
/// Mark the bound of a manipulator dirty so it's excluded from mouse hit detection.
/// This should be called whenever a manipulator is moved.
//! Mark the bound of a manipulator dirty so it's excluded from mouse hit detection.
//! This should be called whenever a manipulator is moved.
virtual void SetBoundDirty(Picking::RegisteredBoundId boundId) = 0;
/// Returns true if the manipulator manager is currently interacting, otherwise false.
//! Returns true if the manipulator manager is currently interacting, otherwise false.
virtual bool Interacting() const = 0;
/// Update the bound for a manipulator.
/// If \ref boundId hasn't been registered before or it's invalid, a new bound is created and set using \ref boundShapeData
/// @param manipulatorId The id of the manipulator whose bound needs to update.
/// @param boundId The id of the bound that needs to update.
/// @param boundShapeData The pointer to the new bound shape data.
/// @return If \ref boundId has been registered return the same id, otherwise create a new bound and return its id.
//! Update the bound for a manipulator.
//! If \ref boundId hasn't been registered before or it's invalid, a new bound is created and set using \ref boundShapeData.
//! @param manipulatorId The id of the manipulator whose bound needs to update.
//! @param boundId The id of the bound that needs to update.
//! @param boundShapeData The pointer to the new bound shape data.
//! @return If \ref boundId has been registered return the same id, otherwise create a new bound and return its id.
virtual Picking::RegisteredBoundId UpdateBound(
ManipulatorId manipulatorId, Picking::RegisteredBoundId boundId,
const Picking::BoundRequestShapeBase& boundShapeData) = 0;
ManipulatorId manipulatorId, Picking::RegisteredBoundId boundId, const Picking::BoundRequestShapeBase& boundShapeData) = 0;
};
/// Type to inherit to implement ManipulatorManagerRequests.
//! Type to inherit to implement ManipulatorManagerRequests.
using ManipulatorManagerRequestBus = AZ::EBus<ManipulatorManagerRequests>;
}//namespace AzToolsFramework
} // namespace AzToolsFramework
@@ -1,17 +1,17 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "BaseManipulator.h"
#include "ManipulatorManager.h"
#include "BaseManipulator.h"
#include <AzCore/std/tuple.h>
#include <AzToolsFramework/Picking/BoundInterface.h>
@@ -51,7 +51,8 @@ namespace AzToolsFramework
if (manipulator->Registered())
{
AZ_Assert(manipulator->GetManipulatorManagerId() == m_manipulatorManagerId,
AZ_Assert(
manipulator->GetManipulatorManagerId() == m_manipulatorManagerId,
"This manipulator was registered with a different manipulator manager!");
return;
}
@@ -75,8 +76,7 @@ namespace AzToolsFramework
}
Picking::RegisteredBoundId ManipulatorManager::UpdateBound(
const ManipulatorId manipulatorId, const Picking::RegisteredBoundId boundId,
const Picking::BoundRequestShapeBase& boundShapeData)
const ManipulatorId manipulatorId, const Picking::RegisteredBoundId boundId, const Picking::BoundRequestShapeBase& boundShapeData)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
@@ -99,8 +99,7 @@ namespace AzToolsFramework
AZ_Assert(boundItr->second == manipulatorId, "Manipulator and its bounds are out of synchronization!");
}
const Picking::RegisteredBoundId newBoundId =
m_boundManager.UpdateOrRegisterBound(boundShapeData, boundId);
const Picking::RegisteredBoundId newBoundId = m_boundManager.UpdateOrRegisterBound(boundShapeData, boundId);
if (newBoundId != boundId)
{
@@ -142,13 +141,6 @@ namespace AzToolsFramework
}
}
void ManipulatorManager::CheckModifierKeysChanged(
[[maybe_unused]] const ViewportInteraction::KeyboardModifiers keyboardModifiers,
const ViewportInteraction::MousePick& mousePick)
{
RefreshMouseOverState(mousePick);
}
void ManipulatorManager::DrawManipulators(
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
@@ -181,7 +173,8 @@ namespace AzToolsFramework
if (found != m_boundIdToManipulatorIdMap.end())
{
const auto manipulatorFound = m_manipulatorIdToPtrMap.find(found->second);
AZ_Assert(manipulatorFound != m_manipulatorIdToPtrMap.end(),
AZ_Assert(
manipulatorFound != m_manipulatorIdToPtrMap.end(),
"Found a bound without a corresponding Manipulator, "
"it's likely a bound was not cleaned up correctly");
rayIntersectionDistance = hitItr.second;
@@ -194,10 +187,9 @@ namespace AzToolsFramework
bool ManipulatorManager::ConsumeViewportMousePress(const ViewportInteraction::MouseInteraction& interaction)
{
if (auto pickedManipulator = PickManipulator(interaction.m_mousePick);
pickedManipulator.has_value())
if (auto pickedManipulator = PickManipulator(interaction.m_mousePick); pickedManipulator.has_value())
{
auto[manipulator, intersectionDistance] = pickedManipulator.value();
auto [manipulator, intersectionDistance] = pickedManipulator.value();
if (interaction.m_mouseButtons.Left())
{
@@ -249,24 +241,19 @@ namespace AzToolsFramework
const ViewportInteraction::MousePick& mousePick)
{
float intersectionDistance = 0.0f;
const AZStd::shared_ptr<BaseManipulator> pickedManipulator = PerformRaycast(
mousePick.m_rayOrigin, mousePick.m_rayDirection, intersectionDistance);
const AZStd::shared_ptr<BaseManipulator> pickedManipulator =
PerformRaycast(mousePick.m_rayOrigin, mousePick.m_rayDirection, intersectionDistance);
return pickedManipulator.get() != nullptr
? AZStd::make_optional(AZStd::make_tuple(pickedManipulator, intersectionDistance))
: AZStd::nullopt;
return pickedManipulator.get() != nullptr ? AZStd::make_optional(AZStd::make_tuple(pickedManipulator, intersectionDistance))
: AZStd::nullopt;
}
ManipulatorManager::PickedManipulatorId ManipulatorManager::PickManipulatorId(
const ViewportInteraction::MousePick& mousePick)
ManipulatorManager::PickedManipulatorId ManipulatorManager::PickManipulatorId(const ViewportInteraction::MousePick& mousePick)
{
auto [manipulator, intersectionDistance] =
PickManipulator(mousePick).value_or(PickedManipulator(nullptr, 0.0f));
const ManipulatorId pickedManipulatorId = manipulator
? manipulator->GetManipulatorId()
: InvalidManipulatorId;
auto [manipulator, intersectionDistance] = PickManipulator(mousePick).value_or(PickedManipulator(nullptr, 0.0f));
const ManipulatorId pickedManipulatorId = manipulator ? manipulator->GetManipulatorId() : InvalidManipulatorId;
return PickedManipulatorId{pickedManipulatorId, intersectionDistance};
return PickedManipulatorId{ pickedManipulatorId, intersectionDistance };
}
ManipulatorManager::ConsumeMouseMoveResult ManipulatorManager::ConsumeViewportMouseMove(
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -23,7 +23,7 @@ namespace AzFramework
{
struct CameraState;
class DebugDisplayRequests;
}
} // namespace AzFramework
namespace AzToolsFramework
{
@@ -40,15 +40,15 @@ namespace AzToolsFramework
class BaseManipulator;
class LinearManipulator;
/// State of overall manipulator manager.
//! State of overall manipulator manager.
struct ManipulatorManagerState
{
bool m_interacting;
};
/// This class serves to manage all relevant mouse events and coordinate all registered manipulators to function properly.
/// ManipulatorManager does not manage the life cycle of specific manipulators. The users of manipulators are responsible
/// for creating and deleting them at right time, as well as registering and unregistering accordingly.
//! This class serves to manage all relevant mouse events and coordinate all registered manipulators to function properly.
//! ManipulatorManager does not manage the life cycle of specific manipulators. The users of manipulators are responsible
//! for creating and deleting them at right time, as well as registering and unregistering accordingly.
class ManipulatorManager
: private ManipulatorManagerRequestBus::Handler
, private EditorEntityInfoNotificationBus::Handler
@@ -59,7 +59,7 @@ namespace AzToolsFramework
explicit ManipulatorManager(ManipulatorManagerId managerId);
~ManipulatorManager();
/// The result of consuming a mouse move.
//! The result of consuming a mouse move.
enum class ConsumeMouseMoveResult
{
None,
@@ -80,57 +80,52 @@ namespace AzToolsFramework
void DeleteManipulatorBound(Picking::RegisteredBoundId boundId) override;
void SetBoundDirty(Picking::RegisteredBoundId boundId) override;
Picking::RegisteredBoundId UpdateBound(
ManipulatorId manipulatorId, Picking::RegisteredBoundId boundId,
const Picking::BoundRequestShapeBase& boundShapeData) override;
bool Interacting() const override { return m_activeManipulator != nullptr; }
ManipulatorId manipulatorId, Picking::RegisteredBoundId boundId, const Picking::BoundRequestShapeBase& boundShapeData) override;
bool Interacting() const override
{
return m_activeManipulator != nullptr;
}
void DrawManipulators(
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction);
// O3DE_DEPRECATED(LY-117150)
/// Check if the modifier key state has changed - if so we may need to refresh
/// certain manipulator bounds.
AZ_DEPRECATED(
void CheckModifierKeysChanged(
ViewportInteraction::KeyboardModifiers keyboardModifiers,
const ViewportInteraction::MousePick& mousePick),
"CheckModifierKeysChanged is deprecated and will be removed in a future release");
protected:
/// @param rayOrigin The origin of the ray to test intersection with.
/// @param rayDirection The direction of the ray to test intersection with.
/// @param[out] rayIntersectionDistance The result intersecting point equals "rayOrigin + rayIntersectionDistance * rayDirection".
/// @return A pointer to a manipulator that the ray intersects. Null pointer if no intersection is detected.
//! @param rayOrigin The origin of the ray to test intersection with.
//! @param rayDirection The direction of the ray to test intersection with.
//! @param[out] rayIntersectionDistance The result intersecting point equals "rayOrigin + rayIntersectionDistance * rayDirection".
//! @return A pointer to a manipulator that the ray intersects. Null pointer if no intersection is detected.
AZStd::shared_ptr<BaseManipulator> PerformRaycast(
const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection, float& rayIntersectionDistance);
// EditorEntityInfoNotifications ...
void OnEntityInfoUpdatedVisibility(AZ::EntityId entityId, bool visible) override;
/// Alias for a Manipulator and intersection distance.
//! Alias for a Manipulator and intersection distance.
using PickedManipulator = AZStd::tuple<AZStd::shared_ptr<BaseManipulator>, float>;
/// Alias for a ManipulatorId and intersection distance.
//! Alias for a ManipulatorId and intersection distance.
using PickedManipulatorId = AZStd::tuple<ManipulatorId, float>;
/// Return the picked manipulator and intersection distance if a manipulator was intersected.
//! Return the picked manipulator and intersection distance if a manipulator was intersected.
AZStd::optional<PickedManipulator> PickManipulator(const ViewportInteraction::MousePick& mousePick);
/// Wrapper for PickManipulator to return the ManipulatorId directly.
//! Wrapper for PickManipulator to return the ManipulatorId directly.
PickedManipulatorId PickManipulatorId(const ViewportInteraction::MousePick& mousePick);
/// Called once per frame after all manipulators have been drawn (and their
/// bounds updated if required).
//! Called once per frame after all manipulators have been drawn (and their
//! bounds updated if required).
void RefreshMouseOverState(const ViewportInteraction::MousePick& mousePick);
ManipulatorManagerId m_manipulatorManagerId; ///< This manipulator manager's id.
ManipulatorId m_nextManipulatorIdToGenerate; ///< Id to use for the next manipulator that is registered with this manager.
ManipulatorManagerId m_manipulatorManagerId; //!< This manipulator manager's id.
ManipulatorId m_nextManipulatorIdToGenerate; //!< Id to use for the next manipulator that is registered with this manager.
AZStd::unordered_map<ManipulatorId, AZStd::shared_ptr<BaseManipulator>> m_manipulatorIdToPtrMap; ///< Mapping from a manipulatorId to the corresponding manipulator.
AZStd::unordered_map<Picking::RegisteredBoundId, ManipulatorId> m_boundIdToManipulatorIdMap; ///< Mapping from a boundId to the corresponding manipulatorId.
AZStd::unordered_map<ManipulatorId, AZStd::shared_ptr<BaseManipulator>>
m_manipulatorIdToPtrMap; //!< Mapping from a manipulatorId to the corresponding manipulator.
AZStd::unordered_map<Picking::RegisteredBoundId, ManipulatorId>
m_boundIdToManipulatorIdMap; //!< Mapping from a boundId to the corresponding manipulatorId.
AZStd::shared_ptr<BaseManipulator> m_activeManipulator; ///< The manipulator we are currently interacting with.
Picking::ManipulatorBoundManager m_boundManager; ///< All active manipulator bounds that could be interacted with.
AZStd::shared_ptr<BaseManipulator> m_activeManipulator; //!< The manipulator we are currently interacting with.
Picking::ManipulatorBoundManager m_boundManager; //!< All active manipulator bounds that could be interacted with.
};
// The main/default ManipulatorManagerId to be used for
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "ManipulatorSnapping.h"
@@ -19,19 +19,27 @@
#include <AzToolsFramework/Viewport/ViewportMessages.h>
AZ_CVAR(
AZ::Color, cl_viewportGridMainColor, AZ::Color::CreateFromRgba(26, 26, 26, 127), nullptr,
AZ::ConsoleFunctorFlags::Null, "Main color for snapping grid");
AZ::Color,
cl_viewportGridMainColor,
AZ::Color::CreateFromRgba(26, 26, 26, 127),
nullptr,
AZ::ConsoleFunctorFlags::Null,
"Main color for snapping grid");
AZ_CVAR(
AZ::Color, cl_viewportGridFadeColor, AZ::Color::CreateFromRgba(127, 127, 127, 0), nullptr,
AZ::ConsoleFunctorFlags::Null, "Fade color for snapping grid");
AZ::Color,
cl_viewportGridFadeColor,
AZ::Color::CreateFromRgba(127, 127, 127, 0),
nullptr,
AZ::ConsoleFunctorFlags::Null,
"Fade color for snapping grid");
AZ_CVAR(int, cl_viewportGridSquareCount, 20, nullptr, AZ::ConsoleFunctorFlags::Null, "Number of grid squares for snapping grid");
AZ_CVAR(float, cl_viewportGridLineWidth, 1.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "Width of grid lines for snapping grid");
AZ_CVAR(
int, cl_viewportGridSquareCount, 20, nullptr, AZ::ConsoleFunctorFlags::Null,
"Number of grid squares for snapping grid");
AZ_CVAR(
float, cl_viewportGridLineWidth, 1.0f, nullptr, AZ::ConsoleFunctorFlags::Null,
"Width of grid lines for snapping grid");
AZ_CVAR(
float, cl_viewportFadeLineDistanceScale, 1.0f, nullptr, AZ::ConsoleFunctorFlags::Null,
float,
cl_viewportFadeLineDistanceScale,
1.0f,
nullptr,
AZ::ConsoleFunctorFlags::Null,
"The scale to be applied to the line that fades out (scales the current gridSize)");
namespace AzToolsFramework
@@ -43,16 +51,17 @@ namespace AzToolsFramework
}
ManipulatorInteraction BuildManipulatorInteraction(
const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale,
const AZ::Vector3& worldRayOrigin, const AZ::Vector3& worldRayDirection)
const AZ::Transform& worldFromLocal,
const AZ::Vector3& nonUniformScale,
const AZ::Vector3& worldRayOrigin,
const AZ::Vector3& worldRayDirection)
{
const AZ::Transform worldFromLocalUniform = AzToolsFramework::TransformUniformScale(worldFromLocal);
const AZ::Transform localFromWorldUniform = worldFromLocalUniform.GetInverse();
return {localFromWorldUniform.TransformPoint(worldRayOrigin),
TransformDirectionNoScaling(localFromWorldUniform, worldRayDirection),
NonUniformScaleReciprocal(nonUniformScale),
ScaleReciprocal(worldFromLocalUniform)};
return { localFromWorldUniform.TransformPoint(worldRayOrigin),
TransformDirectionNoScaling(localFromWorldUniform, worldRayDirection), NonUniformScaleReciprocal(nonUniformScale),
ScaleReciprocal(worldFromLocalUniform) };
}
struct SnapAdjustment
@@ -87,8 +96,7 @@ namespace AzToolsFramework
}
AZ::Vector3 CalculateSnappedTerrainPosition(
const AZ::Vector3& worldSurfacePosition, const AZ::Transform& worldFromLocal,
const int viewportId, const float gridSize)
const AZ::Vector3& worldSurfacePosition, const AZ::Transform& worldFromLocal, const int viewportId, const float gridSize)
{
const AZ::Transform localFromWorld = worldFromLocal.GetInverse();
const AZ::Vector3 localSurfacePosition = localFromWorld.TransformPoint(worldSurfacePosition);
@@ -101,8 +109,7 @@ namespace AzToolsFramework
// find terrain height at xy snapped location
float terrainHeight = 0.0f;
ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult(
terrainHeight, viewportId,
&ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::TerrainHeight,
terrainHeight, viewportId, &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::TerrainHeight,
Vector3ToVector2(worldFromLocal.TransformPoint(localSnappedSurfacePosition)));
// set snapped z value to terrain height
@@ -116,8 +123,7 @@ namespace AzToolsFramework
{
bool snapping = false;
ViewportInteraction::ViewportInteractionRequestBus::EventResult(
snapping, viewportId,
&ViewportInteraction::ViewportInteractionRequestBus::Events::GridSnappingEnabled);
snapping, viewportId, &ViewportInteraction::ViewportInteractionRequestBus::Events::GridSnappingEnabled);
return snapping;
}
@@ -126,8 +132,7 @@ namespace AzToolsFramework
{
float gridSize = 0.0f;
ViewportInteraction::ViewportInteractionRequestBus::EventResult(
gridSize, viewportId,
&ViewportInteraction::ViewportInteractionRequestBus::Events::GridSize);
gridSize, viewportId, &ViewportInteraction::ViewportInteractionRequestBus::Events::GridSize);
return gridSize;
}
@@ -136,7 +141,8 @@ namespace AzToolsFramework
{
bool snapping = GridSnapping(viewportId);
const float gridSize = GridSize(viewportId);
if (AZ::IsClose(gridSize, 0.0f, 1e-2f)) // Same threshold value as min value for m_spinBox in SnapToWidget constructor in MainWindow.cpp
if (AZ::IsClose(
gridSize, 0.0f, 1e-2f)) // Same threshold value as min value for m_spinBox in SnapToWidget constructor in MainWindow.cpp
{
snapping = false;
}
@@ -148,8 +154,7 @@ namespace AzToolsFramework
{
bool snapping = false;
ViewportInteraction::ViewportInteractionRequestBus::EventResult(
snapping, viewportId,
&ViewportInteraction::ViewportInteractionRequestBus::Events::AngleSnappingEnabled);
snapping, viewportId, &ViewportInteraction::ViewportInteractionRequestBus::Events::AngleSnappingEnabled);
return snapping;
}
@@ -158,8 +163,7 @@ namespace AzToolsFramework
{
float angle = 0.0f;
ViewportInteraction::ViewportInteractionRequestBus::EventResult(
angle, viewportId,
&ViewportInteraction::ViewportInteractionRequestBus::Events::AngleStep);
angle, viewportId, &ViewportInteraction::ViewportInteractionRequestBus::Events::AngleStep);
return angle;
}
@@ -168,14 +172,12 @@ namespace AzToolsFramework
{
bool show = false;
ViewportInteraction::ViewportInteractionRequestBus::EventResult(
show, viewportId,
&ViewportInteraction::ViewportInteractionRequestBus::Events::ShowGrid);
show, viewportId, &ViewportInteraction::ViewportInteractionRequestBus::Events::ShowGrid);
return show;
}
void DrawSnappingGrid(
AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Transform& worldFromLocal, const float squareSize)
void DrawSnappingGrid(AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Transform& worldFromLocal, const float squareSize)
{
debugDisplay.PushMatrix(worldFromLocal);
@@ -197,21 +199,17 @@ namespace AzToolsFramework
// draw the faded end parts of the grid lines
debugDisplay.DrawLine(
AZ::Vector3(lineOffset, -halfGridSize, 0.0f),
AZ::Vector3(lineOffset, -(halfGridSize + fadeLineLength), 0.0f),
AZ::Vector3(lineOffset, -halfGridSize, 0.0f), AZ::Vector3(lineOffset, -(halfGridSize + fadeLineLength), 0.0f),
gridMainColor, gridFadeColor);
debugDisplay.DrawLine(
AZ::Vector3(lineOffset, halfGridSize, 0.0f),
AZ::Vector3(lineOffset, (halfGridSize + fadeLineLength), 0.0f),
AZ::Vector3(lineOffset, halfGridSize, 0.0f), AZ::Vector3(lineOffset, (halfGridSize + fadeLineLength), 0.0f), gridMainColor,
gridFadeColor);
debugDisplay.DrawLine(
AZ::Vector3(-halfGridSize, lineOffset, 0.0f), AZ::Vector3(-(halfGridSize + fadeLineLength), lineOffset, 0.0f),
gridMainColor, gridFadeColor);
debugDisplay.DrawLine(
AZ::Vector3(-halfGridSize, lineOffset, 0.0f),
AZ::Vector3(-(halfGridSize + fadeLineLength), lineOffset, 0.0f),
gridMainColor, gridFadeColor);
debugDisplay.DrawLine(
AZ::Vector3(halfGridSize, lineOffset, 0.0f),
AZ::Vector3((halfGridSize + fadeLineLength), lineOffset, 0.0f),
gridMainColor, gridFadeColor);
AZ::Vector3(halfGridSize, lineOffset, 0.0f), AZ::Vector3((halfGridSize + fadeLineLength), lineOffset, 0.0f), gridMainColor,
gridFadeColor);
// build a vector of the main grid lines to draw (start and end positions)
lines.push_back(AZ::Vector3(lineOffset, -halfGridSize, 0.0f));
@@ -1,19 +1,19 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Math/Vector3.h>
#include <AzCore/Math/Transform.h>
#include <AzCore/Math/Vector3.h>
namespace AzFramework
{
@@ -22,7 +22,7 @@ namespace AzFramework
namespace AzToolsFramework
{
/// Structure to encapsulate grid snapping properties.
//! Structure to encapsulate grid snapping properties.
struct GridSnapParameters
{
GridSnapParameters(bool gridSnap, float gridSize);
@@ -31,96 +31,92 @@ namespace AzToolsFramework
float m_gridSize;
};
/// Structure to hold transformed incoming viewport interaction from world space to manipulator space.
//! Structure to hold transformed incoming viewport interaction from world space to manipulator space.
struct ManipulatorInteraction
{
AZ::Vector3 m_localRayOrigin; ///< The ray origin (start) in the reference from of the manipulator.
AZ::Vector3 m_localRayDirection; ///< The ray direction in the reference from of the manipulator.
AZ::Vector3 m_nonUniformScaleReciprocal; ///< Handles inverting any non-uniform scale which was applied
///< separately from the transform.
float m_scaleReciprocal; ///< The scale reciprocal (1.0 / scale) of the transform used to move the
///< ray from world space to local space.
AZ::Vector3 m_localRayOrigin; //!< The ray origin (start) in the reference from of the manipulator.
AZ::Vector3 m_localRayDirection; //!< The ray direction in the reference from of the manipulator.
AZ::Vector3 m_nonUniformScaleReciprocal; //!< Handles inverting any non-uniform scale which was applied
//!< separately from the transform.
float m_scaleReciprocal; //!< The scale reciprocal (1.0 / scale) of the transform used to move the
//!< ray from world space to local space.
};
/// Build a ManipulatorInteraction structure from the incoming viewport interaction.
//! Build a ManipulatorInteraction structure from the incoming viewport interaction.
ManipulatorInteraction BuildManipulatorInteraction(
const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale,
const AZ::Vector3& worldRayOrigin, const AZ::Vector3& worldRayDirection);
const AZ::Transform& worldFromLocal,
const AZ::Vector3& nonUniformScale,
const AZ::Vector3& worldRayOrigin,
const AZ::Vector3& worldRayDirection);
/// Calculate the offset along an axis to adjust a position to stay snapped to a given grid size.
/// @note This is snap up or down to the nearest grid segment (e.g. 0.2 snaps to 0.0 -> delta 0.2,
/// 0.7 snaps to 1.0 -> delta 0.3).
AZ::Vector3 CalculateSnappedOffset(
const AZ::Vector3& unsnappedPosition, const AZ::Vector3& axis, float size);
//! Calculate the offset along an axis to adjust a position to stay snapped to a given grid size.
//! @note This is snap up or down to the nearest grid segment (e.g. 0.2 snaps to 0.0 -> delta 0.2,
//! 0.7 snaps to 1.0 -> delta 0.3).
AZ::Vector3 CalculateSnappedOffset(const AZ::Vector3& unsnappedPosition, const AZ::Vector3& axis, float size);
/// Return the amount to snap from the starting position given the current grid size.
/// @note A movement of more than half size (in either direction) will cause a snap by size.
//! Return the amount to snap from the starting position given the current grid size.
//! @note A movement of more than half size (in either direction) will cause a snap by size.
AZ::Vector3 CalculateSnappedAmount(const AZ::Vector3& unsnappedPosition, const AZ::Vector3& axis, float size);
/// For a given point on the terrain, calculate the closest xy position snapped to the grid
/// (z position is aligned to terrain height, not snapped to z grid)
//! For a given point on the terrain, calculate the closest xy position snapped to the grid
//! (z position is aligned to terrain height, not snapped to z grid)
AZ::Vector3 CalculateSnappedTerrainPosition(
const AZ::Vector3& worldSurfacePosition, const AZ::Transform& worldFromLocal,
int viewportId, float gridSize);
const AZ::Vector3& worldSurfacePosition, const AZ::Transform& worldFromLocal, int viewportId, float gridSize);
/// Wrapper for grid snapping and grid size bus calls.
//! Wrapper for grid snapping and grid size bus calls.
GridSnapParameters GridSnapSettings(int viewportId);
/// Wrapper for angle snapping enabled bus call.
//! Wrapper for angle snapping enabled bus call.
bool AngleSnapping(int viewportId);
/// Wrapper for angle snapping increment bus call.
/// @return Angle in degrees
//! Wrapper for angle snapping increment bus call.
//! @return Angle in degrees.
float AngleStep(int viewportId);
/// Wrapper for grid rendering check call.
//! Wrapper for grid rendering check call.
bool ShowingGrid(int viewportId);
/// Render the grid used for snapping.
void DrawSnappingGrid(
AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Transform& worldFromLocal, float squareSize);
//! Render the grid used for snapping.
void DrawSnappingGrid(AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Transform& worldFromLocal, float squareSize);
/// Round to x number of significant digits.
/// @param value Number to round.
/// @param exponent Precision to use when rounding.
//! Round to x number of significant digits.
//! @param value Number to round.
//! @param exponent Precision to use when rounding.
inline float Round(const float value, const float exponent)
{
const float precision = std::pow(10.0f, exponent);
return roundf(value * precision) / precision;
}
/// Round to 3 significant digits (3 digits common usage).
//! Round to 3 significant digits (3 digits common usage).
inline float Round3(const float value)
{
return Round(value, 3.0f);
}
/// Util to return sign of floating point number.
/// value > 0 return 1.0
/// value < 0 return -1.0
/// value == 0 return 0.0
//! Util to return sign of floating point number.
//! value > 0 return 1.0
//! value < 0 return -1.0
//! value == 0 return 0.0
inline float Sign(const float value)
{
return static_cast<float>((0.0f < value) - (value < 0.0f));
}
/// Find the max scale element and return the reciprocal of it.
/// Note: The reciprocal will be rounded to three significant digits to eliminate
/// noise in the value returned when dealing with values far from the origin.
//! Find the max scale element and return the reciprocal of it.
//! Note: The reciprocal will be rounded to three significant digits to eliminate
//! noise in the value returned when dealing with values far from the origin.
inline float ScaleReciprocal(const AZ::Transform& transform)
{
return Round3(1.0f / transform.GetUniformScale());
}
/// Find the reciprocal of the non-uniform scale.
/// Each element will be rounded to three significant digits to eliminate noise
/// when dealing with values far from the origin.
//! Find the reciprocal of the non-uniform scale.
//! Each element will be rounded to three significant digits to eliminate noise
//! when dealing with values far from the origin.
inline AZ::Vector3 NonUniformScaleReciprocal(const AZ::Vector3& nonUniformScale)
{
AZ::Vector3 scaleReciprocal = nonUniformScale.GetReciprocal();
return AZ::Vector3(
Round3(scaleReciprocal.GetX()),
Round3(scaleReciprocal.GetY()),
Round3(scaleReciprocal.GetZ()));
return AZ::Vector3(Round3(scaleReciprocal.GetX()), Round3(scaleReciprocal.GetY()), Round3(scaleReciprocal.GetZ()));
}
} // namespace AzToolsFramework
@@ -20,7 +20,7 @@ namespace AZ
namespace AzToolsFramework
{
/// Handles location for manipulators which have a global space but no local transformation.
//! Handles location for manipulators which have a global space but no local transformation.
class ManipulatorSpace
{
public:
@@ -32,17 +32,16 @@ namespace AzToolsFramework
const AZ::Vector3& GetNonUniformScale() const;
void SetNonUniformScale(const AZ::Vector3& nonUniformScale);
/// Calculates a transform combining the space and local transform, taking non-uniform scale into account.
//! Calculates a transform combining the space and local transform, taking non-uniform scale into account.
AZ::Transform ApplySpace(const AZ::Transform& localTransform) const;
private:
AZ::Transform m_space = AZ::Transform::CreateIdentity(); ///< Space the manipulator is in.
AZ::Vector3 m_nonUniformScale = AZ::Vector3::CreateOne(); ///< Handles non-uniform scale for the space the manipulator is in.
AZ::Transform m_space = AZ::Transform::CreateIdentity(); //!< Space the manipulator is in.
AZ::Vector3 m_nonUniformScale = AZ::Vector3::CreateOne(); //!< Handles non-uniform scale for the space the manipulator is in.
};
/// Handles location for manipulators which have a global space and a local position, but no local rotation.
class ManipulatorSpaceWithLocalPosition
: public ManipulatorSpace
//! Handles location for manipulators which have a global space and a local position, but no local rotation.
class ManipulatorSpaceWithLocalPosition : public ManipulatorSpace
{
public:
AZ_TYPE_INFO(ManipulatorSpaceWithLocalPosition, "{47BE15AF-60A8-436B-8F3F-7DDFB97220E6}")
@@ -52,12 +51,11 @@ namespace AzToolsFramework
void SetLocalPosition(const AZ::Vector3& localPosition);
private:
AZ::Vector3 m_localPosition = AZ::Vector3::CreateZero(); ///< Position in local space.
AZ::Vector3 m_localPosition = AZ::Vector3::CreateZero(); //!< Position in local space.
};
/// Handles location for manipulators which have a global space and a local transform (position and rotation).
class ManipulatorSpaceWithLocalTransform
: public ManipulatorSpace
//! Handles location for manipulators which have a global space and a local transform (position and rotation).
class ManipulatorSpaceWithLocalTransform : public ManipulatorSpace
{
public:
AZ_TYPE_INFO(ManipulatorSpaceWithLocalTransform, "{6D100797-1DD8-45B0-A21C-8893B770C0BC}")
@@ -72,6 +70,6 @@ namespace AzToolsFramework
void SetLocalOrientation(const AZ::Quaternion& localOrientation);
private:
AZ::Transform m_localTransform = AZ::Transform::CreateIdentity(); ///< Local transform.
AZ::Transform m_localTransform = AZ::Transform::CreateIdentity(); //!< Local transform.
};
} // namespace AzToolsFramework
@@ -1,26 +1,26 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "ManipulatorView.h"
#include <AzCore/Component/TransformBus.h>
#include <AzCore/Component/NonUniformScaleBus.h>
#include <AzCore/Component/TransformBus.h>
#include <AzCore/Math/VectorConversions.h>
#include <AzCore/std/containers/array.h>
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
#include <AzToolsFramework/Manipulators/AngularManipulator.h>
#include <AzToolsFramework/Manipulators/LinearManipulator.h>
#include <AzToolsFramework/Manipulators/LineSegmentSelectionManipulator.h>
#include <AzToolsFramework/Manipulators/LinearManipulator.h>
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
#include <AzToolsFramework/Manipulators/PlanarManipulator.h>
#include <AzToolsFramework/Manipulators/SplineSelectionManipulator.h>
#include <AzToolsFramework/Maths/TransformUtils.h>
@@ -33,8 +33,7 @@ namespace AzToolsFramework
AZ::Transform WorldFromLocalWithUniformScale(const AZ::EntityId entityId)
{
AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity();
AZ::TransformBus::EventResult(
worldFromLocal, entityId, &AZ::TransformBus::Events::GetWorldTM);
AZ::TransformBus::EventResult(worldFromLocal, entityId, &AZ::TransformBus::Events::GetWorldTM);
return TransformUniformScale(worldFromLocal);
}
@@ -56,13 +55,16 @@ namespace AzToolsFramework
return AzToolsFramework::TransformDirectionNoScaling(m_worldFromLocal, direction);
}
/// Take into account the location of the camera and orientate the axis so it faces the camera.
/// if we did correct the camera (shouldCorrect is true) then we know the axis facing us it negative.
/// we can use this to change the rendering for a flipped axis if we wish.
// Take into account the location of the camera and orientate the axis so it faces the camera.
// if we did correct the camera (shouldCorrect is true) then we know the axis facing us it negative.
// we can use this to change the rendering for a flipped axis if we wish.
static void CameraCorrectAxis(
const AZ::Vector3& axis, AZ::Vector3& correctedAxis, const ManipulatorManagerState& managerState,
const AZ::Vector3& axis,
AZ::Vector3& correctedAxis,
const ManipulatorManagerState& managerState,
const ViewportInteraction::MouseInteraction& mouseInteraction,
const AZ::Transform& worldFromLocal, const AZ::Vector3& localPosition,
const AZ::Transform& worldFromLocal,
const AZ::Vector3& localPosition,
const AzFramework::CameraState& cameraState,
bool* shouldCorrect = nullptr)
{
@@ -74,9 +76,7 @@ namespace AzToolsFramework
const bool correcting = ShouldFlipCameraAxis(worldFromLocal, localPosition, axis, cameraState);
// the corrected axis, if no flip was required, output == input
correctedAxis = correcting
? -axis
: axis;
correctedAxis = correcting ? -axis : axis;
// optional out ref to use if we care about the result
if (shouldCorrect)
@@ -86,10 +86,13 @@ namespace AzToolsFramework
}
}
/// Calculate quad bound in world space.
// calculate quad bound in world space.
static Picking::BoundShapeQuad CalculateQuadBound(
const AZ::Vector3& localPosition, const ManipulatorState& manipulatorState,
const AZ::Vector3& axis1, const AZ::Vector3& axis2, const float size)
const AZ::Vector3& localPosition,
const ManipulatorState& manipulatorState,
const AZ::Vector3& axis1,
const AZ::Vector3& axis2,
const float size)
{
const AZ::Vector3 worldPosition = manipulatorState.TransformPoint(localPosition);
const AZ::Vector3 endAxis1World = manipulatorState.TransformDirectionNoScaling(axis1) * size;
@@ -104,8 +107,10 @@ namespace AzToolsFramework
}
static Picking::BoundShapeQuad CalculateQuadBoundBillboard(
const AZ::Vector3& localPosition, const AZ::Transform& worldFromLocal,
const float size, const AzFramework::CameraState& cameraState)
const AZ::Vector3& localPosition,
const AZ::Transform& worldFromLocal,
const float size,
const AzFramework::CameraState& cameraState)
{
const AZ::Vector3 worldPosition = worldFromLocal.TransformPoint(localPosition);
@@ -117,10 +122,13 @@ namespace AzToolsFramework
return quadBound;
}
/// Calculate line bound in world space (axis and length).
// calculate line bound in world space (axis and length).
static Picking::BoundShapeLineSegment CalculateLineBound(
const AZ::Vector3& localPosition, const AZ::Transform& worldFromLocal,
const AZ::Vector3& axis, const float length, const float width)
const AZ::Vector3& localPosition,
const AZ::Transform& worldFromLocal,
const AZ::Vector3& axis,
const float length,
const float width)
{
Picking::BoundShapeLineSegment lineBound;
lineBound.m_start = worldFromLocal.TransformPoint(localPosition);
@@ -129,7 +137,7 @@ namespace AzToolsFramework
return lineBound;
}
/// Calculate line bound in world space (start and end point).
// calculate line bound in world space (start and end point).
static Picking::BoundShapeLineSegment CalculateLineBound(
const AZ::Vector3& localStartPosition,
const AZ::Vector3& localEndPosition,
@@ -143,10 +151,14 @@ namespace AzToolsFramework
return lineBound;
}
/// Calculate cone bound in world space.
// calculate cone bound in world space.
static Picking::BoundShapeCone CalculateConeBound(
const AZ::Vector3& localPosition, const AZ::Transform& worldFromLocal,
const AZ::Vector3& axis, const AZ::Vector3& offset, const float length, const float radius)
const AZ::Vector3& localPosition,
const AZ::Transform& worldFromLocal,
const AZ::Vector3& axis,
const AZ::Vector3& offset,
const float length,
const float radius)
{
Picking::BoundShapeCone coneBound;
coneBound.m_radius = radius;
@@ -156,10 +168,13 @@ namespace AzToolsFramework
return coneBound;
}
/// Calculate box bound in world space.
// calculate box bound in world space.
static Picking::BoundShapeBox CalculateBoxBound(
const AZ::Vector3& localPosition, const AZ::Transform& worldFromLocal,
const AZ::Quaternion& orientation, const AZ::Vector3& offset, const AZ::Vector3& halfExtents)
const AZ::Vector3& localPosition,
const AZ::Transform& worldFromLocal,
const AZ::Quaternion& orientation,
const AZ::Vector3& offset,
const AZ::Vector3& halfExtents)
{
Picking::BoundShapeBox boxBound;
boxBound.m_halfExtents = halfExtents;
@@ -168,10 +183,13 @@ namespace AzToolsFramework
return boxBound;
}
/// Calculate cylinder bound in world space.
// calculate cylinder bound in world space.
static Picking::BoundShapeCylinder CalculateCylinderBound(
const AZ::Vector3& localPosition, const AZ::Transform& worldFromLocal,
const AZ::Vector3& axis, const float length, const float radius)
const AZ::Vector3& localPosition,
const AZ::Transform& worldFromLocal,
const AZ::Vector3& axis,
const float length,
const float radius)
{
Picking::BoundShapeCylinder boxBound;
boxBound.m_base = worldFromLocal.TransformPoint(localPosition);
@@ -181,10 +199,9 @@ namespace AzToolsFramework
return boxBound;
}
/// Calculate sphere bound in world space.
// calculate sphere bound in world space.
static Picking::BoundShapeSphere CalculateSphereBound(
const AZ::Vector3& localPosition, const ManipulatorState& manipulatorState,
const float radius)
const AZ::Vector3& localPosition, const ManipulatorState& manipulatorState, const float radius)
{
Picking::BoundShapeSphere sphereBound;
sphereBound.m_center = manipulatorState.TransformPoint(localPosition);
@@ -192,10 +209,13 @@ namespace AzToolsFramework
return sphereBound;
}
/// Calculate torus bound in world space.
// calculate torus bound in world space.
static Picking::BoundShapeTorus CalculateTorusBound(
const AZ::Vector3& localPosition, const AZ::Transform& worldFromLocal,
const AZ::Vector3& axis, const float radius, const float width)
const AZ::Vector3& localPosition,
const AZ::Transform& worldFromLocal,
const AZ::Vector3& axis,
const float radius,
const float width)
{
Picking::BoundShapeTorus torusBound;
torusBound.m_center = worldFromLocal.TransformPoint(localPosition);
@@ -205,7 +225,7 @@ namespace AzToolsFramework
return torusBound;
}
/// Calculate spline bound in world space.
// calculate spline bound in world space.
static Picking::BoundShapeSpline CalculateSplineBound(
const AZStd::weak_ptr<const AZ::Spline>& spline, const AZ::Transform& worldFromLocal, const float width)
{
@@ -224,8 +244,7 @@ namespace AzToolsFramework
return lineWidth[mouseOver];
}
static AZ::Color ViewColor(
const bool mouseOver, const AZ::Color& defaultColor, const AZ::Color& mouseOverColor)
static AZ::Color ViewColor(const bool mouseOver, const AZ::Color& defaultColor, const AZ::Color& mouseOverColor)
{
const AZStd::array<AZ::Color, 2> viewColor = { { defaultColor, mouseOverColor } };
return viewColor[mouseOver].GetAsVector4();
@@ -250,19 +269,16 @@ namespace AzToolsFramework
void ManipulatorView::SetBoundDirty(const ManipulatorManagerId managerId)
{
ManipulatorManagerRequestBus::Event(
managerId, &ManipulatorManagerRequestBus::Events::SetBoundDirty, m_boundId);
ManipulatorManagerRequestBus::Event(managerId, &ManipulatorManagerRequestBus::Events::SetBoundDirty, m_boundId);
m_boundDirty = true;
}
void ManipulatorView::RefreshBound(
const ManipulatorManagerId managerId, const ManipulatorId manipulatorId,
const Picking::BoundRequestShapeBase& bound)
const ManipulatorManagerId managerId, const ManipulatorId manipulatorId, const Picking::BoundRequestShapeBase& bound)
{
ManipulatorManagerRequestBus::EventResult(
m_boundId, managerId, &ManipulatorManagerRequestBus::Events::UpdateBound,
manipulatorId, m_boundId, bound);
m_boundId, managerId, &ManipulatorManagerRequestBus::Events::UpdateBound, manipulatorId, m_boundId, bound);
// store the manager id if we know the bound has been registered
m_managerId = managerId;
@@ -271,8 +287,7 @@ namespace AzToolsFramework
}
void ManipulatorView::RefreshBoundInternal(
const ManipulatorManagerId managerId, const ManipulatorId manipulatorId,
const Picking::BoundRequestShapeBase& bound)
const ManipulatorManagerId managerId, const ManipulatorId manipulatorId, const Picking::BoundRequestShapeBase& bound)
{
// update the manipulator's bounds if necessary
// if m_screenSizeFixed is true, any camera movement can potentially change the size
@@ -287,8 +302,7 @@ namespace AzToolsFramework
{
if (m_boundId != Picking::InvalidBoundId)
{
ManipulatorManagerRequestBus::Event(
managerId, &ManipulatorManagerRequestBus::Events::DeleteManipulatorBound, m_boundId);
ManipulatorManagerRequestBus::Event(managerId, &ManipulatorManagerRequestBus::Events::DeleteManipulatorBound, m_boundId);
m_boundId = Picking::InvalidBoundId;
}
@@ -297,33 +311,34 @@ namespace AzToolsFramework
float ManipulatorView::ManipulatorViewScaleMultiplier(
const AZ::Vector3& worldPosition, const AzFramework::CameraState& cameraState) const
{
return ScreenSizeFixed()
? CalculateScreenToWorldMultiplier(worldPosition, cameraState)
: 1.0f;
return ScreenSizeFixed() ? CalculateScreenToWorldMultiplier(worldPosition, cameraState) : 1.0f;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ManipulatorViewQuad::Draw(
const ManipulatorManagerId managerId, const ManipulatorManagerState& managerState,
const ManipulatorId manipulatorId, const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState,
const ManipulatorManagerId managerId,
const ManipulatorManagerState& managerState,
const ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction)
{
const AZ::Vector3 axis1 = m_axis1;
const AZ::Vector3 axis2 = m_axis2;
CameraCorrectAxis(
axis1, m_cameraCorrectedAxis1, managerState, mouseInteraction,
manipulatorState.m_worldFromLocal, manipulatorState.m_localPosition, cameraState);
axis1, m_cameraCorrectedAxis1, managerState, mouseInteraction, manipulatorState.m_worldFromLocal,
manipulatorState.m_localPosition, cameraState);
CameraCorrectAxis(
axis2, m_cameraCorrectedAxis2, managerState, mouseInteraction,
manipulatorState.m_worldFromLocal, manipulatorState.m_localPosition, cameraState);
axis2, m_cameraCorrectedAxis2, managerState, mouseInteraction, manipulatorState.m_worldFromLocal,
manipulatorState.m_localPosition, cameraState);
const Picking::BoundShapeQuad quadBound =
CalculateQuadBound(
manipulatorState.m_localPosition, manipulatorState, m_cameraCorrectedAxis1, m_cameraCorrectedAxis2,
m_size * ManipulatorViewScaleMultiplier(
const Picking::BoundShapeQuad quadBound = CalculateQuadBound(
manipulatorState.m_localPosition, manipulatorState, m_cameraCorrectedAxis1, m_cameraCorrectedAxis2,
m_size *
ManipulatorViewScaleMultiplier(
manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState));
debugDisplay.SetLineWidth(defaultLineWidth(manipulatorState.m_mouseOver));
@@ -339,9 +354,7 @@ namespace AzToolsFramework
debugDisplay.SetColor(Vector3ToVector4(m_mouseOverColor.GetAsVector3(), 0.5f));
debugDisplay.CullOff();
debugDisplay.DrawQuad(
quadBound.m_corner1, quadBound.m_corner2,
quadBound.m_corner3, quadBound.m_corner4);
debugDisplay.DrawQuad(quadBound.m_corner1, quadBound.m_corner2, quadBound.m_corner3, quadBound.m_corner4);
debugDisplay.CullOn();
}
@@ -349,41 +362,46 @@ namespace AzToolsFramework
}
void ManipulatorViewQuadBillboard::Draw(
const ManipulatorManagerId managerId, const ManipulatorManagerState& /*managerState*/,
const ManipulatorId manipulatorId, const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState,
const ManipulatorManagerId managerId,
const ManipulatorManagerState& /*managerState*/,
const ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& /*mouseInteraction*/)
{
const Picking::BoundShapeQuad quadBound =
CalculateQuadBoundBillboard(manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal,
m_size * ManipulatorViewScaleMultiplier(
manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState), cameraState);
const Picking::BoundShapeQuad quadBound = CalculateQuadBoundBillboard(
manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal,
m_size *
ManipulatorViewScaleMultiplier(
manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState),
cameraState);
debugDisplay.SetColor(ViewColor(manipulatorState.m_mouseOver, m_color, m_mouseOverColor).GetAsVector4());
debugDisplay.DrawQuad(
quadBound.m_corner1, quadBound.m_corner2,
quadBound.m_corner3, quadBound.m_corner4);
debugDisplay.DrawQuad(quadBound.m_corner1, quadBound.m_corner2, quadBound.m_corner3, quadBound.m_corner4);
RefreshBoundInternal(managerId, manipulatorId, quadBound);
}
void ManipulatorViewLine::Draw(
const ManipulatorManagerId managerId, const ManipulatorManagerState& managerState,
const ManipulatorId manipulatorId, const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState,
const ManipulatorManagerId managerId,
const ManipulatorManagerState& managerState,
const ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction)
{
const float viewScale = ManipulatorViewScaleMultiplier(
manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState);
const float viewScale =
ManipulatorViewScaleMultiplier(manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState);
CameraCorrectAxis(
m_axis, m_cameraCorrectedAxis, managerState, mouseInteraction,
manipulatorState.m_worldFromLocal, manipulatorState.m_localPosition, cameraState);
m_axis, m_cameraCorrectedAxis, managerState, mouseInteraction, manipulatorState.m_worldFromLocal,
manipulatorState.m_localPosition, cameraState);
const Picking::BoundShapeLineSegment lineBound =
CalculateLineBound(
manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal,
m_cameraCorrectedAxis, m_length * viewScale, m_width * viewScale);
const Picking::BoundShapeLineSegment lineBound = CalculateLineBound(
manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal, m_cameraCorrectedAxis, m_length * viewScale,
m_width * viewScale);
debugDisplay.SetColor(ViewColor(manipulatorState.m_mouseOver, m_color, m_mouseOverColor).GetAsVector4());
debugDisplay.SetLineWidth(defaultLineWidth(manipulatorState.m_mouseOver));
@@ -393,13 +411,16 @@ namespace AzToolsFramework
}
void ManipulatorViewLineSelect::Draw(
const ManipulatorManagerId managerId, const ManipulatorManagerState& /*managerState*/,
const ManipulatorId manipulatorId, const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState,
const ManipulatorManagerId managerId,
const ManipulatorManagerState& /*managerState*/,
const ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction)
{
const float viewScale = ManipulatorViewScaleMultiplier(
manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState);
const float viewScale =
ManipulatorViewScaleMultiplier(manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState);
const Picking::BoundShapeLineSegment lineBound =
CalculateLineBound(m_localStart, m_localEnd, manipulatorState, m_width * viewScale);
@@ -407,44 +428,42 @@ namespace AzToolsFramework
if (manipulatorState.m_mouseOver)
{
const LineSegmentSelectionManipulator::Action action = CalculateManipulationDataAction(
manipulatorState.m_worldFromLocal, manipulatorState.m_nonUniformScale,
mouseInteraction.m_mousePick.m_rayOrigin, mouseInteraction.m_mousePick.m_rayDirection,
cameraState.m_farClip, m_localStart, m_localEnd);
manipulatorState.m_worldFromLocal, manipulatorState.m_nonUniformScale, mouseInteraction.m_mousePick.m_rayOrigin,
mouseInteraction.m_mousePick.m_rayDirection, cameraState.m_farClip, m_localStart, m_localEnd);
const AZ::Vector3 worldLineHitPosition = manipulatorState.TransformPoint(action.m_localLineHitPosition);
debugDisplay.SetColor(AZ::Vector4(0.0f, 1.0f, 0.0f, 1.0f));
debugDisplay.DrawBall(
worldLineHitPosition, ManipulatorViewScaleMultiplier(worldLineHitPosition, cameraState)
* g_defaultManipulatorSphereRadius, false);
worldLineHitPosition, ManipulatorViewScaleMultiplier(worldLineHitPosition, cameraState) * g_defaultManipulatorSphereRadius,
false);
}
RefreshBoundInternal(managerId, manipulatorId, lineBound);
}
void ManipulatorViewCone::Draw(
const ManipulatorManagerId managerId, const ManipulatorManagerState& managerState,
const ManipulatorId manipulatorId, const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState,
const ManipulatorManagerId managerId,
const ManipulatorManagerState& managerState,
const ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction)
{
const float viewScale = ManipulatorViewScaleMultiplier(
manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState);
const float viewScale =
ManipulatorViewScaleMultiplier(manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState);
CameraCorrectAxis(
m_axis, m_cameraCorrectedAxis, managerState, mouseInteraction,
manipulatorState.m_worldFromLocal, manipulatorState.m_localPosition,
cameraState, &m_shouldCorrect);
m_axis, m_cameraCorrectedAxis, managerState, mouseInteraction, manipulatorState.m_worldFromLocal,
manipulatorState.m_localPosition, cameraState, &m_shouldCorrect);
CameraCorrectAxis(
m_offset, m_cameraCorrectedOffset, managerState, mouseInteraction,
manipulatorState.m_worldFromLocal, manipulatorState.m_localPosition, cameraState);
m_offset, m_cameraCorrectedOffset, managerState, mouseInteraction, manipulatorState.m_worldFromLocal,
manipulatorState.m_localPosition, cameraState);
const Picking::BoundShapeCone coneBound =
CalculateConeBound(
manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal, m_cameraCorrectedAxis,
m_cameraCorrectedOffset * viewScale,
m_length * viewScale,
m_radius * viewScale);
const Picking::BoundShapeCone coneBound = CalculateConeBound(
manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal, m_cameraCorrectedAxis, m_cameraCorrectedOffset * viewScale,
m_length * viewScale, m_radius * viewScale);
debugDisplay.SetColor(ViewColor(manipulatorState.m_mouseOver, m_color, m_mouseOverColor).GetAsVector4());
if (m_shouldCorrect)
@@ -460,73 +479,77 @@ namespace AzToolsFramework
}
void ManipulatorViewBox::Draw(
const ManipulatorManagerId managerId, const ManipulatorManagerState& managerState,
const ManipulatorId manipulatorId, const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState,
const ManipulatorManagerId managerId,
const ManipulatorManagerState& managerState,
const ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction)
{
const float viewScale = ManipulatorViewScaleMultiplier(
manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState);
const float viewScale =
ManipulatorViewScaleMultiplier(manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState);
const AZ::Quaternion orientation = m_orientation;
CameraCorrectAxis(
m_offset, m_cameraCorrectedOffset, managerState, mouseInteraction,
manipulatorState.m_worldFromLocal, manipulatorState.m_localPosition,
cameraState);
m_offset, m_cameraCorrectedOffset, managerState, mouseInteraction, manipulatorState.m_worldFromLocal,
manipulatorState.m_localPosition, cameraState);
const Picking::BoundShapeBox boxBound =
CalculateBoxBound(manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal, orientation,
m_cameraCorrectedOffset * viewScale,
m_halfExtents * viewScale);
const Picking::BoundShapeBox boxBound = CalculateBoxBound(
manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal, orientation, m_cameraCorrectedOffset * viewScale,
m_halfExtents * viewScale);
const AZ::Vector3 xAxis = boxBound.m_orientation.TransformVector(AZ::Vector3::CreateAxisX());
const AZ::Vector3 yAxis = boxBound.m_orientation.TransformVector(AZ::Vector3::CreateAxisY());
const AZ::Vector3 zAxis = boxBound.m_orientation.TransformVector(AZ::Vector3::CreateAxisZ());
debugDisplay.SetColor(ViewColor(manipulatorState.m_mouseOver, m_color, m_mouseOverColor).GetAsVector4());
debugDisplay.DrawSolidOBB(boxBound.m_center,
xAxis, yAxis, zAxis, boxBound.m_halfExtents);
debugDisplay.DrawSolidOBB(boxBound.m_center, xAxis, yAxis, zAxis, boxBound.m_halfExtents);
RefreshBoundInternal(managerId, manipulatorId, boxBound);
}
void ManipulatorViewCylinder::Draw(
const ManipulatorManagerId managerId, const ManipulatorManagerState& managerState,
const ManipulatorId manipulatorId, const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState,
const ManipulatorManagerId managerId,
const ManipulatorManagerState& managerState,
const ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction)
{
const float viewScale = ManipulatorViewScaleMultiplier(
manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState);
const float viewScale =
ManipulatorViewScaleMultiplier(manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState);
CameraCorrectAxis(
m_axis, m_cameraCorrectedAxis, managerState, mouseInteraction,
manipulatorState.m_worldFromLocal, manipulatorState.m_localPosition, cameraState);
m_axis, m_cameraCorrectedAxis, managerState, mouseInteraction, manipulatorState.m_worldFromLocal,
manipulatorState.m_localPosition, cameraState);
const Picking::BoundShapeCylinder cylinderBound =
CalculateCylinderBound(
manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal, m_cameraCorrectedAxis,
m_length * viewScale,
m_radius * viewScale);
const Picking::BoundShapeCylinder cylinderBound = CalculateCylinderBound(
manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal, m_cameraCorrectedAxis, m_length * viewScale,
m_radius * viewScale);
debugDisplay.SetColor(ViewColor(manipulatorState.m_mouseOver, m_color, m_mouseOverColor).GetAsVector4());
debugDisplay.DrawSolidCylinder(cylinderBound.m_base + cylinderBound.m_axis * cylinderBound.m_height * 0.5f,
cylinderBound.m_axis, cylinderBound.m_radius, cylinderBound.m_height, false);
debugDisplay.DrawSolidCylinder(
cylinderBound.m_base + cylinderBound.m_axis * cylinderBound.m_height * 0.5f, cylinderBound.m_axis, cylinderBound.m_radius,
cylinderBound.m_height, false);
RefreshBoundInternal(managerId, manipulatorId, cylinderBound);
}
void ManipulatorViewSphere::Draw(
const ManipulatorManagerId managerId, const ManipulatorManagerState& /*managerState*/,
const ManipulatorId manipulatorId, const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState,
const ManipulatorManagerId managerId,
const ManipulatorManagerState& /*managerState*/,
const ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction)
{
const Picking::BoundShapeSphere sphereBound =
CalculateSphereBound(manipulatorState.m_localPosition, manipulatorState,
m_radius * ManipulatorViewScaleMultiplier(
manipulatorState.TransformPoint(manipulatorState.m_localPosition), cameraState));
const Picking::BoundShapeSphere sphereBound = CalculateSphereBound(
manipulatorState.m_localPosition, manipulatorState,
m_radius * ManipulatorViewScaleMultiplier(manipulatorState.TransformPoint(manipulatorState.m_localPosition), cameraState));
if (m_depthTest)
{
@@ -545,31 +568,32 @@ namespace AzToolsFramework
}
void ManipulatorViewCircle::Draw(
const ManipulatorManagerId managerId, const ManipulatorManagerState& /*managerState*/,
const ManipulatorId manipulatorId, const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState,
const ManipulatorManagerId managerId,
const ManipulatorManagerState& /*managerState*/,
const ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& /*mouseInteraction*/)
{
const float viewScale = ManipulatorViewScaleMultiplier(
manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState);
const float viewScale =
ManipulatorViewScaleMultiplier(manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState);
const Picking::BoundShapeTorus torusBound =
CalculateTorusBound(
manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal, m_axis,
m_radius * viewScale,
m_width * viewScale);
const Picking::BoundShapeTorus torusBound = CalculateTorusBound(
manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal, m_axis, m_radius * viewScale, m_width * viewScale);
// transform circle based on delta between default z up axis and other axes
const AZ::Transform worldFromLocalWithOrientation =
AZ::Transform::CreateTranslation(manipulatorState.m_worldFromLocal.GetTranslation()) *
AZ::Transform::CreateFromQuaternion(
(QuaternionFromTransformNoScaling(manipulatorState.m_worldFromLocal) *
AZ::Quaternion::CreateShortestArc(AZ::Vector3::CreateAxisZ(), m_axis)).GetNormalized());
AZ::Transform::CreateFromQuaternion((QuaternionFromTransformNoScaling(manipulatorState.m_worldFromLocal) *
AZ::Quaternion::CreateShortestArc(AZ::Vector3::CreateAxisZ(), m_axis))
.GetNormalized());
debugDisplay.CullOn();
debugDisplay.PushMatrix(worldFromLocalWithOrientation);
debugDisplay.SetColor(ViewColor(manipulatorState.m_mouseOver, m_color, m_mouseOverColor).GetAsVector4());
m_drawCircleFunc(debugDisplay, manipulatorState.m_localPosition, torusBound.m_majorRadius,
m_drawCircleFunc(
debugDisplay, manipulatorState.m_localPosition, torusBound.m_majorRadius,
worldFromLocalWithOrientation.GetInverse().TransformPoint(cameraState.m_position));
debugDisplay.PopMatrix();
debugDisplay.CullOff();
@@ -578,27 +602,28 @@ namespace AzToolsFramework
}
void DrawHalfDottedCircle(
AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Vector3& position,
const float radius, const AZ::Vector3& viewPos)
AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Vector3& position, const float radius, const AZ::Vector3& viewPos)
{
debugDisplay.DrawHalfDottedCircle(position, radius, viewPos);
}
void DrawFullCircle(
AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Vector3& position,
const float radius, const AZ::Vector3& /*viewPos*/)
AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Vector3& position, const float radius, const AZ::Vector3& /*viewPos*/)
{
debugDisplay.DrawCircle(position, radius);
debugDisplay.DrawCircle(position, radius);
}
void ManipulatorViewSplineSelect::Draw(
const ManipulatorManagerId managerId, const ManipulatorManagerState& /*managerState*/,
const ManipulatorId manipulatorId, const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState,
const ManipulatorManagerId managerId,
const ManipulatorManagerState& /*managerState*/,
const ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction)
{
const float viewScale = ManipulatorViewScaleMultiplier(
manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState);
const float viewScale =
ManipulatorViewScaleMultiplier(manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState);
const Picking::BoundShapeSpline splineBound =
CalculateSplineBound(m_spline, manipulatorState.m_worldFromLocal, m_width * viewScale);
@@ -606,16 +631,15 @@ namespace AzToolsFramework
if (manipulatorState.m_mouseOver)
{
const SplineSelectionManipulator::Action action = CalculateManipulationDataAction(
manipulatorState.m_worldFromLocal, mouseInteraction.m_mousePick.m_rayOrigin,
mouseInteraction.m_mousePick.m_rayDirection, m_spline);
manipulatorState.m_worldFromLocal, mouseInteraction.m_mousePick.m_rayOrigin, mouseInteraction.m_mousePick.m_rayDirection,
m_spline);
const AZ::Vector3 worldSplineHitPosition =
manipulatorState.m_worldFromLocal.TransformPoint(action.m_localSplineHitPosition);
const AZ::Vector3 worldSplineHitPosition = manipulatorState.m_worldFromLocal.TransformPoint(action.m_localSplineHitPosition);
debugDisplay.SetColor(m_color.GetAsVector4());
debugDisplay.DrawBall(
worldSplineHitPosition, ManipulatorViewScaleMultiplier(worldSplineHitPosition, cameraState)
* g_defaultManipulatorSphereRadius, false);
worldSplineHitPosition,
ManipulatorViewScaleMultiplier(worldSplineHitPosition, cameraState) * g_defaultManipulatorSphereRadius, false);
}
RefreshBoundInternal(managerId, manipulatorId, splineBound);
@@ -624,8 +648,7 @@ namespace AzToolsFramework
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
AZStd::unique_ptr<ManipulatorViewQuad> CreateManipulatorViewQuad(
const PlanarManipulator& planarManipulator, const AZ::Color& axis1Color,
const AZ::Color& axis2Color, const float size)
const PlanarManipulator& planarManipulator, const AZ::Color& axis1Color, const AZ::Color& axis2Color, const float size)
{
AZStd::unique_ptr<ManipulatorViewQuad> viewQuad = AZStd::make_unique<ManipulatorViewQuad>();
viewQuad->m_axis1 = planarManipulator.GetAxis1();
@@ -636,8 +659,7 @@ namespace AzToolsFramework
return viewQuad;
}
AZStd::unique_ptr<ManipulatorViewQuadBillboard> CreateManipulatorViewQuadBillboard(
const AZ::Color& color, const float size)
AZStd::unique_ptr<ManipulatorViewQuadBillboard> CreateManipulatorViewQuadBillboard(const AZ::Color& color, const float size)
{
AZStd::unique_ptr<ManipulatorViewQuadBillboard> viewQuad = AZStd::make_unique<ManipulatorViewQuadBillboard>();
viewQuad->m_size = size;
@@ -646,8 +668,7 @@ namespace AzToolsFramework
}
AZStd::unique_ptr<ManipulatorViewLine> CreateManipulatorViewLine(
const LinearManipulator& linearManipulator, const AZ::Color& color,
const float length, const float width)
const LinearManipulator& linearManipulator, const AZ::Color& color, const float length, const float width)
{
AZStd::unique_ptr<ManipulatorViewLine> viewLine = AZStd::make_unique<ManipulatorViewLine>();
viewLine->m_axis = linearManipulator.GetAxis();
@@ -658,8 +679,7 @@ namespace AzToolsFramework
}
AZStd::unique_ptr<ManipulatorViewLineSelect> CreateManipulatorViewLineSelect(
const LineSegmentSelectionManipulator& lineSegmentManipulator,
const AZ::Color& color, const float width)
const LineSegmentSelectionManipulator& lineSegmentManipulator, const AZ::Color& color, const float width)
{
AZStd::unique_ptr<ManipulatorViewLineSelect> viewLineSelect = AZStd::make_unique<ManipulatorViewLineSelect>();
viewLineSelect->m_localStart = lineSegmentManipulator.GetStart();
@@ -670,8 +690,11 @@ namespace AzToolsFramework
}
AZStd::unique_ptr<ManipulatorViewCone> CreateManipulatorViewCone(
const LinearManipulator& linearManipulator, const AZ::Color& color,
const AZ::Vector3& offset, const float length, const float radius)
const LinearManipulator& linearManipulator,
const AZ::Color& color,
const AZ::Vector3& offset,
const float length,
const float radius)
{
AZStd::unique_ptr<ManipulatorViewCone> viewCone = AZStd::make_unique<ManipulatorViewCone>();
viewCone->m_axis = linearManipulator.GetAxis();
@@ -683,8 +706,7 @@ namespace AzToolsFramework
}
AZStd::unique_ptr<ManipulatorViewBox> CreateManipulatorViewBox(
const AZ::Transform& transform, const AZ::Color& color,
const AZ::Vector3& offset, const AZ::Vector3& halfExtents)
const AZ::Transform& transform, const AZ::Color& color, const AZ::Vector3& offset, const AZ::Vector3& halfExtents)
{
AZStd::unique_ptr<ManipulatorViewBox> viewBox = AZStd::make_unique<ManipulatorViewBox>();
viewBox->m_orientation = transform.GetRotation();
@@ -695,8 +717,7 @@ namespace AzToolsFramework
}
AZStd::unique_ptr<ManipulatorViewCylinder> CreateManipulatorViewCylinder(
const LinearManipulator& linearManipulator, const AZ::Color& color,
const float length, const float radius)
const LinearManipulator& linearManipulator, const AZ::Color& color, const float length, const float radius)
{
AZStd::unique_ptr<ManipulatorViewCylinder> viewCylinder = AZStd::make_unique<ManipulatorViewCylinder>();
viewCylinder->m_axis = linearManipulator.GetAxis();
@@ -718,8 +739,11 @@ namespace AzToolsFramework
}
AZStd::unique_ptr<ManipulatorViewCircle> CreateManipulatorViewCircle(
const AngularManipulator& angularManipulator, const AZ::Color& color,
const float radius, const float width, const ManipulatorViewCircle::DrawCircleFunc drawFunc)
const AngularManipulator& angularManipulator,
const AZ::Color& color,
const float radius,
const float width,
const ManipulatorViewCircle::DrawCircleFunc drawFunc)
{
AZStd::unique_ptr<ManipulatorViewCircle> viewCircle = AZStd::make_unique<ManipulatorViewCircle>();
viewCircle->m_axis = angularManipulator.GetAxis();
@@ -731,8 +755,7 @@ namespace AzToolsFramework
}
AZStd::unique_ptr<ManipulatorViewSplineSelect> CreateManipulatorViewSplineSelect(
const SplineSelectionManipulator& splineManipulator,
const AZ::Color& color, const float width)
const SplineSelectionManipulator& splineManipulator, const AZ::Color& color, const float width)
{
AZStd::unique_ptr<ManipulatorViewSplineSelect> viewSplineSelect = AZStd::make_unique<ManipulatorViewSplineSelect>();
viewSplineSelect->m_spline = splineManipulator.GetSpline();
@@ -741,16 +764,12 @@ namespace AzToolsFramework
return viewSplineSelect;
}
AZ::Vector3 CalculateViewDirection(
const Manipulators& manipulators, const AZ::Vector3& worldViewPosition)
AZ::Vector3 CalculateViewDirection(const Manipulators& manipulators, const AZ::Vector3& worldViewPosition)
{
const AZ::Transform worldFromLocalWithTransform =
manipulators.GetSpace() * manipulators.GetLocalTransform();
const AZ::Transform worldFromLocalWithTransform = manipulators.GetSpace() * manipulators.GetLocalTransform();
AZ::Vector3 lookDirection =
(worldFromLocalWithTransform.GetTranslation() - worldViewPosition).GetNormalized();
AZ::Vector3 lookDirection = (worldFromLocalWithTransform.GetTranslation() - worldViewPosition).GetNormalized();
return TransformDirectionNoScaling(
worldFromLocalWithTransform.GetInverse(), lookDirection);
return TransformDirectionNoScaling(worldFromLocalWithTransform.GetInverse(), lookDirection);
}
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -26,13 +26,12 @@ namespace AzToolsFramework
class LineSegmentSelectionManipulator;
class SplineSelectionManipulator;
using DecideColorFn = AZStd::function<AZ::Color(
const ViewportInteraction::MouseInteraction&,
bool mouseOver, const AZ::Color& defaultColor)>;
using DecideColorFn =
AZStd::function<AZ::Color(const ViewportInteraction::MouseInteraction&, bool mouseOver, const AZ::Color& defaultColor)>;
extern const float g_defaultManipulatorSphereRadius;
/// State of an individual manipulator.
//! State of an individual manipulator.
struct ManipulatorState
{
AZ::Transform m_worldFromLocal;
@@ -40,18 +39,18 @@ namespace AzToolsFramework
AZ::Vector3 m_localPosition;
bool m_mouseOver;
/// Transforms a point, taking non-uniform scale into account.
//! Transforms a point, taking non-uniform scale into account.
AZ::Vector3 TransformPoint(const AZ::Vector3& point) const;
/// Rotates a direction into the space of the manipulator and normalizes it.
/// Non-uniform scaling and translation are not applied.
//! Rotates a direction into the space of the manipulator and normalizes it.
//! Non-uniform scaling and translation are not applied.
AZ::Vector3 TransformDirectionNoScaling(const AZ::Vector3& direction) const;
};
/// The base interface for the visual representation of manipulators.
/// The View represents the appearance and bounds of the manipulator for
/// the user to interact with. Any manipulator can have any view (some may
/// be more appropriate than others in certain cases).
//! The base interface for the visual representation of manipulators.
//! The View represents the appearance and bounds of the manipulator for
//! the user to interact with. Any manipulator can have any view (some may
//! be more appropriate than others in certain cases).
class ManipulatorView
{
public:
@@ -65,98 +64,107 @@ namespace AzToolsFramework
ManipulatorView& operator=(ManipulatorView&&) = default;
void SetBoundDirty(ManipulatorManagerId managerId);
void RefreshBound(
ManipulatorManagerId managerId, ManipulatorId manipulatorId, const Picking::BoundRequestShapeBase& bound);
void RefreshBound(ManipulatorManagerId managerId, ManipulatorId manipulatorId, const Picking::BoundRequestShapeBase& bound);
void Invalidate(ManipulatorManagerId managerId);
virtual void Draw(
ManipulatorManagerId managerId, const ManipulatorManagerState& managerState,
ManipulatorId manipulatorId, const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState,
ManipulatorManagerId managerId,
const ManipulatorManagerState& managerState,
ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction) = 0;
bool ScreenSizeFixed() const { return m_screenSizeFixed; }
bool ScreenSizeFixed() const
{
return m_screenSizeFixed;
}
protected:
AZ::Color m_mouseOverColor = BaseManipulator::s_defaultMouseOverColor; ///< What color should the manipulator
///< be when the mouse is hovering over it.
/// Scale the manipulator based on the distance
/// from the camera if m_screenSizeFixed is true.
float ManipulatorViewScaleMultiplier(
const AZ::Vector3& worldPosition, const AzFramework::CameraState& cameraState) const;
AZ::Color m_mouseOverColor = BaseManipulator::s_defaultMouseOverColor; //!< What color should the manipulator
//!< be when the mouse is hovering over it.
//! Scale the manipulator based on the distance
//! from the camera if m_screenSizeFixed is true.
float ManipulatorViewScaleMultiplier(const AZ::Vector3& worldPosition, const AzFramework::CameraState& cameraState) const;
/// Wrap the logic for updating a bound.
/// Should be called at the end of the Draw function once a concrete BoundRequestShape has
/// been created to use for dimensions for rendering.
void RefreshBoundInternal(
ManipulatorManagerId managerId, ManipulatorId manipulatorId, const Picking::BoundRequestShapeBase& bound);
//! Wrap the logic for updating a bound.
//! Should be called at the end of the Draw function once a concrete BoundRequestShape has
//! been created to use for dimensions for rendering.
void RefreshBoundInternal(ManipulatorManagerId managerId, ManipulatorId manipulatorId, const Picking::BoundRequestShapeBase& bound);
private:
Picking::RegisteredBoundId m_boundId = Picking::InvalidBoundId; ///< Used for hit detection.
ManipulatorManagerId m_managerId = InvalidManipulatorManagerId; /// The manipulator manager this view has been registered with.
bool m_screenSizeFixed = true; ///< Should manipulator size be adjusted based on camera distance.
bool m_boundDirty = true; ///< Do the bounds need to be recalculated.
Picking::RegisteredBoundId m_boundId = Picking::InvalidBoundId; //!< Used for hit detection.
ManipulatorManagerId m_managerId = InvalidManipulatorManagerId; //! The manipulator manager this view has been registered with.
bool m_screenSizeFixed = true; //!< Should manipulator size be adjusted based on camera distance.
bool m_boundDirty = true; //!< Do the bounds need to be recalculated.
};
// A collection of views (a manipulator may have 1 - * views)
using ManipulatorViews = AZStd::vector<AZStd::shared_ptr<ManipulatorView>>;
/// Display a quad representing part of a plane, rendered as 4 lines.
class ManipulatorViewQuad
: public ManipulatorView
//! Display a quad representing part of a plane, rendered as 4 lines.
class ManipulatorViewQuad : public ManipulatorView
{
public:
AZ_CLASS_ALLOCATOR(ManipulatorViewQuad, AZ::SystemAllocator, 0)
AZ_RTTI(ManipulatorViewQuad, "{D85E1B45-495E-4755-BCF2-6AE45F8BB2B0}", ManipulatorView)
void Draw(
ManipulatorManagerId managerId, const ManipulatorManagerState& managerState,
ManipulatorId manipulatorId, const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState,
ManipulatorManagerId managerId,
const ManipulatorManagerState& managerState,
ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction) override;
AZ::Vector3 m_axis1 = AZ::Vector3(1.0f, 0.0f, 0.0f);
AZ::Vector3 m_axis2 = AZ::Vector3(0.0f, 1.0f, 0.0f);
AZ::Color m_axis1Color = AZ::Color(1.0f, 0.0f, 0.0f, 1.0f);
AZ::Color m_axis2Color = AZ::Color(1.0f, 0.0f, 0.0f, 1.0f);
float m_size = 0.06f; ///< size to render and do mouse ray intersection tests against.
float m_size = 0.06f; //!< size to render and do mouse ray intersection tests against.
private:
AZ::Vector3 m_cameraCorrectedAxis1;
AZ::Vector3 m_cameraCorrectedAxis2;
};
/// A screen aligned quad, centered at the position of the manipulator, display filled.
class ManipulatorViewQuadBillboard
: public ManipulatorView
//! A screen aligned quad, centered at the position of the manipulator, display filled.
class ManipulatorViewQuadBillboard : public ManipulatorView
{
public:
AZ_CLASS_ALLOCATOR(ManipulatorViewQuadBillboard, AZ::SystemAllocator, 0)
AZ_RTTI(ManipulatorViewQuadBillboard, "{C205E967-E8C6-4A73-A31B-41EE5529B15B}", ManipulatorView)
void Draw(
ManipulatorManagerId managerId, const ManipulatorManagerState& managerState,
ManipulatorId manipulatorId, const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState,
ManipulatorManagerId managerId,
const ManipulatorManagerState& managerState,
ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction) override;
AZ::Color m_color = AZ::Color(1.0f, 0.0f, 0.0f, 1.0f);
float m_size = 0.005f; ///< size to render and do mouse ray intersection tests against.
float m_size = 0.005f; //!< size to render and do mouse ray intersection tests against.
};
/// Displays a debug style line starting from the manipulator's transform,
/// width determines the click area.
class ManipulatorViewLine
: public ManipulatorView
//! Displays a debug style line starting from the manipulator's transform,
//! width determines the click area.
class ManipulatorViewLine : public ManipulatorView
{
public:
AZ_CLASS_ALLOCATOR(ManipulatorViewLine, AZ::SystemAllocator, 0)
AZ_RTTI(ManipulatorViewLine, "{831EEF66-4A5C-450C-B152-EA4A0BC8A272}", ManipulatorView)
void Draw(
ManipulatorManagerId managerId, const ManipulatorManagerState& managerState,
ManipulatorId manipulatorId, const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState,
ManipulatorManagerId managerId,
const ManipulatorManagerState& managerState,
ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction) override;
AZ::Vector3 m_axis;
@@ -168,19 +176,21 @@ namespace AzToolsFramework
AZ::Vector3 m_cameraCorrectedAxis;
};
/// Variant of ManipulatorViewLine which instead of using an axis, provides begin and end
/// points for the line. Used for selection when inserting points along a line.
class ManipulatorViewLineSelect
: public ManipulatorView
//! Variant of ManipulatorViewLine which instead of using an axis, provides begin and end
//! points for the line. Used for selection when inserting points along a line.
class ManipulatorViewLineSelect : public ManipulatorView
{
public:
AZ_CLASS_ALLOCATOR(ManipulatorViewLineSelect, AZ::SystemAllocator, 0)
AZ_RTTI(ManipulatorViewLineSelect, "{BF26A947-91F8-4595-9A5B-481876EB2C48}", ManipulatorView)
void Draw(
ManipulatorManagerId managerId, const ManipulatorManagerState& managerState,
ManipulatorId manipulatorId, const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState,
ManipulatorManagerId managerId,
const ManipulatorManagerState& managerState,
ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction) override;
AZ::Vector3 m_localStart;
@@ -189,20 +199,22 @@ namespace AzToolsFramework
float m_width = 0.0f;
};
/// Displays a filled cone along the specified axis, offset is local translation from
/// the manipulator transform (often used in conjunction with other views to build
/// aggregate views such as arrows - e.g. a line and cone).
class ManipulatorViewCone
: public ManipulatorView
//! Displays a filled cone along the specified axis, offset is local translation from
//! the manipulator transform (often used in conjunction with other views to build
//! aggregate views such as arrows - e.g. a line and cone).
class ManipulatorViewCone : public ManipulatorView
{
public:
AZ_CLASS_ALLOCATOR(ManipulatorViewCone, AZ::SystemAllocator, 0)
AZ_RTTI(ManipulatorViewCone, "{BF042887-1F51-4FD8-8CA5-4A649B4AF356}", ManipulatorView)
void Draw(
ManipulatorManagerId managerId, const ManipulatorManagerState& managerState,
ManipulatorId manipulatorId, const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState,
ManipulatorManagerId managerId,
const ManipulatorManagerState& managerState,
ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction) override;
AZ::Vector3 m_offset;
@@ -217,20 +229,22 @@ namespace AzToolsFramework
bool m_shouldCorrect = false;
};
/// Displays a filled box, offset is local translation from the manipulator
/// transform, box is often used in conjunction with other views, orientation allows
/// the box to be orientated separately from the manipulator transform.
class ManipulatorViewBox
: public ManipulatorView
//! Displays a filled box, offset is local translation from the manipulator
//! transform, box is often used in conjunction with other views, orientation allows
//! the box to be orientated separately from the manipulator transform.
class ManipulatorViewBox : public ManipulatorView
{
public:
AZ_CLASS_ALLOCATOR(ManipulatorViewBox, AZ::SystemAllocator, 0)
AZ_RTTI(ManipulatorViewBox, "{2D082201-7878-4C1B-A3DD-7A629E5AD598}", ManipulatorView)
void Draw(
ManipulatorManagerId managerId, const ManipulatorManagerState& managerState,
ManipulatorId manipulatorId, const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState,
ManipulatorManagerId managerId,
const ManipulatorManagerState& managerState,
ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction) override;
AZ::Vector3 m_offset;
@@ -242,18 +256,20 @@ namespace AzToolsFramework
AZ::Vector3 m_cameraCorrectedOffset;
};
/// Displays a filled cylinder along the axis provided.
class ManipulatorViewCylinder
: public ManipulatorView
//! Displays a filled cylinder along the axis provided.
class ManipulatorViewCylinder : public ManipulatorView
{
public:
AZ_CLASS_ALLOCATOR(ManipulatorViewCylinder, AZ::SystemAllocator, 0)
AZ_RTTI(ManipulatorViewCylinder, "{9B8E5EF4-0F85-4CD0-A5FF-3C7097DF58AC}", ManipulatorView)
void Draw(
ManipulatorManagerId managerId, const ManipulatorManagerState& managerState,
ManipulatorId manipulatorId, const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState,
ManipulatorManagerId managerId,
const ManipulatorManagerState& managerState,
ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction) override;
AZ::Vector3 m_axis;
@@ -265,20 +281,22 @@ namespace AzToolsFramework
AZ::Vector3 m_cameraCorrectedAxis;
};
/// Displays a filled sphere at the transform of the manipulator, often used as
/// a selection manipulator. DecideColorFn allows more complex logic to be used
/// to decide the color of the manipulator (based on hover state etc.)
class ManipulatorViewSphere
: public ManipulatorView
//! Displays a filled sphere at the transform of the manipulator, often used as
//! a selection manipulator. DecideColorFn allows more complex logic to be used
//! to decide the color of the manipulator (based on hover state etc.)
class ManipulatorViewSphere : public ManipulatorView
{
public:
AZ_CLASS_ALLOCATOR(ManipulatorViewSphere, AZ::SystemAllocator, 0)
AZ_RTTI(ManipulatorViewSphere, "{324D8329-6E7B-4A5D-AC8A-8C0E1C984E38}", ManipulatorView)
void Draw(
ManipulatorManagerId managerId, const ManipulatorManagerState& managerState,
ManipulatorId manipulatorId, const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState,
ManipulatorManagerId managerId,
const ManipulatorManagerState& managerState,
ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction) override;
float m_radius = 0.0f;
@@ -287,23 +305,24 @@ namespace AzToolsFramework
bool m_depthTest = false;
};
/// Displays a wire circle. DrawCircleFunc can be used to either draw a full
/// circle or a half dotted circle where the part of the circle facing away
/// from the camera is dotted (useful for angular/rotation manipulators).
class ManipulatorViewCircle
: public ManipulatorView
//! Displays a wire circle. DrawCircleFunc can be used to either draw a full
//! circle or a half dotted circle where the part of the circle facing away
//! from the camera is dotted (useful for angular/rotation manipulators).
class ManipulatorViewCircle : public ManipulatorView
{
public:
AZ_CLASS_ALLOCATOR(ManipulatorViewCircle, AZ::SystemAllocator, 0)
AZ_RTTI(ManipulatorViewCircle, "{26563A03-3E48-49EB-9DCF-30EE4F567FCD}", ManipulatorView)
using DrawCircleFunc =
void(*)(AzFramework::DebugDisplayRequests&, const AZ::Vector3&, float, const AZ::Vector3&);
using DrawCircleFunc = void (*)(AzFramework::DebugDisplayRequests&, const AZ::Vector3&, float, const AZ::Vector3&);
void Draw(
ManipulatorManagerId managerId, const ManipulatorManagerState& managerState,
ManipulatorId manipulatorId, const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState,
ManipulatorManagerId managerId,
const ManipulatorManagerState& managerState,
ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction) override;
AZ::Vector3 m_axis;
@@ -316,26 +335,26 @@ namespace AzToolsFramework
// helpers to provide consistent function pointer interface for deciding
// on type of circle to draw (see DrawCircleFunc in ManipulatorViewCircle above)
void DrawHalfDottedCircle(
AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Vector3& position,
float radius, const AZ::Vector3& viewPos);
AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Vector3& position, float radius, const AZ::Vector3& viewPos);
void DrawFullCircle(
AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Vector3& position,
float radius, const AZ::Vector3& viewPos);
AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Vector3& position, float radius, const AZ::Vector3& viewPos);
/// Used for interaction with spline primitive - it will generate a spline bound
/// to be interacted with and will display the intersection point on the spline
/// where a user may wish to insert a point.
class ManipulatorViewSplineSelect
: public ManipulatorView
//! Used for interaction with spline primitive - it will generate a spline bound
//! to be interacted with and will display the intersection point on the spline
//! where a user may wish to insert a point.
class ManipulatorViewSplineSelect : public ManipulatorView
{
public:
AZ_CLASS_ALLOCATOR(ManipulatorViewSplineSelect, AZ::SystemAllocator, 0)
AZ_RTTI(ManipulatorViewSplineSelect, "{60996E49-D6BF-4817-BAA3-D27A407DD21A}", ManipulatorView)
void Draw(
ManipulatorManagerId managerId, const ManipulatorManagerState& managerState,
ManipulatorId manipulatorId, const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay, const AzFramework::CameraState& cameraState,
ManipulatorManagerId managerId,
const ManipulatorManagerState& managerState,
ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction) override;
AZStd::weak_ptr<const AZ::Spline> m_spline;
@@ -343,65 +362,61 @@ namespace AzToolsFramework
AZ::Color m_color = AZ::Color(0.0f, 1.0f, 0.0f, 1.0f);
};
/// Returns true if axis is pointing away from us (we should flip it).
//! Returns true if axis is pointing away from us (we should flip it).
inline bool ShouldFlipCameraAxis(
const AZ::Transform& worldFromLocal, const AZ::Vector3& localPosition,
const AZ::Vector3& axis, const AzFramework::CameraState& cameraState)
const AZ::Transform& worldFromLocal,
const AZ::Vector3& localPosition,
const AZ::Vector3& axis,
const AzFramework::CameraState& cameraState)
{
return (worldFromLocal.TransformPoint(localPosition) - cameraState.m_position).Dot(
TransformDirectionNoScaling(worldFromLocal, axis)) > 0.0f;
return (worldFromLocal.TransformPoint(localPosition) - cameraState.m_position)
.Dot(TransformDirectionNoScaling(worldFromLocal, axis)) > 0.0f;
}
/// @brief Return the world transform of the entity with uniform scale - choose
/// the largest element.
//! @brief Return the world transform of the entity with uniform scale - choose
//! the largest element.
AZ::Transform WorldFromLocalWithUniformScale(AZ::EntityId entityId);
/// Get the non-uniform scale for this entity id.
//! Get the non-uniform scale for this entity id.
AZ::Vector3 GetNonUniformScale(AZ::EntityId entityId);
// Helpers to create various manipulator views.
AZStd::unique_ptr<ManipulatorViewQuad> CreateManipulatorViewQuad(
const PlanarManipulator& planarManipulator, const AZ::Color& axis1Color,
const AZ::Color& axis2Color, float size);
const PlanarManipulator& planarManipulator, const AZ::Color& axis1Color, const AZ::Color& axis2Color, float size);
AZStd::unique_ptr<ManipulatorViewQuadBillboard> CreateManipulatorViewQuadBillboard(
const AZ::Color& color, float size);
AZStd::unique_ptr<ManipulatorViewQuadBillboard> CreateManipulatorViewQuadBillboard(const AZ::Color& color, float size);
AZStd::unique_ptr<ManipulatorViewLine> CreateManipulatorViewLine(
const LinearManipulator& linearManipulator, const AZ::Color& color,
float length, float width);
const LinearManipulator& linearManipulator, const AZ::Color& color, float length, float width);
AZStd::unique_ptr<ManipulatorViewLineSelect> CreateManipulatorViewLineSelect(
const LineSegmentSelectionManipulator& lineSegmentManipulator, const AZ::Color& color,
float width);
const LineSegmentSelectionManipulator& lineSegmentManipulator, const AZ::Color& color, float width);
AZStd::unique_ptr<ManipulatorViewCone> CreateManipulatorViewCone(
const LinearManipulator& linearManipulator, const AZ::Color& color,
const AZ::Vector3& offset, float length, float radius);
const LinearManipulator& linearManipulator, const AZ::Color& color, const AZ::Vector3& offset, float length, float radius);
AZStd::unique_ptr<ManipulatorViewBox> CreateManipulatorViewBox(
const AZ::Transform& transform, const AZ::Color& color,
const AZ::Vector3& offset, const AZ::Vector3& halfExtents);
const AZ::Transform& transform, const AZ::Color& color, const AZ::Vector3& offset, const AZ::Vector3& halfExtents);
AZStd::unique_ptr<ManipulatorViewCylinder> CreateManipulatorViewCylinder(
const LinearManipulator& linearManipulator, const AZ::Color& color,
float length, float radius);
const LinearManipulator& linearManipulator, const AZ::Color& color, float length, float radius);
AZStd::unique_ptr<ManipulatorViewSphere> CreateManipulatorViewSphere(
const AZ::Color& color, float radius, const DecideColorFn& decideColor, bool enableDepthTest = false);
AZStd::unique_ptr<ManipulatorViewCircle> CreateManipulatorViewCircle(
const AngularManipulator& angularManipulator, const AZ::Color& color,
float radius, float width, ManipulatorViewCircle::DrawCircleFunc drawFunc);
const AngularManipulator& angularManipulator,
const AZ::Color& color,
float radius,
float width,
ManipulatorViewCircle::DrawCircleFunc drawFunc);
AZStd::unique_ptr<ManipulatorViewSplineSelect> CreateManipulatorViewSplineSelect(
const SplineSelectionManipulator& splineManipulator, const AZ::Color& color,
float width);
const SplineSelectionManipulator& splineManipulator, const AZ::Color& color, float width);
/// Returns the vector between the view (camera) and the manipulator in the space
/// of the Manipulator (manipulator space + local transform).
AZ::Vector3 CalculateViewDirection(
const Manipulators& manipulators, const AZ::Vector3& worldViewPosition);
//! Returns the vector between the view (camera) and the manipulator in the space
//! of the Manipulator (manipulator space + local transform).
AZ::Vector3 CalculateViewDirection(const Manipulators& manipulators, const AZ::Vector3& worldViewPosition);
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "MultiLinearManipulator.h"
@@ -56,10 +56,13 @@ namespace AzToolsFramework
}
static MultiLinearManipulator::Action BuildMultiLinearManipulatorAction(
const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale, const AZ::Transform& localTransform,
const AZ::Transform& worldFromLocal,
const AZ::Vector3& nonUniformScale,
const AZ::Transform& localTransform,
const ViewportInteraction::MouseInteraction& interaction,
const AZStd::vector<LinearManipulator::Fixed>& fixedAxes,
const AZStd::vector<LinearManipulator::Starter>& starterStates, const GridSnapParameters& gridSnapParams)
const AZStd::vector<LinearManipulator::Starter>& starterStates,
const GridSnapParameters& gridSnapParams)
{
MultiLinearManipulator::Action action;
action.m_viewportId = interaction.m_interactionId.m_viewportId;
@@ -96,8 +99,8 @@ namespace AzToolsFramework
const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId);
// pass action containing all linear actions for each axis to handler
m_onLeftMouseDownCallback(BuildMultiLinearManipulatorAction(
worldFromLocalUniformScale, GetNonUniformScale(), GetLocalTransform(),
interaction, m_fixedAxes, m_starters, gridSnapParams));
worldFromLocalUniformScale, GetNonUniformScale(), GetLocalTransform(), interaction, m_fixedAxes, m_starters,
gridSnapParams));
}
}
@@ -108,8 +111,8 @@ namespace AzToolsFramework
const AZ::Transform worldFromLocalUniformScale = TransformUniformScale(GetSpace());
const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId);
m_onMouseMoveCallback(BuildMultiLinearManipulatorAction(
worldFromLocalUniformScale, GetNonUniformScale(), GetLocalTransform(),
interaction, m_fixedAxes, m_starters, gridSnapParams));
worldFromLocalUniformScale, GetNonUniformScale(), GetLocalTransform(), interaction, m_fixedAxes, m_starters,
gridSnapParams));
}
}
@@ -120,8 +123,8 @@ namespace AzToolsFramework
const AZ::Transform worldFromLocalUniformScale = TransformUniformScale(GetSpace());
const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId);
m_onLeftMouseUpCallback(BuildMultiLinearManipulatorAction(
worldFromLocalUniformScale, GetNonUniformScale(), GetLocalTransform(),
interaction, m_fixedAxes, m_starters, gridSnapParams));
worldFromLocalUniformScale, GetNonUniformScale(), GetLocalTransform(), interaction, m_fixedAxes, m_starters,
gridSnapParams));
m_starters.clear();
}
@@ -138,36 +141,31 @@ namespace AzToolsFramework
const AZ::Transform combined = TransformUniformScale(GetSpace()) * GetLocalTransform();
for (const auto& fixed : m_fixedAxes)
{
DrawAxis(
debugDisplay, combined.GetTranslation(), TransformDirectionNoScaling(combined, fixed.m_axis));
DrawAxis(debugDisplay, combined.GetTranslation(), TransformDirectionNoScaling(combined, fixed.m_axis));
}
}
for (auto& view : m_manipulatorViews)
{
view->Draw(
GetManipulatorManagerId(), managerState,
GetManipulatorId(), {
ApplySpace(GetLocalTransform()), GetNonUniformScale(),
AZ::Vector3::CreateZero(), MouseOver()
},
debugDisplay, cameraState, mouseInteraction);
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay,
cameraState, mouseInteraction);
}
}
void MultiLinearManipulator::AddAxis(const AZ::Vector3& axis)
{
m_fixedAxes.push_back(LinearManipulator::Fixed{axis});
m_fixedAxes.push_back(LinearManipulator::Fixed{ axis });
}
void MultiLinearManipulator::AddAxes(const AZStd::vector<AZ::Vector3>& axes)
{
AZStd::transform(
axes.begin(), axes.end(),
AZStd::back_inserter(m_fixedAxes),
axes.begin(), axes.end(), AZStd::back_inserter(m_fixedAxes),
[](const AZ::Vector3& axis)
{
return LinearManipulator::Fixed{axis};
return LinearManipulator::Fixed{ axis };
});
}
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -80,12 +80,9 @@ namespace AzToolsFramework
}
private:
void OnLeftMouseDownImpl(
const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override;
void OnLeftMouseUpImpl(
const ViewportInteraction::MouseInteraction& interaction) override;
void OnMouseMoveImpl(
const ViewportInteraction::MouseInteraction& interaction) override;
void OnLeftMouseDownImpl(const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override;
void OnLeftMouseUpImpl(const ViewportInteraction::MouseInteraction& interaction) override;
void OnMouseMoveImpl(const ViewportInteraction::MouseInteraction& interaction) override;
void InvalidateImpl() override;
void SetBoundsDirtyImpl() override;
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "PlanarManipulator.h"
@@ -22,12 +22,15 @@
namespace AzToolsFramework
{
PlanarManipulator::StartInternal PlanarManipulator::CalculateManipulationDataStart(
const Fixed& fixed, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale, const AZ::Transform& localTransform,
const ViewportInteraction::MouseInteraction& interaction, const float intersectionDistance)
const Fixed& fixed,
const AZ::Transform& worldFromLocal,
const AZ::Vector3& nonUniformScale,
const AZ::Transform& localTransform,
const ViewportInteraction::MouseInteraction& interaction,
const float intersectionDistance)
{
const ManipulatorInteraction manipulatorInteraction =
BuildManipulatorInteraction(
worldFromLocal, nonUniformScale, interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection);
const ManipulatorInteraction manipulatorInteraction = BuildManipulatorInteraction(
worldFromLocal, nonUniformScale, interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection);
const AZ::Vector3 normal = TransformDirectionNoScaling(localTransform, fixed.m_normal);
@@ -37,8 +40,8 @@ namespace AzToolsFramework
StartInternal startInternal;
Internal::CalculateRayPlaneIntersectingPoint(
manipulatorInteraction.m_localRayOrigin, manipulatorInteraction.m_localRayDirection,
localIntersectionPoint, normal, startInternal.m_localHitPosition);
manipulatorInteraction.m_localRayOrigin, manipulatorInteraction.m_localRayDirection, localIntersectionPoint, normal,
startInternal.m_localHitPosition);
startInternal.m_localPosition = localTransform.GetTranslation();
@@ -46,13 +49,16 @@ namespace AzToolsFramework
}
PlanarManipulator::Action PlanarManipulator::CalculateManipulationDataAction(
const Fixed& fixed, const StartInternal& startInternal, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale,
const AZ::Transform& localTransform, const GridSnapParameters& gridSnapParams,
const Fixed& fixed,
const StartInternal& startInternal,
const AZ::Transform& worldFromLocal,
const AZ::Vector3& nonUniformScale,
const AZ::Transform& localTransform,
const GridSnapParameters& gridSnapParams,
const ViewportInteraction::MouseInteraction& interaction)
{
const ManipulatorInteraction manipulatorInteraction =
BuildManipulatorInteraction(
worldFromLocal, nonUniformScale, interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection);
const ManipulatorInteraction manipulatorInteraction = BuildManipulatorInteraction(
worldFromLocal, nonUniformScale, interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection);
const AZ::Vector3 normal = TransformDirectionNoScaling(localTransform, fixed.m_normal);
@@ -61,8 +67,8 @@ namespace AzToolsFramework
// if an invalid ray intersection is attempted
AZ::Vector3 localHitPosition = startInternal.m_localHitPosition;
Internal::CalculateRayPlaneIntersectingPoint(
manipulatorInteraction.m_localRayOrigin, manipulatorInteraction.m_localRayDirection,
startInternal.m_localHitPosition, normal, localHitPosition);
manipulatorInteraction.m_localRayOrigin, manipulatorInteraction.m_localRayDirection, startInternal.m_localHitPosition, normal,
localHitPosition);
localHitPosition = Internal::TryConstrainHitPositionToView(
localHitPosition, startInternal.m_localHitPosition, worldFromLocal.GetInverse(),
@@ -126,8 +132,8 @@ namespace AzToolsFramework
const AZ::Transform worldFromLocalUniformScale = TransformUniformScale(GetSpace());
m_startInternal = CalculateManipulationDataStart(
m_fixed, worldFromLocalUniformScale, GetNonUniformScale(), TransformNormalizedScale(GetLocalTransform()),
interaction, rayIntersectionDistance);
m_fixed, worldFromLocalUniformScale, GetNonUniformScale(), TransformNormalizedScale(GetLocalTransform()), interaction,
rayIntersectionDistance);
if (m_onLeftMouseDownCallback)
{
@@ -180,9 +186,10 @@ namespace AzToolsFramework
// display the exact hit (ray intersection) of the mouse pick on the manipulator
DrawTransformAxes(
debugDisplay, TransformUniformScale(GetSpace()) *
AZ::Transform::CreateTranslation(
action.m_start.m_localHitPosition + GetNonUniformScale() * action.m_current.m_localOffset));
debugDisplay,
TransformUniformScale(GetSpace()) *
AZ::Transform::CreateTranslation(
action.m_start.m_localHitPosition + GetNonUniformScale() * action.m_current.m_localOffset));
}
AZ::Transform combined = GetLocalTransform();
@@ -191,23 +198,16 @@ namespace AzToolsFramework
DrawTransformAxes(debugDisplay, combined);
DrawAxis(
debugDisplay, combined.GetTranslation(),
TransformDirectionNoScaling(GetLocalTransform(), m_fixed.m_axis1));
DrawAxis(
debugDisplay, combined.GetTranslation(),
TransformDirectionNoScaling(GetLocalTransform(), m_fixed.m_axis2));
DrawAxis(debugDisplay, combined.GetTranslation(), TransformDirectionNoScaling(GetLocalTransform(), m_fixed.m_axis1));
DrawAxis(debugDisplay, combined.GetTranslation(), TransformDirectionNoScaling(GetLocalTransform(), m_fixed.m_axis2));
}
for (auto& view : m_manipulatorViews)
{
view->Draw(
GetManipulatorManagerId(), managerState,
GetManipulatorId(), {
ApplySpace(GetLocalTransform()), GetNonUniformScale(),
AZ::Vector3::CreateZero(), MouseOver()
},
debugDisplay, cameraState, mouseInteraction);
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay,
cameraState, mouseInteraction);
}
}
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -23,13 +23,13 @@ namespace AzToolsFramework
class ManipulatorView;
struct GridSnapParameters;
/// PlanarManipulator serves as a visual tool for users to modify values
/// in two dimension in a plane defined two non-collinear axes in 3D space.
//! PlanarManipulator serves as a visual tool for users to modify values
//! in two dimension in a plane defined two non-collinear axes in 3D space.
class PlanarManipulator
: public BaseManipulator
, public ManipulatorSpaceWithLocalTransform
{
/// Private constructor.
//! Private constructor.
explicit PlanarManipulator(const AZ::Transform& worldFromLocal);
public:
@@ -42,43 +42,51 @@ namespace AzToolsFramework
~PlanarManipulator() = default;
/// A Manipulator must only be created and managed through a shared_ptr.
//! A Manipulator must only be created and managed through a shared_ptr.
static AZStd::shared_ptr<PlanarManipulator> MakeShared(const AZ::Transform& worldFromLocal);
/// Unchanging data set once for the planar manipulator.
//! Unchanging data set once for the planar manipulator.
struct Fixed
{
AZ::Vector3 m_axis1 = AZ::Vector3::CreateAxisX(); ///< m_axis1 and m_axis2 have to be orthogonal, they together define a plane in 3d space.
AZ::Vector3 m_axis1 =
AZ::Vector3::CreateAxisX(); //!< m_axis1 and m_axis2 have to be orthogonal, they together define a plane in 3d space.
AZ::Vector3 m_axis2 = AZ::Vector3::CreateAxisY();
AZ::Vector3 m_normal = AZ::Vector3::CreateAxisZ(); ///< m_normal is calculated automatically when setting the axes.
AZ::Vector3 m_normal = AZ::Vector3::CreateAxisZ(); //!< m_normal is calculated automatically when setting the axes.
};
/// The state of the manipulator at the start of an interaction.
//! The state of the manipulator at the start of an interaction.
struct Start
{
AZ::Vector3 m_localPosition; ///< The current position of the manipulator in local space.
AZ::Vector3 m_localHitPosition; ///< The intersection point in local space between the ray and the manipulator when the mouse down event happens.
AZ::Vector3 m_localPosition; //!< The current position of the manipulator in local space.
AZ::Vector3 m_localHitPosition; //!< The intersection point in local space between the ray and the manipulator when the mouse
//!< down event happens.
};
/// The state of the manipulator during an interaction.
//! The state of the manipulator during an interaction.
struct Current
{
AZ::Vector3 m_localOffset; ///< The current position of the manipulator in local space.
AZ::Vector3 m_localOffset; //!< The current position of the manipulator in local space.
};
/// Mouse action data used by MouseActionCallback (wraps Start and Current manipulator state).
//! Mouse action data used by MouseActionCallback (wraps Start and Current manipulator state).
struct Action
{
Fixed m_fixed;
Start m_start;
Current m_current;
ViewportInteraction::KeyboardModifiers m_modifiers;
AZ::Vector3 LocalPosition() const { return m_start.m_localPosition + m_current.m_localOffset; }
AZ::Vector3 LocalPositionOffset() const { return m_current.m_localOffset; }
AZ::Vector3 LocalPosition() const
{
return m_start.m_localPosition + m_current.m_localOffset;
}
AZ::Vector3 LocalPositionOffset() const
{
return m_current.m_localOffset;
}
};
/// This is the function signature of callbacks that will be invoked whenever a manipulator
/// is being clicked on or dragged.
//! This is the function signature of callbacks that will be invoked whenever a manipulator
//! is being clicked on or dragged.
using MouseActionCallback = AZStd::function<void(const Action&)>;
void InstallLeftMouseDownCallback(const MouseActionCallback& onMouseDownCallback);
@@ -91,11 +99,17 @@ namespace AzToolsFramework
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction) override;
/// Ensure @param axis1 and @param axis2 are not collinear.
//! Ensure @param axis1 and @param axis2 are not collinear.
void SetAxes(const AZ::Vector3& axis1, const AZ::Vector3& axis2);
const AZ::Vector3& GetAxis1() const { return m_fixed.m_axis1; }
const AZ::Vector3& GetAxis2() const { return m_fixed.m_axis2; }
const AZ::Vector3& GetAxis1() const
{
return m_fixed.m_axis1;
}
const AZ::Vector3& GetAxis2() const
{
return m_fixed.m_axis2;
}
template<typename Views>
void SetViews(Views&& views)
@@ -104,21 +118,19 @@ namespace AzToolsFramework
}
private:
void OnLeftMouseDownImpl(
const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override;
void OnLeftMouseUpImpl(
const ViewportInteraction::MouseInteraction& interaction) override;
void OnMouseMoveImpl(
const ViewportInteraction::MouseInteraction& interaction) override;
void OnLeftMouseDownImpl(const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override;
void OnLeftMouseUpImpl(const ViewportInteraction::MouseInteraction& interaction) override;
void OnMouseMoveImpl(const ViewportInteraction::MouseInteraction& interaction) override;
void InvalidateImpl() override;
void SetBoundsDirtyImpl() override;
/// Initial data recorded when a press first happens with a planar manipulator.
//! Initial data recorded when a press first happens with a planar manipulator.
struct StartInternal
{
AZ::Vector3 m_localPosition; ///< The starting position of the manipulator in local space.
AZ::Vector3 m_localHitPosition; ///< The intersection point in world space between the ray and the manipulator when the mouse down event happens.
AZ::Vector3 m_localPosition; //!< The starting position of the manipulator in local space.
AZ::Vector3 m_localHitPosition; //!< The intersection point in world space between the ray and the manipulator when the mouse
//!< down event happens.
};
Fixed m_fixed;
@@ -128,15 +140,23 @@ namespace AzToolsFramework
MouseActionCallback m_onLeftMouseUpCallback = nullptr;
MouseActionCallback m_onMouseMoveCallback = nullptr;
ManipulatorViews m_manipulatorViews; ///< Look of manipulator.
ManipulatorViews m_manipulatorViews; //!< Look of manipulator.
static StartInternal CalculateManipulationDataStart(
const Fixed& fixed, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale,
const AZ::Transform& localTransform, const ViewportInteraction::MouseInteraction& interaction, float intersectionDistance);
const Fixed& fixed,
const AZ::Transform& worldFromLocal,
const AZ::Vector3& nonUniformScale,
const AZ::Transform& localTransform,
const ViewportInteraction::MouseInteraction& interaction,
float intersectionDistance);
static Action CalculateManipulationDataAction(
const Fixed& fixed, const StartInternal& startInternal, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale,
const AZ::Transform& localTransform, const GridSnapParameters& gridSnapParams,
const Fixed& fixed,
const StartInternal& startInternal,
const AZ::Transform& worldFromLocal,
const AZ::Vector3& nonUniformScale,
const AZ::Transform& localTransform,
const GridSnapParameters& gridSnapParams,
const ViewportInteraction::MouseInteraction& interaction);
};
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "RotationManipulators.h"
@@ -28,8 +28,7 @@ namespace AzToolsFramework
m_manipulatorSpaceWithLocalTransform.SetSpace(worldFromLocal);
}
void RotationManipulators::InstallLeftMouseDownCallback(
const AngularManipulator::MouseActionCallback& onMouseDownCallback)
void RotationManipulators::InstallLeftMouseDownCallback(const AngularManipulator::MouseActionCallback& onMouseDownCallback)
{
for (AZStd::shared_ptr<AngularManipulator>& manipulator : m_localAngularManipulators)
{
@@ -39,8 +38,7 @@ namespace AzToolsFramework
m_viewAngularManipulator->InstallLeftMouseDownCallback(onMouseDownCallback);
}
void RotationManipulators::InstallMouseMoveCallback(
const AngularManipulator::MouseActionCallback& onMouseMoveCallback)
void RotationManipulators::InstallMouseMoveCallback(const AngularManipulator::MouseActionCallback& onMouseMoveCallback)
{
for (AZStd::shared_ptr<AngularManipulator>& manipulator : m_localAngularManipulators)
{
@@ -50,8 +48,7 @@ namespace AzToolsFramework
m_viewAngularManipulator->InstallMouseMoveCallback(onMouseMoveCallback);
}
void RotationManipulators::InstallLeftMouseUpCallback(
const AngularManipulator::MouseActionCallback& onMouseUpCallback)
void RotationManipulators::InstallLeftMouseUpCallback(const AngularManipulator::MouseActionCallback& onMouseUpCallback)
{
for (AZStd::shared_ptr<AngularManipulator>& manipulator : m_localAngularManipulators)
{
@@ -109,14 +106,13 @@ namespace AzToolsFramework
m_viewAngularManipulator->SetSpace(worldFromLocal);
}
void RotationManipulators::SetLocalAxes(
const AZ::Vector3& axis1, const AZ::Vector3& axis2, const AZ::Vector3& axis3)
void RotationManipulators::SetLocalAxes(const AZ::Vector3& axis1, const AZ::Vector3& axis2, const AZ::Vector3& axis3)
{
const AZ::Vector3 axes[] = { axis1, axis2, axis3 };
for (size_t manipulatorIndex = 0; manipulatorIndex < m_localAngularManipulators.size(); ++manipulatorIndex)
{
m_localAngularManipulators[manipulatorIndex]->SetAxis(axes[manipulatorIndex]);
m_localAngularManipulators[manipulatorIndex]->SetAxis(axes[manipulatorIndex]);
}
}
@@ -124,34 +120,25 @@ namespace AzToolsFramework
{
m_viewAngularManipulator->SetAxis(axis);
if (auto circleView = azrtti_cast<ManipulatorViewCircle*>(
m_viewAngularManipulator->GetView()))
if (auto circleView = azrtti_cast<ManipulatorViewCircle*>(m_viewAngularManipulator->GetView()))
{
circleView->m_axis = axis;
}
}
void RotationManipulators::ConfigureView(
const float radius, const AZ::Color& axis1Color,
const AZ::Color& axis2Color, const AZ::Color& axis3Color)
const float radius, const AZ::Color& axis1Color, const AZ::Color& axis2Color, const AZ::Color& axis3Color)
{
const AZ::Color colors[] = {
axis1Color, axis2Color, axis3Color
};
const AZ::Color colors[] = { axis1Color, axis2Color, axis3Color };
for (size_t manipulatorIndex = 0; manipulatorIndex < m_localAngularManipulators.size(); ++manipulatorIndex)
{
m_localAngularManipulators[manipulatorIndex]->SetView(
CreateManipulatorViewCircle(
*m_localAngularManipulators[manipulatorIndex], colors[manipulatorIndex],
radius, 0.05f, DrawHalfDottedCircle));
m_localAngularManipulators[manipulatorIndex]->SetView(CreateManipulatorViewCircle(
*m_localAngularManipulators[manipulatorIndex], colors[manipulatorIndex], radius, 0.05f, DrawHalfDottedCircle));
}
m_viewAngularManipulator->SetView(
CreateManipulatorViewCircle(
*m_viewAngularManipulator,
AZ::Color(1.0f, 1.0f, 1.0f, 1.0f),
radius + (radius * 0.12f), 0.05f, DrawFullCircle));
m_viewAngularManipulator->SetView(CreateManipulatorViewCircle(
*m_viewAngularManipulator, AZ::Color(1.0f, 1.0f, 1.0f, 1.0f), radius + (radius * 0.12f), 0.05f, DrawFullCircle));
}
bool RotationManipulators::PerformingActionViewAxis() const
@@ -1,27 +1,26 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Memory/SystemAllocator.h>
#include <AzToolsFramework/Manipulators/AngularManipulator.h>
#include <AzToolsFramework/API/EditorCameraBus.h>
#include <AzToolsFramework/Manipulators/AngularManipulator.h>
namespace AzToolsFramework
{
/// RotationManipulators is an aggregation of 3 angular manipulators who share the same origin
/// in addition to a view aligned angular manipulator (facing the camera).
class RotationManipulators
: public Manipulators
//! RotationManipulators is an aggregation of 3 angular manipulators who share the same origin
//! in addition to a view aligned angular manipulator (facing the camera).
class RotationManipulators : public Manipulators
{
public:
AZ_RTTI(RotationManipulators, "{5D1F1D47-1D5B-4E42-B47E-23F108F8BF7D}")
@@ -40,12 +39,10 @@ namespace AzToolsFramework
void SetLocalOrientationImpl(const AZ::Quaternion& localOrientation) override;
void RefreshView(const AZ::Vector3& worldViewPosition) override;
void SetLocalAxes(
const AZ::Vector3& axis1, const AZ::Vector3& axis2, const AZ::Vector3& axis3);
void SetLocalAxes(const AZ::Vector3& axis1, const AZ::Vector3& axis2, const AZ::Vector3& axis3);
void SetViewAxis(const AZ::Vector3& axis);
void ConfigureView(
float radius, const AZ::Color& axis1Color, const AZ::Color& axis2Color, const AZ::Color& axis3Color);
void ConfigureView(float radius, const AZ::Color& axis1Color, const AZ::Color& axis2Color, const AZ::Color& axis3Color);
bool PerformingActionViewAxis() const;
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "ScaleManipulators.h"
@@ -28,8 +28,7 @@ namespace AzToolsFramework
m_manipulatorSpaceWithLocalTransform.SetSpace(worldFromLocal);
}
void ScaleManipulators::InstallAxisLeftMouseDownCallback(
const LinearManipulator::MouseActionCallback& onMouseDownCallback)
void ScaleManipulators::InstallAxisLeftMouseDownCallback(const LinearManipulator::MouseActionCallback& onMouseDownCallback)
{
for (AZStd::shared_ptr<LinearManipulator>& manipulator : m_axisScaleManipulators)
{
@@ -37,8 +36,7 @@ namespace AzToolsFramework
}
}
void ScaleManipulators::InstallAxisMouseMoveCallback(
const LinearManipulator::MouseActionCallback& onMouseMoveCallback)
void ScaleManipulators::InstallAxisMouseMoveCallback(const LinearManipulator::MouseActionCallback& onMouseMoveCallback)
{
for (AZStd::shared_ptr<LinearManipulator>& manipulator : m_axisScaleManipulators)
{
@@ -46,8 +44,7 @@ namespace AzToolsFramework
}
}
void ScaleManipulators::InstallAxisLeftMouseUpCallback(
const LinearManipulator::MouseActionCallback& onMouseUpCallback)
void ScaleManipulators::InstallAxisLeftMouseUpCallback(const LinearManipulator::MouseActionCallback& onMouseUpCallback)
{
for (AZStd::shared_ptr<LinearManipulator>& manipulator : m_axisScaleManipulators)
{
@@ -55,22 +52,19 @@ namespace AzToolsFramework
}
}
void ScaleManipulators::InstallUniformLeftMouseDownCallback(
const LinearManipulator::MouseActionCallback& onMouseDownCallback)
void ScaleManipulators::InstallUniformLeftMouseDownCallback(const LinearManipulator::MouseActionCallback& onMouseDownCallback)
{
m_uniformScaleManipulator->InstallLeftMouseDownCallback(onMouseDownCallback);
}
void ScaleManipulators::InstallUniformMouseMoveCallback(
const LinearManipulator::MouseActionCallback& onMouseMoveCallback)
void ScaleManipulators::InstallUniformMouseMoveCallback(const LinearManipulator::MouseActionCallback& onMouseMoveCallback)
{
m_uniformScaleManipulator->InstallMouseMoveCallback(onMouseMoveCallback);
m_uniformScaleManipulator->InstallMouseMoveCallback(onMouseMoveCallback);
}
void ScaleManipulators::InstallUniformLeftMouseUpCallback(
const LinearManipulator::MouseActionCallback& onMouseUpCallback)
void ScaleManipulators::InstallUniformLeftMouseUpCallback(const LinearManipulator::MouseActionCallback& onMouseUpCallback)
{
m_uniformScaleManipulator->InstallLeftMouseUpCallback(onMouseUpCallback);
m_uniformScaleManipulator->InstallLeftMouseUpCallback(onMouseUpCallback);
}
void ScaleManipulators::SetLocalTransformImpl(const AZ::Transform& localTransform)
@@ -80,8 +74,7 @@ namespace AzToolsFramework
manipulator->SetLocalTransform(localTransform);
}
m_uniformScaleManipulator->SetVisualOrientationOverride(
QuaternionFromTransformNoScaling(localTransform));
m_uniformScaleManipulator->SetVisualOrientationOverride(QuaternionFromTransformNoScaling(localTransform));
m_uniformScaleManipulator->SetLocalOrientation(AZ::Quaternion::CreateIdentity());
}
@@ -113,14 +106,13 @@ namespace AzToolsFramework
m_uniformScaleManipulator->SetSpace(worldFromLocal);
}
void ScaleManipulators::SetAxes(
const AZ::Vector3& axis1, const AZ::Vector3& axis2, const AZ::Vector3& axis3)
void ScaleManipulators::SetAxes(const AZ::Vector3& axis1, const AZ::Vector3& axis2, const AZ::Vector3& axis3)
{
AZ::Vector3 axes[] = { axis1, axis2, axis3 };
AZ::Vector3 axes[] = { axis1, axis2, axis3 };
for (size_t manipulatorIndex = 0; manipulatorIndex < m_axisScaleManipulators.size(); ++manipulatorIndex)
{
m_axisScaleManipulators[manipulatorIndex]->SetAxis(axes[manipulatorIndex]);
m_axisScaleManipulators[manipulatorIndex]->SetAxis(axes[manipulatorIndex]);
}
// uniform scale manipulator uses Z axis for scaling (always in world space)
@@ -129,32 +121,27 @@ namespace AzToolsFramework
}
void ScaleManipulators::ConfigureView(
const float axisLength, const AZ::Color& axis1Color,
const AZ::Color& axis2Color, const AZ::Color& axis3Color)
const float axisLength, const AZ::Color& axis1Color, const AZ::Color& axis2Color, const AZ::Color& axis3Color)
{
const float boxSize = 0.1f;
const float lineWidth = 0.05f;
const AZ::Color colors[] = {
axis1Color, axis2Color, axis3Color
};
const AZ::Color colors[] = { axis1Color, axis2Color, axis3Color };
for (size_t manipulatorIndex = 0; manipulatorIndex < m_axisScaleManipulators.size(); ++manipulatorIndex)
{
ManipulatorViews views;
views.emplace_back(CreateManipulatorViewLine(
*m_axisScaleManipulators[manipulatorIndex], colors[manipulatorIndex], axisLength, lineWidth));
views.emplace_back(
CreateManipulatorViewLine(*m_axisScaleManipulators[manipulatorIndex], colors[manipulatorIndex], axisLength, lineWidth));
views.emplace_back(CreateManipulatorViewBox(
AZ::Transform::CreateIdentity(), colors[manipulatorIndex],
m_axisScaleManipulators[manipulatorIndex]->GetAxis() * (axisLength - boxSize),
AZ::Vector3(boxSize)));
m_axisScaleManipulators[manipulatorIndex]->GetAxis() * (axisLength - boxSize), AZ::Vector3(boxSize)));
m_axisScaleManipulators[manipulatorIndex]->SetViews(AZStd::move(views));
}
ManipulatorViews views;
views.emplace_back(CreateManipulatorViewBox(
AZ::Transform::CreateIdentity(), AZ::Color::CreateOne(),
AZ::Vector3::CreateZero(), AZ::Vector3(boxSize)));
AZ::Transform::CreateIdentity(), AZ::Color::CreateOne(), AZ::Vector3::CreateZero(), AZ::Vector3(boxSize)));
m_uniformScaleManipulator->SetViews(AZStd::move(views));
}
@@ -167,4 +154,4 @@ namespace AzToolsFramework
manipulatorFn(m_uniformScaleManipulator.get());
}
}
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -17,11 +17,10 @@
namespace AzToolsFramework
{
/// ScaleManipulators is an aggregation of 3 linear manipulators for each basis axis who share
/// the same transform, and a single linear manipulator at the center of the transform whose
/// axis is world up (z).
class ScaleManipulators
: public Manipulators
//! ScaleManipulators is an aggregation of 3 linear manipulators for each basis axis who share
//! the same transform, and a single linear manipulator at the center of the transform whose
//! axis is world up (z).
class ScaleManipulators : public Manipulators
{
public:
AZ_RTTI(ScaleManipulators, "{C6350CE0-7B7A-46F8-B65F-D4A54DD9A7D9}")
@@ -42,16 +41,9 @@ namespace AzToolsFramework
void SetLocalPositionImpl(const AZ::Vector3& localPosition) override;
void SetLocalOrientationImpl(const AZ::Quaternion& localOrientation) override;
void SetAxes(
const AZ::Vector3& axis1,
const AZ::Vector3& axis2,
const AZ::Vector3& axis3);
void SetAxes(const AZ::Vector3& axis1, const AZ::Vector3& axis2, const AZ::Vector3& axis3);
void ConfigureView(
float axisLength,
const AZ::Color& axis1Color,
const AZ::Color& axis2Color,
const AZ::Color& axis3Color);
void ConfigureView(float axisLength, const AZ::Color& axis1Color, const AZ::Color& axis2Color, const AZ::Color& axis3Color);
private:
AZ_DISABLE_COPY_MOVE(ScaleManipulators)
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "SelectionManipulator.h"
@@ -16,8 +16,8 @@
namespace AzToolsFramework
{
AZStd::shared_ptr<SelectionManipulator> SelectionManipulator::MakeShared(const AZ::Transform& worldFromLocal,
const AZ::Vector3& nonUniformScale)
AZStd::shared_ptr<SelectionManipulator> SelectionManipulator::MakeShared(
const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale)
{
return AZStd::shared_ptr<SelectionManipulator>(aznew SelectionManipulator(worldFromLocal, nonUniformScale));
}
@@ -93,12 +93,9 @@ namespace AzToolsFramework
for (auto& view : m_manipulatorViews)
{
view->Draw(
GetManipulatorManagerId(), managerState,
GetManipulatorId(), {
TransformUniformScale(GetSpace()), GetNonUniformScale(),
GetLocalPosition(), MouseOver()
},
debugDisplay, cameraState, mouseInteraction);
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalPosition(), MouseOver() }, debugDisplay, cameraState,
mouseInteraction);
}
}
@@ -117,4 +114,4 @@ namespace AzToolsFramework
view->Invalidate(GetManipulatorManagerId());
}
}
}
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -20,13 +20,13 @@ namespace AzToolsFramework
{
class ManipulatorView;
/// Represents a sphere that can be clicked on to trigger a particular behavior
/// For example clicking a preview point to create a translation manipulator.
//! Represents a sphere that can be clicked on to trigger a particular behavior.
//! For example clicking a preview point to create a translation manipulator.
class SelectionManipulator
: public BaseManipulator
, public ManipulatorSpaceWithLocalPosition
{
/// Private constructor.
//! Private constructor.
SelectionManipulator(const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale = AZ::Vector3::CreateOne());
public:
@@ -39,12 +39,12 @@ namespace AzToolsFramework
~SelectionManipulator() = default;
/// A Manipulator must only be created and managed through a shared_ptr.
static AZStd::shared_ptr<SelectionManipulator> MakeShared(const AZ::Transform& worldFromLocal,
const AZ::Vector3& nonUniformScale = AZ::Vector3::CreateOne());
//! A Manipulator must only be created and managed through a shared_ptr.
static AZStd::shared_ptr<SelectionManipulator> MakeShared(
const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale = AZ::Vector3::CreateOne());
/// This is the function signature of callbacks that will be invoked
/// whenever a selection manipulator is clicked on.
//! This is the function signature of callbacks that will be invoked
//! whenever a selection manipulator is clicked on.
using MouseActionCallback = AZStd::function<void(const ViewportInteraction::MouseInteraction&)>;
void InstallLeftMouseDownCallback(const MouseActionCallback& onMouseDownCallback);
@@ -58,10 +58,25 @@ namespace AzToolsFramework
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction) override;
bool Selected() const { return m_selected; }
void Select() { m_selected = true; }
void Deselect() { m_selected = false; }
void ToggleSelected() { m_selected = !m_selected; }
bool Selected() const
{
return m_selected;
}
void Select()
{
m_selected = true;
}
void Deselect()
{
m_selected = false;
}
void ToggleSelected()
{
m_selected = !m_selected;
}
template<typename Views>
void SetViews(Views&& views)
@@ -70,13 +85,9 @@ namespace AzToolsFramework
}
private:
void OnLeftMouseDownImpl(
const ViewportInteraction::MouseInteraction& interaction,
float rayIntersectionDistance) override;
void OnLeftMouseDownImpl(const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override;
void OnLeftMouseUpImpl(const ViewportInteraction::MouseInteraction& interaction) override;
void OnRightMouseDownImpl(
const ViewportInteraction::MouseInteraction& interaction,
float rayIntersectionDistance) override;
void OnRightMouseDownImpl(const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override;
void OnRightMouseUpImpl(const ViewportInteraction::MouseInteraction& interaction) override;
void InvalidateImpl() override;
@@ -89,6 +100,6 @@ namespace AzToolsFramework
MouseActionCallback m_onRightMouseDownCallback = nullptr;
MouseActionCallback m_onRightMouseUpCallback = nullptr;
ManipulatorViews m_manipulatorViews; ///< Look of manipulator.
ManipulatorViews m_manipulatorViews; //!< Look of manipulator.
};
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "SplineHoverSelection.h"
@@ -20,11 +20,12 @@
namespace AzToolsFramework
{
static const AZ::Color s_splineSelectManipulatorColor = AZ::Color(0.0f, 1.0f, 0.0f, 1.0f);
static const AZ::Color SplineSelectManipulatorColor = AZ::Color(0.0f, 1.0f, 0.0f, 1.0f);
SplineHoverSelection::SplineHoverSelection(
const AZ::EntityComponentIdPair& entityComponentIdPair,
const ManipulatorManagerId managerId, const AZStd::shared_ptr<AZ::Spline>& spline)
const ManipulatorManagerId managerId,
const AZStd::shared_ptr<AZ::Spline>& spline)
{
m_splineSelectionManipulator = SplineSelectionManipulator::MakeShared();
m_splineSelectionManipulator->Register(managerId);
@@ -33,16 +34,14 @@ namespace AzToolsFramework
const float splineWidth = 0.05f;
m_splineSelectionManipulator->SetSpline(spline);
m_splineSelectionManipulator->SetView(CreateManipulatorViewSplineSelect(
*m_splineSelectionManipulator, s_splineSelectManipulatorColor, splineWidth));
m_splineSelectionManipulator->SetView(
CreateManipulatorViewSplineSelect(*m_splineSelectionManipulator, SplineSelectManipulatorColor, splineWidth));
m_splineSelectionManipulator->InstallLeftMouseUpCallback(
[entityComponentIdPair](const SplineSelectionManipulator::Action& action)
{
InsertVertexAfter(
entityComponentIdPair, action.m_splineAddress.m_segmentIndex,
action.m_localSplineHitPosition);
});
{
InsertVertexAfter(entityComponentIdPair, action.m_splineAddress.m_segmentIndex, action.m_localSplineHitPosition);
});
}
SplineHoverSelection::~SplineHoverSelection()
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -19,20 +19,20 @@ namespace AZ
{
class Spline;
class EntityComponentIdPair;
}
} // namespace AZ
namespace AzToolsFramework
{
class SplineSelectionManipulator;
/// SplineHoverSelection is a concrete implementation of HoverSelection wrapping a Spline and
/// SplineManipulator. The underlying manipulators are used to control selection.
class SplineHoverSelection
: public HoverSelection
//! SplineHoverSelection is a concrete implementation of HoverSelection wrapping a Spline and
//! SplineManipulator. The underlying manipulators are used to control selection.
class SplineHoverSelection : public HoverSelection
{
public:
explicit SplineHoverSelection(
const AZ::EntityComponentIdPair& entityComponentIdPair, ManipulatorManagerId managerId,
const AZ::EntityComponentIdPair& entityComponentIdPair,
ManipulatorManagerId managerId,
const AZStd::shared_ptr<AZ::Spline>& spline);
SplineHoverSelection(const SplineHoverSelection&) = delete;
SplineHoverSelection& operator=(const SplineHoverSelection&) = delete;
@@ -46,6 +46,6 @@ namespace AzToolsFramework
void SetNonUniformScale(const AZ::Vector3& nonUniformScale) override;
private:
AZStd::shared_ptr<SplineSelectionManipulator> m_splineSelectionManipulator; ///< Manipulator for adding points to spline.
AZStd::shared_ptr<SplineSelectionManipulator> m_splineSelectionManipulator; //!< Manipulator for adding points to spline.
};
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "SplineSelectionManipulator.h"
@@ -18,8 +18,10 @@
namespace AzToolsFramework
{
SplineSelectionManipulator::Action CalculateManipulationDataAction(
const AZ::Transform& worldFromLocal, const AZ::Vector3& rayOrigin,
const AZ::Vector3& rayDirection, const AZStd::weak_ptr<const AZ::Spline>& spline)
const AZ::Transform& worldFromLocal,
const AZ::Vector3& rayOrigin,
const AZ::Vector3& rayDirection,
const AZStd::weak_ptr<const AZ::Spline>& spline)
{
SplineSelectionManipulator::Action action;
if (const AZStd::shared_ptr<const AZ::Spline> splinePtr = spline.lock())
@@ -65,9 +67,7 @@ namespace AzToolsFramework
if (m_onLeftMouseDownCallback)
{
m_onLeftMouseDownCallback(CalculateManipulationDataAction(
TransformUniformScale(GetSpace()),
interaction.m_mousePick.m_rayOrigin,
interaction.m_mousePick.m_rayDirection, m_spline));
TransformUniformScale(GetSpace()), interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection, m_spline));
}
}
@@ -76,9 +76,7 @@ namespace AzToolsFramework
if (MouseOver() && m_onLeftMouseUpCallback)
{
m_onLeftMouseUpCallback(CalculateManipulationDataAction(
TransformUniformScale(GetSpace()),
interaction.m_mousePick.m_rayOrigin,
interaction.m_mousePick.m_rayDirection, m_spline));
TransformUniformScale(GetSpace()), interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection, m_spline));
}
}
@@ -99,12 +97,9 @@ namespace AzToolsFramework
if (mouseInteraction.m_keyboardModifiers.Ctrl() && !mouseInteraction.m_keyboardModifiers.Shift())
{
m_manipulatorView->Draw(
GetManipulatorManagerId(), managerState,
GetManipulatorId(), {
TransformUniformScale(GetSpace()), GetNonUniformScale(),
AZ::Vector3::CreateZero(), MouseOver()
},
debugDisplay, cameraState, mouseInteraction);
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ TransformUniformScale(GetSpace()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay,
cameraState, mouseInteraction);
}
}
@@ -122,4 +117,4 @@ namespace AzToolsFramework
{
m_manipulatorView->Invalidate(GetManipulatorManagerId());
}
}
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -23,13 +23,13 @@ namespace AzToolsFramework
{
class ManipulatorView;
/// A manipulator to represent selection of a spline. Underlying spline data is
/// used to test mouse picking ray against to preview closest point on spline.
//! A manipulator to represent selection of a spline. Underlying spline data is
//! used to test mouse picking ray against to preview closest point on spline.
class SplineSelectionManipulator
: public BaseManipulator
, public ManipulatorSpace
{
/// Private constructor.
//! Private constructor.
SplineSelectionManipulator();
public:
@@ -41,10 +41,10 @@ namespace AzToolsFramework
~SplineSelectionManipulator();
/// A Manipulator must only be created and managed through a shared_ptr.
//! A Manipulator must only be created and managed through a shared_ptr.
static AZStd::shared_ptr<SplineSelectionManipulator> MakeShared();
/// Mouse action data used by MouseActionCallback.
//! Mouse action data used by MouseActionCallback.
struct Action
{
AZ::Vector3 m_localSplineHitPosition;
@@ -62,29 +62,36 @@ namespace AzToolsFramework
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction) override;
void SetSpline(AZStd::shared_ptr<const AZ::Spline> spline) { m_spline = AZStd::move(spline); }
AZStd::weak_ptr<const AZ::Spline> GetSpline() const { return m_spline; }
void SetSpline(AZStd::shared_ptr<const AZ::Spline> spline)
{
m_spline = AZStd::move(spline);
}
AZStd::weak_ptr<const AZ::Spline> GetSpline() const
{
return m_spline;
}
void SetView(AZStd::unique_ptr<ManipulatorView>&& view);
private:
void OnLeftMouseDownImpl(
const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override;
void OnLeftMouseUpImpl(
const ViewportInteraction::MouseInteraction& interaction) override;
void OnLeftMouseDownImpl(const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override;
void OnLeftMouseUpImpl(const ViewportInteraction::MouseInteraction& interaction) override;
void InvalidateImpl() override;
void SetBoundsDirtyImpl() override;
AZStd::weak_ptr<const AZ::Spline> m_spline;
AZStd::unique_ptr<ManipulatorView> m_manipulatorView = nullptr; ///< Look of manipulator and bounds for interaction.
AZStd::unique_ptr<ManipulatorView> m_manipulatorView = nullptr; //!< Look of manipulator and bounds for interaction.
MouseActionCallback m_onLeftMouseDownCallback = nullptr;
MouseActionCallback m_onLeftMouseUpCallback = nullptr;
ViewportInteraction::KeyboardModifiers m_keyboardModifiers; ///< What modifier keys are pressed when interacting with this manipulator.
ViewportInteraction::KeyboardModifiers
m_keyboardModifiers; //!< What modifier keys are pressed when interacting with this manipulator.
};
SplineSelectionManipulator::Action CalculateManipulationDataAction(
const AZ::Transform& worldFromLocal, const AZ::Vector3& rayOrigin,
const AZ::Vector3& rayDirection, const AZStd::weak_ptr<const AZ::Spline>& spline);
const AZ::Transform& worldFromLocal,
const AZ::Vector3& rayOrigin,
const AZ::Vector3& rayDirection,
const AZStd::weak_ptr<const AZ::Spline>& spline);
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "SurfaceManipulator.h"
@@ -18,19 +18,22 @@
namespace AzToolsFramework
{
SurfaceManipulator::StartInternal SurfaceManipulator::CalculateManipulationDataStart(
const AZ::Transform& worldFromLocal, const AZ::Vector3& worldSurfacePosition,
const AZ::Vector3& localStartPosition, const bool snapping, const float gridSize, const int viewportId)
const AZ::Transform& worldFromLocal,
const AZ::Vector3& worldSurfacePosition,
const AZ::Vector3& localStartPosition,
const bool snapping,
const float gridSize,
const int viewportId)
{
const AZ::Transform worldFromLocalUniform = AzToolsFramework::TransformUniformScale(worldFromLocal);
const AZ::Transform localFromWorldUniform = worldFromLocalUniform.GetInverse();
const AZ::Vector3 localFinalSurfacePosition = snapping
? CalculateSnappedTerrainPosition(
// note: gridSize is not scaled by scaleRecip here as localStartPosition is
// unscaled itself so the position returned by CalculateSnappedTerrainPosition
// must be in the same space (if localStartPosition were also scaled, gridSize
// would need to be multiplied by scaleRecip)
worldSurfacePosition, worldFromLocalUniform, viewportId, gridSize)
// note: gridSize is not scaled by scaleRecip here as localStartPosition is
// unscaled itself so the position returned by CalculateSnappedTerrainPosition
// must be in the same space (if localStartPosition were also scaled, gridSize
// would need to be multiplied by scaleRecip)
? CalculateSnappedTerrainPosition(worldSurfacePosition, worldFromLocalUniform, viewportId, gridSize)
: localFromWorldUniform.TransformPoint(worldSurfacePosition);
// delta/offset between initial vertex position and terrain pick position
@@ -44,9 +47,13 @@ namespace AzToolsFramework
}
SurfaceManipulator::Action SurfaceManipulator::CalculateManipulationDataAction(
const StartInternal& startInternal, const AZ::Transform& worldFromLocal,
const AZ::Vector3& worldSurfacePosition, const bool snapping, const float gridSize,
const ViewportInteraction::KeyboardModifiers keyboardModifiers, const int viewportId)
const StartInternal& startInternal,
const AZ::Transform& worldFromLocal,
const AZ::Vector3& worldSurfacePosition,
const bool snapping,
const float gridSize,
const ViewportInteraction::KeyboardModifiers keyboardModifiers,
const int viewportId)
{
const AZ::Transform worldFromLocalUniform = AzToolsFramework::TransformUniformScale(worldFromLocal);
const AZ::Transform localFromWorldUniform = worldFromLocalUniform.GetInverse();
@@ -54,8 +61,7 @@ namespace AzToolsFramework
const float scaleRecip = ScaleReciprocal(worldFromLocalUniform);
const AZ::Vector3 localFinalSurfacePosition = snapping
? CalculateSnappedTerrainPosition(
worldSurfacePosition, worldFromLocalUniform, viewportId, gridSize * scaleRecip)
? CalculateSnappedTerrainPosition(worldSurfacePosition, worldFromLocalUniform, viewportId, gridSize * scaleRecip)
: localFromWorldUniform.TransformPoint(worldSurfacePosition);
Action action;
@@ -106,17 +112,14 @@ namespace AzToolsFramework
interaction.m_mousePick.m_screenCoordinates);
m_startInternal = CalculateManipulationDataStart(
worldFromLocalUniformScale, worldSurfacePosition, GetLocalPosition(),
gridSnapParams.m_gridSnap, gridSnapParams.m_gridSize,
worldFromLocalUniformScale, worldSurfacePosition, GetLocalPosition(), gridSnapParams.m_gridSnap, gridSnapParams.m_gridSize,
interaction.m_interactionId.m_viewportId);
if (m_onLeftMouseDownCallback)
{
m_onLeftMouseDownCallback(CalculateManipulationDataAction(
m_startInternal, worldFromLocalUniformScale, worldSurfacePosition,
gridSnapParams.m_gridSnap, gridSnapParams.m_gridSize,
interaction.m_keyboardModifiers,
interaction.m_interactionId.m_viewportId));
m_startInternal, worldFromLocalUniformScale, worldSurfacePosition, gridSnapParams.m_gridSnap, gridSnapParams.m_gridSize,
interaction.m_keyboardModifiers, interaction.m_interactionId.m_viewportId));
}
}
@@ -133,10 +136,8 @@ namespace AzToolsFramework
const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId);
m_onLeftMouseUpCallback(CalculateManipulationDataAction(
m_startInternal, TransformUniformScale(GetSpace()), worldSurfacePosition,
gridSnapParams.m_gridSnap,
gridSnapParams.m_gridSize,
interaction.m_keyboardModifiers, interaction.m_interactionId.m_viewportId));
m_startInternal, TransformUniformScale(GetSpace()), worldSurfacePosition, gridSnapParams.m_gridSnap,
gridSnapParams.m_gridSize, interaction.m_keyboardModifiers, interaction.m_interactionId.m_viewportId));
}
}
@@ -153,10 +154,8 @@ namespace AzToolsFramework
const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId);
m_onMouseMoveCallback(CalculateManipulationDataAction(
m_startInternal, TransformUniformScale(GetSpace()), worldSurfacePosition,
gridSnapParams.m_gridSnap,
gridSnapParams.m_gridSize,
interaction.m_keyboardModifiers, interaction.m_interactionId.m_viewportId));
m_startInternal, TransformUniformScale(GetSpace()), worldSurfacePosition, gridSnapParams.m_gridSnap,
gridSnapParams.m_gridSize, interaction.m_keyboardModifiers, interaction.m_interactionId.m_viewportId));
}
}
@@ -172,12 +171,9 @@ namespace AzToolsFramework
const ViewportInteraction::MouseInteraction& mouseInteraction)
{
m_manipulatorView->Draw(
GetManipulatorManagerId(), managerState,
GetManipulatorId(), {
TransformUniformScale(GetSpace()), GetNonUniformScale(),
GetLocalPosition(), MouseOver()
},
debugDisplay, cameraState, mouseInteraction);
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalPosition(), MouseOver() }, debugDisplay, cameraState,
mouseInteraction);
}
void SurfaceManipulator::InvalidateImpl()
@@ -189,4 +185,4 @@ namespace AzToolsFramework
{
m_manipulatorView = AZStd::move(view);
}
}
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -21,13 +21,13 @@ namespace AzToolsFramework
{
class ManipulatorView;
/// Surface manipulator will ensure the point(s) it controls snap precisely to the xy grid
/// while also staying aligned exactly to the height of the terrain.
//! Surface manipulator will ensure the point(s) it controls snap precisely to the xy grid
//! while also staying aligned exactly to the height of the terrain.
class SurfaceManipulator
: public BaseManipulator
, public ManipulatorSpaceWithLocalPosition
{
/// Private constructor.
//! Private constructor.
explicit SurfaceManipulator(const AZ::Transform& worldFromLocal);
public:
@@ -40,30 +40,36 @@ namespace AzToolsFramework
~SurfaceManipulator() = default;
/// A Manipulator must only be created and managed through a shared_ptr.
//! A Manipulator must only be created and managed through a shared_ptr.
static AZStd::shared_ptr<SurfaceManipulator> MakeShared(const AZ::Transform& worldFromLocal);
/// The state of the manipulator at the start of an interaction.
//! The state of the manipulator at the start of an interaction.
struct Start
{
AZ::Vector3 m_localPosition; ///< The current position of the manipulator in local space.
AZ::Vector3 m_snapOffset; ///< The snap offset amount to ensure manipulator is aligned to the grid.
AZ::Vector3 m_localPosition; //!< The current position of the manipulator in local space.
AZ::Vector3 m_snapOffset; //!< The snap offset amount to ensure manipulator is aligned to the grid.
};
/// The state of the manipulator during an interaction.
//! The state of the manipulator during an interaction.
struct Current
{
AZ::Vector3 m_localOffset; ///< The current offset of the manipulator from its starting position in local space.
AZ::Vector3 m_localOffset; //!< The current offset of the manipulator from its starting position in local space.
};
/// Mouse action data used by MouseActionCallback (wraps Start and Current manipulator state).
//! Mouse action data used by MouseActionCallback (wraps Start and Current manipulator state).
struct Action
{
Start m_start;
Current m_current;
ViewportInteraction::KeyboardModifiers m_modifiers;
AZ::Vector3 LocalPosition() const { return m_start.m_localPosition + m_current.m_localOffset; }
AZ::Vector3 LocalPositionOffset() const { return m_current.m_localOffset; }
AZ::Vector3 LocalPosition() const
{
return m_start.m_localPosition + m_current.m_localOffset;
}
AZ::Vector3 LocalPositionOffset() const
{
return m_current.m_localOffset;
}
};
using MouseActionCallback = AZStd::function<void(const Action&)>;
@@ -81,39 +87,44 @@ namespace AzToolsFramework
void SetView(AZStd::unique_ptr<ManipulatorView>&& view);
private:
void OnLeftMouseDownImpl(
const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override;
void OnLeftMouseUpImpl(
const ViewportInteraction::MouseInteraction& interaction) override;
void OnMouseMoveImpl(
const ViewportInteraction::MouseInteraction& interaction) override;
void OnLeftMouseDownImpl(const ViewportInteraction::MouseInteraction& interaction, float rayIntersectionDistance) override;
void OnLeftMouseUpImpl(const ViewportInteraction::MouseInteraction& interaction) override;
void OnMouseMoveImpl(const ViewportInteraction::MouseInteraction& interaction) override;
void InvalidateImpl() override;
void SetBoundsDirtyImpl() override;
/// Initial data recorded when a press first happens with a surface manipulator.
//! Initial data recorded when a press first happens with a surface manipulator.
struct StartInternal
{
AZ::Vector3 m_localPosition; ///< The current position of the manipulator in local space.
AZ::Vector3 m_localHitPosition; ///< The hit position with the terrain in local space.
AZ::Vector3 m_snapOffset; ///< The snap offset amount to ensure manipulator is aligned to the grid.
AZ::Vector3 m_localPosition; //!< The current position of the manipulator in local space.
AZ::Vector3 m_localHitPosition; //!< The hit position with the terrain in local space.
AZ::Vector3 m_snapOffset; //!< The snap offset amount to ensure manipulator is aligned to the grid.
};
StartInternal m_startInternal; ///< Internal initial state recorded/created in OnMouseDown.
StartInternal m_startInternal; //!< Internal initial state recorded/created in OnMouseDown.
AZStd::unique_ptr<ManipulatorView> m_manipulatorView = nullptr; ///< Look of manipulator.
AZStd::unique_ptr<ManipulatorView> m_manipulatorView = nullptr; //!< Look of manipulator.
MouseActionCallback m_onLeftMouseDownCallback = nullptr;
MouseActionCallback m_onLeftMouseUpCallback = nullptr;
MouseActionCallback m_onMouseMoveCallback = nullptr;
static StartInternal CalculateManipulationDataStart(
const AZ::Transform& worldFromLocal, const AZ::Vector3& worldSurfacePosition,
const AZ::Vector3& localPosition, bool snapping, float gridSize, int viewportId);
const AZ::Transform& worldFromLocal,
const AZ::Vector3& worldSurfacePosition,
const AZ::Vector3& localPosition,
bool snapping,
float gridSize,
int viewportId);
static Action CalculateManipulationDataAction(
const StartInternal& startInternal, const AZ::Transform& worldFromLocal,
const AZ::Vector3& worldSurfacePosition, bool snapping, float gridSize,
ViewportInteraction::KeyboardModifiers keyboardModifiers, int viewportId);
const StartInternal& startInternal,
const AZ::Transform& worldFromLocal,
const AZ::Vector3& worldSurfacePosition,
bool snapping,
float gridSize,
ViewportInteraction::KeyboardModifiers keyboardModifiers,
int viewportId);
};
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "TranslationManipulators.h"
@@ -77,8 +77,7 @@ namespace AzToolsFramework
}
}
void TranslationManipulators::InstallLinearManipulatorMouseUpCallback(
const LinearManipulator::MouseActionCallback& onMouseUpCallback)
void TranslationManipulators::InstallLinearManipulatorMouseUpCallback(const LinearManipulator::MouseActionCallback& onMouseUpCallback)
{
for (AZStd::shared_ptr<LinearManipulator>& manipulator : m_linearManipulators)
{
@@ -104,8 +103,7 @@ namespace AzToolsFramework
}
}
void TranslationManipulators::InstallPlanarManipulatorMouseUpCallback(
const PlanarManipulator::MouseActionCallback& onMouseUpCallback)
void TranslationManipulators::InstallPlanarManipulatorMouseUpCallback(const PlanarManipulator::MouseActionCallback& onMouseUpCallback)
{
for (AZStd::shared_ptr<PlanarManipulator>& manipulator : m_planarManipulators)
{
@@ -122,8 +120,7 @@ namespace AzToolsFramework
}
}
void TranslationManipulators::InstallSurfaceManipulatorMouseUpCallback(
const SurfaceManipulator::MouseActionCallback& onMouseUpCallback)
void TranslationManipulators::InstallSurfaceManipulatorMouseUpCallback(const SurfaceManipulator::MouseActionCallback& onMouseUpCallback)
{
if (m_surfaceManipulator)
{
@@ -242,7 +239,9 @@ namespace AzToolsFramework
}
void TranslationManipulators::ConfigureLinearView(
float axisLength, const AZ::Color& axis1Color, const AZ::Color& axis2Color,
float axisLength,
const AZ::Color& axis1Color,
const AZ::Color& axis2Color,
const AZ::Color& axis3Color /*= AZ::Color(0.0f, 0.0f, 1.0f, 0.5f)*/)
{
const float coneLength = 0.28f;
@@ -251,15 +250,13 @@ namespace AzToolsFramework
const AZ::Color axesColor[] = { axis1Color, axis2Color, axis3Color };
const auto configureLinearView = [lineWidth, coneLength, axisLength, coneRadius](
LinearManipulator* linearManipulator, const AZ::Color& color)
const auto configureLinearView =
[lineWidth, coneLength, axisLength, coneRadius](LinearManipulator* linearManipulator, const AZ::Color& color)
{
ManipulatorViews views;
views.emplace_back(CreateManipulatorViewLine(
*linearManipulator, color, axisLength, lineWidth));
views.emplace_back(CreateManipulatorViewLine(*linearManipulator, color, axisLength, lineWidth));
views.emplace_back(CreateManipulatorViewCone(
*linearManipulator, color, linearManipulator->GetAxis() * (axisLength - coneLength),
coneLength, coneRadius));
*linearManipulator, color, linearManipulator->GetAxis() * (axisLength - coneLength), coneLength, coneRadius));
linearManipulator->SetViews(AZStd::move(views));
};
@@ -270,7 +267,8 @@ namespace AzToolsFramework
}
void TranslationManipulators::ConfigurePlanarView(
const AZ::Color& plane1Color, const AZ::Color& plane2Color /*= AZ::Color(0.0f, 1.0f, 0.0f, 0.5f)*/,
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 float planeSize = 0.6f;
@@ -278,34 +276,29 @@ namespace AzToolsFramework
for (size_t manipulatorIndex = 0; manipulatorIndex < m_planarManipulators.size(); ++manipulatorIndex)
{
const AZStd::shared_ptr<ManipulatorViewQuad> manipulatorView =
CreateManipulatorViewQuad(
*m_planarManipulators[manipulatorIndex], planesColor[manipulatorIndex],
planesColor[(manipulatorIndex + 1) % 3],
planeSize);
const AZStd::shared_ptr<ManipulatorViewQuad> manipulatorView = CreateManipulatorViewQuad(
*m_planarManipulators[manipulatorIndex], planesColor[manipulatorIndex], planesColor[(manipulatorIndex + 1) % 3], planeSize);
m_planarManipulators[manipulatorIndex]->SetViews(ManipulatorViews{manipulatorView});
m_planarManipulators[manipulatorIndex]->SetViews(ManipulatorViews{ manipulatorView });
}
}
void TranslationManipulators::ConfigureSurfaceView(
const float radius, const AZ::Color& color)
void TranslationManipulators::ConfigureSurfaceView(const float radius, const AZ::Color& color)
{
if (m_surfaceManipulator)
{
m_surfaceManipulator->SetView(CreateManipulatorViewSphere(color, radius,
[](const ViewportInteraction::MouseInteraction& /*mouseInteraction*/,
bool mouseOver, const AZ::Color& defaultColor) -> AZ::Color
{
const AZ::Color color[2] =
m_surfaceManipulator->SetView(CreateManipulatorViewSphere(
color, radius,
[](const ViewportInteraction::MouseInteraction& /*mouseInteraction*/, bool mouseOver,
const AZ::Color& defaultColor) -> AZ::Color
{
defaultColor,
Vector3ToVector4(
BaseManipulator::s_defaultMouseOverColor.GetAsVector3(), s_surfaceManipulatorTransparency)
};
const AZ::Color color[2] = {
defaultColor,
Vector3ToVector4(BaseManipulator::s_defaultMouseOverColor.GetAsVector3(), s_surfaceManipulatorTransparency)
};
return color[mouseOver];
}));
return color[mouseOver];
}));
}
}
@@ -327,27 +320,17 @@ namespace AzToolsFramework
}
}
void ConfigureTranslationManipulatorAppearance3d(
TranslationManipulators* translationManipulators)
void ConfigureTranslationManipulatorAppearance3d(TranslationManipulators* translationManipulators)
{
translationManipulators->SetAxes(
AZ::Vector3::CreateAxisX(),
AZ::Vector3::CreateAxisY(),
AZ::Vector3::CreateAxisZ());
translationManipulators->ConfigurePlanarView(
s_xAxisColor, s_yAxisColor, s_zAxisColor);
translationManipulators->ConfigureLinearView(
s_axisLength, s_xAxisColor, s_yAxisColor, s_zAxisColor);
translationManipulators->ConfigureSurfaceView(
s_surfaceManipulatorRadius, s_surfaceManipulatorColor);
translationManipulators->SetAxes(AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY(), AZ::Vector3::CreateAxisZ());
translationManipulators->ConfigurePlanarView(s_xAxisColor, s_yAxisColor, s_zAxisColor);
translationManipulators->ConfigureLinearView(s_axisLength, s_xAxisColor, s_yAxisColor, s_zAxisColor);
translationManipulators->ConfigureSurfaceView(s_surfaceManipulatorRadius, s_surfaceManipulatorColor);
}
void ConfigureTranslationManipulatorAppearance2d(
TranslationManipulators* translationManipulators)
void ConfigureTranslationManipulatorAppearance2d(TranslationManipulators* translationManipulators)
{
translationManipulators->SetAxes(
AZ::Vector3::CreateAxisX(),
AZ::Vector3::CreateAxisY());
translationManipulators->SetAxes(AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY());
translationManipulators->ConfigurePlanarView(s_xAxisColor);
translationManipulators->ConfigureLinearView(s_axisLength, s_xAxisColor, s_yAxisColor);
}
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -19,16 +19,15 @@
namespace AzToolsFramework
{
/// TranslationManipulators is an aggregation of 3 linear manipulators, 3 planar manipulators
/// and one surface manipulator who share the same transform.
class TranslationManipulators
: public Manipulators
//! TranslationManipulators is an aggregation of 3 linear manipulators, 3 planar manipulators
//! and one surface manipulator who share the same transform.
class TranslationManipulators : public Manipulators
{
public:
AZ_RTTI(TranslationManipulators, "{D5E49EA2-30E0-42BC-A51D-6A7F87818260}")
AZ_CLASS_ALLOCATOR(TranslationManipulators, AZ::SystemAllocator, 0)
/// How many dimensions does this translation manipulator have
//! How many dimensions does this translation manipulator have.
enum class Dimensions
{
Two,
@@ -55,9 +54,7 @@ namespace AzToolsFramework
void SetLocalOrientationImpl(const AZ::Quaternion& localOrientation) override;
void SetNonUniformScaleImpl(const AZ::Vector3& nonUniformScale) override;
void SetAxes(
const AZ::Vector3& axis1, const AZ::Vector3& axis2,
const AZ::Vector3& axis3 = AZ::Vector3::CreateAxisZ());
void SetAxes(const AZ::Vector3& axis1, const AZ::Vector3& axis2, const AZ::Vector3& axis3 = AZ::Vector3::CreateAxisZ());
void ConfigurePlanarView(
const AZ::Color& plane1Color,
@@ -66,11 +63,11 @@ namespace AzToolsFramework
void ConfigureLinearView(
float axisLength,
const AZ::Color& axis1Color, const AZ::Color& axis2Color,
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);
void ConfigureSurfaceView(float radius, const AZ::Color& color);
private:
AZ_DISABLE_COPY_MOVE(TranslationManipulators)
@@ -78,37 +75,43 @@ namespace AzToolsFramework
// Manipulators
void ProcessManipulators(const AZStd::function<void(BaseManipulator*)>&) override;
const Dimensions m_dimensions; ///< How many dimensions of freedom does this manipulator have.
const Dimensions m_dimensions; //!< How many dimensions of freedom does this manipulator have.
AZStd::vector<AZStd::shared_ptr<LinearManipulator>> m_linearManipulators;
AZStd::vector<AZStd::shared_ptr<PlanarManipulator>> m_planarManipulators;
AZStd::shared_ptr<SurfaceManipulator> m_surfaceManipulator = nullptr;
};
/// IndexedTranslationManipulator wraps a standard TranslationManipulators and allows it to be linked
/// to a particular index in a list of vertices/points.
//! IndexedTranslationManipulator wraps a standard TranslationManipulators and allows it to be linked
//! to a particular index in a list of vertices/points.
template<typename Vertex>
struct IndexedTranslationManipulator
{
explicit IndexedTranslationManipulator(
TranslationManipulators::Dimensions dimensions, AZ::u64 vertIndex,
const Vertex& position, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale)
: m_manipulator(dimensions, worldFromLocal, nonUniformScale)
TranslationManipulators::Dimensions dimensions,
AZ::u64 vertIndex,
const Vertex& position,
const AZ::Transform& worldFromLocal,
const AZ::Vector3& nonUniformScale)
: m_manipulator(dimensions, worldFromLocal, nonUniformScale)
{
m_vertices.push_back({ position, Vertex::CreateZero(), vertIndex });
}
/// Store vertex start position as manipulator event occurs, index refers to location in container.
//! Store vertex start position as manipulator event occurs, index refers to location in container.
struct VertexLookup
{
Vertex m_start;
Vertex m_offset;
AZ::u64 m_index;
Vertex CurrentPosition() const { return m_start + m_offset; }
Vertex CurrentPosition() const
{
return m_start + m_offset;
}
};
/// Helper to iterate over all vertices stored by the manipulator.
//! Helper to iterate over all vertices stored by the manipulator.
void Process(AZStd::function<void(VertexLookup&)> fn)
{
for (VertexLookup& vertex : m_vertices)
@@ -117,16 +120,14 @@ namespace AzToolsFramework
}
}
AZStd::vector<VertexLookup> m_vertices; ///< List of vertices currently associated with this translation manipulator.
AZStd::vector<VertexLookup> m_vertices; //!< List of vertices currently associated with this translation manipulator.
TranslationManipulators m_manipulator;
};
/// Function pointer to configure how a translation manipulator should look and behave (dimensions/axes/views).
using TranslationManipulatorConfiguratorFn = void(*)(TranslationManipulators*);
//! Function pointer to configure how a translation manipulator should look and behave (dimensions/axes/views).
using TranslationManipulatorConfiguratorFn = void (*)(TranslationManipulators*);
void ConfigureTranslationManipulatorAppearance3d(
TranslationManipulators* translationManipulators);
void ConfigureTranslationManipulatorAppearance2d(
TranslationManipulators* translationManipulators);
void ConfigureTranslationManipulatorAppearance3d(TranslationManipulators* translationManipulators);
void ConfigureTranslationManipulatorAppearance2d(TranslationManipulators* translationManipulators);
} // namespace AzToolsFramework
@@ -1,14 +1,15 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Math/Vector3.h>
@@ -16,30 +17,44 @@
namespace AzToolsFramework
{
/**
* Provide unique type alias for AZ::u64 for manipulator, bounds and manager.
*/
//! Provide unique type alias for AZ::u64 for manipulator, bounds and manager.
template<typename T>
class IdType
{
public:
explicit IdType(AZ::u64 id = 0)
: m_id(id) {}
operator AZ::u64() const { return m_id; }
: m_id(id)
{
}
operator AZ::u64() const
{
return m_id;
}
bool operator==(IdType other) const
{
return m_id == other.m_id;
}
bool operator!=(IdType other) const
{
return m_id != other.m_id;
}
bool operator==(IdType other) const { return m_id == other.m_id; }
bool operator!=(IdType other) const { return m_id != other.m_id; }
IdType& operator++() // pre-increment
{
++m_id;
return *this;
}
IdType operator++(int) // post-increment
{
IdType temp = *this;
++*this;
return temp;
}
private:
AZ::u64 m_id;
};
@@ -51,10 +66,8 @@ namespace AzToolsFramework
using RegisteredBoundId = IdType<struct RegisteredBoundType>;
static const RegisteredBoundId InvalidBoundId = RegisteredBoundId(0);
/**
* This class serves as the base class for the actual bound shapes that various DefaultContextBoundManager-derived
* classes return from the function CreateShape.
*/
//! This class serves as the base class for the actual bound shapes that various DefaultContextBoundManager-derived
//! classes return from the function CreateShape.
class BoundShapeInterface
{
public:
@@ -63,25 +76,33 @@ namespace AzToolsFramework
explicit BoundShapeInterface(const RegisteredBoundId boundId)
: m_boundId(boundId)
, m_valid(false)
{}
{
}
virtual ~BoundShapeInterface() = default;
RegisteredBoundId GetBoundId() const { return m_boundId; }
RegisteredBoundId GetBoundId() const
{
return m_boundId;
}
/**
* @param rayOrigin The origin of the ray to test with.
* @param rayDir The direction of the ray to test with.
* @param[out] rayIntersectionDistance The distance of the intersecting point closest to the ray origin.
* @return Boolean indicating whether there is a least one intersecting point between this bound shape and the ray.
*/
virtual bool IntersectRay(
const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) = 0;
//! @param rayOrigin The origin of the ray to test with.
//! @param rayDir The direction of the ray to test with.
//! @param[out] rayIntersectionDistance The distance of the intersecting point closest to the ray origin.
//! @return Boolean indicating whether there is a least one intersecting point between this bound shape and the ray.
virtual bool IntersectRay(const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) = 0;
virtual void SetShapeData(const BoundRequestShapeBase& shapeData) = 0;
void SetValidity(bool valid) { m_valid = valid; }
bool IsValid() const { return m_valid; }
void SetValidity(bool valid)
{
m_valid = valid;
}
bool IsValid() const
{
return m_valid;
}
private:
RegisteredBoundId m_boundId;
@@ -1,22 +1,22 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/Math/Vector3.h>
#include <AzCore/Math/Quaternion.h>
#include <AzCore/Math/Spline.h>
#include <AzCore/Math/Transform.h>
#include <AzCore/Math/Vector3.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzCore/RTTI/RTTI.h>
#include <AzCore/std/smart_ptr/make_shared.h>
@@ -27,9 +27,7 @@ namespace AzToolsFramework
{
namespace Picking
{
/**
* An interface concrete shape types can implement to create specific BoundShapeInterfaces.
*/
//! An interface concrete shape types can implement to create specific BoundShapeInterfaces.
class BoundRequestShapeBase
{
public:
@@ -114,11 +112,9 @@ namespace AzToolsFramework
float m_radius;
};
/**
* The quad shape consists of 4 points in 3D space. Please set them from \ref m_corner1 to \ref m_corner4
* in either clock-wise winding or counter clock-wise winding. In another word, \ref m_corner1 and
* \ref corner_2 cannot be diagonal corners.
*/
//! The quad shape consists of 4 points in 3D space. Please set them from \ref m_corner1 to \ref m_corner4
//! in either clock-wise winding or counter clock-wise winding. In another word, \ref m_corner1 and
//! \ref corner_2 cannot be diagonal corners.
class BoundShapeQuad : public BoundRequestShapeBase
{
public:
@@ -138,9 +134,7 @@ namespace AzToolsFramework
AZ::Vector3 m_corner4;
};
/**
* The line segment consists of two points in 3D space defining a line the user can interact with.
*/
//! The line segment consists of two points in 3D space defining a line the user can interact with.
class BoundShapeLineSegment : public BoundRequestShapeBase
{
public:
@@ -159,10 +153,8 @@ namespace AzToolsFramework
float m_width;
};
/**
* The torus shape is approximated by a cylinder whose radius is the sum of the torus's major radius
* and minor radius and height is twice the torus's minor radius.
*/
//! The torus shape is approximated by a cylinder whose radius is the sum of the torus's major radius
//! and minor radius and height is twice the torus's minor radius.
class BoundShapeTorus : public BoundRequestShapeBase
{
public:
@@ -182,10 +174,8 @@ namespace AzToolsFramework
float m_minorRadius;
};
/**
* The spline is specified by a number of vertices. A piecewise approximation of the curve
* is computed by using a number of linear steps (defined by the granularity of the curve).
*/
//! The spline is specified by a number of vertices. A piecewise approximation of the curve
//! is computed by using a number of linear steps (defined by the granularity of the curve).
class BoundShapeSpline : public BoundRequestShapeBase
{
public:
@@ -204,16 +194,14 @@ namespace AzToolsFramework
float m_width;
};
/**
* Ray query for intersection against bounds.
*/
//! Ray query for intersection against bounds.
struct RaySelectInfo
{
AZ::Vector3 m_origin; ///< Start of ray.
AZ::Vector3 m_direction; ///< Direction of ray - make sure m_direction is unit length.
AZStd::vector<AZStd::pair<RegisteredBoundId, float>> m_boundIdsHit; ///< Store the id of the intersected bound
///< and the parameter of the corresponding
///< intersecting point.
AZ::Vector3 m_origin; //!< Start of ray.
AZ::Vector3 m_direction; //!< Direction of ray - make sure m_direction is unit length.
AZStd::vector<AZStd::pair<RegisteredBoundId, float>> m_boundIdsHit; //!< Store the id of the intersected bound
//!< and the parameter of the corresponding
//!< intersecting point.
};
} // namespace Picking
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "ManipulatorBoundManager.h"
@@ -16,8 +16,7 @@ namespace AzToolsFramework
{
namespace Picking
{
RegisteredBoundId ManipulatorBoundManager::UpdateOrRegisterBound(
const BoundRequestShapeBase& shapeData, RegisteredBoundId boundId)
RegisteredBoundId ManipulatorBoundManager::UpdateOrRegisterBound(const BoundRequestShapeBase& shapeData, RegisteredBoundId boundId)
{
if (boundId == InvalidBoundId)
{
@@ -25,8 +24,7 @@ namespace AzToolsFramework
boundId = m_nextBoundId++;
}
if (auto result = m_boundIdToShapeMap.find(boundId);
result == m_boundIdToShapeMap.end())
if (auto result = m_boundIdToShapeMap.find(boundId); result == m_boundIdToShapeMap.end())
{
if (AZStd::shared_ptr<BoundShapeInterface> createdShape = CreateShape(shapeData, boundId))
{
@@ -49,19 +47,16 @@ namespace AzToolsFramework
void ManipulatorBoundManager::UnregisterBound(const RegisteredBoundId boundId)
{
if (const auto findIter = m_boundIdToShapeMap.find(boundId);
findIter != m_boundIdToShapeMap.end())
if (const auto findIter = m_boundIdToShapeMap.find(boundId); findIter != m_boundIdToShapeMap.end())
{
DeleteShape(findIter->second.get());
m_boundIdToShapeMap.erase(findIter);
}
}
void ManipulatorBoundManager::SetBoundValidity(
const RegisteredBoundId boundId, const bool valid)
void ManipulatorBoundManager::SetBoundValidity(const RegisteredBoundId boundId, const bool valid)
{
if (auto found = m_boundIdToShapeMap.find(boundId);
found != m_boundIdToShapeMap.end())
if (auto found = m_boundIdToShapeMap.find(boundId); found != m_boundIdToShapeMap.end())
{
found->second->SetValidity(valid);
}
@@ -104,9 +99,9 @@ namespace AzToolsFramework
const auto hitItr = AZStd::lower_bound(
rayHits.begin(), rayHits.end(), BoundIdHitDistance(0, t),
[](const BoundIdHitDistance& lhs, const BoundIdHitDistance& rhs)
{
return lhs.second < rhs.second;
});
{
return lhs.second < rhs.second;
});
rayHits.insert(hitItr, AZStd::make_pair(bound->GetBoundId(), t));
}
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -21,10 +21,8 @@ namespace AzToolsFramework
{
class BoundShapeInterface;
/**
* Handle creating, destroying and storing all active manipulator
* bounds for performing raycasts/picking against.
*/
//! Handle creating, destroying and storing all active manipulator
//! bounds for performing raycasts/picking against.
class ManipulatorBoundManager
{
public:
@@ -35,21 +33,19 @@ namespace AzToolsFramework
ManipulatorBoundManager& operator=(const ManipulatorBoundManager&) = delete;
~ManipulatorBoundManager() = default;
RegisteredBoundId UpdateOrRegisterBound(
const BoundRequestShapeBase& shapeData, RegisteredBoundId id);
RegisteredBoundId UpdateOrRegisterBound(const BoundRequestShapeBase& shapeData, RegisteredBoundId id);
void UnregisterBound(RegisteredBoundId boundId);
void SetBoundValidity(RegisteredBoundId boundId, bool valid);
void RaySelect(RaySelectInfo &rayInfo);
void RaySelect(RaySelectInfo& rayInfo);
private:
AZStd::shared_ptr<BoundShapeInterface> CreateShape(
const BoundRequestShapeBase& ptrShape, RegisteredBoundId id);
AZStd::shared_ptr<BoundShapeInterface> CreateShape(const BoundRequestShapeBase& ptrShape, RegisteredBoundId id);
void DeleteShape(const BoundShapeInterface* boundShape);
AZStd::unordered_map<RegisteredBoundId, AZStd::shared_ptr<BoundShapeInterface>> m_boundIdToShapeMap;
AZStd::vector<AZStd::shared_ptr<BoundShapeInterface>> m_bounds; ///< All current manipulator bounds.
AZStd::vector<AZStd::shared_ptr<BoundShapeInterface>> m_bounds; //!< All current manipulator bounds.
RegisteredBoundId m_nextBoundId = RegisteredBoundId(1); ///< Next bound id to use when a bound is registered.
RegisteredBoundId m_nextBoundId = RegisteredBoundId(1); //!< Next bound id to use when a bound is registered.
};
} // namespace Picking
} // namespace AzToolsFramework
@@ -1,17 +1,18 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzCore/Math/IntersectSegment.h>
#include <AzCore/Math/Spline.h>
#include <AzCore/std/limits.h>
#include <AzToolsFramework/Picking/ContextBoundAPI.h>
#include <AzToolsFramework/Picking/Manipulators/ManipulatorBounds.h>
@@ -23,8 +24,7 @@ namespace AzToolsFramework
const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection, float& rayIntersectionDistance)
{
float vecRayIntersectionDistance;
if (AZ::Intersect::IntersectRaySphere(
rayOrigin, rayDirection, m_center, m_radius, vecRayIntersectionDistance) > 0)
if (AZ::Intersect::IntersectRaySphere(rayOrigin, rayDirection, m_center, m_radius, vecRayIntersectionDistance) > 0)
{
rayIntersectionDistance = vecRayIntersectionDistance;
return true;
@@ -45,8 +45,9 @@ namespace AzToolsFramework
bool ManipulatorBoundBox::IntersectRay(
const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection, float& rayIntersectionDistance)
{
return AZ::Intersect::IntersectRayBox(rayOrigin, rayDirection, m_center, m_axis1, m_axis2, m_axis3,
m_halfExtents.GetX(), m_halfExtents.GetY(), m_halfExtents.GetZ(), rayIntersectionDistance) > 0;
return AZ::Intersect::IntersectRayBox(
rayOrigin, rayDirection, m_center, m_axis1, m_axis2, m_axis3, m_halfExtents.GetX(), m_halfExtents.GetY(),
m_halfExtents.GetZ(), rayIntersectionDistance) > 0;
}
void ManipulatorBoundBox::SetShapeData(const BoundRequestShapeBase& shapeData)
@@ -66,8 +67,7 @@ namespace AzToolsFramework
{
float t1 = std::numeric_limits<float>::max();
float t2 = std::numeric_limits<float>::max();
if (AZ::Intersect::IntersectRayCappedCylinder(
rayOrigin, rayDirection, m_base, m_axis, m_height, m_radius, t1, t2) > 0)
if (AZ::Intersect::IntersectRayCappedCylinder(rayOrigin, rayDirection, m_base, m_axis, m_height, m_radius, t1, t2) > 0)
{
rayIntersectionDistance = AZStd::GetMin(t1, t2);
return true;
@@ -92,8 +92,7 @@ namespace AzToolsFramework
{
float t1 = std::numeric_limits<float>::max();
float t2 = std::numeric_limits<float>::max();
if (AZ::Intersect::IntersectRayCone(
rayOrigin, rayDirection, m_apexPosition, m_dir, m_height, m_radius, t1, t2) > 0)
if (AZ::Intersect::IntersectRayCone(rayOrigin, rayDirection, m_apexPosition, m_dir, m_height, m_radius, t1, t2) > 0)
{
rayIntersectionDistance = AZStd::GetMin(t1, t2);
return true;
@@ -117,7 +116,7 @@ namespace AzToolsFramework
const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection, float& rayIntersectionDistance)
{
return AZ::Intersect::IntersectRayQuad(
rayOrigin, rayDirection, m_corner1, m_corner2, m_corner3, m_corner4, rayIntersectionDistance) > 0;
rayOrigin, rayDirection, m_corner1, m_corner2, m_corner3, m_corner4, rayIntersectionDistance) > 0;
}
void ManipulatorBoundQuad::SetShapeData(const BoundRequestShapeBase& shapeData)
@@ -157,8 +156,7 @@ namespace AzToolsFramework
float rayProportion, lineSegmentProportion;
// note: here out param is proportion/percentage of line
AZ::Intersect::ClosestSegmentSegment(
rayOrigin, rayOrigin + rayDirection * rayLength,
m_worldStart, m_worldEnd, rayProportion, lineSegmentProportion,
rayOrigin, rayOrigin + rayDirection * rayLength, m_worldStart, m_worldEnd, rayProportion, lineSegmentProportion,
closestPosRay, closestPosLineSegment);
float distanceFromLine = (closestPosRay - closestPosLineSegment).GetLength();
@@ -188,8 +186,7 @@ namespace AzToolsFramework
{
if (const AZStd::shared_ptr<const AZ::Spline> spline = m_spline.lock())
{
AZ::RaySplineQueryResult splineQueryResult =
AZ::IntersectSpline(m_transform, rayOrigin, rayDirection, *spline);
AZ::RaySplineQueryResult splineQueryResult = AZ::IntersectSpline(m_transform, rayOrigin, rayDirection, *spline);
if (splineQueryResult.m_distanceSq <= m_width * m_width)
{
@@ -214,22 +211,25 @@ namespace AzToolsFramework
}
bool IntersectHollowCylinder(
const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection,
const AZ::Vector3& center, const AZ::Vector3& axis,
const float minorRadius, const float majorRadius,
const AZ::Vector3& rayOrigin,
const AZ::Vector3& rayDirection,
const AZ::Vector3& center,
const AZ::Vector3& axis,
const float minorRadius,
const float majorRadius,
float& rayIntersectionDistance)
{
float t1 = std::numeric_limits<float>::max();
float t2 = std::numeric_limits<float>::max();
float t1 = AZStd::numeric_limits<float>::max();
float t2 = AZStd::numeric_limits<float>::max();
const AZ::Vector3 base = center - axis * minorRadius;
if (AZ::Intersect::IntersectRayCappedCylinder(
rayOrigin, rayDirection, base, axis, minorRadius * 2.0f, majorRadius + minorRadius, t1, t2) > 0)
rayOrigin, rayDirection, base, axis, minorRadius * 2.0f, majorRadius + minorRadius, t1, t2) > 0)
{
const float thresholdSq = powf(majorRadius - minorRadius, 2.0f);
const float threshold = majorRadius - minorRadius;
const float thresholdSq = threshold * threshold;
// util lambda used for distance checks at both 't' values
const auto validHolowCylinderHit =
[&rayOrigin, &rayDirection, &center, thresholdSq](const float t)
const auto validHolowCylinderHit = [&rayOrigin, &rayDirection, &center, thresholdSq](const float t)
{
// only return a valid intersection if the hit was
// not in the 'hollow' part of the cylinder
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -27,36 +27,36 @@ namespace AzToolsFramework
{
namespace Picking
{
class ManipulatorBoundSphere
: public BoundShapeInterface
class ManipulatorBoundSphere : public BoundShapeInterface
{
public:
AZ_RTTI(ManipulatorBoundSphere, "{64D1B863-F574-4B31-A4F2-C9744D8567B3}", BoundShapeInterface);
AZ_CLASS_ALLOCATOR(ManipulatorBoundSphere, AZ::SystemAllocator, 0);
explicit ManipulatorBoundSphere(RegisteredBoundId boundId)
: BoundShapeInterface(boundId) {}
: BoundShapeInterface(boundId)
{
}
bool IntersectRay(
const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override;
bool IntersectRay(const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override;
void SetShapeData(const BoundRequestShapeBase& shapeData) override;
AZ::Vector3 m_center = AZ::Vector3::CreateZero();
float m_radius = 0.0f;
};
class ManipulatorBoundBox
: public BoundShapeInterface
class ManipulatorBoundBox : public BoundShapeInterface
{
public:
AZ_RTTI(ManipulatorBoundBox, "{3AD46067-933F-49B4-82E1-DBF12C7BC02E}", BoundShapeInterface);
AZ_CLASS_ALLOCATOR(ManipulatorBoundBox, AZ::SystemAllocator, 0);
explicit ManipulatorBoundBox(RegisteredBoundId boundId)
: BoundShapeInterface(boundId) {}
: BoundShapeInterface(boundId)
{
}
bool IntersectRay(
const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override;
bool IntersectRay(const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override;
void SetShapeData(const BoundRequestShapeBase& shapeData) override;
AZ::Vector3 m_center = AZ::Vector3::CreateZero();
@@ -66,38 +66,38 @@ namespace AzToolsFramework
AZ::Vector3 m_halfExtents = AZ::Vector3::CreateZero();
};
class ManipulatorBoundCylinder
: public BoundShapeInterface
class ManipulatorBoundCylinder : public BoundShapeInterface
{
public:
AZ_RTTI(ManipulatorBoundCylinder, "{D248F9E4-22E6-41A8-898D-704DF307B533}", BoundShapeInterface);
AZ_CLASS_ALLOCATOR(ManipulatorBoundCylinder, AZ::SystemAllocator, 0);
explicit ManipulatorBoundCylinder(RegisteredBoundId boundId)
: BoundShapeInterface(boundId) {}
: BoundShapeInterface(boundId)
{
}
bool IntersectRay(
const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override;
bool IntersectRay(const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override;
void SetShapeData(const BoundRequestShapeBase& shapeData) override;
AZ::Vector3 m_base = AZ::Vector3::CreateZero(); ///< The center of the circle at the base of the cylinder.
AZ::Vector3 m_base = AZ::Vector3::CreateZero(); //!< The center of the circle at the base of the cylinder.
AZ::Vector3 m_axis = AZ::Vector3::CreateZero();
float m_height = 0.0f;
float m_radius = 0.0f;
};
class ManipulatorBoundCone
: public BoundShapeInterface
class ManipulatorBoundCone : public BoundShapeInterface
{
public:
AZ_RTTI(ManipulatorBoundCone, "{9430440D-DFF2-4A60-9073-507C4E9DD65D}", BoundShapeInterface);
AZ_CLASS_ALLOCATOR(ManipulatorBoundCone, AZ::SystemAllocator, 0);
explicit ManipulatorBoundCone(RegisteredBoundId boundId)
: BoundShapeInterface(boundId) {}
: BoundShapeInterface(boundId)
{
}
bool IntersectRay(
const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override;
bool IntersectRay(const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override;
void SetShapeData(const BoundRequestShapeBase& shapeData) override;
AZ::Vector3 m_apexPosition = AZ::Vector3::CreateZero();
@@ -106,23 +106,21 @@ namespace AzToolsFramework
float m_height = 0.0f;
};
/**
* The quad shape consists of 4 points in 3D space. Please set them from \ref m_corner1 to \ref m_corner4
* in either clock-wise winding or counter clock-wise winding. In another word, \ref m_corner1 and
* \ref corner_2 cannot be diagonal corners.
*/
class ManipulatorBoundQuad
: public BoundShapeInterface
//! The quad shape consists of 4 points in 3D space. Please set them from \ref m_corner1 to \ref m_corner4
//! in either clock-wise winding or counter clock-wise winding. In another word, \ref m_corner1 and
//! \ref corner_2 cannot be diagonal corners.
class ManipulatorBoundQuad : public BoundShapeInterface
{
public:
AZ_RTTI(ManipulatorBoundQuad, "{3CDED61C-5786-4299-B5F2-5970DE4457AD}", BoundShapeInterface);
AZ_CLASS_ALLOCATOR(ManipulatorBoundQuad, AZ::SystemAllocator, 0);
explicit ManipulatorBoundQuad(RegisteredBoundId boundId)
: BoundShapeInterface(boundId) {}
: BoundShapeInterface(boundId)
{
}
bool IntersectRay(
const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override;
bool IntersectRay(const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override;
void SetShapeData(const BoundRequestShapeBase& shapeData) override;
AZ::Vector3 m_corner1 = AZ::Vector3::CreateZero();
@@ -131,18 +129,18 @@ namespace AzToolsFramework
AZ::Vector3 m_corner4 = AZ::Vector3::CreateZero();
};
class ManipulatorBoundTorus
: public BoundShapeInterface
class ManipulatorBoundTorus : public BoundShapeInterface
{
public:
AZ_RTTI(ManipulatorBoundTorus, "{46E4711C-178A-4F97-BC14-A048D096E7A1}", BoundShapeInterface);
AZ_CLASS_ALLOCATOR(ManipulatorBoundTorus, AZ::SystemAllocator, 0);
explicit ManipulatorBoundTorus(RegisteredBoundId boundId)
: BoundShapeInterface(boundId) {}
: BoundShapeInterface(boundId)
{
}
bool IntersectRay(
const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override;
bool IntersectRay(const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override;
void SetShapeData(const BoundRequestShapeBase& shapeData) override;
// Approximate a torus as a thin cylinder. A ray intersects a torus when the ray and the torus'
@@ -150,22 +148,22 @@ namespace AzToolsFramework
// center of the torus.
AZ::Vector3 m_center = AZ::Vector3::CreateZero();
AZ::Vector3 m_axis = AZ::Vector3::CreateZero();
float m_majorRadius = 0.0f; ///< Usually denoted as "R", the distance from the center of the tube to the center of the torus.
float m_minorRadius = 0.0f; ///< Usually denoted as "r", the radius of the tube.
float m_majorRadius = 0.0f; //!< Usually denoted as "R", the distance from the center of the tube to the center of the torus.
float m_minorRadius = 0.0f; //!< Usually denoted as "r", the radius of the tube.
};
class ManipulatorBoundLineSegment
: public BoundShapeInterface
class ManipulatorBoundLineSegment : public BoundShapeInterface
{
public:
AZ_RTTI(ManipulatorBoundLineSegment, "{66801554-1C1A-4E79-B1E7-342DFA779D53}", BoundShapeInterface);
AZ_CLASS_ALLOCATOR(ManipulatorBoundLineSegment, AZ::SystemAllocator, 0);
explicit ManipulatorBoundLineSegment(RegisteredBoundId boundId)
: BoundShapeInterface(boundId) {}
: BoundShapeInterface(boundId)
{
}
bool IntersectRay(
const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override;
bool IntersectRay(const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override;
void SetShapeData(const BoundRequestShapeBase& shapeData) override;
AZ::Vector3 m_worldStart = AZ::Vector3::CreateZero();
@@ -173,18 +171,18 @@ namespace AzToolsFramework
float m_width = 0.0f;
};
class ManipulatorBoundSpline
: public BoundShapeInterface
class ManipulatorBoundSpline : public BoundShapeInterface
{
public:
AZ_RTTI(ManipulatorBoundSpline, "{777760FF-8547-45AD-876F-16BA4D9D0584}", BoundShapeInterface);
AZ_CLASS_ALLOCATOR(ManipulatorBoundSpline, AZ::SystemAllocator, 0);
explicit ManipulatorBoundSpline(RegisteredBoundId boundId)
: BoundShapeInterface(boundId) {}
: BoundShapeInterface(boundId)
{
}
bool IntersectRay(
const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override;
bool IntersectRay(const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDir, float& rayIntersectionDistance) override;
void SetShapeData(const BoundRequestShapeBase& shapeData) override;
AZStd::weak_ptr<const AZ::Spline> m_spline;
@@ -192,11 +190,14 @@ namespace AzToolsFramework
float m_width = 0.0f;
};
/// Approximate intersection with a torus-like shape.
//! Approximate intersection with a torus-like shape.
bool IntersectHollowCylinder(
const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection,
const AZ::Vector3& center, const AZ::Vector3& axis,
float minorRadius, float majorRadius,
const AZ::Vector3& rayOrigin,
const AZ::Vector3& rayDirection,
const AZ::Vector3& center,
const AZ::Vector3& axis,
float minorRadius,
float majorRadius,
float& rayIntersectionDistance);
} // namespace Picking
@@ -47,8 +47,13 @@ namespace AzToolsFramework
virtual void AppendEntityAliasToPatchPaths(PrefabDom& providedPatch, const AZ::EntityId& entityId) = 0;
//! Updates the template links (updating instances) for the given templateId using the providedPatch
virtual bool PatchTemplate(PrefabDomValue& providedPatch, TemplateId templateId) = 0;
//! Updates the template links (updating instances) for the given template and triggers propagation on its instances.
//! @param providedPatch The patch to apply to the template.
//! @param templateId The id of the template to update.
//! @param instanceToExclude An optional reference to an instance of the template being updated that should not be refreshes as part of propagation.
//! Defaults to nullopt, which means that all instances will be refreshed.
//! @return True if the template was patched correctly, false if the operation failed.
virtual bool PatchTemplate(PrefabDomValue& providedPatch, TemplateId templateId, InstanceOptionalReference instanceToExclude = AZStd::nullopt) = 0;
virtual void ApplyPatchesToInstance(const AZ::EntityId& entityId, PrefabDom& patches, const Instance& instanceToAddPatches) = 0;
@@ -172,7 +172,7 @@ namespace AzToolsFramework
}
}
bool InstanceToTemplatePropagator::PatchTemplate(PrefabDomValue& providedPatch, TemplateId templateId)
bool InstanceToTemplatePropagator::PatchTemplate(PrefabDomValue& providedPatch, TemplateId templateId, InstanceOptionalReference instanceToExclude)
{
PrefabDom& templateDomReference = m_prefabSystemComponentInterface->FindTemplateDom(templateId);
@@ -184,7 +184,7 @@ namespace AzToolsFramework
if (result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success)
{
m_prefabSystemComponentInterface->SetTemplateDirtyFlag(templateId, true);
m_prefabSystemComponentInterface->PropagateTemplateChanges(templateId);
m_prefabSystemComponentInterface->PropagateTemplateChanges(templateId, instanceToExclude);
return true;
}
else
@@ -37,7 +37,7 @@ namespace AzToolsFramework
InstanceOptionalReference GetTopMostInstanceInHierarchy(AZ::EntityId entityId);
bool PatchTemplate(PrefabDomValue& providedPatch, TemplateId templateId) override;
bool PatchTemplate(PrefabDomValue& providedPatch, TemplateId templateId, InstanceOptionalReference instanceToExclude = AZStd::nullopt) override;
void ApplyPatchesToInstance(const AZ::EntityId& entityId, PrefabDom& patches, const Instance& instanceToAddPatches) override;
@@ -56,7 +56,7 @@ namespace AzToolsFramework
AZ::Interface<InstanceUpdateExecutorInterface>::Unregister(this);
}
void InstanceUpdateExecutor::AddTemplateInstancesToQueue(TemplateId instanceTemplateId)
void InstanceUpdateExecutor::AddTemplateInstancesToQueue(TemplateId instanceTemplateId, InstanceOptionalReference instanceToExclude)
{
auto findInstancesResult =
m_templateInstanceMapperInterface->FindInstancesOwnedByTemplate(instanceTemplateId);
@@ -70,9 +70,18 @@ namespace AzToolsFramework
return;
}
Instance* instanceToExcludePtr = nullptr;
if (instanceToExclude.has_value())
{
instanceToExcludePtr = &(instanceToExclude->get());
}
for (auto instance : findInstancesResult->get())
{
m_instancesUpdateQueue.emplace_back(instance);
if (instance != instanceToExcludePtr)
{
m_instancesUpdateQueue.emplace_back(instance);
}
}
}
@@ -103,7 +112,7 @@ namespace AzToolsFramework
EntityIdList selectedEntityIds;
ToolsApplicationRequestBus::BroadcastResult(selectedEntityIds, &ToolsApplicationRequests::GetSelectedEntities);
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, EntityIdList());
PrefabDom instanceDomFromRootDocument;
// Process all instances in the queue, capped to the batch size.
// Even though we potentially initialized the batch size to the queue, it's possible for the queue size to shrink
@@ -148,13 +157,62 @@ namespace AzToolsFramework
continue;
}
Template& currentTemplate = currentTemplateReference->get();
Instance::EntityList newEntities;
if (PrefabDomUtils::LoadInstanceFromPrefabDom(*instanceToUpdate, newEntities, currentTemplate.GetPrefabDom()))
// Climb up to the root of the instance hierarchy from this instance
InstanceOptionalConstReference rootInstance = *instanceToUpdate;
AZStd::vector<InstanceOptionalConstReference> pathOfInstances;
while (rootInstance->get().GetParentInstance() != AZStd::nullopt)
{
// If a link was created for a nested instance before the changes were propagated,
// then we associate it correctly here
instanceToUpdate->GetNestedInstances([&](AZStd::unique_ptr<Instance>& nestedInstance) {
pathOfInstances.emplace_back(rootInstance);
rootInstance = rootInstance->get().GetParentInstance();
}
AZStd::string aliasPathResult = "";
for (auto instanceIter = pathOfInstances.rbegin(); instanceIter != pathOfInstances.rend(); ++instanceIter)
{
aliasPathResult.append("/Instances/");
aliasPathResult.append((*instanceIter)->get().GetInstanceAlias());
}
PrefabDomPath rootPrefabDomPath(aliasPathResult.c_str());
PrefabDom& rootPrefabTemplateDom =
m_prefabSystemComponentInterface->FindTemplateDom(rootInstance->get().GetTemplateId());
auto instanceDomFromRootValue = rootPrefabDomPath.Get(rootPrefabTemplateDom);
if (!instanceDomFromRootValue)
{
AZ_Assert(
false,
"InstanceUpdateExecutor::UpdateTemplateInstancesInQueue - "
"Could not load Instance DOM from the top level ancestor's DOM.");
isUpdateSuccessful = false;
continue;
}
PrefabDomValueReference instanceDomFromRoot = *instanceDomFromRootValue;
if (!instanceDomFromRoot.has_value())
{
AZ_Assert(
false,
"InstanceUpdateExecutor::UpdateTemplateInstancesInQueue - "
"Could not load Instance DOM from the top level ancestor's DOM.");
isUpdateSuccessful = false;
continue;
}
// If a link was created for a nested instance before the changes were propagated,
// then we associate it correctly here
instanceDomFromRootDocument.CopyFrom(instanceDomFromRoot->get(), instanceDomFromRootDocument.GetAllocator());
if (PrefabDomUtils::LoadInstanceFromPrefabDom(*instanceToUpdate, newEntities, instanceDomFromRootDocument))
{
Template& currentTemplate = currentTemplateReference->get();
instanceToUpdate->GetNestedInstances([&](AZStd::unique_ptr<Instance>& nestedInstance)
{
if (nestedInstance->GetLinkId() != InvalidLinkId)
{
return;
@@ -179,22 +237,11 @@ namespace AzToolsFramework
AzToolsFramework::EditorEntityContextRequestBus::Broadcast(
&AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded, newEntities);
}
else
{
AZ_Error(
"Prefab", false,
"InstanceUpdateExecutor::UpdateTemplateInstancesInQueue - "
"Could not load Instance from Prefab DOM of Template with Id '%llu' on file path '%s'.",
currentTemplateId, currentTemplate.GetFilePath().c_str());
isUpdateSuccessful = false;
}
}
for (auto entityIdIterator = selectedEntityIds.begin(); entityIdIterator != selectedEntityIds.end(); entityIdIterator++)
{
// Since entities get recreated during propagation, we need to check whether the entities correspoding to the list
// of selected entity ids are present or not.
// Since entities get recreated during propagation, we need to check whether the entities
// corresponding to the list of selected entity ids are present or not.
AZ::Entity* entity = GetEntityById(*entityIdIterator);
if (entity == nullptr)
{
@@ -35,7 +35,7 @@ namespace AzToolsFramework
explicit InstanceUpdateExecutor(int instanceCountToUpdateInBatch = 0);
void AddTemplateInstancesToQueue(TemplateId instanceTemplateId) override;
void AddTemplateInstancesToQueue(TemplateId instanceTemplateId, InstanceOptionalReference instanceToExclude = AZStd::nullopt) override;
bool UpdateTemplateInstancesInQueue() override;
virtual void RemoveTemplateInstanceFromQueue(const Instance* instance) override;
@@ -27,7 +27,7 @@ namespace AzToolsFramework
virtual ~InstanceUpdateExecutorInterface() = default;
// Add all Instances of Template with given Id into a queue for updating them later.
virtual void AddTemplateInstancesToQueue(TemplateId instanceTemplateId) = 0;
virtual void AddTemplateInstancesToQueue(TemplateId instanceTemplateId, InstanceOptionalReference instanceToExclude = AZStd::nullopt) = 0;
// Update Instances in the waiting queue.
virtual bool UpdateTemplateInstancesInQueue() = 0;
@@ -242,11 +242,13 @@ namespace AzToolsFramework
m_instanceToTemplateInterface->GenerateDomForEntity(containerAfterReset, *containerEntity);
// Update the state of the entity
PrefabUndoEntityUpdate* state = aznew PrefabUndoEntityUpdate(AZStd::to_string(static_cast<AZ::u64>(containerEntityId)));
state->SetParent(undoBatch.GetUndoBatch());
state->Capture(containerBeforeReset, containerAfterReset, containerEntityId);
auto templateId = instanceToCreate->get().GetTemplateId();
state->Redo();
PrefabDom transformPatch;
m_instanceToTemplateInterface->GeneratePatch(transformPatch, containerBeforeReset, containerAfterReset);
m_instanceToTemplateInterface->AppendEntityAliasToPatchPaths(transformPatch, containerEntityId);
m_instanceToTemplateInterface->PatchTemplate(transformPatch, templateId);
}
// This clears any entities marked as dirty due to reparenting of entities during the process of creating a prefab.
@@ -661,12 +663,12 @@ namespace AzToolsFramework
else
{
Internal_HandleContainerOverride(
parentUndoBatch, entityId, patch, owningInstance->get().GetLinkId());
parentUndoBatch, entityId, patch, owningInstance->get().GetLinkId(), owningInstance->get().GetParentInstance());
}
}
else
{
Internal_HandleEntityChange(parentUndoBatch, entityId, beforeState, afterState);
Internal_HandleEntityChange(parentUndoBatch, entityId, beforeState, afterState, owningInstance);
if (isNewParentOwnedByDifferentInstance)
{
@@ -679,25 +681,27 @@ namespace AzToolsFramework
}
void PrefabPublicHandler::Internal_HandleContainerOverride(
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId entityId, const PrefabDom& patch, const LinkId linkId)
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId entityId, const PrefabDom& patch,
const LinkId linkId, InstanceOptionalReference parentInstance)
{
// Save these changes as patches to the link
PrefabUndoLinkUpdate* linkUpdate = aznew PrefabUndoLinkUpdate(AZStd::to_string(static_cast<AZ::u64>(entityId)));
linkUpdate->SetParent(undoBatch);
linkUpdate->Capture(patch, linkId);
linkUpdate->Redo();
linkUpdate->Redo(parentInstance);
}
void PrefabPublicHandler::Internal_HandleEntityChange(
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId entityId, PrefabDom& beforeState, PrefabDom& afterState)
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId entityId, PrefabDom& beforeState,
PrefabDom& afterState, InstanceOptionalReference instance)
{
// Update the state of the entity
PrefabUndoEntityUpdate* state = aznew PrefabUndoEntityUpdate(AZStd::to_string(static_cast<AZ::u64>(entityId)));
state->SetParent(undoBatch);
state->Capture(beforeState, afterState, entityId);
state->Redo();
state->Redo(instance);
}
void PrefabPublicHandler::Internal_HandleInstanceChange(
@@ -162,9 +162,11 @@ namespace AzToolsFramework
InstanceOptionalConstReference instance, const AZStd::unordered_set<AZ::IO::Path>& templateSourcePaths);
static void Internal_HandleContainerOverride(
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId entityId, const PrefabDom& patch, const LinkId linkId);
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId entityId, const PrefabDom& patch,
const LinkId linkId, InstanceOptionalReference parentInstance = AZStd::nullopt);
static void Internal_HandleEntityChange(
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId entityId, PrefabDom& beforeState, PrefabDom& afterState);
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId entityId, PrefabDom& beforeState,
PrefabDom& afterState, InstanceOptionalReference instance = AZStd::nullopt);
void Internal_HandleInstanceChange(UndoSystem::URSequencePoint* undoBatch, AZ::Entity* entity, AZ::EntityId beforeParentId, AZ::EntityId afterParentId);
void UpdateLinkPatchesWithNewEntityAliases(
@@ -141,8 +141,10 @@ namespace AzToolsFramework
return newInstance;
}
void PrefabSystemComponent::PropagateTemplateChanges(TemplateId templateId)
void PrefabSystemComponent::PropagateTemplateChanges(TemplateId templateId, InstanceOptionalReference instanceToExclude)
{
UpdatePrefabInstances(templateId, instanceToExclude);
auto templateIdToLinkIdsIterator = m_templateToLinkIdsMap.find(templateId);
if (templateIdToLinkIdsIterator != m_templateToLinkIdsMap.end())
{
@@ -153,10 +155,6 @@ namespace AzToolsFramework
templateIdToLinkIdsIterator->second.end()));
UpdateLinkedInstances(linkIdsToUpdateQueue);
}
else
{
UpdatePrefabInstances(templateId);
}
}
void PrefabSystemComponent::UpdatePrefabTemplate(TemplateId templateId, const PrefabDom& updatedDom)
@@ -174,9 +172,9 @@ namespace AzToolsFramework
}
}
void PrefabSystemComponent::UpdatePrefabInstances(const TemplateId& templateId)
void PrefabSystemComponent::UpdatePrefabInstances(const TemplateId& templateId, InstanceOptionalReference instanceToExclude)
{
m_instanceUpdateExecutor.AddTemplateInstancesToQueue(templateId);
m_instanceUpdateExecutor.AddTemplateInstancesToQueue(templateId, instanceToExclude);
}
void PrefabSystemComponent::UpdateLinkedInstances(AZStd::queue<LinkIds>& linkIdsQueue)
@@ -250,8 +248,6 @@ namespace AzToolsFramework
if (targetTemplateIdToLinkIdMap[targetTemplateId].first.empty() &&
targetTemplateIdToLinkIdMap[targetTemplateId].second)
{
UpdatePrefabInstances(targetTemplateId);
auto templateToLinkIter = m_templateToLinkIdsMap.find(targetTemplateId);
if (templateToLinkIter != m_templateToLinkIdsMap.end())
{
@@ -215,14 +215,14 @@ namespace AzToolsFramework
*/
void UpdatePrefabTemplate(TemplateId templateId, const PrefabDom& updatedDom) override;
void PropagateTemplateChanges(TemplateId templateId) override;
void PropagateTemplateChanges(TemplateId templateId, InstanceOptionalReference instanceToExclude = AZStd::nullopt) override;
/**
* Updates all Instances owned by a Template.
*
* @param templateId The id of the Template owning Instances to update.
*/
void UpdatePrefabInstances(const TemplateId& templateId);
void UpdatePrefabInstances(const TemplateId& templateId, InstanceOptionalReference instanceToExclude = AZStd::nullopt);
private:
AZ_DISABLE_COPY_MOVE(PrefabSystemComponent);
@@ -56,7 +56,7 @@ namespace AzToolsFramework
virtual PrefabDom& FindTemplateDom(TemplateId templateId) = 0;
virtual void UpdatePrefabTemplate(TemplateId templateId, const PrefabDom& updatedDom) = 0;
virtual void PropagateTemplateChanges(TemplateId templateId) = 0;
virtual void PropagateTemplateChanges(TemplateId templateId, InstanceOptionalReference instanceToExclude = AZStd::nullopt) = 0;
virtual AZStd::unique_ptr<Instance> InstantiatePrefab(AZ::IO::PathView filePath) = 0;
virtual AZStd::unique_ptr<Instance> InstantiatePrefab(const TemplateId& templateId) = 0;
@@ -70,10 +70,10 @@ namespace AzToolsFramework
const AZ::EntityId& entityId)
{
//get the entity alias for future undo/redo
InstanceOptionalReference instanceOptionalReference = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
AZ_Error("Prefab", instanceOptionalReference,
auto instanceReference = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
AZ_Error("Prefab", instanceReference,
"Failed to find an owning instance for the entity with id %llu.", static_cast<AZ::u64>(entityId));
Instance& instance = instanceOptionalReference->get();
Instance& instance = instanceReference->get();
m_templateId = instance.GetTemplateId();
m_entityAlias = (instance.GetEntityAlias(entityId)).value();
@@ -106,6 +106,17 @@ namespace AzToolsFramework
m_templateId);
}
void PrefabUndoEntityUpdate::Redo(InstanceOptionalReference instanceToExclude)
{
[[maybe_unused]] bool isPatchApplicationSuccessful =
m_instanceToTemplateInterface->PatchTemplate(m_redoPatch, m_templateId, instanceToExclude);
AZ_Error(
"Prefab", isPatchApplicationSuccessful,
"Applying the patch on the entity with alias '%s' in template with id '%llu' was unsuccessful", m_entityAlias.c_str(),
m_templateId);
}
//PrefabInstanceLinkUndo
PrefabUndoInstanceLink::PrefabUndoInstanceLink(const AZStd::string& undoOperationName)
: PrefabUndoBase(undoOperationName)
@@ -290,7 +301,12 @@ namespace AzToolsFramework
UpdateLink(m_linkDomNext);
}
void PrefabUndoLinkUpdate::UpdateLink(PrefabDom& linkDom)
void PrefabUndoLinkUpdate::Redo(InstanceOptionalReference instanceToExclude)
{
UpdateLink(m_linkDomNext, instanceToExclude);
}
void PrefabUndoLinkUpdate::UpdateLink(PrefabDom& linkDom, InstanceOptionalReference instanceToExclude)
{
LinkReference link = m_prefabSystemComponentInterface->FindLink(m_linkId);
@@ -304,7 +320,7 @@ namespace AzToolsFramework
//propagate the link changes
link->get().UpdateTarget();
m_prefabSystemComponentInterface->PropagateTemplateChanges(link->get().GetTargetTemplateId());
m_prefabSystemComponentInterface->PropagateTemplateChanges(link->get().GetTargetTemplateId(), instanceToExclude);
//mark as dirty
m_prefabSystemComponentInterface->SetTemplateDirtyFlag(link->get().GetTargetTemplateId(), true);
@@ -71,11 +71,12 @@ namespace AzToolsFramework
void Capture(
PrefabDom& initialState,
PrefabDom& endState,
const AZ::EntityId& entity);
PrefabDom& endState, const AZ::EntityId& entity);
void Undo() override;
void Redo() override;
//! Overload to allow to apply the change, but prevent instanceToExclude from being refreshed.
void Redo(InstanceOptionalReference instanceToExclude);
private:
InstanceEntityMapperInterface* m_instanceEntityMapperInterface = nullptr;
@@ -139,9 +140,11 @@ namespace AzToolsFramework
void Undo() override;
void Redo() override;
//! Overload to allow to apply the change, but prevent instanceToExclude from being refreshed.
void Redo(InstanceOptionalReference instanceToExclude);
private:
void UpdateLink(PrefabDom& linkDom);
void UpdateLink(PrefabDom& linkDom, InstanceOptionalReference instanceToExclude = AZStd::nullopt);
LinkId m_linkId;
PrefabDom m_linkDomNext; //data for delete/update
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "EditorContextMenu.h"
@@ -16,8 +16,7 @@
namespace AzToolsFramework
{
void EditorContextMenuUpdate(
EditorContextMenu& contextMenu, const ViewportInteraction::MouseInteractionEvent& mouseInteraction)
void EditorContextMenuUpdate(EditorContextMenu& contextMenu, const ViewportInteraction::MouseInteractionEvent& mouseInteraction)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
@@ -26,18 +25,17 @@ namespace AzToolsFramework
mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::Down)
{
contextMenu.m_shouldOpen = true;
contextMenu.m_clickPoint = ViewportInteraction::QPointFromScreenPoint(
mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates);
contextMenu.m_clickPoint =
ViewportInteraction::QPointFromScreenPoint(mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates);
}
// disable shouldOpen if right clicking an moving the mouse
if (mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::Move)
{
const QPoint currentScreenCoords = ViewportInteraction::QPointFromScreenPoint(
mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates);
const QPoint currentScreenCoords =
ViewportInteraction::QPointFromScreenPoint(mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates);
contextMenu.m_shouldOpen = contextMenu.m_shouldOpen &&
(currentScreenCoords - contextMenu.m_clickPoint).manhattanLength() < 2;
contextMenu.m_shouldOpen = contextMenu.m_shouldOpen && (currentScreenCoords - contextMenu.m_clickPoint).manhattanLength() < 2;
}
// do show the context menu
@@ -58,16 +56,16 @@ namespace AzToolsFramework
// Populate global context menu.
const int contextMenuFlag = 0;
EditorEvents::Bus::BroadcastReverse(
&EditorEvents::PopulateEditorGlobalContextMenu,
contextMenu.m_menu.data(), AzFramework::Vector2FromScreenPoint(
mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates),
&EditorEvents::PopulateEditorGlobalContextMenu, contextMenu.m_menu.data(),
AzFramework::Vector2FromScreenPoint(mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates),
contextMenuFlag);
if (!contextMenu.m_menu->isEmpty())
{
contextMenu.m_menu->exec(QCursor::pos());
// Use popup instead of exec; this avoids blocking input event processing while the menu dialog is active
contextMenu.m_menu->popup(QCursor::pos());
}
}
}
}
}
} // namespace AzToolsFramework
@@ -1,22 +1,22 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <QMenu>
#include <QPoint>
#include <QPointer>
#include <QMenu>
namespace AzToolsFramework
{
@@ -25,7 +25,7 @@ namespace AzToolsFramework
struct MouseInteractionEvent;
}
/// State of when and where the right-click context menu should appear.
//! State of when and where the right-click context menu should appear.
struct EditorContextMenu final
{
bool m_shouldOpen = false;
@@ -33,8 +33,6 @@ namespace AzToolsFramework
QPointer<QMenu> m_menu;
};
/// Update to run for context menu (when should it appear/disappear etc).
void EditorContextMenuUpdate(
EditorContextMenu& contextMenu,
const ViewportInteraction::MouseInteractionEvent& mouseInteraction);
//! Update to run for context menu (when should it appear/disappear etc).
void EditorContextMenuUpdate(EditorContextMenu& contextMenu, const ViewportInteraction::MouseInteractionEvent& mouseInteraction);
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "VertexContainerDisplay.h"
@@ -23,8 +23,7 @@ namespace AzToolsFramework
const AZ::Vector3 DefaultVertexTextOffset = AZ::Vector3(0.0f, 0.0f, -0.1f);
void DisplayVertexContainerIndex(
AzFramework::DebugDisplayRequests& debugDisplay,
const AZ::Vector3& position, const size_t index, const float textSize)
AzFramework::DebugDisplayRequests& debugDisplay, const AZ::Vector3& position, const size_t index, const float textSize)
{
AZStd::string indexFormat = AZStd::string::format("[%zu]", index);
debugDisplay.DrawTextLabel(position, textSize, indexFormat.c_str(), true);
@@ -36,7 +35,8 @@ namespace AzToolsFramework
const AZ::FixedVertices<Vertex>& vertices,
const AZ::Transform& transform,
const AZ::Vector3& nonUniformScale,
const bool selected, const float textSize,
const bool selected,
const float textSize,
const AZ::Color& textColor,
const AZ::Vector3& textOffset)
{
@@ -52,11 +52,12 @@ namespace AzToolsFramework
if (vertices.GetVertex(vertIndex, vertex))
{
DisplayVertexContainerIndex(
debugDisplay, transform.TransformPoint(nonUniformScale * (AdaptVertexOut(vertex) + textOffset)), vertIndex, textSize);
debugDisplay, transform.TransformPoint(nonUniformScale * (AdaptVertexOut(vertex) + textOffset)), vertIndex,
textSize);
}
}
}
}
} // namespace VertexContainerDisplay
// explicit template instantiations
template void VertexContainerDisplay::DisplayVertexContainerIndices(
@@ -64,7 +65,8 @@ namespace AzToolsFramework
const AZ::FixedVertices<AZ::Vector2>& vertices,
const AZ::Transform& transform,
const AZ::Vector3& nonUniformScale,
bool selected, float textSize,
bool selected,
float textSize,
const AZ::Color& textColor,
const AZ::Vector3& textOffset);
template void VertexContainerDisplay::DisplayVertexContainerIndices(
@@ -72,7 +74,8 @@ namespace AzToolsFramework
const AZ::FixedVertices<AZ::Vector3>& vertices,
const AZ::Transform& transform,
const AZ::Vector3& nonUniformScale,
bool selected, float textSize,
bool selected,
float textSize,
const AZ::Color& textColor,
const AZ::Vector3& textOffset);
}
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -22,22 +22,23 @@ namespace AzFramework
namespace AzToolsFramework
{
/// Utility functions for rendering vertex container indices.
//! Utility functions for rendering vertex container indices.
namespace VertexContainerDisplay
{
extern const float DefaultVertexTextSize;
extern const AZ::Color DefaultVertexTextColor;
extern const AZ::Vector3 DefaultVertexTextOffset;
/// Displays all vertex container indices as text at the position of each vertex when selected
//! Displays all vertex container indices as text at the position of each vertex when selected
template<typename Vertex>
void DisplayVertexContainerIndices(
AzFramework::DebugDisplayRequests& debugDisplay,
const AZ::FixedVertices<Vertex>& vertices,
const AZ::Transform& transform,
const AZ::Vector3& nonUniformScale,
bool selected, float textSize = DefaultVertexTextSize,
bool selected,
float textSize = DefaultVertexTextSize,
const AZ::Color& textColor = DefaultVertexTextColor,
const AZ::Vector3& textOffset = DefaultVertexTextOffset);
}
} // namespace VertexContainerDisplay
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -17,8 +17,8 @@
#include <AzFramework/Entity/EntityContextBus.h>
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
#include <AzFramework/Viewport/CameraState.h>
#include <AzFramework/Viewport/ViewportId.h>
#include <AzFramework/Viewport/ClickDetector.h>
#include <AzFramework/Viewport/ViewportId.h>
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <AzToolsFramework/Viewport/ViewportTypes.h>
@@ -31,45 +31,51 @@ namespace AzToolsFramework
{
namespace ViewportInteraction
{
/// Result of handling mouse interaction.
//! Result of handling mouse interaction.
enum class MouseInteractionResult
{
Manipulator, ///< The manipulator manager handled the interaction.
Viewport, ///< The viewport handled the interaction.
None ///< The interaction was not handled.
Manipulator, //!< The manipulator manager handled the interaction.
Viewport, //!< The viewport handled the interaction.
None //!< The interaction was not handled.
};
/// Interface for handling mouse viewport events.
//! Interface for handling mouse viewport events.
class MouseViewportRequests
{
public:
/// @cond
//! @cond
virtual ~MouseViewportRequests() = default;
/// @endcond
//! @endcond
/// Implement this function to handle a particular mouse event.
virtual bool HandleMouseInteraction(
const MouseInteractionEvent& /*mouseInteraction*/) { return false; }
//! Implement this function to handle a particular mouse event.
virtual bool HandleMouseInteraction(const MouseInteractionEvent& /*mouseInteraction*/)
{
return false;
}
};
/// Interface for internal handling mouse viewport events.
//! Interface for internal handling mouse viewport events.
class InternalMouseViewportRequests
{
public:
/// @cond
//! @cond
virtual ~InternalMouseViewportRequests() = default;
/// @endcond
//! @endcond
/// Implement this function to have the viewport handle this mouse event.
virtual bool InternalHandleMouseViewportInteraction(
const MouseInteractionEvent& /*mouseInteraction*/) { return false; }
//! Implement this function to have the viewport handle this mouse event.
virtual bool InternalHandleMouseViewportInteraction(const MouseInteractionEvent& /*mouseInteraction*/)
{
return false;
}
/// Implement this function to have manipulators handle this mouse event.
virtual bool InternalHandleMouseManipulatorInteraction(
const MouseInteractionEvent& /*mouseInteraction*/) { return false; }
//! Implement this function to have manipulators handle this mouse event.
virtual bool InternalHandleMouseManipulatorInteraction(const MouseInteractionEvent& /*mouseInteraction*/)
{
return false;
}
/// Helper to call both viewport and manipulator handle mouse events
/// @note Manipulators always attempt to intercept the event first.
//! Helper to call both viewport and manipulator handle mouse events
//! @note Manipulators always attempt to intercept the event first.
MouseInteractionResult InternalHandleAllMouseInteractions(const MouseInteractionEvent& mouseInteraction);
};
@@ -90,117 +96,118 @@ namespace AzToolsFramework
}
}
/// Interface for viewport selection behaviors.
//! Interface for viewport selection behaviors.
class ViewportDisplayNotifications
{
public:
/// @cond
//! @cond
virtual ~ViewportDisplayNotifications() = default;
/// @endcond
//! @endcond
/// Display drawing in world space.
/// \ref DisplayViewportSelection is called from \ref EditorInteractionSystemComponent::DisplayViewport.
/// DisplayViewport exists on the \ref AzFramework::ViewportDebugDisplayEventBus and is called from \ref CRenderViewport.
/// \ref DisplayViewportSelection is called after \ref CalculateVisibleEntityDatas on the \ref EditorVisibleEntityDataCache,
/// this ensures usage of the entity cache will be up to date (do not implement \ref AzFramework::ViewportDebugDisplayEventBus
/// directly if wishing to use the \ref EditorVisibleEntityDataCache).
//! Display drawing in world space.
//! \ref DisplayViewportSelection is called from \ref EditorInteractionSystemComponent::DisplayViewport.
//! DisplayViewport exists on the \ref AzFramework::ViewportDebugDisplayEventBus and is called from \ref CRenderViewport.
//! \ref DisplayViewportSelection is called after \ref CalculateVisibleEntityDatas on the \ref EditorVisibleEntityDataCache,
//! this ensures usage of the entity cache will be up to date (do not implement \ref AzFramework::ViewportDebugDisplayEventBus
//! directly if wishing to use the \ref EditorVisibleEntityDataCache).
virtual void DisplayViewportSelection(
const AzFramework::ViewportInfo& /*viewportInfo*/,
AzFramework::DebugDisplayRequests& /*debugDisplay*/) {}
/// Display drawing in screen space.
/// \ref DisplayViewportSelection2d is called after \ref DisplayViewportSelection when the viewport has been
/// configured to be orthographic in \ref CRenderViewport. All screen space drawing can be performed here.
const AzFramework::ViewportInfo& /*viewportInfo*/, AzFramework::DebugDisplayRequests& /*debugDisplay*/)
{
}
//! Display drawing in screen space.
//! \ref DisplayViewportSelection2d is called after \ref DisplayViewportSelection when the viewport has been
//! configured to be orthographic in \ref CRenderViewport. All screen space drawing can be performed here.
virtual void DisplayViewportSelection2d(
const AzFramework::ViewportInfo& /*viewportInfo*/,
AzFramework::DebugDisplayRequests& /*debugDisplay*/) {}
const AzFramework::ViewportInfo& /*viewportInfo*/, AzFramework::DebugDisplayRequests& /*debugDisplay*/)
{
}
};
/// Interface for internal handling mouse viewport events and display notifications.
/// Implement this for types wishing to provide viewport functionality and
/// set it by using \ref EditorInteractionSystemViewportSelectionRequestBus.
//! Interface for internal handling mouse viewport events and display notifications.
//! Implement this for types wishing to provide viewport functionality and
//! set it by using \ref EditorInteractionSystemViewportSelectionRequestBus.
class InternalViewportSelectionRequests
: public ViewportDisplayNotifications
, public InternalMouseViewportRequests
{
};
/// Interface for handling mouse viewport events and display notifications.
/// Use this interface for composition types used by InternalViewportSelectionRequests.
//! Interface for handling mouse viewport events and display notifications.
//! Use this interface for composition types used by InternalViewportSelectionRequests.
class ViewportSelectionRequests
: public ViewportDisplayNotifications
, public MouseViewportRequests
{
};
/// The EBusTraits for ViewportInteractionRequests.
class ViewportEBusTraits
: public AZ::EBusTraits
//! The EBusTraits for ViewportInteractionRequests.
class ViewportEBusTraits : public AZ::EBusTraits
{
public:
using BusIdType = AzFramework::ViewportId; ///< ViewportId - used to address requests to this EBus.
using BusIdType = AzFramework::ViewportId; //!< ViewportId - used to address requests to this EBus.
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
};
/// A ray projection, originating from a point and extending in a direction specified as a normal.
//! A ray projection, originating from a point and extending in a direction specified as a normal.
struct ProjectedViewportRay
{
AZ::Vector3 origin;
AZ::Vector3 direction;
};
/// Requests that can be made to the viewport to query and modify its state.
//! Requests that can be made to the viewport to query and modify its state.
class ViewportInteractionRequests
{
public:
/// Return the current camera state for this viewport.
//! Return the current camera state for this viewport.
virtual AzFramework::CameraState GetCameraState() = 0;
/// Return if grid snapping is enabled.
//! Return if grid snapping is enabled.
virtual bool GridSnappingEnabled() = 0;
/// Return the grid snapping size.
//! Return the grid snapping size.
virtual float GridSize() = 0;
/// Does the grid currently want to be displayed.
//! Does the grid currently want to be displayed.
virtual bool ShowGrid() = 0;
/// Return if angle snapping is enabled.
//! Return if angle snapping is enabled.
virtual bool AngleSnappingEnabled() = 0;
/// Return the angle snapping/step size.
//! Return the angle snapping/step size.
virtual float AngleStep() = 0;
/// Transform a point in world space to screen space coordinates in Qt Widget space.
/// Multiply by DeviceScalingFactor to get the position in viewport pixel space.
//! Transform a point in world space to screen space coordinates in Qt Widget space.
//! Multiply by DeviceScalingFactor to get the position in viewport pixel space.
virtual AzFramework::ScreenPoint ViewportWorldToScreen(const AZ::Vector3& worldPosition) = 0;
/// Transform a point from Qt widget screen space to world space based on the given clip space depth.
/// Depth specifies a relative camera depth to project in the range of [0.f, 1.f].
/// Returns the world space position if successful.
//! Transform a point from Qt widget screen space to world space based on the given clip space depth.
//! Depth specifies a relative camera depth to project in the range of [0.f, 1.f].
//! Returns the world space position if successful.
virtual AZStd::optional<AZ::Vector3> ViewportScreenToWorld(const AzFramework::ScreenPoint& screenPosition, float depth) = 0;
/// Casts a point in screen space to a ray in world space originating from the viewport camera frustum's near plane.
/// Returns a ray containing the ray's origin and a direction normal, if successful.
//! Casts a point in screen space to a ray in world space originating from the viewport camera frustum's near plane.
//! Returns a ray containing the ray's origin and a direction normal, if successful.
virtual AZStd::optional<ProjectedViewportRay> ViewportScreenToWorldRay(const AzFramework::ScreenPoint& screenPosition) = 0;
/// Gets the DPI scaling factor that translates Qt widget space into viewport pixel space.
//! Gets the DPI scaling factor that translates Qt widget space into viewport pixel space.
virtual float DeviceScalingFactor() = 0;
protected:
~ViewportInteractionRequests() = default;
};
/// Interface to return only viewport specific settings (e.g. snapping).
//! Interface to return only viewport specific settings (e.g. snapping).
class ViewportSettings
{
public:
virtual ~ViewportSettings() = default;
/// Return if grid snapping is enabled.
//! Return if grid snapping is enabled.
virtual bool GridSnappingEnabled() const = 0;
/// Return the grid snapping size.
//! Return the grid snapping size.
virtual float GridSize() const = 0;
/// Does the grid currently want to be displayed.
//! Does the grid currently want to be displayed.
virtual bool ShowGrid() const = 0;
/// Return if angle snapping is enabled.
//! Return if angle snapping is enabled.
virtual bool AngleSnappingEnabled() const = 0;
/// Return the angle snapping/step size.
//! Return the angle snapping/step size.
virtual float AngleStep() const = 0;
};
/// Type to inherit to implement ViewportInteractionRequests.
//! Type to inherit to implement ViewportInteractionRequests.
using ViewportInteractionRequestBus = AZ::EBus<ViewportInteractionRequests, ViewportEBusTraits>;
//! Requests to freeze the Viewport Input
@@ -221,62 +228,62 @@ namespace AzToolsFramework
//! Type to inherit to implement ViewportFreezeRequests.
using ViewportFreezeRequestBus = AZ::EBus<ViewportFreezeRequests, ViewportEBusTraits>;
/// Viewport requests that are only guaranteed to be serviced by the Main Editor viewport.
//! Viewport requests that are only guaranteed to be serviced by the Main Editor viewport.
class MainEditorViewportInteractionRequests
{
public:
/// Given a point in screen space, return the picked entity (if any).
/// Picked EntityId will be returned, InvalidEntityId will be returned on failure.
//! Given a point in screen space, return the picked entity (if any).
//! Picked EntityId will be returned, InvalidEntityId will be returned on failure.
virtual AZ::EntityId PickEntity(const AzFramework::ScreenPoint& point) = 0;
/// Given a point in screen space, return the terrain position in world space.
//! Given a point in screen space, return the terrain position in world space.
virtual AZ::Vector3 PickTerrain(const AzFramework::ScreenPoint& point) = 0;
/// Return the terrain height given a world position in 2d (xy plane).
//! Return the terrain height given a world position in 2d (xy plane).
virtual float TerrainHeight(const AZ::Vector2& position) = 0;
/// Given the current view frustum (viewport) return all visible entities.
//! Given the current view frustum (viewport) return all visible entities.
virtual void FindVisibleEntities(AZStd::vector<AZ::EntityId>& visibleEntities) = 0;
/// Is the user holding a modifier key to move the manipulator space from local to world.
//! Is the user holding a modifier key to move the manipulator space from local to world.
virtual bool ShowingWorldSpace() = 0;
/// Return the widget to use as the parent for the viewport context menu.
//! Return the widget to use as the parent for the viewport context menu.
virtual QWidget* GetWidgetForViewportContextMenu() = 0;
/// Set the render context for the viewport.
//! Set the render context for the viewport.
virtual void BeginWidgetContext() = 0;
/// End the render context for the viewport.
/// Return to previous context before Begin was called.
//! End the render context for the viewport.
//! Return to previous context before Begin was called.
virtual void EndWidgetContext() = 0;
protected:
~MainEditorViewportInteractionRequests() = default;
};
/// Type to inherit to implement MainEditorViewportInteractionRequests.
//! Type to inherit to implement MainEditorViewportInteractionRequests.
using MainEditorViewportInteractionRequestBus = AZ::EBus<MainEditorViewportInteractionRequests, ViewportEBusTraits>;
/// Viewport requests for managing the viewport's cursor state.
//! Viewport requests for managing the viewport's cursor state.
class ViewportMouseCursorRequests
{
public:
/// Begins hiding the cursor and locking it in place, to prevent the cursor from escaping the viewport window.
//! Begins hiding the cursor and locking it in place, to prevent the cursor from escaping the viewport window.
virtual void BeginCursorCapture() = 0;
/// Restores the cursor and ends locking it in place, allowing it to be moved freely.
//! Restores the cursor and ends locking it in place, allowing it to be moved freely.
virtual void EndCursorCapture() = 0;
/// Gets the most recent recorded cursor position in the viewport in screen space coordinates.
//! Gets the most recent recorded cursor position in the viewport in screen space coordinates.
virtual AzFramework::ScreenPoint ViewportCursorScreenPosition() = 0;
/// Gets the cursor position recorded prior to the most recent cursor position.
/// Note: The cursor may be captured by the viewport, in which case this may not correspond to the last result
/// from ViewportCursorScreenPosition. This method will always return the correct position to generate a mouse
/// position delta.
//! Gets the cursor position recorded prior to the most recent cursor position.
//! Note: The cursor may be captured by the viewport, in which case this may not correspond to the last result
//! from ViewportCursorScreenPosition. This method will always return the correct position to generate a mouse
//! position delta.
virtual AZStd::optional<AzFramework::ScreenPoint> PreviousViewportCursorScreenPosition() = 0;
/// Is mouse over viewport.
//! Is mouse over viewport.
virtual bool IsMouseOver() const = 0;
protected:
~ViewportMouseCursorRequests() = default;
};
/// Type to inherit to implement MainEditorViewportInteractionRequests.
//! Type to inherit to implement MainEditorViewportInteractionRequests.
using ViewportMouseCursorRequestBus = AZ::EBus<ViewportMouseCursorRequests, ViewportEBusTraits>;
/// A helper to wrap Begin/EndWidgetContext.
//! A helper to wrap Begin/EndWidgetContext.
class WidgetContextGuard
{
public:
@@ -294,17 +301,16 @@ namespace AzToolsFramework
}
private:
int m_viewportId; ///< The viewport id the widget context is being set on.
int m_viewportId; //!< The viewport id the widget context is being set on.
};
} // namespace ViewportInteraction
/// Utility function to return EntityContextId.
//! Utility function to return EntityContextId.
inline AzFramework::EntityContextId GetEntityContextId()
{
AzFramework::EntityContextId entityContextId;
EditorEntityContextRequestBus::BroadcastResult(
entityContextId, &EditorEntityContextRequests::GetEditorEntityContextId);
EditorEntityContextRequestBus::BroadcastResult(entityContextId, &EditorEntityContextRequests::GetEditorEntityContextId);
return entityContextId;
}
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "ViewportTypes.h"
@@ -23,26 +23,24 @@ namespace AzToolsFramework
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<KeyboardModifiers>()->
Field("KeyboardModifiers", &KeyboardModifiers::m_keyModifiers);
serializeContext->Class<KeyboardModifiers>()->Field("KeyboardModifiers", &KeyboardModifiers::m_keyModifiers);
serializeContext->Class<MouseButtons>()->
Field("MouseButtons", &MouseButtons::m_mouseButtons);
serializeContext->Class<MouseButtons>()->Field("MouseButtons", &MouseButtons::m_mouseButtons);
serializeContext->Class<InteractionId>()->
Field("CameraId", &InteractionId::m_cameraId)->
Field("ViewportId", &InteractionId::m_viewportId);
serializeContext->Class<InteractionId>()
->Field("CameraId", &InteractionId::m_cameraId)
->Field("ViewportId", &InteractionId::m_viewportId);
serializeContext->Class<MousePick>()->
Field("RayOrigin", &MousePick::m_rayOrigin)->
Field("RayDirection", &MousePick::m_rayDirection)->
Field("ScreenCoordinates", &MousePick::m_screenCoordinates);
serializeContext->Class<MousePick>()
->Field("RayOrigin", &MousePick::m_rayOrigin)
->Field("RayDirection", &MousePick::m_rayDirection)
->Field("ScreenCoordinates", &MousePick::m_screenCoordinates);
serializeContext->Class<MouseInteraction>()->
Field("MousePick", &MouseInteraction::m_mousePick)->
Field("MouseButtons", &MouseInteraction::m_mouseButtons)->
Field("InteractionId", &MouseInteraction::m_interactionId)->
Field("KeyboardModifiers", &MouseInteraction::m_keyboardModifiers);
serializeContext->Class<MouseInteraction>()
->Field("MousePick", &MouseInteraction::m_mousePick)
->Field("MouseButtons", &MouseInteraction::m_mouseButtons)
->Field("InteractionId", &MouseInteraction::m_interactionId)
->Field("KeyboardModifiers", &MouseInteraction::m_keyboardModifiers);
MouseInteractionEvent::Reflect(*serializeContext);
}
@@ -50,10 +48,10 @@ namespace AzToolsFramework
void MouseInteractionEvent::Reflect(AZ::SerializeContext& serializeContext)
{
serializeContext.Class<MouseInteractionEvent>()->
Field("MouseInteraction", &MouseInteractionEvent::m_mouseInteraction)->
Field("MouseEvent", &MouseInteractionEvent::m_mouseEvent)->
Field("WheelDelta", &MouseInteractionEvent::m_wheelDelta);
serializeContext.Class<MouseInteractionEvent>()
->Field("MouseInteraction", &MouseInteractionEvent::m_mouseInteraction)
->Field("MouseEvent", &MouseInteractionEvent::m_mouseEvent)
->Field("WheelDelta", &MouseInteractionEvent::m_wheelDelta);
}
}
}
} // namespace ViewportInteraction
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -27,57 +27,75 @@ namespace AZ
namespace AzToolsFramework
{
/// Viewport related types that are used when interacting with the viewport.
//! Viewport related types that are used when interacting with the viewport.
namespace ViewportInteraction
{
/// Flags to represent each modifier key.
//! Flags to represent each modifier key.
enum class KeyboardModifier : AZ::u32
{
None = 0, ///< No keyboard modifier.
Alt = 0x01, ///< Alt keyboard modifier.
Shift = 0x02, ///< Shift keyboard modifier.
Ctrl = 0x04, ///< Ctrl keyboard modifier.
Control = Ctrl ///< Alias for Ctrl modifier.
None = 0, //!< No keyboard modifier.
Alt = 0x01, //!< Alt keyboard modifier.
Shift = 0x02, //!< Shift keyboard modifier.
Ctrl = 0x04, //!< Ctrl keyboard modifier.
Control = Ctrl //!< Alias for Ctrl modifier.
};
/// Flags to represent each mouse button.
//! Flags to represent each mouse button.
enum class MouseButton : AZ::u32
{
None = 0, ///< No mouse buttons.
Left = 0x01, ///< Left mouse button.
Middle = 0x02, ///< Middle mouse button.
Right = 0x04 ///< Right mouse button.
None = 0, //!< No mouse buttons.
Left = 0x01, //!< Left mouse button.
Middle = 0x02, //!< Middle mouse button.
Right = 0x04 //!< Right mouse button.
};
/// The type of mouse event that occurred.
//! The type of mouse event that occurred.
enum class MouseEvent
{
Up, ///< Mouse up event,
Down, ///< Mouse down event.
DoubleClick, ///< Mouse double click event.
Wheel, ///< Mouse wheel event.
Move, ///< Mouse move event.
Up, //!< Mouse up event,
Down, //!< Mouse down event.
DoubleClick, //!< Mouse double click event.
Wheel, //!< Mouse wheel event.
Move, //!< Mouse move event.
};
/// Interface over keyboard modifier to query which key is pressed.
//! Interface over keyboard modifier to query which key is pressed.
struct KeyboardModifiers
{
/// @cond
//! @cond
AZ_TYPE_INFO(KeyboardModifiers, "{2635F4DF-E7DC-4919-A97B-9AE35FE086D8}");
KeyboardModifiers() = default;
/// @endcond
//! @endcond
/// Explicit constructor to create a KeyboardModifier struct.
explicit KeyboardModifiers(const AZ::u32 keyModifiers) : m_keyModifiers(keyModifiers) {}
//! Explicit constructor to create a KeyboardModifier struct.
explicit KeyboardModifiers(const AZ::u32 keyModifiers)
: m_keyModifiers(keyModifiers)
{
}
/// Given the current keyboard modifiers, is the Alt key held.
bool Alt() const { return (m_keyModifiers & static_cast<AZ::u32>(KeyboardModifier::Alt)) != 0; }
/// Given the current keyboard modifiers, is the Shift key held.
bool Shift() const { return (m_keyModifiers & static_cast<AZ::u32>(KeyboardModifier::Shift)) != 0; }
/// Given the current keyboard modifiers, is the Ctrl key held.
bool Ctrl() const { return (m_keyModifiers & static_cast<AZ::u32>(KeyboardModifier::Ctrl)) != 0; }
/// Given the current keyboard modifiers, are none being held.
bool None() const { return m_keyModifiers == static_cast<AZ::u32>(KeyboardModifier::None); }
//! Given the current keyboard modifiers, is the Alt key held.
bool Alt() const
{
return (m_keyModifiers & static_cast<AZ::u32>(KeyboardModifier::Alt)) != 0;
}
//! Given the current keyboard modifiers, is the Shift key held.
bool Shift() const
{
return (m_keyModifiers & static_cast<AZ::u32>(KeyboardModifier::Shift)) != 0;
}
//! Given the current keyboard modifiers, is the Ctrl key held.
bool Ctrl() const
{
return (m_keyModifiers & static_cast<AZ::u32>(KeyboardModifier::Ctrl)) != 0;
}
//! Given the current keyboard modifiers, are none being held.
bool None() const
{
return m_keyModifiers == static_cast<AZ::u32>(KeyboardModifier::None);
}
bool operator==(const KeyboardModifiers& keyboardModifiers) const
{
@@ -89,132 +107,162 @@ namespace AzToolsFramework
return m_keyModifiers != keyboardModifiers.m_keyModifiers;
}
AZ::u32 m_keyModifiers = 0; ///< Raw keyboard modifier state.
AZ::u32 m_keyModifiers = 0; //!< Raw keyboard modifier state.
};
/// Interface over mouse buttons to query which button is pressed.
//! Interface over mouse buttons to query which button is pressed.
struct MouseButtons
{
/// @cond
//! @cond
AZ_TYPE_INFO(MouseButtons, "{1D137B5D-73BF-4FD9-BECA-85E6DC3786CB}");
MouseButtons() = default;
/// @endcond
//! @endcond
/// Explicit constructor to create a MouseButton struct.
explicit MouseButtons(const AZ::u32 mouseButtons) : m_mouseButtons(mouseButtons) {}
//! Explicit constructor to create a MouseButton struct.
explicit MouseButtons(const AZ::u32 mouseButtons)
: m_mouseButtons(mouseButtons)
{
}
/// Given the current mouse state, is the left mouse button held.
bool Left() const { return (m_mouseButtons & static_cast<AZ::u32>(MouseButton::Left)) != 0; }
/// Given the current mouse state, is the middle mouse button held.
bool Middle() const { return (m_mouseButtons & static_cast<AZ::u32>(MouseButton::Middle)) != 0; }
/// Given the current mouse state, is the right mouse button held.
bool Right() const { return (m_mouseButtons & static_cast<AZ::u32>(MouseButton::Right)) != 0; }
/// Given the current mouse state, are no mouse buttons held.
bool None() const { return m_mouseButtons == static_cast<AZ::u32>(MouseButton::None); }
/// Given the current mouse state, are any mouse buttons held.
bool Any() const { return m_mouseButtons != static_cast<AZ::u32>(MouseButton::None); }
//! Given the current mouse state, is the left mouse button held.
bool Left() const
{
return (m_mouseButtons & static_cast<AZ::u32>(MouseButton::Left)) != 0;
}
AZ::u32 m_mouseButtons = 0; ///< Current mouse button state (flags).
//! Given the current mouse state, is the middle mouse button held.
bool Middle() const
{
return (m_mouseButtons & static_cast<AZ::u32>(MouseButton::Middle)) != 0;
}
//! Given the current mouse state, is the right mouse button held.
bool Right() const
{
return (m_mouseButtons & static_cast<AZ::u32>(MouseButton::Right)) != 0;
}
//! Given the current mouse state, are no mouse buttons held.
bool None() const
{
return m_mouseButtons == static_cast<AZ::u32>(MouseButton::None);
}
//! Given the current mouse state, are any mouse buttons held.
bool Any() const
{
return m_mouseButtons != static_cast<AZ::u32>(MouseButton::None);
}
AZ::u32 m_mouseButtons = 0; //!< Current mouse button state (flags).
};
/// Information relevant when interacting with a particular viewport.
//! Information relevant when interacting with a particular viewport.
struct InteractionId
{
/// @cond
//! @cond
AZ_TYPE_INFO(InteractionId, "{35593FC2-846F-4AAD-8044-4CD84EC84F9A}");
InteractionId() = default;
/// @endcond
//! @endcond
InteractionId(AZ::EntityId cameraId, int viewportId)
: m_cameraId(cameraId), m_viewportId(viewportId) {}
: m_cameraId(cameraId)
, m_viewportId(viewportId)
{
}
AZ::EntityId m_cameraId; ///< The entity id of the viewport camera.
int m_viewportId = 0; ///< The id of the viewport being interacted with.
AZ::EntityId m_cameraId; //!< The entity id of the viewport camera.
int m_viewportId = 0; //!< The id of the viewport being interacted with.
};
/// Data representing a mouse pick ray.
//! Data representing a mouse pick ray.
struct MousePick
{
/// @cond
//! @cond
AZ_TYPE_INFO(MousePick, "{A69B9562-FC8C-4DE7-9137-0FF867B1513D}");
MousePick() = default;
/// @endcond
//! @endcond
AZ::Vector3 m_rayOrigin = AZ::Vector3::CreateZero(); ///< World space.
AZ::Vector3 m_rayDirection = AZ::Vector3::CreateZero(); ///< World space - normalized.
AzFramework::ScreenPoint m_screenCoordinates = {}; ///< Screen space.
AZ::Vector3 m_rayOrigin = AZ::Vector3::CreateZero(); //!< World space.
AZ::Vector3 m_rayDirection = AZ::Vector3::CreateZero(); //!< World space - normalized.
AzFramework::ScreenPoint m_screenCoordinates = {}; //!< Screen space.
};
/// State relating to an individual mouse interaction.
//! State relating to an individual mouse interaction.
struct MouseInteraction
{
/// @cond
//! @cond
AZ_TYPE_INFO(MouseInteraction, "{E67357C3-DFE1-40DF-921F-9CBCFE63A68C}");
MouseInteraction() = default;
/// @endcond
//! @endcond
MousePick m_mousePick; ///< The mouse pick ray in world space and screen coordinates in screen space.
MouseButtons m_mouseButtons; ///< The current state of the mouse buttons.
MousePick m_mousePick; //!< The mouse pick ray in world space and screen coordinates in screen space.
MouseButtons m_mouseButtons; //!< The current state of the mouse buttons.
InteractionId m_interactionId; /**< The EntityId of the camera this click came from
* and the id of the viewport it originated from. */
KeyboardModifiers m_keyboardModifiers; ///< The state of the keyboard modifiers (Alt/Ctrl/Shift).
* and the id of the viewport it originated from. */
KeyboardModifiers m_keyboardModifiers; //!< The state of the keyboard modifiers (Alt/Ctrl/Shift).
};
/// Structure to compose MouseInteraction (mouse state) and
/// MouseEvent (MouseEvent::MouseUp/MouseEvent::DownMove etc.)
//! Structure to compose MouseInteraction (mouse state) and
//! MouseEvent (MouseEvent::MouseUp/MouseEvent::DownMove etc.)
struct MouseInteractionEvent
{
/// @cond
//! @cond
AZ_TYPE_INFO(MouseInteractionEvent, "{67FE0826-DD59-4B5B-BEFE-421E83EA7F31}");
MouseInteractionEvent() = default;
/// @endcond
//! @endcond
static void Reflect(AZ::SerializeContext& context);
/// Constructor to create a default MouseInteractionEvent
//! Constructor to create a default MouseInteractionEvent
MouseInteractionEvent(MouseInteraction mouseInteraction, const MouseEvent mouseEvent)
: m_mouseInteraction(std::move(mouseInteraction))
, m_mouseEvent(mouseEvent) {}
, m_mouseEvent(mouseEvent)
{
}
/// Special constructor for mouse wheel event.
//! Special constructor for mouse wheel event.
MouseInteractionEvent(MouseInteraction mouseInteraction, const float wheelDelta)
: m_mouseInteraction(std::move(mouseInteraction))
, m_mouseEvent(MouseEvent::Wheel)
, m_wheelDelta(wheelDelta) {}
, m_wheelDelta(wheelDelta)
{
}
MouseInteraction m_mouseInteraction; ///< Mouse state.
MouseEvent m_mouseEvent; ///< Mouse event.
MouseInteraction m_mouseInteraction; //!< Mouse state.
MouseEvent m_mouseEvent; //!< Mouse event.
/// Special friend function to return the mouse wheel delta (scroll amount)
/// if the event was of type MouseEvent::Wheel.
//! Special friend function to return the mouse wheel delta (scroll amount)
//! if the event was of type MouseEvent::Wheel.
friend float MouseWheelDelta(const MouseInteractionEvent& mouseInteractionEvent);
private:
float m_wheelDelta = 0.0f; ///< The amount the mouse wheel moved during a mouse wheel event.
float m_wheelDelta = 0.0f; //!< The amount the mouse wheel moved during a mouse wheel event.
};
/// Checked access to mouse wheel delta - ensure event originated from the mouse wheel.
//! Checked access to mouse wheel delta - ensure event originated from the mouse wheel.
inline float MouseWheelDelta(const MouseInteractionEvent& mouseInteractionEvent)
{
AZ_Assert(mouseInteractionEvent.m_mouseEvent == MouseEvent::Wheel,
AZ_Assert(
mouseInteractionEvent.m_mouseEvent == MouseEvent::Wheel,
"Attempting to access mouse wheel delta when mouse interaction event was not mouse wheel");
return mouseInteractionEvent.m_wheelDelta;
}
/// Return QPoint from AzFramework::ScreenPoint.
//! Return QPoint from AzFramework::ScreenPoint.
inline QPoint QPointFromScreenPoint(const AzFramework::ScreenPoint& screenPoint)
{
return {screenPoint.m_x, screenPoint.m_y};
return { screenPoint.m_x, screenPoint.m_y };
}
/// Return AzFramework::ScreenPoint from QPoint.
//! Return AzFramework::ScreenPoint from QPoint.
inline AzFramework::ScreenPoint ScreenPointFromQPoint(const QPoint& qpoint)
{
return AzFramework::ScreenPoint{qpoint.x(), qpoint.y()};
return AzFramework::ScreenPoint{ qpoint.x(), qpoint.y() };
}
/// Map from Qt -> Open 3D Engine buttons.>>>>>>> main
//! Map from Qt -> Open 3D Engine buttons.>>>>>>> main
inline AZ::u32 TranslateMouseButtons(const Qt::MouseButtons buttons)
{
AZ::u32 result = 0;
@@ -224,7 +272,7 @@ namespace AzToolsFramework
return result;
}
/// Map from Qt -> Open 3D Engine modifiers.
//! Map from Qt -> Open 3D Engine modifiers.
inline AZ::u32 TranslateKeyboardModifiers(const Qt::KeyboardModifiers modifiers)
{
AZ::u32 result = 0;
@@ -234,19 +282,19 @@ namespace AzToolsFramework
return result;
}
/// Interface to translate Qt modifiers to Open 3D Engine modifiers.
//! Interface to translate Qt modifiers to Open 3D Engine modifiers.
inline KeyboardModifiers BuildKeyboardModifiers(const Qt::KeyboardModifiers modifiers)
{
return KeyboardModifiers(TranslateKeyboardModifiers(modifiers));
}
/// Interface to translate Qt buttons to Open 3D Engine buttons.
//! Interface to translate Qt buttons to Open 3D Engine buttons.
inline MouseButtons BuildMouseButtons(const Qt::MouseButtons buttons)
{
return MouseButtons(TranslateMouseButtons(buttons));
}
/// Generate mouse buttons from single button enum.
//! Generate mouse buttons from single button enum.
inline MouseButtons MouseButtonsFromButton(MouseButton button)
{
MouseButtons mouseButtons;
@@ -254,7 +302,7 @@ namespace AzToolsFramework
return mouseButtons;
}
/// Reflect all viewport related types.
//! Reflect all viewport related types.
void ViewportInteractionReflect(AZ::ReflectContext* context);
} // namespace ViewportInteraction
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "EditorDefaultSelection.h"
@@ -30,8 +30,7 @@ namespace AzToolsFramework
ActionOverrideRequestBus::Handler::BusConnect(GetEntityContextId());
ComponentModeFramework::ComponentModeSystemRequestBus::Handler::BusConnect();
m_manipulatorManager =
AZStd::make_shared<AzToolsFramework::ManipulatorManager>(AzToolsFramework::g_mainManipulatorManagerId);
m_manipulatorManager = AZStd::make_shared<AzToolsFramework::ManipulatorManager>(AzToolsFramework::g_mainManipulatorManagerId);
m_transformComponentSelection = AZStd::make_unique<EditorTransformComponentSelection>(entityDataCache);
}
@@ -75,23 +74,18 @@ namespace AzToolsFramework
for (const auto& componentModeBuilder : entityAndComponentModeBuilders.m_componentModeBuilders)
{
m_componentModeCollection.AddComponentMode(
AZ::EntityComponentIdPair(
entityAndComponentModeBuilders.m_entityId, componentModeBuilder.m_componentId),
componentModeBuilder.m_componentType,
componentModeBuilder.m_componentModeBuilder);
AZ::EntityComponentIdPair(entityAndComponentModeBuilders.m_entityId, componentModeBuilder.m_componentId),
componentModeBuilder.m_componentType, componentModeBuilder.m_componentModeBuilder);
}
}
void EditorDefaultSelection::TransitionToComponentMode()
{
// entering ComponentMode - disable all default actions in the ActionManager
EditorActionRequestBus::Broadcast(
&EditorActionRequests::DisableDefaultActions);
EditorActionRequestBus::Broadcast(&EditorActionRequests::DisableDefaultActions);
// attach widget to store ComponentMode specific actions
EditorActionRequestBus::Broadcast(
&EditorActionRequests::AttachOverride,
&PhantomWidget());
EditorActionRequestBus::Broadcast(&EditorActionRequests::AttachOverride, &PhantomWidget());
if (m_transformComponentSelection)
{
@@ -103,8 +97,7 @@ namespace AzToolsFramework
// refresh button ui
ToolsApplicationEvents::Bus::Broadcast(
&ToolsApplicationEvents::Bus::Events::InvalidatePropertyDisplay,
PropertyModificationRefreshLevel::Refresh_EntireTree);
&ToolsApplicationEvents::Bus::Events::InvalidatePropertyDisplay, PropertyModificationRefreshLevel::Refresh_EntireTree);
}
void EditorDefaultSelection::TransitionFromComponentMode()
@@ -117,19 +110,16 @@ namespace AzToolsFramework
m_transformComponentSelection->RegisterManipulator();
}
EditorActionRequestBus::Broadcast(
&EditorActionRequests::DetachOverride);
EditorActionRequestBus::Broadcast(&EditorActionRequests::DetachOverride);
ClearActionOverrides();
// leaving ComponentMode - enable all default actions in ActionManager
EditorActionRequestBus::Broadcast(
&EditorActionRequests::EnableDefaultActions);
EditorActionRequestBus::Broadcast(&EditorActionRequests::EnableDefaultActions);
// refresh button ui
ToolsApplicationEvents::Bus::Broadcast(
&ToolsApplicationEvents::Bus::Events::InvalidatePropertyDisplay,
PropertyModificationRefreshLevel::Refresh_EntireTree);
&ToolsApplicationEvents::Bus::Events::InvalidatePropertyDisplay, PropertyModificationRefreshLevel::Refresh_EntireTree);
}
void EditorDefaultSelection::EndComponentMode()
@@ -142,8 +132,7 @@ namespace AzToolsFramework
m_componentModeCollection.Refresh(entityComponentIdPair);
}
bool EditorDefaultSelection::AddedToComponentMode(
const AZ::EntityComponentIdPair& entityComponentIdPair, const AZ::Uuid& componentType)
bool EditorDefaultSelection::AddedToComponentMode(const AZ::EntityComponentIdPair& entityComponentIdPair, const AZ::Uuid& componentType)
{
return m_componentModeCollection.AddedToComponentMode(entityComponentIdPair, componentType);
}
@@ -152,10 +141,10 @@ namespace AzToolsFramework
{
ComponentModeFramework::ComponentModeDelegateRequestBus::EnumerateHandlers(
[componentType](ComponentModeFramework::ComponentModeDelegateRequestBus::InterfaceType* componentModeMouseRequests)
{
componentModeMouseRequests->AddComponentModeOfType(componentType);
return true;
});
{
componentModeMouseRequests->AddComponentModeOfType(componentType);
return true;
});
TransitionToComponentMode();
}
@@ -238,8 +227,7 @@ namespace AzToolsFramework
}
}
bool EditorDefaultSelection::InternalHandleMouseViewportInteraction(
const ViewportInteraction::MouseInteractionEvent& mouseInteraction)
bool EditorDefaultSelection::InternalHandleMouseViewportInteraction(const ViewportInteraction::MouseInteractionEvent& mouseInteraction)
{
bool enterComponentModeAttempted = false;
const bool componentModeBefore = InComponentMode();
@@ -249,15 +237,15 @@ namespace AzToolsFramework
{
// enumerate all ComponentModeDelegateRequestBus and check if any triggered AddComponentModes
ComponentModeFramework::ComponentModeDelegateRequestBus::EnumerateHandlers(
[&mouseInteraction, &enterComponentModeAttempted]
(ComponentModeFramework::ComponentModeDelegateRequestBus::InterfaceType* componentModeMouseRequests)
{
// detect if a double click happened on any Component in the viewport, attempting
// to move it into ComponentMode (note: this is not guaranteed to succeed as an
// incompatible multi-selection may prevent it)
enterComponentModeAttempted = componentModeMouseRequests->DetectEnterComponentModeInteraction(mouseInteraction);
return !enterComponentModeAttempted;
});
[&mouseInteraction, &enterComponentModeAttempted](
ComponentModeFramework::ComponentModeDelegateRequestBus::InterfaceType* componentModeMouseRequests)
{
// detect if a double click happened on any Component in the viewport, attempting
// to move it into ComponentMode (note: this is not guaranteed to succeed as an
// incompatible multi-selection may prevent it)
enterComponentModeAttempted = componentModeMouseRequests->DetectEnterComponentModeInteraction(mouseInteraction);
return !enterComponentModeAttempted;
});
// here we know ComponentMode was entered successfully and was not prohibited
if (m_componentModeCollection.ModesAdded())
@@ -272,25 +260,24 @@ namespace AzToolsFramework
else
{
ComponentModeFramework::ComponentModeRequestBus::EnumerateHandlers(
[&mouseInteraction, &handled]
(ComponentModeFramework::ComponentModeRequestBus::InterfaceType* componentModeRequest)
{
if (componentModeRequest->HandleMouseInteraction(mouseInteraction))
[&mouseInteraction, &handled](ComponentModeFramework::ComponentModeRequestBus::InterfaceType* componentModeRequest)
{
handled = true;
}
if (componentModeRequest->HandleMouseInteraction(mouseInteraction))
{
handled = true;
}
return true;
});
return true;
});
if (!handled)
{
ComponentModeFramework::ComponentModeDelegateRequestBus::EnumerateHandlers(
[&mouseInteraction]
(ComponentModeFramework::ComponentModeDelegateRequestBus::InterfaceType* componentModeDelegateRequests)
{
return !componentModeDelegateRequests->DetectLeaveComponentModeInteraction(mouseInteraction);
});
[&mouseInteraction](
ComponentModeFramework::ComponentModeDelegateRequestBus::InterfaceType* componentModeDelegateRequests)
{
return !componentModeDelegateRequests->DetectLeaveComponentModeInteraction(mouseInteraction);
});
}
}
@@ -311,8 +298,7 @@ namespace AzToolsFramework
}
void EditorDefaultSelection::DisplayViewportSelection(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay)
const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay)
{
if (m_transformComponentSelection)
{
@@ -330,8 +316,7 @@ namespace AzToolsFramework
}
void EditorDefaultSelection::DisplayViewportSelection2d(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay)
const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay)
{
if (m_transformComponentSelection)
{
@@ -355,11 +340,12 @@ namespace AzToolsFramework
void EditorDefaultSelection::AddActionOverride(const ActionOverride& actionOverride)
{
// check if an action with this uri is already added
const auto actionIt = AZStd::find_if(m_actions.begin(), m_actions.end(),
const auto actionIt = AZStd::find_if(
m_actions.begin(), m_actions.end(),
[actionOverride](const AZStd::shared_ptr<ActionOverrideMapping>& actionOverrideMapping)
{
return actionOverride.m_uri == actionOverrideMapping->m_uri;
});
{
return actionOverride.m_uri == actionOverrideMapping->m_uri;
});
// if an action with the same uri is already added, store the callback for this action
if (actionIt != m_actions.end())
@@ -381,44 +367,45 @@ namespace AzToolsFramework
// set callbacks that should happen when this action is triggered
auto index = static_cast<int>(m_actions.size());
QObject::connect(action.get(), &QAction::triggered, [this, index]()
{
const auto vec = m_actions; // increment ref count of shared_ptr, callback may clear actions
for (auto& callback : vec[index]->m_callbacks)
QObject::connect(
action.get(), &QAction::triggered,
[this, index]()
{
callback();
}
});
const auto vec = m_actions; // increment ref count of shared_ptr, callback may clear actions
for (auto& callback : vec[index]->m_callbacks)
{
callback();
}
});
m_actions.emplace_back(
AZStd::make_shared<ActionOverrideMapping>(
actionOverride.m_uri, AZStd::vector<AZStd::function<void()>>{ actionOverride.m_callback },
AZStd::move(action)));
m_actions.emplace_back(AZStd::make_shared<ActionOverrideMapping>(
actionOverride.m_uri, AZStd::vector<AZStd::function<void()>>{ actionOverride.m_callback }, AZStd::move(action)));
// register action with edit menu
EditorMenuRequestBus::Broadcast(
&EditorMenuRequests::AddEditMenuAction, m_actions.back()->m_action.get());
EditorMenuRequestBus::Broadcast(&EditorMenuRequests::AddEditMenuAction, m_actions.back()->m_action.get());
}
}
void EditorDefaultSelection::ClearActionOverrides()
{
AZStd::for_each(m_actions.begin(), m_actions.end(),
AZStd::for_each(
m_actions.begin(), m_actions.end(),
[this](const AZStd::shared_ptr<ActionOverrideMapping>& actionMapping)
{
PhantomWidget().removeAction(actionMapping->m_action.get());
});
{
PhantomWidget().removeAction(actionMapping->m_action.get());
});
m_actions.clear();
}
void EditorDefaultSelection::RemoveActionOverride(const AZ::Crc32 actionOverrideUri)
{
const auto it = AZStd::find_if(m_actions.begin(), m_actions.end(),
const auto it = AZStd::find_if(
m_actions.begin(), m_actions.end(),
[actionOverrideUri](const AZStd::shared_ptr<ActionOverrideMapping>& actionMapping)
{
return actionMapping->m_uri == actionOverrideUri;
});
{
return actionMapping->m_uri == actionOverrideUri;
});
if (it != m_actions.end())
{
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -19,7 +19,7 @@
namespace AzToolsFramework
{
/// The default selection/input handler for the editor (includes handling ComponentMode).
//! The default selection/input handler for the editor (includes handling ComponentMode).
class EditorDefaultSelection
: public ViewportInteraction::InternalViewportSelectionRequests
, private ActionOverrideRequestBus::Handler
@@ -28,30 +28,26 @@ namespace AzToolsFramework
public:
AZ_CLASS_ALLOCATOR_DECL
/// @cond
//! @cond
explicit EditorDefaultSelection(const EditorVisibleEntityDataCache* entityDataCache);
EditorDefaultSelection(const EditorDefaultSelection&) = delete;
EditorDefaultSelection& operator=(const EditorDefaultSelection&) = delete;
virtual ~EditorDefaultSelection();
/// @endcond
//! @endcond
/// Override the default widget used to store QActions while in ComponentMode.
/// @note This should not be necessary during normal operation and is provided
/// as a customization point to aid with testing.
//! Override the default widget used to store QActions while in ComponentMode.
//! @note This should not be necessary during normal operation and is provided
//! as a customization point to aid with testing.
void SetOverridePhantomWidget(QWidget* phantomOverrideWidget);
private:
// ViewportInteraction::InternalMouseViewportRequests ...
bool InternalHandleMouseViewportInteraction(
const ViewportInteraction::MouseInteractionEvent& mouseInteraction) override;
bool InternalHandleMouseManipulatorInteraction(
const ViewportInteraction::MouseInteractionEvent& mouseInteraction) override;
bool InternalHandleMouseViewportInteraction(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) override;
bool InternalHandleMouseManipulatorInteraction(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) override;
void DisplayViewportSelection(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay) override;
const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override;
void DisplayViewportSelection2d(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay) override;
const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override;
// ActionOverrideRequestBus ...
void SetupActionOverrideHandler(QWidget* parent) override;
@@ -65,7 +61,10 @@ namespace AzToolsFramework
const AZStd::vector<ComponentModeFramework::EntityAndComponentModeBuilders>& entityAndComponentModeBuilders) override;
void AddComponentModes(const ComponentModeFramework::EntityAndComponentModeBuilders& entityAndComponentModeBuilders) override;
void EndComponentMode() override;
bool InComponentMode() override { return m_componentModeCollection.InComponentMode(); }
bool InComponentMode() override
{
return m_componentModeCollection.InComponentMode();
}
void Refresh(const AZ::EntityComponentIdPair& entityComponentIdPair) override;
bool AddedToComponentMode(const AZ::EntityComponentIdPair& entityComponentIdPair, const AZ::Uuid& componentType) override;
void AddSelectedComponentModesOfType(const AZ::Uuid& componentType) override;
@@ -77,41 +76,43 @@ namespace AzToolsFramework
bool HasMultipleComponentTypes() override;
void RefreshActions() override;
/// Helpers to deal with moving in and out of ComponentMode.
//! Helpers to deal with moving in and out of ComponentMode.
void TransitionToComponentMode();
void TransitionFromComponentMode();
/// Accessor used internally to refer to the phantom widget.
/// This will either be the default widget or the override if non-null.
//! Accessor used internally to refer to the phantom widget.
//! This will either be the default widget or the override if non-null.
QWidget& PhantomWidget();
QWidget m_phantomWidget; ///< The phantom widget responsible for holding QActions while in ComponentMode.
QWidget* m_phantomOverrideWidget = nullptr; ///< It's possible to override the phantom widget in special circumstances (eg testing).
ComponentModeFramework::ComponentModeCollection m_componentModeCollection; ///< Handles all active ComponentMode types.
AZStd::unique_ptr<EditorTransformComponentSelection> m_transformComponentSelection = nullptr; ///< Viewport selection (responsible for
///< manipulators and transform modifications).
const EditorVisibleEntityDataCache* m_entityDataCache = nullptr; ///< Reference to cached visible EntityData.
QWidget m_phantomWidget; //!< The phantom widget responsible for holding QActions while in ComponentMode.
QWidget* m_phantomOverrideWidget = nullptr; //!< It's possible to override the phantom widget in special circumstances (eg testing).
ComponentModeFramework::ComponentModeCollection m_componentModeCollection; //!< Handles all active ComponentMode types.
AZStd::unique_ptr<EditorTransformComponentSelection> m_transformComponentSelection =
nullptr; //!< Viewport selection (responsible for
//!< manipulators and transform modifications).
const EditorVisibleEntityDataCache* m_entityDataCache = nullptr; //!< Reference to cached visible EntityData.
/// Mapping between passed ActionOverride (AddActionOverride) and allocated QAction.
//! Mapping between passed ActionOverride (AddActionOverride) and allocated QAction.
struct ActionOverrideMapping
{
ActionOverrideMapping(
const AZ::Crc32 uri, const AZStd::vector<AZStd::function<void()>>& callbacks,
AZStd::unique_ptr<QAction> action)
const AZ::Crc32 uri, const AZStd::vector<AZStd::function<void()>>& callbacks, AZStd::unique_ptr<QAction> action)
: m_uri(uri)
, m_callbacks(callbacks)
, m_action(AZStd::move(action)) {}
, m_action(AZStd::move(action))
{
}
AZ::Crc32 m_uri; ///< Unique identifier for the Action. (In the form 'com.amazon.action.---").
AZStd::vector<AZStd::function<void()>> m_callbacks; ///< Callbacks associated with this Action (note: with multi-selections there
///< will be a callback per Entity/Component).
AZStd::unique_ptr<QAction> m_action; ///< The QAction associated with the overrideWidget for all ComponentMode actions.
AZ::Crc32 m_uri; //!< Unique identifier for the Action. (In the form 'com.amazon.action.---").
AZStd::vector<AZStd::function<void()>> m_callbacks; //!< Callbacks associated with this Action (note: with multi-selections
//!< there will be a callback per Entity/Component).
AZStd::unique_ptr<QAction> m_action; //!< The QAction associated with the overrideWidget for all ComponentMode actions.
};
AZStd::vector<AZStd::shared_ptr<ActionOverrideMapping>> m_actions; ///< Currently bound actions (corresponding to those set
///< on the override widget).
AZStd::vector<AZStd::shared_ptr<ActionOverrideMapping>> m_actions; //!< Currently bound actions (corresponding to those set
//!< on the override widget).
AZStd::shared_ptr<AzToolsFramework::ManipulatorManager> m_manipulatorManager; ///< The default manipulator manager.
ViewportInteraction::MouseInteraction m_currentInteraction; ///< Current mouse interaction to be used for drawing manipulators.
AZStd::shared_ptr<AzToolsFramework::ManipulatorManager> m_manipulatorManager; //!< The default manipulator manager.
ViewportInteraction::MouseInteraction m_currentInteraction; //!< Current mouse interaction to be used for drawing manipulators.
};
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "EditorHelpers.h"
@@ -16,21 +16,33 @@
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
#include <AzFramework/Viewport/CameraState.h>
#include <AzFramework/Visibility/BoundsBus.h>
#include <AzToolsFramework/API/EditorViewportIconDisplayInterface.h>
#include <AzToolsFramework/ToolsComponents/EditorEntityIconComponentBus.h>
#include <AzToolsFramework/Viewport/ViewportMessages.h>
#include <AzToolsFramework/Viewport/ViewportTypes.h>
#include <AzToolsFramework/ViewportSelection/EditorVisibleEntityDataCache.h>
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
#include <AzToolsFramework/API/EditorViewportIconDisplayInterface.h>
#include <AzToolsFramework/ViewportSelection/EditorVisibleEntityDataCache.h>
AZ_CVAR(
bool, ed_visibility_showAggregateEntitySelectionBounds, false, nullptr, AZ::ConsoleFunctorFlags::Null,
bool,
ed_visibility_showAggregateEntitySelectionBounds,
false,
nullptr,
AZ::ConsoleFunctorFlags::Null,
"Display the aggregate selection bounds for a given entity (the union of all component Aabbs)");
AZ_CVAR(
bool, ed_visibility_showAggregateEntityTransformedLocalBounds, false, nullptr, AZ::ConsoleFunctorFlags::Null,
bool,
ed_visibility_showAggregateEntityTransformedLocalBounds,
false,
nullptr,
AZ::ConsoleFunctorFlags::Null,
"Display the aggregate transformed local bounds for a given entity (the union of all local component Aabbs)");
AZ_CVAR(
bool, ed_visibility_showAggregateEntityWorldBounds, false, nullptr, AZ::ConsoleFunctorFlags::Null,
bool,
ed_visibility_showAggregateEntityWorldBounds,
false,
nullptr,
AZ::ConsoleFunctorFlags::Null,
"Display the aggregate world bounds for a given entity (the union of all world component Aabbs)");
namespace AzToolsFramework
@@ -48,8 +60,7 @@ namespace AzToolsFramework
static bool HelpersVisible()
{
bool helpersVisible = false;
EditorRequestBus::BroadcastResult(
helpersVisible, &EditorRequests::DisplayHelpersVisible);
EditorRequestBus::BroadcastResult(helpersVisible, &EditorRequests::DisplayHelpersVisible);
return helpersVisible;
}
@@ -59,25 +70,23 @@ namespace AzToolsFramework
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
return s_iconMinScale + (s_iconMaxScale - s_iconMinScale) *
return s_iconMinScale +
(s_iconMaxScale - s_iconMinScale) *
(1.0f - AZ::GetClamp(AZ::GetMax(0.0f, sqrtf(distSq) - s_iconCloseDist) / s_iconFarDist, 0.0f, 1.0f));
}
static void DisplayComponents(
const AZ::EntityId entityId, const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay)
const AZ::EntityId entityId, const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
const AZ::Entity* entity = AZ::Interface<AZ::ComponentApplicationRequests>::Get()->FindEntity(entityId);
AzFramework::EntityDebugDisplayEventBus::Event(
entityId, &AzFramework::EntityDebugDisplayEvents::DisplayEntityViewport,
viewportInfo, debugDisplay);
entityId, &AzFramework::EntityDebugDisplayEvents::DisplayEntityViewport, viewportInfo, debugDisplay);
if (ed_visibility_showAggregateEntitySelectionBounds)
{
if (const AZ::Aabb aabb = AzToolsFramework::CalculateEditorEntitySelectionBounds(entityId, viewportInfo);
aabb.IsValid())
if (const AZ::Aabb aabb = AzToolsFramework::CalculateEditorEntitySelectionBounds(entityId, viewportInfo); aabb.IsValid())
{
debugDisplay.SetColor(AZ::Colors::Orange);
debugDisplay.DrawWireBox(aabb.GetMin(), aabb.GetMax());
@@ -107,8 +116,7 @@ namespace AzToolsFramework
}
AZ::EntityId EditorHelpers::HandleMouseInteraction(
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteractionEvent& mouseInteraction)
const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteractionEvent& mouseInteraction)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
@@ -127,8 +135,7 @@ namespace AzToolsFramework
{
const AZ::EntityId entityId = m_entityDataCache->GetVisibleEntityId(entityCacheIndex);
if ( m_entityDataCache->IsVisibleEntityLocked(entityCacheIndex)
|| !m_entityDataCache->IsVisibleEntityVisible(entityCacheIndex))
if (m_entityDataCache->IsVisibleEntityLocked(entityCacheIndex) || !m_entityDataCache->IsVisibleEntityVisible(entityCacheIndex))
{
continue;
}
@@ -148,10 +155,8 @@ namespace AzToolsFramework
const auto iconRange = static_cast<float>(GetIconScale(distSqFromCamera) * s_iconSize * 0.5f);
const auto screenCoords = mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates;
if ( screenCoords.m_x >= screenPosition.m_x - iconRange
&& screenCoords.m_x <= screenPosition.m_x + iconRange
&& screenCoords.m_y >= screenPosition.m_y - iconRange
&& screenCoords.m_y <= screenPosition.m_y + iconRange)
if (screenCoords.m_x >= screenPosition.m_x - iconRange && screenCoords.m_x <= screenPosition.m_x + iconRange &&
screenCoords.m_y >= screenPosition.m_y - iconRange && screenCoords.m_y <= screenPosition.m_y + iconRange)
{
entityIdUnderCursor = entityId;
break;
@@ -161,16 +166,13 @@ namespace AzToolsFramework
using AzFramework::ViewportInfo;
// check if components provide an aabb
if (const AZ::Aabb aabb = CalculateEditorEntitySelectionBounds(entityId, ViewportInfo{viewportId});
aabb.IsValid())
if (const AZ::Aabb aabb = CalculateEditorEntitySelectionBounds(entityId, ViewportInfo{ viewportId }); aabb.IsValid())
{
// coarse grain check
if (AabbIntersectMouseRay(mouseInteraction.m_mouseInteraction, aabb))
{
// if success, pick against specific component
if (PickEntity(
entityId, mouseInteraction.m_mouseInteraction,
closestDistance, viewportId))
if (PickEntity(entityId, mouseInteraction.m_mouseInteraction, closestDistance, viewportId))
{
entityIdUnderCursor = entityId;
}
@@ -182,7 +184,8 @@ namespace AzToolsFramework
}
void EditorHelpers::DisplayHelpers(
const AzFramework::ViewportInfo& viewportInfo, const AzFramework::CameraState& cameraState,
const AzFramework::ViewportInfo& viewportInfo,
const AzFramework::CameraState& cameraState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AZStd::function<bool(AZ::EntityId)>& showIconCheck)
{
@@ -202,8 +205,8 @@ namespace AzToolsFramework
// notify components to display
DisplayComponents(entityId, viewportInfo, debugDisplay);
if ( m_entityDataCache->IsVisibleEntityIconHidden(entityCacheIndex)
|| (m_entityDataCache->IsVisibleEntitySelected(entityCacheIndex) && !showIconCheck(entityId)))
if (m_entityDataCache->IsVisibleEntityIconHidden(entityCacheIndex) ||
(m_entityDataCache->IsVisibleEntitySelected(entityCacheIndex) && !showIconCheck(entityId)))
{
continue;
}
@@ -219,7 +222,8 @@ namespace AzToolsFramework
const float iconSize = s_iconSize * iconScale;
using ComponentEntityAccentType = Components::EditorSelectionAccentSystemComponent::ComponentEntityAccentType;
const AZ::Color iconHighlight = [this, entityCacheIndex]() {
const AZ::Color iconHighlight = [this, entityCacheIndex]()
{
if (m_entityDataCache->IsVisibleEntityLocked(entityCacheIndex))
{
return AZ::Color(AZ::u8(100), AZ::u8(100), AZ::u8(100), AZ::u8(255));
@@ -233,14 +237,9 @@ namespace AzToolsFramework
return AZ::Color(1.0f, 1.0f, 1.0f, 1.0f);
}();
EditorViewportIconDisplay::Get()->DrawIcon({
viewportInfo.m_viewportId,
iconTextureId,
iconHighlight,
entityPosition,
EditorViewportIconDisplayInterface::CoordinateSpace::WorldSpace,
AZ::Vector2{iconSize, iconSize}
});
EditorViewportIconDisplay::Get()->DrawIcon({ viewportInfo.m_viewportId, iconTextureId, iconHighlight, entityPosition,
EditorViewportIconDisplayInterface::CoordinateSpace::WorldSpace,
AZ::Vector2{ iconSize, iconSize } });
}
}
}
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -21,7 +21,7 @@ namespace AzFramework
class DebugDisplayRequests;
struct ViewportInfo;
struct CameraState;
}
} // namespace AzFramework
namespace AzToolsFramework
{
@@ -32,37 +32,39 @@ namespace AzToolsFramework
struct MouseInteractionEvent;
}
/// EditorHelpers are the visualizations that appear for entities
/// when 'Display Helpers' is toggled on inside the editor.
/// These include but are not limited to entity icons and shape visualizations.
//! EditorHelpers are the visualizations that appear for entities
//! when 'Display Helpers' is toggled on inside the editor.
//! These include but are not limited to entity icons and shape visualizations.
class EditorHelpers
{
public:
AZ_CLASS_ALLOCATOR_DECL
/// An EditorVisibleEntityDataCache must be passed to EditorHelpers to allow it to
/// efficiently read entity data without resorting to EBus calls.
//! An EditorVisibleEntityDataCache must be passed to EditorHelpers to allow it to
//! efficiently read entity data without resorting to EBus calls.
explicit EditorHelpers(const EditorVisibleEntityDataCache* entityDataCache)
: m_entityDataCache(entityDataCache) {}
: m_entityDataCache(entityDataCache)
{
}
EditorHelpers(const EditorHelpers&) = delete;
EditorHelpers& operator=(const EditorHelpers&) = delete;
~EditorHelpers() = default;
/// Handle any mouse interaction with the EditorHelpers.
/// Used to check if a particular entity was selected.
//! Handle any mouse interaction with the EditorHelpers.
//! Used to check if a particular entity was selected.
AZ::EntityId HandleMouseInteraction(
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteractionEvent& mouseInteraction);
const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteractionEvent& mouseInteraction);
/// Do the drawing responsible for the EditorHelpers.
/// @param showIconCheck Provide a custom callback to filter certain entities from
/// displaying an icon under certain conditions.
//! Do the drawing responsible for the EditorHelpers.
//! @param showIconCheck Provide a custom callback to filter certain entities from
//! displaying an icon under certain conditions.
void DisplayHelpers(
const AzFramework::ViewportInfo& viewportInfo, const AzFramework::CameraState& cameraState,
const AzFramework::ViewportInfo& viewportInfo,
const AzFramework::CameraState& cameraState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AZStd::function<bool(AZ::EntityId)>& showIconCheck);
private:
const EditorVisibleEntityDataCache* m_entityDataCache = nullptr; ///< Entity Data queried by the EditorHelpers.
const EditorVisibleEntityDataCache* m_entityDataCache = nullptr; //!< Entity Data queried by the EditorHelpers.
};
} // namespace AzToolsFramework
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "EditorInteractionSystemComponent.h"
@@ -45,8 +45,7 @@ namespace AzToolsFramework
return m_interactionRequests->InternalHandleMouseManipulatorInteraction(mouseInteraction);
}
void EditorInteractionSystemComponent::SetHandler(
const ViewportSelectionRequestsBuilderFn& interactionRequestsBuilder)
void EditorInteractionSystemComponent::SetHandler(const ViewportSelectionRequestsBuilderFn& interactionRequestsBuilder)
{
// when setting a handler, make sure we're connected to the ViewportDebugDisplayEventBus so we
// can forward calls to the specific type implementing ViewportSelectionRequests
@@ -57,32 +56,30 @@ namespace AzToolsFramework
m_entityDataCache = AZStd::make_unique<EditorVisibleEntityDataCache>();
m_interactionRequests.reset(); // BusConnect/Disconnect in constructor/destructor,
m_interactionRequests.reset(); // BusConnect/Disconnect in constructor/destructor,
// so have to reset before assigning the new one
m_interactionRequests = interactionRequestsBuilder(m_entityDataCache.get());
}
void EditorInteractionSystemComponent::SetDefaultHandler()
{
SetHandler([](const EditorVisibleEntityDataCache* entityDataCache)
{
return AZStd::make_unique<EditorDefaultSelection>(entityDataCache);
});
SetHandler(
[](const EditorVisibleEntityDataCache* entityDataCache)
{
return AZStd::make_unique<EditorDefaultSelection>(entityDataCache);
});
}
void EditorInteractionSystemComponent::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<EditorInteractionSystemComponent, AZ::Component>()
->Version(0)
;
serializeContext->Class<EditorInteractionSystemComponent, AZ::Component>()->Version(0);
}
}
void EditorInteractionSystemComponent::DisplayViewport(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay)
const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
@@ -93,8 +90,7 @@ namespace AzToolsFramework
}
void EditorInteractionSystemComponent::DisplayViewport2d(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay)
const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay)
{
m_interactionRequests->DisplayViewportSelection2d(viewportInfo, debugDisplay);
}
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -18,9 +18,9 @@
namespace AzToolsFramework
{
/// System Component to wrap active input handler.
/// EditorInteractionSystemComponent is notified of viewport mouse events from RenderViewport
/// and forwards them to a concrete implementation of ViewportSelectionRequests.
//! System Component to wrap active input handler.
//! EditorInteractionSystemComponent is notified of viewport mouse events from RenderViewport
//! and forwards them to a concrete implementation of ViewportSelectionRequests.
class EditorInteractionSystemComponent
: public AZ::Component
, private EditorInteractionSystemViewportSelectionRequestBus::Handler
@@ -37,18 +37,12 @@ namespace AzToolsFramework
void SetDefaultHandler() override;
// EditorInteractionSystemViewportSelectionRequestBus ...
bool InternalHandleMouseViewportInteraction(
const ViewportInteraction::MouseInteractionEvent& mouseInteraction) override;
bool InternalHandleMouseManipulatorInteraction(
const ViewportInteraction::MouseInteractionEvent& mouseInteraction) override;
bool InternalHandleMouseViewportInteraction(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) override;
bool InternalHandleMouseManipulatorInteraction(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) override;
// AzFramework::ViewportDebugDisplayEventBus
void DisplayViewport(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay) override;
void DisplayViewport2d(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay) override;
void DisplayViewport(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override;
void DisplayViewport2d(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override;
private:
// AZ::Component
@@ -58,11 +52,11 @@ namespace AzToolsFramework
// EditorEventsBus
void NotifyCentralWidgetInitialized() override;
AZStd::unique_ptr<EditorVisibleEntityDataCache> m_entityDataCache = nullptr; ///< Visible EntityData cache to be used by concrete
///< instantiations of ViewportSelectionRequests.
AZStd::unique_ptr<EditorVisibleEntityDataCache> m_entityDataCache = nullptr; //!< Visible EntityData cache to be used by concrete
//!< instantiations of ViewportSelectionRequests.
AZStd::unique_ptr<InternalViewportSelectionRequests> m_interactionRequests; ///< Hold a concrete implementation of
///< ViewportSelectionRequests to handle viewport
///< input and drawing for the Editor.
AZStd::unique_ptr<InternalViewportSelectionRequests> m_interactionRequests; //!< Hold a concrete implementation of
//!< ViewportSelectionRequests to handle viewport
//!< input and drawing for the Editor.
};
} // namespace AzToolsFramework

Some files were not shown because too many files have changed in this diff Show More