Merge branch 'main' into Atom/antonmic/PassChanges

main
antonmic 5 years ago
commit 451de8e782

@ -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());

@ -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>

@ -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*/)
{
}
//! 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.
//! 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)
{
}
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.
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);
/// Returns startLocalHitPosition if currentLocalHitPosition is further away than the camera's far clip plane.
//! 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.
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) {}
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(); }
: 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();
}
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;
}
//! 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.
//! 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),
gridMainColor, gridFadeColor);
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),
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);
/// 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.
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);
//! 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;
/// 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);
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);
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);
/// 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
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
{
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

@ -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,9 +56,8 @@ 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())
@ -70,4 +67,4 @@ namespace AzToolsFramework
}
}
}
}
} // 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
/// 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).
//! @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).
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 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 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
/// 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); }
AZ::u32 m_mouseButtons = 0; ///< Current mouse button state (flags).
//! @endcond
//! 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);
}
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)) {}
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.
, 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.
};
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

@ -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,10 +22,9 @@ namespace AzToolsFramework
{
class EditorVisibleEntityDataCache;
/// Bus to handle all mouse events originating from the viewport.
/// Coordinated by the EditorInteractionSystemComponent
class EditorInteractionSystemViewportSelectionRequests
: public AZ::EBusTraits
//! Bus to handle all mouse events originating from the viewport.
//! Coordinated by the EditorInteractionSystemComponent
class EditorInteractionSystemViewportSelectionRequests : public AZ::EBusTraits
{
public:
using BusIdType = AzFramework::EntityContextId;
@ -36,32 +35,31 @@ namespace AzToolsFramework
~EditorInteractionSystemViewportSelectionRequests() = default;
};
/// Alias for factory function to create a new type implementing the ViewportSelectionRequests interface.
//! Alias for factory function to create a new type implementing the ViewportSelectionRequests interface.
using ViewportSelectionRequestsBuilderFn =
AZStd::function<AZStd::unique_ptr<ViewportInteraction::InternalViewportSelectionRequests>(const EditorVisibleEntityDataCache*)>;
/// Interface for system component implementing the ViewportSelectionRequests interface.
/// This interface also includes a setter to set a custom handler also implementing
/// the ViewportSelectionRequests interface to customize editor behavior.
class EditorInteractionSystemViewportSelection
: public ViewportInteraction::InternalViewportSelectionRequests
//! Interface for system component implementing the ViewportSelectionRequests interface.
//! This interface also includes a setter to set a custom handler also implementing
//! the ViewportSelectionRequests interface to customize editor behavior.
class EditorInteractionSystemViewportSelection : public ViewportInteraction::InternalViewportSelectionRequests
{
public:
/// \ref SetHandler takes a factory function to create a new type implementing
/// the ViewportSelectionRequests interface.
/// It provides a handler implementing ViewportSelectionRequests to handle all
/// viewport mouse input and drawing.
//! \ref SetHandler takes a factory function to create a new type implementing
//! the ViewportSelectionRequests interface.
//! It provides a handler implementing ViewportSelectionRequests to handle all
//! viewport mouse input and drawing.
virtual void SetHandler(const ViewportSelectionRequestsBuilderFn& interactionRequestsBuilder) = 0;
/// \ref SetDefaultHandler is a utility function to set the
/// default editor handler (currently \ref EditorDefaultSelection).
/// This is useful to call after setting another mode and then wishing
/// to return to normal operation of the editor.
//! \ref SetDefaultHandler is a utility function to set the
//! default editor handler (currently \ref EditorDefaultSelection).
//! This is useful to call after setting another mode and then wishing
//! to return to normal operation of the editor.
virtual void SetDefaultHandler() = 0;
};
/// Type to inherit to implement EditorInteractionSystemViewportSelection.
/// @note Called by viewport events (RenderViewport) and then handled by concrete
/// implementation of InternalViewportSelectionRequests.
//! Type to inherit to implement EditorInteractionSystemViewportSelection.
//! @note Called by viewport events (RenderViewport) and then handled by concrete
//! implementation of InternalViewportSelectionRequests.
using EditorInteractionSystemViewportSelectionRequestBus =
AZ::EBus<EditorInteractionSystemViewportSelection, EditorInteractionSystemViewportSelectionRequests>;

@ -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 "EditorPickEntitySelection.h"
@ -19,9 +19,8 @@ namespace AzToolsFramework
{
AZ_CLASS_ALLOCATOR_IMPL(EditorPickEntitySelection, AZ::SystemAllocator, 0)
EditorPickEntitySelection::EditorPickEntitySelection(
const EditorVisibleEntityDataCache* entityDataCache)
: m_editorHelpers(AZStd::make_unique<EditorHelpers>(entityDataCache))
EditorPickEntitySelection::EditorPickEntitySelection(const EditorVisibleEntityDataCache* entityDataCache)
: m_editorHelpers(AZStd::make_unique<EditorHelpers>(entityDataCache))
{
}
@ -29,8 +28,7 @@ namespace AzToolsFramework
{
if (m_hoveredEntityId.IsValid())
{
ToolsApplicationRequestBus::Broadcast(
&ToolsApplicationRequests::SetEntityHighlighted, m_hoveredEntityId, false);
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetEntityHighlighted, m_hoveredEntityId, false);
}
}
@ -41,8 +39,7 @@ namespace AzToolsFramework
// highlighted - hoveredEntityId is an in/out param that is updated based on the change in
// entityIdUnderCursor.
static void HandleAccents(
const AZ::EntityId entityIdUnderCursor, AZ::EntityId& hoveredEntityId,
const ViewportInteraction::MouseButtons mouseButtons)
const AZ::EntityId entityIdUnderCursor, AZ::EntityId& hoveredEntityId, const ViewportInteraction::MouseButtons mouseButtons)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
@ -55,8 +52,7 @@ namespace AzToolsFramework
{
if (hoveredEntityId.IsValid())
{
ToolsApplicationRequestBus::Broadcast(
&ToolsApplicationRequests::SetEntityHighlighted, hoveredEntityId, false);
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetEntityHighlighted, hoveredEntityId, false);
hoveredEntityId.SetInvalid();
}
@ -68,8 +64,7 @@ namespace AzToolsFramework
{
if (entityIdUnderCursor.IsValid() && entityIdUnderCursor != hoveredEntityId)
{
ToolsApplicationRequestBus::Broadcast(
&ToolsApplicationRequests::SetEntityHighlighted, entityIdUnderCursor, true);
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetEntityHighlighted, entityIdUnderCursor, true);
hoveredEntityId = entityIdUnderCursor;
}
@ -93,8 +88,7 @@ namespace AzToolsFramework
if (m_cachedEntityIdUnderCursor.IsValid())
{
// if we clicked on a valid entity id, actually try to set it
EditorPickModeRequestBus::Broadcast(
&EditorPickModeRequests::PickModeSelectEntity, m_cachedEntityIdUnderCursor);
EditorPickModeRequestBus::Broadcast(&EditorPickModeRequests::PickModeSelectEntity, m_cachedEntityIdUnderCursor);
}
// after a click, always stop pick mode, whether we set an entity or not
@ -105,16 +99,18 @@ namespace AzToolsFramework
}
void EditorPickEntitySelection::DisplayViewportSelection(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay)
const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay)
{
const AzFramework::CameraState cameraState = GetCameraState(viewportInfo.m_viewportId);
m_editorHelpers->DisplayHelpers(
viewportInfo, cameraState, debugDisplay, [](AZ::EntityId){ return true; });
viewportInfo, cameraState, debugDisplay,
[](AZ::EntityId)
{
return true;
});
HandleAccents(
m_cachedEntityIdUnderCursor, m_hoveredEntityId,
ViewportInteraction::BuildMouseButtons(QGuiApplication::mouseButtons()));
m_cachedEntityIdUnderCursor, m_hoveredEntityId, ViewportInteraction::BuildMouseButtons(QGuiApplication::mouseButtons()));
}
} // 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,10 +17,9 @@
namespace AzToolsFramework
{
/// Viewport interaction that will handle assigning an entity in the viewport to
/// an entity field in the entity inspector.
class EditorPickEntitySelection
: public ViewportInteraction::InternalViewportSelectionRequests
//! Viewport interaction that will handle assigning an entity in the viewport to
//! an entity field in the entity inspector.
class EditorPickEntitySelection : public ViewportInteraction::InternalViewportSelectionRequests
{
public:
AZ_CLASS_ALLOCATOR_DECL
@ -30,15 +29,12 @@ namespace AzToolsFramework
private:
// ViewportInteraction::InternalViewportSelectionRequests ...
bool InternalHandleMouseViewportInteraction(
const ViewportInteraction::MouseInteractionEvent& mouseInteraction) override;
bool InternalHandleMouseViewportInteraction(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) override;
void DisplayViewportSelection(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay) override;
const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override;
AZStd::unique_ptr<EditorHelpers> m_editorHelpers; ///< Editor visualization of entities (icons, shapes, debug visuals etc).
AZ::EntityId m_hoveredEntityId; ///< What EntityId is the mouse currently hovering over (if any).
AZ::EntityId m_cachedEntityIdUnderCursor; ///< Store the EntityId on each mouse move for use in Display.
AZStd::unique_ptr<EditorHelpers> m_editorHelpers; //!< Editor visualization of entities (icons, shapes, debug visuals etc).
AZ::EntityId m_hoveredEntityId; //!< What EntityId is the mouse currently hovering over (if any).
AZ::EntityId m_cachedEntityIdUnderCursor; //!< Store the EntityId on each mouse move for use in Display.
};
} // namespace AzToolsFramework

@ -1,38 +1,36 @@
/*
* 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 "EditorSelectionUtil.h"
#include <AzCore/Math/Aabb.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/Interface/Interface.h>
#include <AzCore/Math/Aabb.h>
#include <AzCore/Math/IntersectSegment.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzFramework/Visibility/BoundsBus.h>
#include <AzToolsFramework/API/ComponentEntitySelectionBus.h>
#include <AzToolsFramework/Viewport/ViewportMessages.h>
namespace AzToolsFramework
{
/// Default ray length for picking in the viewport.
// default ray length for picking in the viewport
static const float s_pickRayLength = 1000.0f;
AZ::Vector3 CalculateCenterOffset(
const AZ::EntityId entityId, const EditorTransformComponentSelectionRequests::Pivot pivot)
AZ::Vector3 CalculateCenterOffset(const AZ::EntityId entityId, const EditorTransformComponentSelectionRequests::Pivot pivot)
{
if (Centered(pivot))
{
const AZ::Entity* entity = AZ::Interface<AZ::ComponentApplicationRequests>::Get()->FindEntity(entityId);
if (const AZ::Aabb localBound = AzFramework::CalculateEntityLocalBoundsUnion(entity);
localBound.IsValid())
if (const AZ::Aabb localBound = AzFramework::CalculateEntityLocalBoundsUnion(entity); localBound.IsValid())
{
return localBound.GetCenter();
}
@ -41,76 +39,71 @@ namespace AzToolsFramework
return AZ::Vector3::CreateZero();
}
float CalculateScreenToWorldMultiplier(
const AZ::Vector3& worldPosition, const AzFramework::CameraState& cameraState)
float CalculateScreenToWorldMultiplier(const AZ::Vector3& worldPosition, const AzFramework::CameraState& cameraState)
{
const float apparentDistance = 10.0f;
// compute the distance from the camera, projected onto the camera's forward direction
// note: this keeps the scale value the same when positions are at the edge of the screen
const float projectedCameraDistance =
std::abs((cameraState.m_position - worldPosition).Dot(cameraState.m_forward));
const float projectedCameraDistance = std::abs((cameraState.m_position - worldPosition).Dot(cameraState.m_forward));
// author sizes of bounds/manipulators as they would appear
// in perspective 10 meters from the camera.
return AZ::GetMax(projectedCameraDistance, cameraState.m_nearClip) / apparentDistance;
}
AzFramework::ScreenPoint GetScreenPosition(const int viewportId, const AZ::Vector3& worldTranslation)
AzFramework::ScreenPoint GetScreenPosition(const int viewportId, const AZ::Vector3& worldTranslation)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
auto screenPosition = AzFramework::ScreenPoint(0, 0);
ViewportInteraction::ViewportInteractionRequestBus::EventResult(
screenPosition, viewportId,
&ViewportInteraction::ViewportInteractionRequestBus::Events::ViewportWorldToScreen,
screenPosition, viewportId, &ViewportInteraction::ViewportInteractionRequestBus::Events::ViewportWorldToScreen,
worldTranslation);
return screenPosition;
}
bool AabbIntersectMouseRay(
const ViewportInteraction::MouseInteraction& mouseInteraction, const AZ::Aabb& aabb)
bool AabbIntersectMouseRay(const ViewportInteraction::MouseInteraction& mouseInteraction, const AZ::Aabb& aabb)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
const AZ::Vector3 rayScaledDir =
mouseInteraction.m_mousePick.m_rayDirection * s_pickRayLength;
const AZ::Vector3 rayScaledDir = mouseInteraction.m_mousePick.m_rayDirection * s_pickRayLength;
AZ::Vector3 startNormal;
float t, end;
return AZ::Intersect::IntersectRayAABB(
mouseInteraction.m_mousePick.m_rayOrigin, rayScaledDir,
rayScaledDir.GetReciprocal(), aabb, t, end, startNormal) > 0;
mouseInteraction.m_mousePick.m_rayOrigin, rayScaledDir, rayScaledDir.GetReciprocal(), aabb, t, end, startNormal) > 0;
}
bool PickEntity(
const AZ::EntityId entityId, const ViewportInteraction::MouseInteraction& mouseInteraction,
float& closestDistance, const int viewportId)
const AZ::EntityId entityId,
const ViewportInteraction::MouseInteraction& mouseInteraction,
float& closestDistance,
const int viewportId)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Entity);
bool entityPicked = false;
EditorComponentSelectionRequestsBus::EnumerateHandlersId(
entityId, [mouseInteraction, &entityPicked, &closestDistance, viewportId]
(EditorComponentSelectionRequests* handler) -> bool
{
if (handler->SupportsEditorRayIntersect())
entityId,
[mouseInteraction, &entityPicked, &closestDistance, viewportId](EditorComponentSelectionRequests* handler) -> bool
{
float distance = std::numeric_limits<float>::max();
const bool intersection = handler->EditorSelectionIntersectRayViewport(
{ viewportId }, mouseInteraction.m_mousePick.m_rayOrigin,
mouseInteraction.m_mousePick.m_rayDirection, distance);
if (intersection && distance < closestDistance)
if (handler->SupportsEditorRayIntersect())
{
entityPicked = true;
closestDistance = distance;
float distance = std::numeric_limits<float>::max();
const bool intersection = handler->EditorSelectionIntersectRayViewport(
{ viewportId }, mouseInteraction.m_mousePick.m_rayOrigin, mouseInteraction.m_mousePick.m_rayDirection, distance);
if (intersection && distance < closestDistance)
{
entityPicked = true;
closestDistance = distance;
}
}
}
return true; // iterate over all handlers
});
return true; // iterate over all handlers
});
return entityPicked;
}
@ -119,9 +112,8 @@ namespace AzToolsFramework
{
AzFramework::CameraState cameraState;
ViewportInteraction::ViewportInteractionRequestBus::EventResult(
cameraState, viewportId,
&ViewportInteraction::ViewportInteractionRequestBus::Events::GetCameraState);
cameraState, viewportId, &ViewportInteraction::ViewportInteractionRequestBus::Events::GetCameraState);
return cameraState;
}

@ -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
@ -30,56 +30,53 @@ namespace AzFramework
namespace AzToolsFramework
{
/// Is the pivot at the center of the object (middle of extents) or at the
/// exported authored object root position.
//! Is the pivot at the center of the object (middle of extents) or at the
//! exported authored object root position.
inline bool Centered(const EditorTransformComponentSelectionRequests::Pivot pivot)
{
return pivot == EditorTransformComponentSelectionRequests::Pivot::Center;
}
/// Return offset from object pivot to center if center is true, otherwise Vector3::Zero.
//! Return offset from object pivot to center if center is true, otherwise Vector3::Zero.
AZ::Vector3 CalculateCenterOffset(AZ::EntityId entityId, EditorTransformComponentSelectionRequests::Pivot pivot);
/// Calculate scale factor based on distance from camera
float CalculateScreenToWorldMultiplier(
const AZ::Vector3& worldPosition, const AzFramework::CameraState& cameraState);
//! Calculate scale factor based on distance from camera
float CalculateScreenToWorldMultiplier(const AZ::Vector3& worldPosition, const AzFramework::CameraState& cameraState);
/// Map from world space to screen space.
AzFramework::ScreenPoint GetScreenPosition(int viewportId, const AZ::Vector3& worldTranslation);
//! Map from world space to screen space.
AzFramework::ScreenPoint GetScreenPosition(int viewportId, const AZ::Vector3& worldTranslation);
/// Given a mouse interaction, determine if the pick ray from its position
/// in screen space intersected an aabb in world space.
bool AabbIntersectMouseRay(
const ViewportInteraction::MouseInteraction& mouseInteraction, const AZ::Aabb& aabb);
//! Given a mouse interaction, determine if the pick ray from its position
//! in screen space intersected an aabb in world space.
bool AabbIntersectMouseRay(const ViewportInteraction::MouseInteraction& mouseInteraction, const AZ::Aabb& aabb);
/// Return if a mouse interaction (pick ray) did intersect the tested EntityId.
//! Return if a mouse interaction (pick ray) did intersect the tested EntityId.
bool PickEntity(
AZ::EntityId entityId, const ViewportInteraction::MouseInteraction& mouseInteraction,
float& closestDistance, int viewportId);
AZ::EntityId entityId, const ViewportInteraction::MouseInteraction& mouseInteraction, float& closestDistance, int viewportId);
/// Wrapper for EBus call to return the CameraState for a given viewport.
//! Wrapper for EBus call to return the CameraState for a given viewport.
AzFramework::CameraState GetCameraState(int viewportId);
/// Wrapper for EBus call to return the DPI scaling for a given viewport.
float GetScreenDisplayScaling(const int viewportId);
//! Wrapper for EBus call to return the DPI scaling for a given viewport.
float GetScreenDisplayScaling(int viewportId);
/// A utility to return the center of several points.
/// Take several positions and store the min and max of each in
/// turn - when all points have been added return the center/midpoint.
//! A utility to return the center of several points.
//! Take several positions and store the min and max of each in
//! turn - when all points have been added return the center/midpoint.
class MidpointCalculator
{
public:
/// Default constructed with min and max initialized to opposites.
//! Default constructed with min and max initialized to opposites.
MidpointCalculator() = default;
/// Call this for all positions you want to be considered.
//! Call this for all positions you want to be considered.
void AddPosition(const AZ::Vector3& position)
{
m_minPosition = position.GetMin(m_minPosition);
m_maxPosition = position.GetMax(m_maxPosition);
}
/// Once all positions have been added, call this to return the midpoint.
//! Once all positions have been added, call this to return the midpoint.
AZ::Vector3 CalculateMidpoint() const
{
return m_minPosition + (m_maxPosition - m_minPosition) * 0.5f;

@ -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 <AzCore/RTTI/BehaviorContext.h>
#include "EditorTransformComponentSelectionRequestBus.h"
#include <AzCore/RTTI/BehaviorContext.h>
namespace AzToolsFramework
{
@ -19,50 +19,68 @@ namespace AzToolsFramework
{
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
#define TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests() \
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) \
->Attribute(AZ::Script::Attributes::Category, "Editor") \
->Attribute(AZ::Script::Attributes::Module, "editor")
#define TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests() \
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) \
->Attribute(AZ::Script::Attributes::Category, "Editor") \
->Attribute(AZ::Script::Attributes::Module, "editor")
behaviorContext->EnumProperty<static_cast<int>(EditorTransformComponentSelectionRequests::Mode::Rotation)>("TransformMode_Rotation")
TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests();
behaviorContext->EnumProperty<static_cast<int>(EditorTransformComponentSelectionRequests::Mode::Translation)>("TransformMode_Translation")
TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests();
behaviorContext->EnumProperty<static_cast<int>(EditorTransformComponentSelectionRequests::Mode::Rotation)>(
"TransformMode_Rotation") TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests();
behaviorContext->EnumProperty<static_cast<int>(EditorTransformComponentSelectionRequests::Mode::Translation)>(
"TransformMode_Translation") TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests();
behaviorContext->EnumProperty<static_cast<int>(EditorTransformComponentSelectionRequests::Mode::Scale)>("TransformMode_Scale")
TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests();
behaviorContext->EnumProperty<static_cast<int>(EditorTransformComponentSelectionRequests::RefreshType::Translation)>("TransformRefreshType_Translation")
TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests();
behaviorContext->EnumProperty<static_cast<int>(EditorTransformComponentSelectionRequests::RefreshType::Orientation)>("TransformRefreshType_Orientation")
TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests();
behaviorContext->EnumProperty<static_cast<int>(EditorTransformComponentSelectionRequests::RefreshType::All)>("TransformRefreshType_All")
TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests();
behaviorContext->EnumProperty<static_cast<int>(EditorTransformComponentSelectionRequests::RefreshType::Translation)>(
"TransformRefreshType_Translation") TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests();
behaviorContext->EnumProperty<static_cast<int>(EditorTransformComponentSelectionRequests::RefreshType::Orientation)>(
"TransformRefreshType_Orientation") TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests();
behaviorContext->EnumProperty<static_cast<int>(EditorTransformComponentSelectionRequests::RefreshType::All)>(
"TransformRefreshType_All") TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests();
behaviorContext->EnumProperty<static_cast<int>(EditorTransformComponentSelectionRequests::Pivot::Object)>("TransformPivot_Object")
TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests();
behaviorContext->EnumProperty<static_cast<int>(EditorTransformComponentSelectionRequests::Pivot::Center)>("TransformPivot_Center")
TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests();
behaviorContext->EnumProperty<static_cast<int>(EditorTransformComponentSelectionRequests::Pivot::Object)>(
"TransformPivot_Object") TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests();
behaviorContext->EnumProperty<static_cast<int>(EditorTransformComponentSelectionRequests::Pivot::Center)>(
"TransformPivot_Center") TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests();
behaviorContext->EBus<EditorTransformComponentSelectionRequestBus>("EditorTransformComponentSelectionRequestBus")
TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests()
behaviorContext
->EBus<EditorTransformComponentSelectionRequestBus>("EditorTransformComponentSelectionRequestBus")
TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests()
->Event("SetTransformMode", &EditorTransformComponentSelectionRequestBus::Events::SetTransformMode)
->Event("GetTransformMode", &EditorTransformComponentSelectionRequestBus::Events::GetTransformMode)
// Reflecting GetManipulatorTransform will require hash<AZ::Transform> to be implemented, a pending task.
//->Event("GetManipulatorTransform", &EditorTransformComponentSelectionRequestBus::Events::GetManipulatorTransform)
->Event("RefreshManipulators", &EditorTransformComponentSelectionRequestBus::Events::RefreshManipulators)
->Event("OverrideManipulatorOrientation", &EditorTransformComponentSelectionRequestBus::Events::OverrideManipulatorOrientation)
->Event("OverrideManipulatorTranslation", &EditorTransformComponentSelectionRequestBus::Events::OverrideManipulatorTranslation)
->Event("CopyTranslationToSelectedEntitiesIndividual", &EditorTransformComponentSelectionRequestBus::Events::CopyTranslationToSelectedEntitiesIndividual)
->Event("CopyTranslationToSelectedEntitiesGroup", &EditorTransformComponentSelectionRequestBus::Events::CopyTranslationToSelectedEntitiesGroup)
->Event("ResetTranslationForSelectedEntitiesLocal", &EditorTransformComponentSelectionRequestBus::Events::ResetTranslationForSelectedEntitiesLocal)
->Event("CopyOrientationToSelectedEntitiesIndividual", &EditorTransformComponentSelectionRequestBus::Events::CopyOrientationToSelectedEntitiesIndividual)
->Event("CopyOrientationToSelectedEntitiesGroup", &EditorTransformComponentSelectionRequestBus::Events::CopyOrientationToSelectedEntitiesGroup)
->Event("ResetOrientationForSelectedEntitiesLocal", &EditorTransformComponentSelectionRequestBus::Events::ResetOrientationForSelectedEntitiesLocal)
->Event("CopyScaleToSelectedEntitiesIndividualLocal", &EditorTransformComponentSelectionRequestBus::Events::CopyScaleToSelectedEntitiesIndividualLocal)
->Event("CopyScaleToSelectedEntitiesIndividualWorld", &EditorTransformComponentSelectionRequestBus::Events::CopyScaleToSelectedEntitiesIndividualWorld)
;
->Event(
"OverrideManipulatorOrientation", &EditorTransformComponentSelectionRequestBus::Events::OverrideManipulatorOrientation)
->Event(
"OverrideManipulatorTranslation", &EditorTransformComponentSelectionRequestBus::Events::OverrideManipulatorTranslation)
->Event(
"CopyTranslationToSelectedEntitiesIndividual",
&EditorTransformComponentSelectionRequestBus::Events::CopyTranslationToSelectedEntitiesIndividual)
->Event(
"CopyTranslationToSelectedEntitiesGroup",
&EditorTransformComponentSelectionRequestBus::Events::CopyTranslationToSelectedEntitiesGroup)
->Event(
"ResetTranslationForSelectedEntitiesLocal",
&EditorTransformComponentSelectionRequestBus::Events::ResetTranslationForSelectedEntitiesLocal)
->Event(
"CopyOrientationToSelectedEntitiesIndividual",
&EditorTransformComponentSelectionRequestBus::Events::CopyOrientationToSelectedEntitiesIndividual)
->Event(
"CopyOrientationToSelectedEntitiesGroup",
&EditorTransformComponentSelectionRequestBus::Events::CopyOrientationToSelectedEntitiesGroup)
->Event(
"ResetOrientationForSelectedEntitiesLocal",
&EditorTransformComponentSelectionRequestBus::Events::ResetOrientationForSelectedEntitiesLocal)
->Event(
"CopyScaleToSelectedEntitiesIndividualLocal",
&EditorTransformComponentSelectionRequestBus::Events::CopyScaleToSelectedEntitiesIndividualLocal)
->Event(
"CopyScaleToSelectedEntitiesIndividualWorld",
&EditorTransformComponentSelectionRequestBus::Events::CopyScaleToSelectedEntitiesIndividualWorld);
#undef TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests
#undef TEMP_SET_ATTRIBUTES_FOR_EditorTransformComponentSelectionRequests
}
}
} // 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,12 +16,10 @@
#include <AzCore/Math/Transform.h>
#include <AzFramework/Entity/EntityContextBus.h>
namespace AzToolsFramework
{
/// Provide interface for EditorTransformComponentSelection requests.
class EditorTransformComponentSelectionRequests
: public AZ::EBusTraits
//! Provide interface for EditorTransformComponentSelection requests.
class EditorTransformComponentSelectionRequests : public AZ::EBusTraits
{
public:
using BusIdType = AzFramework::EntityContextId;
@ -30,7 +28,7 @@ namespace AzToolsFramework
static void Reflect(AZ::ReflectContext* context);
/// What type of transform editing are we in.
//! What type of transform editing are we in.
enum class Mode
{
// note: ordering of these is important - do not change.
@ -40,7 +38,7 @@ namespace AzToolsFramework
Scale
};
/// Specify the type of refresh (what type of transform modification caused the refresh).
//! Specify the type of refresh (what type of transform modification caused the refresh).
enum class RefreshType
{
Translation,
@ -48,69 +46,69 @@ namespace AzToolsFramework
All
};
/// How is the pivot aligned (object/authored position or center).
//! How is the pivot aligned (object/authored position or center).
enum class Pivot
{
Object,
Center
};
/// Set what kind of transform the type that implements this bus should use.
//! Set what kind of transform the type that implements this bus should use.
virtual void SetTransformMode(Mode mode) = 0;
/// Return what transform mode the type that implements this bus is using.
//! Return what transform mode the type that implements this bus is using.
virtual Mode GetTransformMode() = 0;
/// Return the current Entity Manipulator transform.
/// An AZStd::optional<AZ::Transform> is returned as if we do not have a selection
/// there will be no Manipulator present. In this case we return an empty optional.
//! Return the current Entity Manipulator transform.
//! An AZStd::optional<AZ::Transform> is returned as if we do not have a selection
//! there will be no Manipulator present. In this case we return an empty optional.
virtual AZStd::optional<AZ::Transform> GetManipulatorTransform() = 0;
/// Refresh the Manipulator based on the current entity selection.
/// This may be useful if the Entity transform has been set outside
/// of the EditorTransformComponentSelection and we want to make sure the
/// Manipulator stays up to date (in sync) with the current Entity transform.
//! Refresh the Manipulator based on the current entity selection.
//! This may be useful if the Entity transform has been set outside
//! of the EditorTransformComponentSelection and we want to make sure the
//! Manipulator stays up to date (in sync) with the current Entity transform.
virtual void RefreshManipulators(RefreshType refreshType) = 0;
/// Set an orientation override for the Manipulator.
/// Useful if we've picked another Entity transform to use as our reference point.
//! Set an orientation override for the Manipulator.
//! Useful if we've picked another Entity transform to use as our reference point.
virtual void OverrideManipulatorOrientation(const AZ::Quaternion& orientation) = 0;
/// Set a translation override for the Manipulator.
/// Useful if we've picked another Entity transform to use as our reference point.
//! Set a translation override for the Manipulator.
//! Useful if we've picked another Entity transform to use as our reference point.
virtual void OverrideManipulatorTranslation(const AZ::Vector3& translation) = 0;
/// Copy translation to each individual entity so they all appear in the exact same position.
//! Copy translation to each individual entity so they all appear in the exact same position.
virtual void CopyTranslationToSelectedEntitiesIndividual(const AZ::Vector3& translation) = 0;
/// Copy translation to manipulator position with each entity keeping the same relative position as before.
//! Copy translation to manipulator position with each entity keeping the same relative position as before.
virtual void CopyTranslationToSelectedEntitiesGroup(const AZ::Vector3& translation) = 0;
/// Reset the translation of an entity to the same position as its parent.
/// Note: This is a noop if the entity does not have a parent.
//! Reset the translation of an entity to the same position as its parent.
//! Note: This is a noop if the entity does not have a parent.
virtual void ResetTranslationForSelectedEntitiesLocal() = 0;
/// Copy orientation to each individual entity so they all appear in the exact same orientation.
//! Copy orientation to each individual entity so they all appear in the exact same orientation.
virtual void CopyOrientationToSelectedEntitiesIndividual(const AZ::Quaternion& orientation) = 0;
/// Copy orientation to manipulator with each entity keeping the same relative orientation as before.
//! Copy orientation to manipulator with each entity keeping the same relative orientation as before.
virtual void CopyOrientationToSelectedEntitiesGroup(const AZ::Quaternion& orientation) = 0;
/// Reset the orientation of an entity to the same orientation as its parent.
/// Note: This will be the aligned to the world axes (identity) if the entity does not have a parent.
//! Reset the orientation of an entity to the same orientation as its parent.
//! Note: This will be the aligned to the world axes (identity) if the entity does not have a parent.
virtual void ResetOrientationForSelectedEntitiesLocal() = 0;
/// Copy scale to each individual entity in local space without moving position.
//! Copy scale to each individual entity in local space without moving position.
virtual void CopyScaleToSelectedEntitiesIndividualLocal(float scale) = 0;
/// Copy scale to to each individual entity in world (absolute) space.
//! Copy scale to to each individual entity in world (absolute) space.
virtual void CopyScaleToSelectedEntitiesIndividualWorld(float scale) = 0;
protected:
~EditorTransformComponentSelectionRequests() = default;
};
/// Type to inherit to implement EditorTransformComponentSelectionRequests.
//! Type to inherit to implement EditorTransformComponentSelectionRequests.
using EditorTransformComponentSelectionRequestBus = AZ::EBus<EditorTransformComponentSelectionRequests>;
} // namespace AzToolsFramework

@ -1,33 +1,31 @@
/*
* 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 "EditorVisibleEntityDataCache.h"
#include <AzCore/std/sort.h>
#include <AzToolsFramework/Entity/EditorEntityModel.h>
#include <AzToolsFramework/Viewport/ViewportMessages.h>
#include <Entity/EditorEntityHelpers.h>
#include <AzToolsFramework/Entity/EditorEntityModel.h>
namespace AzToolsFramework
{
/// Cached Entity data required by the selection.
//! Cached Entity data required by the selection.
struct EntityData final
{
using ComponentEntityAccentType = Components::EditorSelectionAccentSystemComponent::ComponentEntityAccentType;
EntityData() = default;
EntityData(
AZ::EntityId entityId, const AZ::Transform& worldFromLocal,
bool locked, bool visible, bool selected, bool iconHidden);
EntityData(AZ::EntityId entityId, const AZ::Transform& worldFromLocal, bool locked, bool visible, bool selected, bool iconHidden);
AZ::Transform m_worldFromLocal;
AZ::EntityId m_entityId;
@ -38,7 +36,7 @@ namespace AzToolsFramework
bool m_iconHidden = false;
};
using EntityDatas = AZStd::vector<EntityData>; ///< Alias for vector of EntityDatas.
using EntityDatas = AZStd::vector<EntityData>; //!< Alias for vector of EntityDatas.
// Predicate to sort EntityIds with EntityDatas interchangeably.
struct EntityDataComparer
@ -52,18 +50,27 @@ namespace AzToolsFramework
class EditorVisibleEntityDataCache::EditorVisibleEntityDataCacheImpl
{
public:
EntityIdList m_visibleEntityIds; ///< The EntityIds that are visible this frame.
EntityIdList m_prevVisibleEntityIds; ///< The EntityIds that were visible the previous frame (unsorted).
EntityDatas m_visibleEntityDatas; ///< Cached EntityData required by EditorTransformComponentSelection.
EntityIdList m_visibleEntityIds; //!< The EntityIds that are visible this frame.
EntityIdList m_prevVisibleEntityIds; //!< The EntityIds that were visible the previous frame (unsorted).
EntityDatas m_visibleEntityDatas; //!< Cached EntityData required by EditorTransformComponentSelection.
};
// constructor for EntityData to support emplace_back in vector
EntityData::EntityData(
const AZ::EntityId entityId, const AZ::Transform& worldFromLocal,
const bool locked, const bool visible, const bool selected, const bool iconHidden)
: m_worldFromLocal(worldFromLocal), m_entityId(entityId)
, m_locked(locked), m_visible(visible), m_selected(selected)
, m_iconHidden(iconHidden) {}
const AZ::EntityId entityId,
const AZ::Transform& worldFromLocal,
const bool locked,
const bool visible,
const bool selected,
const bool iconHidden)
: m_worldFromLocal(worldFromLocal)
, m_entityId(entityId)
, m_locked(locked)
, m_visible(visible)
, m_selected(selected)
, m_iconHidden(iconHidden)
{
}
bool EntityDataComparer::operator()(const AZ::EntityId lhs, const EntityData& rhs) const
{
@ -98,20 +105,17 @@ namespace AzToolsFramework
static EntityData EntityDataFromEntityId(const AZ::EntityId entityId)
{
bool visible = false;
EditorEntityInfoRequestBus::EventResult(
visible, entityId, &EditorEntityInfoRequestBus::Events::IsVisible);
EditorEntityInfoRequestBus::EventResult(visible, entityId, &EditorEntityInfoRequestBus::Events::IsVisible);
bool locked = false;
EditorEntityInfoRequestBus::EventResult(
locked, entityId, &EditorEntityInfoRequestBus::Events::IsLocked);
EditorEntityInfoRequestBus::EventResult(locked, entityId, &EditorEntityInfoRequestBus::Events::IsLocked);
bool iconHidden = false;
EditorEntityIconComponentRequestBus::EventResult(
iconHidden, entityId, &EditorEntityIconComponentRequests::IsEntityIconHiddenInViewport);
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 { entityId, worldFromLocal, locked, visible, IsSelected(entityId), iconHidden };
}
@ -155,16 +159,14 @@ namespace AzToolsFramework
AZStd::sort(m_impl->m_visibleEntityDatas.begin(), m_impl->m_visibleEntityDatas.end());
}
void EditorVisibleEntityDataCache::CalculateVisibleEntityDatas(
const AzFramework::ViewportInfo& viewportInfo)
void EditorVisibleEntityDataCache::CalculateVisibleEntityDatas(const AzFramework::ViewportInfo& viewportInfo)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
// request list of visible entities from authoritative system
EntityIdList nextVisibleEntityIds;
ViewportInteraction::MainEditorViewportInteractionRequestBus::Event(
viewportInfo.m_viewportId,
&ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::FindVisibleEntities,
viewportInfo.m_viewportId, &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::FindVisibleEntities,
nextVisibleEntityIds);
// only bother resorting if we know the lists have changed
@ -181,31 +183,26 @@ namespace AzToolsFramework
// find entities that are visible this frame but weren't last frame
AZStd::vector<AZ::EntityId> added;
std::set_difference(
m_impl->m_visibleEntityIds.begin(), m_impl->m_visibleEntityIds.end(),
m_impl->m_visibleEntityDatas.begin(), m_impl->m_visibleEntityDatas.end(),
std::back_inserter(added), EntityDataComparer());
m_impl->m_visibleEntityIds.begin(), m_impl->m_visibleEntityIds.end(), m_impl->m_visibleEntityDatas.begin(),
m_impl->m_visibleEntityDatas.end(), std::back_inserter(added), EntityDataComparer());
// find entities that are not visible this frame but were last frame
AZStd::vector<EntityData> removed;
std::set_difference(
m_impl->m_visibleEntityDatas.begin(), m_impl->m_visibleEntityDatas.end(),
m_impl->m_visibleEntityIds.begin(), m_impl->m_visibleEntityIds.end(),
std::back_inserter(removed), EntityDataComparer());
m_impl->m_visibleEntityDatas.begin(), m_impl->m_visibleEntityDatas.end(), m_impl->m_visibleEntityIds.begin(),
m_impl->m_visibleEntityIds.end(), std::back_inserter(removed), EntityDataComparer());
// search for entityData in removed list, return true if it is found
const auto removePredicate = [&removed](const EntityData& entityData)
{
const auto removeIt = std::equal_range(
removed.begin(), removed.end(), entityData);
const auto removeIt = std::equal_range(removed.begin(), removed.end(), entityData);
return removeIt.first != removeIt.second;
};
// erase-remove idiom - bubble entities to be removed to the end, then erase them in one go
m_impl->m_visibleEntityDatas.erase(
AZStd::remove_if(
m_impl->m_visibleEntityDatas.begin(),
m_impl->m_visibleEntityDatas.end(), removePredicate),
AZStd::remove_if(m_impl->m_visibleEntityDatas.begin(), m_impl->m_visibleEntityDatas.end(), removePredicate),
m_impl->m_visibleEntityDatas.end());
// for newly added entities, request their initial state when first cached
@ -240,8 +237,7 @@ namespace AzToolsFramework
return m_impl->m_visibleEntityDatas[index].m_entityId;
}
EditorVisibleEntityDataCache::ComponentEntityAccentType EditorVisibleEntityDataCache::GetVisibleEntityAccent(
const size_t index) const
EditorVisibleEntityDataCache::ComponentEntityAccentType EditorVisibleEntityDataCache::GetVisibleEntityAccent(const size_t index) const
{
return m_impl->m_visibleEntityDatas[index].m_accent;
}
@ -273,8 +269,8 @@ namespace AzToolsFramework
AZStd::optional<size_t> EditorVisibleEntityDataCache::GetVisibleEntityIndexFromId(const AZ::EntityId entityId) const
{
const auto entityIdIt = std::equal_range(
m_impl->m_visibleEntityDatas.begin(), m_impl->m_visibleEntityDatas.end(), entityId, EntityDataComparer());
const auto entityIdIt =
std::equal_range(m_impl->m_visibleEntityDatas.begin(), m_impl->m_visibleEntityDatas.end(), entityId, EntityDataComparer());
if (entityIdIt.first != entityIdIt.second)
{
@ -318,8 +314,7 @@ namespace AzToolsFramework
}
}
void EditorVisibleEntityDataCache::OnTransformChanged(
const AZ::Transform& /*local*/, const AZ::Transform& world)
void EditorVisibleEntityDataCache::OnTransformChanged(const AZ::Transform& /*local*/, const AZ::Transform& world)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
@ -367,8 +362,7 @@ namespace AzToolsFramework
}
}
void EditorVisibleEntityDataCache::OnEntityIconChanged(
const AZ::Data::AssetId& /*entityIconAssetId*/)
void EditorVisibleEntityDataCache::OnEntityIconChanged(const AZ::Data::AssetId& /*entityIconAssetId*/)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::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,8 +22,8 @@
namespace AzToolsFramework
{
/// A cache of packed EntityData that can be iterated over efficiently without
/// the need to make individual EBus calls
//! A cache of packed EntityData that can be iterated over efficiently without
//! the need to make individual EBus calls
class EditorVisibleEntityDataCache
: private EditorEntityVisibilityNotificationBus::Router
, private EditorEntityLockComponentNotificationBus::Router
@ -45,7 +45,7 @@ namespace AzToolsFramework
void CalculateVisibleEntityDatas(const AzFramework::ViewportInfo& viewportInfo);
/// EditorVisibleEntityDataCache interface
//! EditorVisibleEntityDataCache interface
size_t VisibleEntityDataCount() const;
AZ::Vector3 GetVisibleEntityPosition(size_t index) const;
const AZ::Transform& GetVisibleEntityTransform(size_t index) const;
@ -72,8 +72,7 @@ namespace AzToolsFramework
void OnEntityLockChanged(bool locked) override;
// TransformNotificationBus
void OnTransformChanged(
const AZ::Transform& local, const AZ::Transform& world) override;
void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override;
// EditorComponentSelectionNotificationsBus
void OnAccentTypeChanged(EntityAccentType accent) override;
@ -86,6 +85,6 @@ namespace AzToolsFramework
void OnEntityIconChanged(const AZ::Data::AssetId& entityIconAssetId) override;
class EditorVisibleEntityDataCacheImpl;
AZStd::unique_ptr<EditorVisibleEntityDataCacheImpl> m_impl; ///< Internal representation of entity data cache.
AZStd::unique_ptr<EditorVisibleEntityDataCacheImpl> m_impl; //!< Internal representation of entity data cache.
};
} // namespace AzToolsFramework

@ -108,6 +108,61 @@ namespace AzToolsFramework::ViewportUi::Internal
m_widgetCallbacks.Update();
}
void ViewportUiCluster::SetButtonLocked(const ButtonId buttonId, const bool isLocked)
{
const auto& buttons = m_buttonGroup->GetButtons();
// unlocked previously locked button
if (m_lockedButtonId.has_value() && isLocked)
{
// find the button to extract the old icon (without overlay)
auto findLocked = [this](const Button* button) { return (button->m_buttonId == m_lockedButtonId); };
if (auto lockedButtonIt = AZStd::find_if(buttons.begin(), buttons.end(), findLocked); lockedButtonIt != buttons.end())
{
// get the action corresponding to the lockedButtonId
if (auto actionEntry = m_buttonActionMap.find(m_lockedButtonId.value()); actionEntry != m_buttonActionMap.end())
{
// remove the overlay
auto action = actionEntry->second;
action->setIcon(QIcon(QString((*lockedButtonIt)->m_icon.c_str())));
}
}
}
auto found = [buttonId](Button* button) { return (button->m_buttonId == buttonId); };
if (auto buttonIt = AZStd::find_if(buttons.begin(), buttons.end(), found); buttonIt != buttons.end())
{
QIcon newIcon;
if (isLocked)
{
// overlay the locked icon ontop of the button's icon
QPixmap comboPixmap(24, 24);
comboPixmap.fill(Qt::transparent);
QPixmap firstImage(QString((*buttonIt)->m_icon.c_str()));
QPixmap secondImage(QString(":/stylesheet/img/UI20/toolbar/Locked_Status.svg"));
QPainter painter(&comboPixmap);
painter.drawPixmap(0, 0, firstImage);
painter.drawPixmap(0, 0, secondImage);
newIcon.addPixmap(comboPixmap);
m_lockedButtonId = buttonId;
}
else
{
// remove the overlay
newIcon = QIcon(QString((*buttonIt)->m_icon.c_str()));
m_lockedButtonId = AZStd::nullopt;
}
if (auto actionEntry = m_buttonActionMap.find(buttonId); actionEntry != m_buttonActionMap.end())
{
auto action = actionEntry->second;
action->setIcon(newIcon);
}
}
}
ViewportUiWidgetCallbacks ViewportUiCluster::GetWidgetCallbacks()
{
return m_widgetCallbacks;

@ -17,6 +17,7 @@
#include <AzToolsFramework/ViewportUi/Button.h>
#include <AzToolsFramework/ViewportUi/ViewportUiWidgetCallbacks.h>
#include <QToolBar>
#include <QPainter>
namespace AzToolsFramework::ViewportUi::Internal
{
@ -38,6 +39,8 @@ namespace AzToolsFramework::ViewportUi::Internal
void RemoveButton(ButtonId buttonId);
//! Updates all registered actions.
void Update();
//! Adds a locked overlay to the button's icon.
void SetButtonLocked(ButtonId buttonId, bool isLocked);
//! Returns the widget manager.
ViewportUiWidgetCallbacks GetWidgetCallbacks();
@ -52,5 +55,6 @@ namespace AzToolsFramework::ViewportUi::Internal
AZStd::shared_ptr<ButtonGroup> m_buttonGroup; //!< Data structure which the cluster will be displaying to the Viewport UI.
AZStd::unordered_map<ButtonId, QPointer<QAction>> m_buttonActionMap; //!< Map for buttons to their corresponding actions.
ViewportUiWidgetCallbacks m_widgetCallbacks; //!< Registers actions and manages updates.
AZStd::optional<ButtonId> m_lockedButtonId = AZStd::nullopt; //!< Used to track the last button locked.
};
} // namespace AzToolsFramework::ViewportUi::Internal

@ -100,6 +100,14 @@ namespace AzToolsFramework::ViewportUi::Internal
}
}
void ViewportUiDisplay::SetClusterButtonLocked(const ViewportUiElementId clusterId, const ButtonId buttonId, const bool isLocked)
{
if (auto viewportUiCluster = qobject_cast<ViewportUiCluster*>(GetViewportUiElement(clusterId).get()))
{
viewportUiCluster->SetButtonLocked(buttonId, isLocked);
}
}
void ViewportUiDisplay::RemoveClusterButton(ViewportUiElementId clusterId, ButtonId buttonId)
{
if (auto cluster = qobject_cast<ViewportUiCluster*>(GetViewportUiElement(clusterId).get()))

@ -58,6 +58,7 @@ namespace AzToolsFramework::ViewportUi::Internal
void AddCluster(AZStd::shared_ptr<ButtonGroup> buttonGroup, Alignment align);
void AddClusterButton(ViewportUiElementId clusterId, Button* button);
void SetClusterButtonLocked(ViewportUiElementId clusterId, ButtonId buttonId, bool isLocked);
void RemoveClusterButton(ViewportUiElementId clusterId, ButtonId buttonId);
void UpdateCluster(const ViewportUiElementId clusterId);

@ -67,6 +67,16 @@ namespace AzToolsFramework::ViewportUi
}
}
void ViewportUiManager::SetClusterButtonLocked(const ClusterId clusterId, const ButtonId buttonId, const bool isLocked)
{
if (auto clusterIt = m_clusterButtonGroups.find(clusterId); clusterIt != m_clusterButtonGroups.end())
{
auto cluster = clusterIt->second;
m_viewportUi->SetClusterButtonLocked(cluster->GetViewportUiElementId(), buttonId, isLocked);
UpdateButtonGroupUi(cluster.get());
}
}
void ViewportUiManager::RegisterClusterEventHandler(const ClusterId clusterId, AZ::Event<ButtonId>::Handler& handler)
{
if (auto clusterIt = m_clusterButtonGroups.find(clusterId); clusterIt != m_clusterButtonGroups.end())

@ -35,6 +35,7 @@ namespace AzToolsFramework::ViewportUi
const SwitcherId CreateSwitcher(Alignment align) override;
void SetClusterActiveButton(ClusterId clusterId, ButtonId buttonId) override;
void SetSwitcherActiveButton(SwitcherId switcherId, ButtonId buttonId) override;
void SetClusterButtonLocked(ClusterId clusterId, ButtonId buttonId, bool isLocked) override;
const ButtonId CreateClusterButton(ClusterId clusterId, const AZStd::string& icon) override;
const ButtonId CreateSwitcherButton(
SwitcherId switcherId, const AZStd::string& icon, const AZStd::string& name = AZStd::string()) override;

@ -65,6 +65,8 @@ namespace AzToolsFramework::ViewportUi
virtual void SetClusterActiveButton(ClusterId clusterId, ButtonId buttonId) = 0;
//! Sets the active button of the switcher. This is the button which has a text label.
virtual void SetSwitcherActiveButton(SwitcherId clusterId, ButtonId buttonId) = 0;
//! Adds a locked overlay to the cluster button's icon.
virtual void SetClusterButtonLocked(ClusterId clusterId, ButtonId buttonId, bool isLocked) = 0;
//! Registers a new button onto a cluster.
virtual const ButtonId CreateClusterButton(const ClusterId clusterId, const AZStd::string& icon) = 0;
//! Registers a new button onto a switcher.

@ -1,30 +1,31 @@
/*
* 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 "ComponentModeTestDoubles.h"
#include "ComponentModeTestFixture.h"
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzFramework/Components/TransformComponent.h>
#include <AzFramework/Entity/EntityContext.h>
#include <AzTest/AzTest.h>
#include <AzToolsFramework/Application/ToolsApplication.h>
#include <AzToolsFramework/API/EntityCompositionRequestBus.h>
#include <AzToolsFramework/Application/ToolsApplication.h>
#include <AzToolsFramework/ComponentMode/ComponentModeCollection.h>
#include <AzToolsFramework/ComponentMode/EditorComponentModeBus.h>
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
#include <AzToolsFramework/ToolsComponents/EditorLockComponent.h>
#include <AzToolsFramework/ToolsComponents/EditorVisibilityComponent.h>
#include <AzToolsFramework/ToolsComponents/EditorPendingCompositionBus.h>
#include <AzToolsFramework/ToolsComponents/EditorVisibilityComponent.h>
#include <AzToolsFramework/ToolsComponents/TransformComponent.h>
#include <AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx>
#include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
@ -32,7 +33,6 @@
#include <AzToolsFramework/ViewportSelection/EditorDefaultSelection.h>
#include <AzToolsFramework/ViewportSelection/EditorInteractionSystemViewportSelectionRequestBus.h>
#include <AzToolsFramework/ViewportSelection/EditorVisibleEntityDataCache.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <QApplication>
namespace UnitTest
@ -47,19 +47,16 @@ namespace UnitTest
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Given
QWidget rootWidget;
ActionOverrideRequestBus::Event(
GetEntityContextId(), &ActionOverrideRequests::SetupActionOverrideHandler, &rootWidget);
ActionOverrideRequestBus::Event(GetEntityContextId(), &ActionOverrideRequests::SetupActionOverrideHandler, &rootWidget);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// When
ComponentModeSystemRequestBus::Broadcast(
&ComponentModeSystemRequests::BeginComponentMode,
AZStd::vector<EntityAndComponentModeBuilders>{});
&ComponentModeSystemRequests::BeginComponentMode, AZStd::vector<EntityAndComponentModeBuilders>{});
bool inComponentMode = false;
ComponentModeSystemRequestBus::BroadcastResult(
inComponentMode, &ComponentModeSystemRequests::InComponentMode);
ComponentModeSystemRequestBus::BroadcastResult(inComponentMode, &ComponentModeSystemRequests::InComponentMode);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -69,11 +66,9 @@ namespace UnitTest
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// When
ComponentModeSystemRequestBus::Broadcast(
&ComponentModeSystemRequests::EndComponentMode);
ComponentModeSystemRequestBus::Broadcast(&ComponentModeSystemRequests::EndComponentMode);
ComponentModeSystemRequestBus::BroadcastResult(
inComponentMode, &ComponentModeSystemRequests::InComponentMode);
ComponentModeSystemRequestBus::BroadcastResult(inComponentMode, &ComponentModeSystemRequests::InComponentMode);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -81,8 +76,7 @@ namespace UnitTest
EXPECT_FALSE(inComponentMode);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
ActionOverrideRequestBus::Event(
GetEntityContextId(), &ActionOverrideRequests::TeardownActionOverrideHandler);
ActionOverrideRequestBus::Event(GetEntityContextId(), &ActionOverrideRequests::TeardownActionOverrideHandler);
}
TEST_F(ComponentModeTestFixture, TwoComponentsOnSingleEntityWithSameComponentModeBothBegin)
@ -104,8 +98,7 @@ namespace UnitTest
// mimic selecting the entity in the viewport (after selection the ComponentModeDelegate
// connects to the ComponentModeDelegateRequestBus on the entity/component pair address)
const AzToolsFramework::EntityIdList entityIds = { entityId };
ToolsApplicationRequestBus::Broadcast(
&ToolsApplicationRequests::SetSelectedEntities, entityIds);
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, entityIds);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -113,8 +106,7 @@ namespace UnitTest
// move all selected components into ComponentMode
// (mimic pressing the 'Edit' button to begin Component Mode)
ComponentModeSystemRequestBus::Broadcast(
&ComponentModeSystemRequests::AddSelectedComponentModesOfType,
AZ::AzTypeInfo<PlaceholderEditorComponent>::Uuid());
&ComponentModeSystemRequests::AddSelectedComponentModesOfType, AZ::AzTypeInfo<PlaceholderEditorComponent>::Uuid());
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -152,8 +144,7 @@ namespace UnitTest
// mimic selecting the entity in the viewport (after selection the ComponentModeDelegate
// connects to the ComponentModeDelegateRequestBus on the entity/component pair address)
const AzToolsFramework::EntityIdList entityIds = { entityId };
ToolsApplicationRequestBus::Broadcast(
&ToolsApplicationRequests::SetSelectedEntities, entityIds);
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, entityIds);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -161,8 +152,7 @@ namespace UnitTest
// move all selected components into ComponentMode
// (mimic pressing the 'Edit' button to begin Component Mode)
ComponentModeSystemRequestBus::Broadcast(
&ComponentModeSystemRequests::AddSelectedComponentModesOfType,
AZ::AzTypeInfo<PlaceholderEditorComponent>::Uuid());
&ComponentModeSystemRequests::AddSelectedComponentModesOfType, AZ::AzTypeInfo<PlaceholderEditorComponent>::Uuid());
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -202,8 +192,7 @@ namespace UnitTest
// mimic selecting the entity in the viewport (after selection the ComponentModeDelegate
// connects to the ComponentModeDelegateRequestBus on the entity/component pair address)
const AzToolsFramework::EntityIdList entityIds = { entityId };
ToolsApplicationRequestBus::Broadcast(
&ToolsApplicationRequests::SetSelectedEntities, entityIds);
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, entityIds);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -211,16 +200,13 @@ namespace UnitTest
// move all selected components into ComponentMode
// (mimic pressing the 'Edit' button to begin Component Mode)
ComponentModeSystemRequestBus::Broadcast(
&ComponentModeSystemRequests::AddSelectedComponentModesOfType,
AZ::AzTypeInfo<PlaceholderEditorComponent>::Uuid());
&ComponentModeSystemRequests::AddSelectedComponentModesOfType, AZ::AzTypeInfo<PlaceholderEditorComponent>::Uuid());
bool nextModeCycled = true;
ComponentModeSystemRequestBus::BroadcastResult(
nextModeCycled, &ComponentModeSystemRequests::SelectNextActiveComponentMode);
ComponentModeSystemRequestBus::BroadcastResult(nextModeCycled, &ComponentModeSystemRequests::SelectNextActiveComponentMode);
bool previousModeCycled = true;
ComponentModeSystemRequestBus::BroadcastResult(
previousModeCycled, &ComponentModeSystemRequests::SelectPreviousActiveComponentMode);
ComponentModeSystemRequestBus::BroadcastResult(previousModeCycled, &ComponentModeSystemRequests::SelectPreviousActiveComponentMode);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -250,8 +236,7 @@ namespace UnitTest
// mimic selecting the entity in the viewport (after selection the ComponentModeDelegate
// connects to the ComponentModeDelegateRequestBus on the entity/component pair address)
const AzToolsFramework::EntityIdList entityIds = { entityId };
ToolsApplicationRequestBus::Broadcast(
&ToolsApplicationRequests::SetSelectedEntities, entityIds);
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, entityIds);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -259,15 +244,13 @@ namespace UnitTest
// move all selected components into ComponentMode
// (mimic pressing the 'Edit' button to begin Component Mode)
ComponentModeSystemRequestBus::Broadcast(
&ComponentModeSystemRequests::AddSelectedComponentModesOfType,
AZ::AzTypeInfo<PlaceholderEditorComponent>::Uuid());
&ComponentModeSystemRequests::AddSelectedComponentModesOfType, AZ::AzTypeInfo<PlaceholderEditorComponent>::Uuid());
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Then
bool multipleComponentModeTypes = true;
ComponentModeSystemRequestBus::BroadcastResult(
multipleComponentModeTypes, &ComponentModeSystemRequests::HasMultipleComponentTypes);
ComponentModeSystemRequestBus::BroadcastResult(multipleComponentModeTypes, &ComponentModeSystemRequests::HasMultipleComponentTypes);
EXPECT_FALSE(multipleComponentModeTypes);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -294,8 +277,7 @@ namespace UnitTest
// mimic selecting the entity in the viewport (after selection the ComponentModeDelegate
// connects to the ComponentModeDelegateRequestBus on the entity/component pair address)
const AzToolsFramework::EntityIdList entityIds = { entityId };
ToolsApplicationRequestBus::Broadcast(
&ToolsApplicationRequests::SetSelectedEntities, entityIds);
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, entityIds);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -303,15 +285,13 @@ namespace UnitTest
// move all selected components into ComponentMode
// (mimic pressing the 'Edit' button to begin Component Mode)
ComponentModeSystemRequestBus::Broadcast(
&ComponentModeSystemRequests::AddSelectedComponentModesOfType,
AZ::AzTypeInfo<AnotherPlaceholderEditorComponent>::Uuid());
&ComponentModeSystemRequests::AddSelectedComponentModesOfType, AZ::AzTypeInfo<AnotherPlaceholderEditorComponent>::Uuid());
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Then
bool multipleComponentModeTypes = true;
ComponentModeSystemRequestBus::BroadcastResult(
multipleComponentModeTypes, &ComponentModeSystemRequests::HasMultipleComponentTypes);
ComponentModeSystemRequestBus::BroadcastResult(multipleComponentModeTypes, &ComponentModeSystemRequests::HasMultipleComponentTypes);
EXPECT_FALSE(multipleComponentModeTypes);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -341,8 +321,7 @@ namespace UnitTest
// mimic selecting the entity in the viewport (after selection the ComponentModeDelegate
// connects to the ComponentModeDelegateRequestBus on the entity/component pair address)
const AzToolsFramework::EntityIdList entityIds = { entityId };
ToolsApplicationRequestBus::Broadcast(
&ToolsApplicationRequests::SetSelectedEntities, entityIds);
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, entityIds);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -350,15 +329,13 @@ namespace UnitTest
// move all selected components into ComponentMode
// (mimic pressing the 'Edit' button to begin Component Mode)
ComponentModeSystemRequestBus::Broadcast(
&ComponentModeSystemRequests::AddSelectedComponentModesOfType,
AZ::AzTypeInfo<DependentPlaceholderEditorComponent>::Uuid());
&ComponentModeSystemRequests::AddSelectedComponentModesOfType, AZ::AzTypeInfo<DependentPlaceholderEditorComponent>::Uuid());
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Then
bool multipleComponentModeTypes = false;
ComponentModeSystemRequestBus::BroadcastResult(
multipleComponentModeTypes, &ComponentModeSystemRequests::HasMultipleComponentTypes);
ComponentModeSystemRequestBus::BroadcastResult(multipleComponentModeTypes, &ComponentModeSystemRequests::HasMultipleComponentTypes);
bool secondComponentModeInstantiated = false;
ComponentModeSystemRequestBus::BroadcastResult(
@ -366,8 +343,7 @@ namespace UnitTest
AZ::EntityComponentIdPair(entityId, placeholder2->GetId()));
AZ::Uuid activeComponentType = AZ::Uuid::CreateNull();
ComponentModeSystemRequestBus::BroadcastResult(
activeComponentType, &ComponentModeSystemRequests::ActiveComponentMode);
ComponentModeSystemRequestBus::BroadcastResult(activeComponentType, &ComponentModeSystemRequests::ActiveComponentMode);
EXPECT_TRUE(multipleComponentModeTypes);
EXPECT_TRUE(secondComponentModeInstantiated);
@ -412,13 +388,11 @@ namespace UnitTest
// Component Mode is will sent the notification to the correct address.
ComponentModeActionSignalRequestBus::Event(
AZ::EntityComponentIdPair(entityId, placeholder1->GetId()),
&ComponentModeActionSignalRequests::SetComponentModeActionNotificationBusToNotify,
checkerBusId);
&ComponentModeActionSignalRequests::SetComponentModeActionNotificationBusToNotify, checkerBusId);
ComponentModeActionSignalRequestBus::Event(
AZ::EntityComponentIdPair(entityId, placeholder2->GetId()),
&ComponentModeActionSignalRequests::SetComponentModeActionNotificationBusToNotify,
checkerBusId);
&ComponentModeActionSignalRequests::SetComponentModeActionNotificationBusToNotify, checkerBusId);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -470,8 +444,7 @@ namespace UnitTest
using MouseInteractionResult = AzToolsFramework::ViewportInteraction::MouseInteractionResult;
MouseInteractionResult handled = MouseInteractionResult::None;
EditorInteractionSystemViewportSelectionRequestBus::BroadcastResult(
handled, &EditorInteractionSystemViewportSelectionRequestBus::Events::InternalHandleAllMouseInteractions,
interactionEvent);
handled, &EditorInteractionSystemViewportSelectionRequestBus::Events::InternalHandleAllMouseInteractions, interactionEvent);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -482,8 +455,7 @@ namespace UnitTest
}
// Test version of EntityPropertyEditor to detect/ensure certain functions were called
class TestEntityPropertyEditor
: public AzToolsFramework::EntityPropertyEditor
class TestEntityPropertyEditor : public AzToolsFramework::EntityPropertyEditor
{
public:
void InvalidatePropertyDisplay(PropertyModificationRefreshLevel level) override;
@ -496,8 +468,7 @@ namespace UnitTest
}
// Simple fixture to encapsulate a TestEntityPropertyEditor
class ComponentModePinnedSelectionFixture
: public ToolsApplicationFixture
class ComponentModePinnedSelectionFixture : public ToolsApplicationFixture
{
public:
void SetUpEditorFixtureImpl() override
@ -533,7 +504,7 @@ namespace UnitTest
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// When
// select entity
const auto selectedEntities = AzToolsFramework::EntityIdList { entityId };
const auto selectedEntities = AzToolsFramework::EntityIdList{ entityId };
SelectEntities(selectedEntities);
// pin entity
@ -549,8 +520,7 @@ namespace UnitTest
EXPECT_TRUE(m_testEntityPropertyEditor->IsLockedToSpecificEntities());
EXPECT_TRUE(m_testEntityPropertyEditor->m_invalidatePropertyDisplayCalled);
bool couldBeginComponentMode =
AzToolsFramework::ComponentModeFramework::CouldBeginComponentModeWithEntity(entityId);
bool couldBeginComponentMode = AzToolsFramework::ComponentModeFramework::CouldBeginComponentModeWithEntity(entityId);
EXPECT_FALSE(couldBeginComponentMode);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -566,29 +536,26 @@ namespace UnitTest
entity->Deactivate();
AzToolsFramework::EntityCompositionRequestBus::Broadcast(
&AzToolsFramework::EntityCompositionRequestBus::Events::AddComponentsToEntities,
AzToolsFramework::EntityIdList{entityId},
&AzToolsFramework::EntityCompositionRequestBus::Events::AddComponentsToEntities, AzToolsFramework::EntityIdList{ entityId },
AZ::ComponentTypeList{ AZ::AzTypeInfo<AnotherPlaceholderEditorComponent>::Uuid() });
AzToolsFramework::EntityCompositionRequestBus::Broadcast(
&AzToolsFramework::EntityCompositionRequestBus::Events::AddComponentsToEntities,
AzToolsFramework::EntityIdList{entityId},
AZ::ComponentTypeList{AZ::AzTypeInfo<IncompatiblePlaceholderEditorComponent>::Uuid()});
&AzToolsFramework::EntityCompositionRequestBus::Events::AddComponentsToEntities, AzToolsFramework::EntityIdList{ entityId },
AZ::ComponentTypeList{ AZ::AzTypeInfo<IncompatiblePlaceholderEditorComponent>::Uuid() });
entity->Activate();
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// When
SelectEntities(AzToolsFramework::EntityIdList{entityId});
SelectEntities(AzToolsFramework::EntityIdList{ entityId });
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Then
AZ::Entity::ComponentArrayType pendingComponents;
AzToolsFramework::EditorPendingCompositionRequestBus::Event(
entityId, &AzToolsFramework::EditorPendingCompositionRequestBus::Events::GetPendingComponents,
pendingComponents);
entityId, &AzToolsFramework::EditorPendingCompositionRequestBus::Events::GetPendingComponents, pendingComponents);
// ensure we do have pending components
EXPECT_EQ(pendingComponents.size(), 1);

@ -281,6 +281,39 @@ namespace UnitTest
TestFGetCachedFileData(fileInArchiveFile, dataString.size(), dataString.data());
}
TEST_F(ArchiveTestFixture, TestArchiveOpenPacks_FindsMultiplePaks_Works)
{
AZ::IO::IArchive* archive = AZ::Interface<AZ::IO::IArchive>::Get();
ASSERT_NE(nullptr, archive);
AZ::IO::FileIOBase* fileIo = AZ::IO::FileIOBase::GetInstance();
ASSERT_NE(nullptr, fileIo);
auto resetArchiveFile = [archive, fileIo](const AZStd::string& filePath)
{
archive->ClosePack(filePath.c_str());
fileIo->Remove(filePath.c_str());
auto pArchive = archive->OpenArchive(filePath.c_str(), nullptr, AZ::IO::INestedArchive::FLAGS_CREATE_NEW);
EXPECT_NE(nullptr, pArchive);
pArchive.reset();
archive->ClosePack(filePath.c_str());
};
AZStd::string testArchivePath_pakOne = "@usercache@/one.pak";
AZStd::string testArchivePath_pakTwo = "@usercache@/two.pak";
// reset test files in case they already exist
resetArchiveFile(testArchivePath_pakOne);
resetArchiveFile(testArchivePath_pakTwo);
// open and fetch the opened pak file using a *.pak
AZStd::vector<AZ::IO::FixedMaxPathString> fullPaths;
archive->OpenPacks("@usercache@/*.pak", AZ::IO::IArchive::EPathResolutionRules::FLAGS_PATH_REAL, &fullPaths);
EXPECT_TRUE(AZStd::any_of(fullPaths.cbegin(), fullPaths.cend(), [](auto& path) { return path.ends_with("one.pak"); }));
EXPECT_TRUE(AZStd::any_of(fullPaths.cbegin(), fullPaths.cend(), [](auto& path) { return path.ends_with("two.pak"); }));
}
TEST_F(ArchiveTestFixture, TestArchiveFGetCachedFileData_LooseFile)
{
// ------setup loose file FGetCachedFileData tests -------------------------

@ -35,6 +35,7 @@
#include "EditorPreferencesPageViewportMovement.h"
#include "EditorPreferencesPageViewportDebug.h"
#include "EditorPreferencesPageExperimentalLighting.h"
#include "EditorPreferencesPageAWS.h"
#include "LyViewPaneNames.h"
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
@ -72,6 +73,7 @@ EditorPreferencesDialog::EditorPreferencesDialog(QWidget* pParent)
CEditorPreferencesPage_ViewportMovement::Reflect(*serializeContext);
CEditorPreferencesPage_ViewportDebug::Reflect(*serializeContext);
CEditorPreferencesPage_ExperimentalLighting::Reflect(*serializeContext);
CEditorPreferencesPage_AWS::Reflect(*serializeContext);
}
}

@ -0,0 +1,151 @@
/*
* 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 "EditorDefs.h"
#include "EditorPreferencesPageAWS.h"
// AzCore
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzCore/Jobs/JobFunction.h>
void CEditorPreferencesPage_AWS::Reflect(AZ::SerializeContext& serialize)
{
serialize.Class<UsageOptions>()
->Version(1)
->Field("AWSAttributionEnabled", &UsageOptions::m_awsAttributionEnabled);
serialize.Class<CEditorPreferencesPage_AWS>()
->Version(1)
->Field("UsageOptions", &CEditorPreferencesPage_AWS::m_usageOptions);
AZ::EditContext* editContext = serialize.GetEditContext();
if (editContext)
{
editContext->Class<UsageOptions>("Options", "")
->DataElement(AZ::Edit::UIHandlers::CheckBox, &UsageOptions::m_awsAttributionEnabled, "Send Metrics usage to AWS",
"Reports Gem usage to AWS on Editor launch");
editContext->Class<CEditorPreferencesPage_AWS>("AWS Preferences", "AWS Preferences")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Visibility, AZ_CRC("PropertyVisibility_ShowChildrenOnly", 0xef428f20))
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_AWS::m_usageOptions, "AWS Usage Data", "AWS Usage Options");
}
}
CEditorPreferencesPage_AWS::CEditorPreferencesPage_AWS()
{
m_settingsRegistry = AZStd::make_unique<AZ::SettingsRegistryImpl>();
InitializeSettings();
// TODO Update with AWS svg.
m_icon = QIcon(":/res/AWS_preferences_icon.svg");
}
CEditorPreferencesPage_AWS::~CEditorPreferencesPage_AWS()
{
m_settingsRegistry.reset();
}
const char* CEditorPreferencesPage_AWS::GetTitle()
{
return "AWS";
}
QIcon& CEditorPreferencesPage_AWS::GetIcon()
{
return m_icon;
}
void CEditorPreferencesPage_AWS::OnApply()
{
m_settingsRegistry->Set(AWSAttributionEnabledKey, m_usageOptions.m_awsAttributionEnabled);
SaveSettingsRegistryFile();
}
const CEditorPreferencesPage_AWS::UsageOptions& CEditorPreferencesPage_AWS::GetUsageOptions()
{
return m_usageOptions;
}
void CEditorPreferencesPage_AWS::SaveSettingsRegistryFile()
{
AZ::Job* job = AZ::CreateJobFunction(
[this]()
{
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
AZ_Assert(fileIO, "File IO is not initialized.");
// Resolve path to editor_aws_preferences.setreg
AZStd::string editorPreferencesFilePath =
AZStd::string::format("@user@/%s/%s", AZ::SettingsRegistryInterface::RegistryFolder, EditorAWSPreferencesFileName);
AZStd::array<char, AZ::IO::MaxPathLength> resolvedPath{};
fileIO->ResolvePath(editorPreferencesFilePath.c_str(), resolvedPath.data(), resolvedPath.size());
AZ::SettingsRegistryMergeUtils::DumperSettings dumperSettings;
dumperSettings.m_prettifyOutput = true;
dumperSettings.m_jsonPointerPrefix = AWSAttributionSettingsPrefixKey;
AZStd::string stringBuffer;
AZ::IO::ByteContainerStream stringStream(&stringBuffer);
if (!AZ::SettingsRegistryMergeUtils::DumpSettingsRegistryToStream(
*m_settingsRegistry, AWSAttributionSettingsPrefixKey, stringStream, dumperSettings))
{
AZ_Warning(
"AWSAttributionManager", false, R"(Unable to save changes to the Editor AWS Preferences registry file at "%s"\n)",
resolvedPath.data());
return;
}
bool saved{};
constexpr auto configurationMode =
AZ::IO::SystemFile::SF_OPEN_CREATE | AZ::IO::SystemFile::SF_OPEN_CREATE_PATH | AZ::IO::SystemFile::SF_OPEN_WRITE_ONLY;
if (AZ::IO::SystemFile outputFile; outputFile.Open(resolvedPath.data(), configurationMode))
{
saved = outputFile.Write(stringBuffer.data(), stringBuffer.size()) == stringBuffer.size();
}
AZ_Warning(
"AWSAttributionManager", saved, R"(Unable to save Editor AWS Preferences registry file to path "%s"\n)",
editorPreferencesFilePath.c_str());
},
true);
job->Start();
}
void CEditorPreferencesPage_AWS::InitializeSettings()
{
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
AZ_Assert(fileIO, "File IO is not initialized.");
// Resolve path to editor_aws_preferences.setreg
AZStd::string editorAWSPreferencesFilePath =
AZStd::string::format("@user@/%s/%s", AZ::SettingsRegistryInterface::RegistryFolder, EditorAWSPreferencesFileName);
AZStd::array<char, AZ::IO::MaxPathLength> resolvedPathAWSPreference{};
if (!fileIO->ResolvePath(editorAWSPreferencesFilePath.c_str(), resolvedPathAWSPreference.data(), resolvedPathAWSPreference.size()))
{
AZ_Warning("AWSAttributionManager", false, "Error resolving path %s", resolvedPathAWSPreference.data());
return;
}
if (fileIO->Exists(resolvedPathAWSPreference.data()))
{
m_settingsRegistry->MergeSettingsFile(resolvedPathAWSPreference.data(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, "");
}
if (!m_settingsRegistry->Get(m_usageOptions.m_awsAttributionEnabled, AWSAttributionEnabledKey))
{
// If key is missing default to on.
m_usageOptions.m_awsAttributionEnabled = true;
}
}

@ -0,0 +1,60 @@
/*
* 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 "Include/IPreferencesPage.h"
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Settings/SettingsRegistryImpl.h>
#include <AzCore/RTTI/RTTI.h>
#include <QIcon>
class CEditorPreferencesPage_AWS
: public IPreferencesPage
{
public:
AZ_RTTI(CEditorPreferencesPage_AWS, "{51FB9557-ABA3-4FD7-803A-1784F5B06F5F}", IPreferencesPage)
static void Reflect(AZ::SerializeContext& serialize);
CEditorPreferencesPage_AWS();
virtual ~CEditorPreferencesPage_AWS();
// IPreferencesPage interface methods.
virtual const char* GetCategory() override { return "AWS"; }
virtual const char* GetTitle() override;
virtual QIcon& GetIcon() override;
virtual void OnApply() override;
virtual void OnCancel() override {}
virtual bool OnQueryCancel() override { return true; }
protected:
struct UsageOptions
{
AZ_TYPE_INFO(UsageOptions, "{2B7D9B19-D13B-4E54-B724-B2FD8D0828B3}")
bool m_awsAttributionEnabled;
};
const UsageOptions& GetUsageOptions();
private:
void InitializeSettings();
void SaveSettingsRegistryFile();
UsageOptions m_usageOptions;
QIcon m_icon;
AZStd::unique_ptr<AZ::SettingsRegistryImpl> m_settingsRegistry;
static constexpr char AWSAttributionEnabledKey[] = "/Amazon/AWS/Preferences/AWSAttributionEnabled";
static constexpr char EditorPreferencesFileName[] = "editorpreferences.setreg";
static constexpr char EditorAWSPreferencesFileName[] = "editor_aws_preferences.setreg";
static constexpr char AWSAttributionSettingsPrefixKey[] = "/Amazon/AWS/Preferences";
};

@ -143,6 +143,7 @@
<file>res/Camera.svg</file>
<file>res/Debug.svg</file>
<file>res/Experimental.svg</file>
<file>res/AWS_preferences_icon.svg</file>
<file>res/Files.svg</file>
<file>res/Gizmos.svg</file>
<file>res/Global.svg</file>

@ -15,6 +15,8 @@
#include "PreferencesStdPages.h"
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
// Editor
#include "EditorPreferencesPageGeneral.h"
#include "EditorPreferencesPageFiles.h"
@ -23,6 +25,7 @@
#include "EditorPreferencesPageViewportMovement.h"
#include "EditorPreferencesPageViewportDebug.h"
#include "EditorPreferencesPageExperimentalLighting.h"
#include "EditorPreferencesPageAWS.h"
//////////////////////////////////////////////////////////////////////////
@ -42,6 +45,11 @@ CStdPreferencesClassDesc::CStdPreferencesClassDesc()
};
m_pageCreators.push_back([]() { return new CEditorPreferencesPage_ExperimentalLighting(); });
if (AzToolsFramework::IsComponentWithServiceRegistered(AZ_CRC_CE("AWSCoreEditorService")))
{
m_pageCreators.push_back([]() { return new CEditorPreferencesPage_AWS(); });
}
}
HRESULT CStdPreferencesClassDesc::QueryInterface(const IID& riid, void** ppvObj)

@ -586,6 +586,8 @@ set(FILES
EditorPreferencesPageViewportDebug.cpp
EditorPreferencesPageExperimentalLighting.h
EditorPreferencesPageExperimentalLighting.cpp
EditorPreferencesPageAWS.h
EditorPreferencesPageAWS.cpp
EditorPreferencesDialog.h
EditorPreferencesDialog.cpp
EditorPreferencesDialog.ui

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

Loading…
Cancel
Save