Atom Tools: Extracted the viewport input controller from ME to ATF
These viewport controls will be shared with material canvas and other tools that share a similar environment and viewport configurations. These classes are currently duplicated between the material editor and prototype projects. This change generalizes some things that are specific to the material editor and moves the system to a common location. Event buses were removed and replaced with a normal interface. Signed-off-by: Guthrie Adams <guthadam@amazon.com>
This commit is contained in:
@@ -1,166 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <Viewport/InputController/Behavior.h>
|
||||
#include <Viewport/InputController/MaterialEditorViewportInputController.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
Behavior::Behavior()
|
||||
{
|
||||
AZ::TickBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
Behavior::~Behavior()
|
||||
{
|
||||
AZ::TickBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void Behavior::Start()
|
||||
{
|
||||
m_x = 0;
|
||||
m_y = 0;
|
||||
m_z = 0;
|
||||
|
||||
MaterialEditorViewportInputControllerRequestBus::BroadcastResult(
|
||||
m_cameraEntityId,
|
||||
&MaterialEditorViewportInputControllerRequestBus::Handler::GetCameraEntityId);
|
||||
AZ_Assert(m_cameraEntityId.IsValid(), "Failed to find m_cameraEntityId");
|
||||
MaterialEditorViewportInputControllerRequestBus::BroadcastResult(
|
||||
m_distanceToTarget,
|
||||
&MaterialEditorViewportInputControllerRequestBus::Handler::GetDistanceToTarget);
|
||||
MaterialEditorViewportInputControllerRequestBus::BroadcastResult(
|
||||
m_targetPosition,
|
||||
&MaterialEditorViewportInputControllerRequestBus::Handler::GetTargetPosition);
|
||||
MaterialEditorViewportInputControllerRequestBus::BroadcastResult(
|
||||
m_radius, &MaterialEditorViewportInputControllerRequestBus::Handler::GetRadius);
|
||||
}
|
||||
|
||||
void Behavior::End()
|
||||
{
|
||||
}
|
||||
|
||||
void Behavior::MoveX(float value)
|
||||
{
|
||||
m_x += value * GetSensitivityX();
|
||||
}
|
||||
|
||||
void Behavior::MoveY(float value)
|
||||
{
|
||||
m_y += value * GetSensitivityY();
|
||||
}
|
||||
|
||||
void Behavior::MoveZ(float value)
|
||||
{
|
||||
m_z += value * GetSensitivityZ();
|
||||
}
|
||||
|
||||
bool Behavior::HasDelta() const
|
||||
{
|
||||
return
|
||||
AZ::GetAbs(m_x) > std::numeric_limits<float>::min() ||
|
||||
AZ::GetAbs(m_y) > std::numeric_limits<float>::min() ||
|
||||
AZ::GetAbs(m_z) > std::numeric_limits<float>::min();
|
||||
}
|
||||
|
||||
void Behavior::TickInternal([[maybe_unused]] float x, [[maybe_unused]] float y, float z)
|
||||
{
|
||||
m_distanceToTarget = m_distanceToTarget - z;
|
||||
|
||||
bool isCameraCentered = false;
|
||||
MaterialEditorViewportInputControllerRequestBus::BroadcastResult(
|
||||
isCameraCentered,
|
||||
&MaterialEditorViewportInputControllerRequestBus::Handler::IsCameraCentered);
|
||||
|
||||
// if camera is looking at the model (locked to the model) we don't want to zoom past the model's center
|
||||
if (isCameraCentered)
|
||||
{
|
||||
m_distanceToTarget = AZ::GetMax(m_distanceToTarget, 0.0f);
|
||||
}
|
||||
|
||||
AZ::Transform transform = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::EventResult(transform, m_cameraEntityId, &AZ::TransformBus::Events::GetLocalTM);
|
||||
AZ::Vector3 position = m_targetPosition -
|
||||
transform.GetRotation().TransformVector(AZ::Vector3::CreateAxisY(m_distanceToTarget));
|
||||
AZ::TransformBus::Event(m_cameraEntityId, &AZ::TransformBus::Events::SetLocalTranslation, position);
|
||||
|
||||
// if camera is not locked to the model, move its focal point so we can free look
|
||||
if (!isCameraCentered)
|
||||
{
|
||||
m_targetPosition += transform.GetRotation().TransformVector(AZ::Vector3::CreateAxisY(z));
|
||||
MaterialEditorViewportInputControllerRequestBus::Broadcast(
|
||||
&MaterialEditorViewportInputControllerRequestBus::Handler::SetTargetPosition,
|
||||
m_targetPosition);
|
||||
MaterialEditorViewportInputControllerRequestBus::BroadcastResult(
|
||||
m_distanceToTarget,
|
||||
&MaterialEditorViewportInputControllerRequestBus::Handler::GetDistanceToTarget);
|
||||
}
|
||||
}
|
||||
|
||||
float Behavior::GetSensitivityX()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
float Behavior::GetSensitivityY()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
float Behavior::GetSensitivityZ()
|
||||
{
|
||||
// adjust zooming sensitivity by model size, so that large models zoom at the same speed as smaller ones
|
||||
return 0.001f * AZ::GetMax(0.5f, m_radius);
|
||||
}
|
||||
|
||||
AZ::Quaternion Behavior::LookRotation(AZ::Vector3 forward)
|
||||
{
|
||||
forward.Normalize();
|
||||
AZ::Vector3 right = forward.CrossZAxis();
|
||||
right.Normalize();
|
||||
AZ::Vector3 up = right.Cross(forward);
|
||||
up.Normalize();
|
||||
AZ::Quaternion rotation = AZ::Quaternion::CreateFromBasis(right, forward, up);
|
||||
rotation.Normalize();
|
||||
return rotation;
|
||||
}
|
||||
|
||||
float Behavior::TakeStep(float& value, float t)
|
||||
{
|
||||
const float absValue = AZ::GetAbs(value);
|
||||
float step;
|
||||
if (absValue < SnapInterval)
|
||||
{
|
||||
step = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
step = AZ::Lerp(0, value, t);
|
||||
}
|
||||
value -= step;
|
||||
return step;
|
||||
}
|
||||
|
||||
void Behavior::OnTick(float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time)
|
||||
{
|
||||
// delta x and y values are accumulated in MoveX and MoveY functions (by dragging the mouse)
|
||||
// in the Tick function we then lerp them down to 0 over short time and apply delta transform to an entity
|
||||
if (HasDelta())
|
||||
{
|
||||
// t is a lerp amount based on time between frames (deltaTime)
|
||||
// GetMin restricts how much we can lerp in case of low fps (and very high deltaTime)
|
||||
const float t = AZ::GetMin(deltaTime / LerpTime, 0.5f);
|
||||
const float x = TakeStep(m_x, t);
|
||||
const float y = TakeStep(m_y, t);
|
||||
const float z = TakeStep(m_z, t);
|
||||
TickInternal(x, y, z);
|
||||
}
|
||||
}
|
||||
} // namespace MaterialEditor
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/Math/Quaternion.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
//! Performs a single type of action for MaterialEditorViewportInputController based on input
|
||||
//! See derived behaviors for specific details
|
||||
class Behavior
|
||||
: public AZ::TickBus::Handler
|
||||
{
|
||||
public:
|
||||
Behavior();
|
||||
virtual ~Behavior();
|
||||
|
||||
virtual void Start();
|
||||
virtual void End();
|
||||
virtual void MoveX(float value);
|
||||
virtual void MoveY(float value);
|
||||
virtual void MoveZ(float value);
|
||||
|
||||
protected:
|
||||
bool HasDelta() const;
|
||||
virtual void TickInternal(float x, float y, float z);
|
||||
virtual float GetSensitivityX();
|
||||
virtual float GetSensitivityY();
|
||||
virtual float GetSensitivityZ();
|
||||
|
||||
//! Calculate rotation quaternion towards a forward vector along world up axis
|
||||
static AZ::Quaternion LookRotation(AZ::Vector3 forward);
|
||||
//! Lerp a float value to 0 then decrement it by that interval and return it
|
||||
static float TakeStep(float& value, float t);
|
||||
|
||||
//! Time in seconds to approximately complete a transformation
|
||||
static constexpr float LerpTime = 0.05f;
|
||||
//! If delta transform less than this, snap instantly
|
||||
static constexpr float SnapInterval = 0.01f;
|
||||
//! delta x movement accumulated during current frame
|
||||
float m_x = 0;
|
||||
//! delta y movement accumulated during current frame
|
||||
float m_y = 0;
|
||||
//! delta scroll wheel accumulated during current frame
|
||||
float m_z = 0;
|
||||
//! Model radius
|
||||
float m_radius = 1.0f;
|
||||
|
||||
AZ::EntityId m_cameraEntityId;
|
||||
AZ::Vector3 m_targetPosition = AZ::Vector3::CreateZero();
|
||||
float m_distanceToTarget = 0;
|
||||
|
||||
private:
|
||||
// AZ::TickBus::Handler interface overrides...
|
||||
void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
|
||||
};
|
||||
} // namespace MaterialEditor
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <Viewport/InputController/DollyCameraBehavior.h>
|
||||
#include <Viewport/InputController/MaterialEditorViewportInputController.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
void DollyCameraBehavior::TickInternal([[maybe_unused]] float x, float y, [[maybe_unused]] float z)
|
||||
{
|
||||
m_distanceToTarget = m_distanceToTarget + y;
|
||||
AZ::Transform transform = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::EventResult(transform, m_cameraEntityId, &AZ::TransformBus::Events::GetLocalTM);
|
||||
AZ::Vector3 position = m_targetPosition -
|
||||
transform.GetRotation().TransformVector(AZ::Vector3::CreateAxisY(m_distanceToTarget));
|
||||
AZ::TransformBus::Event(m_cameraEntityId, &AZ::TransformBus::Events::SetLocalTranslation, position);
|
||||
}
|
||||
|
||||
float DollyCameraBehavior::GetSensitivityX()
|
||||
{
|
||||
return SensitivityX;
|
||||
}
|
||||
|
||||
float DollyCameraBehavior::GetSensitivityY()
|
||||
{
|
||||
return SensitivityY;
|
||||
}
|
||||
} // namespace MaterialEditor
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Viewport/InputController/Behavior.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
//! Moves(zooms) camera back and forth towards the target
|
||||
class DollyCameraBehavior final
|
||||
: public Behavior
|
||||
{
|
||||
public:
|
||||
DollyCameraBehavior() = default;
|
||||
virtual ~DollyCameraBehavior() = default;
|
||||
protected:
|
||||
void TickInternal(float x, float y, float z) override;
|
||||
float GetSensitivityX() override;
|
||||
float GetSensitivityY() override;
|
||||
|
||||
private:
|
||||
static constexpr float SensitivityX = 0;
|
||||
static constexpr float SensitivityY = 0.005f;
|
||||
};
|
||||
} // namespace MaterialEditor
|
||||
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Viewport/InputController/IdleBehavior.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
} // namespace MaterialEditor
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Viewport/InputController/Behavior.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
//! No action taken
|
||||
class IdleBehavior final
|
||||
: public Behavior
|
||||
{
|
||||
public:
|
||||
IdleBehavior() = default;
|
||||
virtual ~IdleBehavior() = default;
|
||||
};
|
||||
} // namespace MaterialEditor
|
||||
-352
@@ -1,352 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QApplication>
|
||||
#include <QWidget>
|
||||
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Math/Matrix4x4.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
#include <AzFramework/Components/CameraBus.h>
|
||||
#include <AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h>
|
||||
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
|
||||
#include <AzFramework/Viewport/ScreenGeometry.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
|
||||
#include <Atom/Feature/SkyBox/SkyBoxFeatureProcessorInterface.h>
|
||||
#include <Atom/RPI.Public/RPISystemInterface.h>
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
#include <Atom/RPI.Reflect/Model/ModelAsset.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Mesh/MeshComponentBus.h>
|
||||
|
||||
#include <Viewport/InputController/DollyCameraBehavior.h>
|
||||
#include <Viewport/InputController/IdleBehavior.h>
|
||||
#include <Viewport/InputController/MaterialEditorViewportInputController.h>
|
||||
#include <Viewport/InputController/MoveCameraBehavior.h>
|
||||
#include <Viewport/InputController/OrbitCameraBehavior.h>
|
||||
#include <Viewport/InputController/PanCameraBehavior.h>
|
||||
#include <Viewport/InputController/RotateEnvironmentBehavior.h>
|
||||
#include <Viewport/InputController/RotateModelBehavior.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
MaterialEditorViewportInputController::MaterialEditorViewportInputController()
|
||||
: AzFramework::SingleViewportController()
|
||||
, m_targetPosition(AZ::Vector3::CreateZero())
|
||||
{
|
||||
m_behaviorMap[None] = AZStd::make_shared<IdleBehavior>();
|
||||
m_behaviorMap[Lmb] = AZStd::make_shared<PanCameraBehavior>();
|
||||
m_behaviorMap[Mmb] = AZStd::make_shared<MoveCameraBehavior>();
|
||||
m_behaviorMap[Rmb] = AZStd::make_shared<OrbitCameraBehavior>();
|
||||
m_behaviorMap[Alt ^ Lmb] = AZStd::make_shared<OrbitCameraBehavior>();
|
||||
m_behaviorMap[Alt ^ Mmb] = AZStd::make_shared<MoveCameraBehavior>();
|
||||
m_behaviorMap[Alt ^ Rmb] = AZStd::make_shared<DollyCameraBehavior>();
|
||||
m_behaviorMap[Lmb ^ Rmb] = AZStd::make_shared<DollyCameraBehavior>();
|
||||
m_behaviorMap[Ctrl ^ Lmb] = AZStd::make_shared<RotateModelBehavior>();
|
||||
m_behaviorMap[Shift ^ Lmb] = AZStd::make_shared<RotateEnvironmentBehavior>();
|
||||
}
|
||||
|
||||
MaterialEditorViewportInputController::~MaterialEditorViewportInputController()
|
||||
{
|
||||
if (m_initialized)
|
||||
{
|
||||
MaterialEditorViewportInputControllerRequestBus::Handler::BusDisconnect();
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialEditorViewportInputController::Init(const AZ::EntityId& cameraEntityId, const AZ::EntityId& targetEntityId, const AZ::EntityId& iblEntityId)
|
||||
{
|
||||
if (m_initialized)
|
||||
{
|
||||
AZ_Error("MaterialEditorViewportInputController", false, "Controller already initialized.");
|
||||
return;
|
||||
}
|
||||
m_initialized = true;
|
||||
m_cameraEntityId = cameraEntityId;
|
||||
m_targetEntityId = targetEntityId;
|
||||
m_iblEntityId = iblEntityId;
|
||||
|
||||
MaterialEditorViewportInputControllerRequestBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
const AZ::EntityId& MaterialEditorViewportInputController::GetCameraEntityId() const
|
||||
{
|
||||
return m_cameraEntityId;
|
||||
}
|
||||
|
||||
const AZ::EntityId& MaterialEditorViewportInputController::GetTargetEntityId() const
|
||||
{
|
||||
return m_targetEntityId;
|
||||
}
|
||||
|
||||
const AZ::EntityId& MaterialEditorViewportInputController::GetIblEntityId() const
|
||||
{
|
||||
return m_iblEntityId;
|
||||
}
|
||||
|
||||
const AZ::Vector3& MaterialEditorViewportInputController::GetTargetPosition() const
|
||||
{
|
||||
return m_targetPosition;
|
||||
}
|
||||
|
||||
void MaterialEditorViewportInputController::SetTargetPosition(const AZ::Vector3& targetPosition)
|
||||
{
|
||||
m_targetPosition = targetPosition;
|
||||
m_isCameraCentered = false;
|
||||
}
|
||||
|
||||
float MaterialEditorViewportInputController::GetDistanceToTarget() const
|
||||
{
|
||||
AZ::Vector3 cameraPosition;
|
||||
AZ::TransformBus::EventResult(cameraPosition, m_cameraEntityId, &AZ::TransformBus::Events::GetLocalTranslation);
|
||||
return cameraPosition.GetDistance(m_targetPosition);
|
||||
}
|
||||
|
||||
void MaterialEditorViewportInputController::GetExtents(float& distanceMin, float& distanceMax) const
|
||||
{
|
||||
distanceMin = m_distanceMin;
|
||||
distanceMax = m_distanceMax;
|
||||
}
|
||||
|
||||
float MaterialEditorViewportInputController::GetRadius() const
|
||||
{
|
||||
return m_radius;
|
||||
}
|
||||
|
||||
void MaterialEditorViewportInputController::UpdateViewport(const AzFramework::ViewportControllerUpdateEvent& event)
|
||||
{
|
||||
if (m_keysChanged)
|
||||
{
|
||||
if (m_timeToBehaviorSwitchMs > 0)
|
||||
{
|
||||
m_timeToBehaviorSwitchMs -= event.m_deltaTime.count();
|
||||
}
|
||||
if (m_timeToBehaviorSwitchMs <= 0)
|
||||
{
|
||||
EvaluateControlBehavior();
|
||||
m_keysChanged = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool MaterialEditorViewportInputController::HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
|
||||
const InputChannelId& inputChannelId = event.m_inputChannel.GetInputChannelId();
|
||||
const InputChannel::State state = event.m_inputChannel.GetState();
|
||||
const KeyMask keysOld = m_keys;
|
||||
|
||||
bool mouseOver = false;
|
||||
AzToolsFramework::ViewportInteraction::ViewportMouseCursorRequestBus::EventResult(
|
||||
mouseOver, GetViewportId(),
|
||||
&AzToolsFramework::ViewportInteraction::ViewportMouseCursorRequestBus::Events::IsMouseOver);
|
||||
|
||||
if (!m_behavior)
|
||||
{
|
||||
EvaluateControlBehavior();
|
||||
}
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case InputChannel::State::Began:
|
||||
if (inputChannelId == InputDeviceMouse::Button::Left)
|
||||
{
|
||||
m_keys |= Lmb;
|
||||
}
|
||||
else if (inputChannelId == InputDeviceMouse::Button::Middle)
|
||||
{
|
||||
m_keys |= Mmb;
|
||||
}
|
||||
else if (inputChannelId == InputDeviceMouse::Button::Right)
|
||||
{
|
||||
m_keys |= Rmb;
|
||||
}
|
||||
else if (inputChannelId == InputDeviceKeyboard::Key::ModifierAltL)
|
||||
{
|
||||
m_keys |= Alt;
|
||||
}
|
||||
else if (inputChannelId == InputDeviceKeyboard::Key::ModifierCtrlL)
|
||||
{
|
||||
m_keys |= Ctrl;
|
||||
}
|
||||
else if (inputChannelId == InputDeviceKeyboard::Key::ModifierShiftL)
|
||||
{
|
||||
m_keys |= Shift;
|
||||
}
|
||||
if (inputChannelId == InputDeviceMouse::Movement::X)
|
||||
{
|
||||
m_behavior->MoveX(event.m_inputChannel.GetValue());
|
||||
}
|
||||
else if (inputChannelId == InputDeviceMouse::Movement::Y)
|
||||
{
|
||||
m_behavior->MoveY(event.m_inputChannel.GetValue());
|
||||
}
|
||||
else if (inputChannelId == InputDeviceMouse::Movement::Z)
|
||||
{
|
||||
if (mouseOver)
|
||||
{
|
||||
m_behavior->MoveZ(event.m_inputChannel.GetValue());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case InputChannel::State::Ended:
|
||||
if (inputChannelId == InputDeviceMouse::Button::Left)
|
||||
{
|
||||
m_keys &= ~Lmb;
|
||||
}
|
||||
else if (inputChannelId == InputDeviceMouse::Button::Middle)
|
||||
{
|
||||
m_keys &= ~Mmb;
|
||||
}
|
||||
else if (inputChannelId == InputDeviceMouse::Button::Right)
|
||||
{
|
||||
m_keys &= ~Rmb;
|
||||
}
|
||||
else if (inputChannelId == InputDeviceKeyboard::Key::ModifierAltL)
|
||||
{
|
||||
m_keys &= ~Alt;
|
||||
}
|
||||
else if (inputChannelId == InputDeviceKeyboard::Key::ModifierCtrlL)
|
||||
{
|
||||
m_keys &= ~Ctrl;
|
||||
}
|
||||
else if (inputChannelId == InputDeviceKeyboard::Key::ModifierShiftL)
|
||||
{
|
||||
m_keys &= ~Shift;
|
||||
}
|
||||
else if (inputChannelId == InputDeviceKeyboard::Key::AlphanumericZ && (m_keys & Ctrl) == None)
|
||||
{
|
||||
// only reset camera if no other widget besides viewport is in focus
|
||||
const auto focus = QApplication::focusWidget();
|
||||
if (!focus || focus->objectName() == "Viewport")
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case InputChannel::State::Updated:
|
||||
if (inputChannelId == InputDeviceMouse::Movement::X)
|
||||
{
|
||||
m_behavior->MoveX(event.m_inputChannel.GetValue());
|
||||
}
|
||||
else if (inputChannelId == InputDeviceMouse::Movement::Y)
|
||||
{
|
||||
m_behavior->MoveY(event.m_inputChannel.GetValue());
|
||||
}
|
||||
else if (inputChannelId == InputDeviceMouse::Movement::Z)
|
||||
{
|
||||
if (mouseOver)
|
||||
{
|
||||
m_behavior->MoveZ(event.m_inputChannel.GetValue());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (keysOld != m_keys)
|
||||
{
|
||||
m_keysChanged = true;
|
||||
m_timeToBehaviorSwitchMs = BehaviorSwitchDelayMs;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MaterialEditorViewportInputController::Reset()
|
||||
{
|
||||
CalculateExtents();
|
||||
|
||||
// reset camera
|
||||
m_targetPosition = m_modelCenter;
|
||||
const float distance = m_distanceMin * StartingDistanceMultiplier;
|
||||
const AZ::Quaternion cameraRotation = AZ::Quaternion::CreateFromAxisAngle(AZ::Vector3::CreateAxisZ(), StartingRotationAngle);
|
||||
AZ::Vector3 cameraPosition(m_targetPosition.GetX(), m_targetPosition.GetY() - distance, m_targetPosition.GetZ());
|
||||
cameraPosition = cameraRotation.TransformVector(cameraPosition);
|
||||
AZ::Transform cameraTransform = AZ::Transform::CreateFromQuaternionAndTranslation(cameraRotation, cameraPosition);
|
||||
AZ::TransformBus::Event(m_cameraEntityId, &AZ::TransformBus::Events::SetLocalTM, cameraTransform);
|
||||
m_isCameraCentered = true;
|
||||
|
||||
// reset model
|
||||
AZ::Transform modelTransform = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::Event(m_targetEntityId, &AZ::TransformBus::Events::SetLocalTM, modelTransform);
|
||||
|
||||
// reset environment
|
||||
AZ::Transform iblTransform = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::Event(m_iblEntityId, &AZ::TransformBus::Events::SetLocalTM, iblTransform);
|
||||
|
||||
const AZ::Matrix4x4 rotationMatrix = AZ::Matrix4x4::CreateIdentity();
|
||||
auto skyBoxFeatureProcessorInterface = AZ::RPI::Scene::GetFeatureProcessorForEntity<AZ::Render::SkyBoxFeatureProcessorInterface>(m_iblEntityId);
|
||||
skyBoxFeatureProcessorInterface->SetCubemapRotationMatrix(rotationMatrix);
|
||||
|
||||
if (m_behavior)
|
||||
{
|
||||
m_behavior->End();
|
||||
m_behavior->Start();
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialEditorViewportInputController::SetFieldOfView(float value)
|
||||
{
|
||||
Camera::CameraRequestBus::Event(m_cameraEntityId, &Camera::CameraRequestBus::Events::SetFovDegrees, value);
|
||||
}
|
||||
|
||||
bool MaterialEditorViewportInputController::IsCameraCentered() const
|
||||
{
|
||||
return m_isCameraCentered;
|
||||
}
|
||||
|
||||
void MaterialEditorViewportInputController::CalculateExtents()
|
||||
{
|
||||
AZ::TransformBus::EventResult(m_modelCenter, m_targetEntityId, &AZ::TransformBus::Events::GetLocalTranslation);
|
||||
|
||||
AZ::Data::AssetId modelAssetId;
|
||||
AZ::Render::MeshComponentRequestBus::EventResult(modelAssetId, m_targetEntityId,
|
||||
&AZ::Render::MeshComponentRequestBus::Events::GetModelAssetId);
|
||||
|
||||
if (modelAssetId.IsValid())
|
||||
{
|
||||
AZ::Data::Asset<AZ::RPI::ModelAsset> modelAsset = AZ::Data::AssetManager::Instance().GetAsset(modelAssetId, azrtti_typeid<AZ::RPI::ModelAsset>(), AZ::Data::AssetLoadBehavior::PreLoad);
|
||||
modelAsset.BlockUntilLoadComplete();
|
||||
if (modelAsset.IsReady())
|
||||
{
|
||||
const AZ::Aabb& aabb = modelAsset->GetAabb();
|
||||
aabb.GetAsSphere(m_modelCenter, m_radius);
|
||||
|
||||
m_distanceMin = 0.5f * AZ::GetMin(AZ::GetMin(aabb.GetExtents().GetX(), aabb.GetExtents().GetY()), aabb.GetExtents().GetZ()) + DepthNear;
|
||||
m_distanceMax = m_radius * MaxDistanceMultiplier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialEditorViewportInputController::EvaluateControlBehavior()
|
||||
{
|
||||
AZStd::shared_ptr<Behavior> nextBehavior;
|
||||
auto it = m_behaviorMap.find(m_keys);
|
||||
if (it == m_behaviorMap.end())
|
||||
{
|
||||
nextBehavior = m_behaviorMap[None];
|
||||
}
|
||||
else
|
||||
{
|
||||
nextBehavior = it->second;
|
||||
}
|
||||
|
||||
if (nextBehavior == m_behavior)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_behavior)
|
||||
{
|
||||
m_behavior->End();
|
||||
}
|
||||
m_behavior = nextBehavior;
|
||||
m_behavior->Start();
|
||||
}
|
||||
} // namespace MaterialEditor
|
||||
-109
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzFramework/Input/Events/InputChannelEventListener.h>
|
||||
#include <AzFramework/Viewport/SingleViewportController.h>
|
||||
#include <Viewport/InputController/Behavior.h>
|
||||
#include <Viewport/InputController/MaterialEditorViewportInputControllerBus.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
class Behavior;
|
||||
|
||||
//! Provides controls for manipulating camera, model, and environment in Material Editor
|
||||
class MaterialEditorViewportInputController
|
||||
: public AzFramework::SingleViewportController
|
||||
, public MaterialEditorViewportInputControllerRequestBus::Handler
|
||||
{
|
||||
public:
|
||||
|
||||
AZ_TYPE_INFO(MaterialEditorViewportInputController, "{569A0544-7654-4DCE-8156-00A71B408374}");
|
||||
AZ_CLASS_ALLOCATOR(MaterialEditorViewportInputController, AZ::SystemAllocator, 0)
|
||||
|
||||
MaterialEditorViewportInputController();
|
||||
virtual ~MaterialEditorViewportInputController();
|
||||
|
||||
void Init(const AZ::EntityId& cameraEntityId, const AZ::EntityId& targetEntityId, const AZ::EntityId& iblEntityId);
|
||||
|
||||
// MaterialEditorViewportInputControllerRequestBus::Handler interface overrides...
|
||||
const AZ::EntityId& GetCameraEntityId() const override;
|
||||
const AZ::EntityId& GetTargetEntityId() const override;
|
||||
const AZ::EntityId& GetIblEntityId() const override;
|
||||
const AZ::Vector3& GetTargetPosition() const override;
|
||||
void SetTargetPosition(const AZ::Vector3& targetPosition) override;
|
||||
float GetDistanceToTarget() const override;
|
||||
void GetExtents(float& distanceMin, float& distanceMax) const override;
|
||||
float GetRadius() const override;
|
||||
void Reset() override;
|
||||
void SetFieldOfView(float value) override;
|
||||
bool IsCameraCentered() const override;
|
||||
|
||||
// AzFramework::ViewportControllerInstance interface overrides...
|
||||
bool HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event) override;
|
||||
void UpdateViewport(const AzFramework::ViewportControllerUpdateEvent& event) override;
|
||||
|
||||
private:
|
||||
using KeyMask = uint32_t;
|
||||
|
||||
enum Keys
|
||||
{
|
||||
None = 0,
|
||||
Lmb = 1 << 0,
|
||||
Mmb = 1 << 1,
|
||||
Rmb = 1 << 2,
|
||||
Alt = 1 << 3,
|
||||
Ctrl = 1 << 4,
|
||||
Shift = 1 << 5
|
||||
};
|
||||
|
||||
//! Calculate min and max dist and center based on mesh size of target model
|
||||
void CalculateExtents();
|
||||
//! Determine which behavior to set based on mouse/keyboard input
|
||||
void EvaluateControlBehavior();
|
||||
|
||||
bool m_initialized = false;
|
||||
|
||||
//! Input keys currently pressed
|
||||
KeyMask m_keys = None;
|
||||
//! Input key sequence changed
|
||||
bool m_keysChanged = false;
|
||||
//! Time remaining before behavior switch
|
||||
float m_timeToBehaviorSwitchMs = 0;
|
||||
|
||||
//! Current behavior of the controller
|
||||
AZStd::shared_ptr<Behavior> m_behavior;
|
||||
AZStd::unordered_map<KeyMask, AZStd::shared_ptr<Behavior>> m_behaviorMap;
|
||||
|
||||
AZ::EntityId m_cameraEntityId;
|
||||
//! Target entity is looking at
|
||||
AZ::EntityId m_targetEntityId;
|
||||
//! IBL entity for rotating environment lighting
|
||||
AZ::EntityId m_iblEntityId;
|
||||
//! Target position camera is pointed towards
|
||||
AZ::Vector3 m_targetPosition;
|
||||
//! Center of the model observed
|
||||
AZ::Vector3 m_modelCenter;
|
||||
//! Minimum distance from camera to target
|
||||
float m_distanceMin = 1.0f;
|
||||
//! Maximum distance from camera to target
|
||||
float m_distanceMax = 10.0f;
|
||||
//! Model radius
|
||||
float m_radius = 1.0f;
|
||||
//! True if camera is centered on a model
|
||||
bool m_isCameraCentered = true;
|
||||
|
||||
static constexpr float MaxDistanceMultiplier = 2.5f;
|
||||
static constexpr float StartingDistanceMultiplier = 2.0f;
|
||||
static constexpr float StartingRotationAngle = AZ::Constants::QuarterPi / 2.0f;
|
||||
static constexpr float DepthNear = 0.01f;
|
||||
//! Artificial delay between behavior switching to avoid switching into undesired behaviors with smaller key sequences
|
||||
//! e.g. pressing RMB+LMB shouldn't switch into RMB behavior (or LMB behavior) first because it's virtually impossible to press both mouse buttons on the same frame
|
||||
static constexpr float BehaviorSwitchDelayMs = 0.1f;
|
||||
};
|
||||
} // namespace MaterialEditor
|
||||
-61
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
class MaterialEditorViewportInputControllerRequests
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
|
||||
|
||||
//! Get entityId of viewport camera
|
||||
virtual const AZ::EntityId& GetCameraEntityId() const = 0;
|
||||
|
||||
//! Get entityId of camera target
|
||||
virtual const AZ::EntityId& GetTargetEntityId() const = 0;
|
||||
|
||||
//! Get entityId of scene's IBL entity
|
||||
virtual const AZ::EntityId& GetIblEntityId() const = 0;
|
||||
|
||||
//! Get actual position where the camera is facing
|
||||
virtual const AZ::Vector3& GetTargetPosition() const = 0;
|
||||
|
||||
//! Set camera target position
|
||||
//! @param targetPosition world space position to point camera at
|
||||
virtual void SetTargetPosition(const AZ::Vector3& targetPosition) = 0;
|
||||
|
||||
//! Get distance between camera and its target
|
||||
virtual float GetDistanceToTarget() const = 0;
|
||||
|
||||
//! Get minimum and maximum camera distance to the model based on mesh size
|
||||
//! @param distanceMin closest camera can be to the target
|
||||
//! @param distanceMax furthest camera can be from the target
|
||||
virtual void GetExtents(float& distanceMin, float& distanceMax) const = 0;
|
||||
|
||||
//! Get bounding sphere radius of the active model
|
||||
virtual float GetRadius() const = 0;
|
||||
|
||||
//! Reset camera to default position and rotation
|
||||
virtual void Reset() = 0;
|
||||
|
||||
//! Modify camera's field of view
|
||||
//! @param value field of view in degrees
|
||||
virtual void SetFieldOfView(float value) = 0;
|
||||
|
||||
//! Check if camera is looking directly at a model
|
||||
virtual bool IsCameraCentered() const = 0;
|
||||
};
|
||||
|
||||
using MaterialEditorViewportInputControllerRequestBus = AZ::EBus<MaterialEditorViewportInputControllerRequests>;
|
||||
} // namespace MaterialEditor
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <Viewport/InputController/MaterialEditorViewportInputControllerBus.h>
|
||||
#include <Viewport/InputController/MoveCameraBehavior.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
void MoveCameraBehavior::End()
|
||||
{
|
||||
float distanceToTarget;
|
||||
MaterialEditorViewportInputControllerRequestBus::BroadcastResult(
|
||||
distanceToTarget,
|
||||
&MaterialEditorViewportInputControllerRequestBus::Handler::GetDistanceToTarget);
|
||||
AZ::Transform transform = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::EventResult(transform, m_cameraEntityId, &AZ::TransformBus::Events::GetLocalTM);
|
||||
AZ::Vector3 targetPosition =
|
||||
transform.GetTranslation() +
|
||||
transform.GetBasisY() * distanceToTarget;
|
||||
MaterialEditorViewportInputControllerRequestBus::Broadcast(
|
||||
&MaterialEditorViewportInputControllerRequestBus::Handler::SetTargetPosition,
|
||||
targetPosition);
|
||||
}
|
||||
|
||||
void MoveCameraBehavior::TickInternal(float x, float y, float z)
|
||||
{
|
||||
AZ::Transform transform = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::EventResult(transform, m_cameraEntityId, &AZ::TransformBus::Events::GetLocalTM);
|
||||
AZ::Vector3 up = transform.GetBasisZ();
|
||||
AZ::Vector3 right = transform.GetBasisX();
|
||||
AZ::Vector3 position = transform.GetTranslation();
|
||||
AZ::Vector3 deltaPosition = up * y + right * -x;
|
||||
position += deltaPosition;
|
||||
m_targetPosition += deltaPosition;
|
||||
AZ::TransformBus::Event(m_cameraEntityId, &AZ::TransformBus::Events::SetLocalTranslation, position);
|
||||
|
||||
Behavior::TickInternal(x, y, z);
|
||||
}
|
||||
|
||||
float MoveCameraBehavior::GetSensitivityX()
|
||||
{
|
||||
return SensitivityX;
|
||||
}
|
||||
|
||||
float MoveCameraBehavior::GetSensitivityY()
|
||||
{
|
||||
return SensitivityY;
|
||||
}
|
||||
} // namespace MaterialEditor
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Viewport/InputController/Behavior.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
//! Moves camera along its vertical and horizontal axis
|
||||
class MoveCameraBehavior final
|
||||
: public Behavior
|
||||
{
|
||||
public:
|
||||
MoveCameraBehavior() = default;
|
||||
virtual ~MoveCameraBehavior() = default;
|
||||
void End() override;
|
||||
|
||||
protected:
|
||||
void TickInternal(float x, float y, float z) override;
|
||||
float GetSensitivityX() override;
|
||||
float GetSensitivityY() override;
|
||||
|
||||
private:
|
||||
static constexpr float SensitivityX = 0.01f;
|
||||
static constexpr float SensitivityY = 0.01f;
|
||||
};
|
||||
} // namespace MaterialEditor
|
||||
-59
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <Viewport/InputController/MaterialEditorViewportInputController.h>
|
||||
#include <Viewport/InputController/OrbitCameraBehavior.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
void OrbitCameraBehavior::TickInternal(float x, float y, float z)
|
||||
{
|
||||
Behavior::TickInternal(x, y, z);
|
||||
|
||||
// don't align camera until a movement has been made so that accidental right-click doesn't reset camera
|
||||
if (!m_aligned)
|
||||
{
|
||||
Align();
|
||||
}
|
||||
|
||||
AZ::Transform transform = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::EventResult(transform, m_cameraEntityId, &AZ::TransformBus::Events::GetLocalTM);
|
||||
AZ::Quaternion rotation = transform.GetRotation();
|
||||
AZ::Vector3 right = transform.GetBasisX();
|
||||
rotation =
|
||||
AZ::Quaternion::CreateFromAxisAngle(AZ::Vector3::CreateAxisZ(), -x) *
|
||||
AZ::Quaternion::CreateFromAxisAngle(right, -y) *
|
||||
rotation;
|
||||
rotation.Normalize();
|
||||
AZ::Vector3 position =
|
||||
rotation.TransformVector(AZ::Vector3(0, -m_distanceToTarget, 0)) + m_targetPosition;
|
||||
transform = AZ::Transform::CreateFromQuaternionAndTranslation(rotation, position);
|
||||
AZ::TransformBus::Event(m_cameraEntityId, &AZ::TransformBus::Events::SetLocalTM, transform);
|
||||
}
|
||||
|
||||
float OrbitCameraBehavior::GetSensitivityX()
|
||||
{
|
||||
return SensitivityX;
|
||||
}
|
||||
|
||||
float OrbitCameraBehavior::GetSensitivityY()
|
||||
{
|
||||
return SensitivityY;
|
||||
}
|
||||
|
||||
void OrbitCameraBehavior::Align()
|
||||
{
|
||||
AZ::Vector3 cameraPosition = AZ::Vector3::CreateZero();
|
||||
AZ::TransformBus::EventResult(cameraPosition, m_cameraEntityId, &AZ::TransformBus::Events::GetLocalTranslation);
|
||||
const AZ::Vector3 delta = m_targetPosition - cameraPosition;
|
||||
AZ::Quaternion targetRotation = LookRotation(delta);
|
||||
AZ::TransformBus::Event(m_cameraEntityId, &AZ::TransformBus::Events::SetLocalRotationQuaternion, targetRotation);
|
||||
m_aligned = true;
|
||||
}
|
||||
} // namespace MaterialEditor
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Viewport/InputController/Behavior.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
//! Rotates the camera around target position,
|
||||
//! this can either be model center or any position in world
|
||||
class OrbitCameraBehavior final
|
||||
: public Behavior
|
||||
{
|
||||
public:
|
||||
OrbitCameraBehavior() = default;
|
||||
virtual ~OrbitCameraBehavior() = default;
|
||||
|
||||
protected:
|
||||
void TickInternal(float x, float y, float z) override;
|
||||
float GetSensitivityX() override;
|
||||
float GetSensitivityY() override;
|
||||
|
||||
private:
|
||||
void Align();
|
||||
|
||||
static constexpr float SensitivityX = 0.005f;
|
||||
static constexpr float SensitivityY = 0.005f;
|
||||
|
||||
bool m_aligned = false;
|
||||
};
|
||||
} // namespace MaterialEditor
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Math/Quaternion.h>
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <Viewport/InputController/MaterialEditorViewportInputControllerBus.h>
|
||||
#include <Viewport/InputController/PanCameraBehavior.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
void PanCameraBehavior::End()
|
||||
{
|
||||
float distanceToTarget;
|
||||
MaterialEditorViewportInputControllerRequestBus::BroadcastResult(
|
||||
distanceToTarget,
|
||||
&MaterialEditorViewportInputControllerRequestBus::Handler::GetDistanceToTarget);
|
||||
AZ::Transform transform = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::EventResult(transform, m_cameraEntityId, &AZ::TransformBus::Events::GetLocalTM);
|
||||
AZ::Vector3 targetPosition =
|
||||
transform.GetTranslation() +
|
||||
transform.GetBasisY() * distanceToTarget;
|
||||
MaterialEditorViewportInputControllerRequestBus::Broadcast(
|
||||
&MaterialEditorViewportInputControllerRequestBus::Handler::SetTargetPosition,
|
||||
targetPosition);
|
||||
}
|
||||
|
||||
void PanCameraBehavior::TickInternal(float x, float y, [[maybe_unused]] float z)
|
||||
{
|
||||
AZ::Transform transform = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::EventResult(transform, m_cameraEntityId, &AZ::TransformBus::Events::GetLocalTM);
|
||||
AZ::Quaternion rotation = transform.GetRotation();
|
||||
const AZ::Vector3 right = transform.GetBasisX();
|
||||
rotation =
|
||||
AZ::Quaternion::CreateFromAxisAngle(AZ::Vector3::CreateAxisZ(), -x) *
|
||||
AZ::Quaternion::CreateFromAxisAngle(right, -y) *
|
||||
rotation;
|
||||
rotation.Normalize();
|
||||
AZ::TransformBus::Event(m_cameraEntityId, &AZ::TransformBus::Events::SetLocalRotationQuaternion, rotation);
|
||||
}
|
||||
|
||||
float PanCameraBehavior::GetSensitivityX()
|
||||
{
|
||||
return SensitivityX;
|
||||
}
|
||||
|
||||
float PanCameraBehavior::GetSensitivityY()
|
||||
{
|
||||
return SensitivityY;
|
||||
}
|
||||
} // namespace MaterialEditor
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Viewport/InputController/Behavior.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
//! Rotates camera around its own axis, allowing to look up/down/left/right
|
||||
class PanCameraBehavior final
|
||||
: public Behavior
|
||||
{
|
||||
public:
|
||||
PanCameraBehavior() = default;
|
||||
virtual ~PanCameraBehavior() = default;
|
||||
|
||||
void End() override;
|
||||
|
||||
protected:
|
||||
void TickInternal(float x, float y, float z) override;
|
||||
float GetSensitivityX() override;
|
||||
float GetSensitivityY() override;
|
||||
|
||||
private:
|
||||
static constexpr float SensitivityX = 0.005f;
|
||||
static constexpr float SensitivityY = 0.005f;
|
||||
};
|
||||
} // namespace MaterialEditor
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
|
||||
#include <Atom/Feature/SkyBox/SkyBoxFeatureProcessorInterface.h>
|
||||
#include <Atom/RPI.Public/RPISystemInterface.h>
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
|
||||
#include <Viewport/InputController/MaterialEditorViewportInputController.h>
|
||||
#include <Viewport/InputController/RotateEnvironmentBehavior.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
void RotateEnvironmentBehavior::Start()
|
||||
{
|
||||
Behavior::Start();
|
||||
|
||||
MaterialEditorViewportInputControllerRequestBus::BroadcastResult(
|
||||
m_iblEntityId,
|
||||
&MaterialEditorViewportInputControllerRequestBus::Handler::GetIblEntityId);
|
||||
AZ_Assert(m_iblEntityId.IsValid(), "Failed to find m_iblEntityId");
|
||||
m_skyBoxFeatureProcessorInterface = AZ::RPI::Scene::GetFeatureProcessorForEntity<AZ::Render::SkyBoxFeatureProcessorInterface>(m_iblEntityId);
|
||||
}
|
||||
|
||||
void RotateEnvironmentBehavior::TickInternal(float x, float y, float z)
|
||||
{
|
||||
Behavior::TickInternal(x, y, z);
|
||||
|
||||
m_rotation += x;
|
||||
AZ::Quaternion rotation = AZ::Quaternion::CreateFromAxisAngle(AZ::Vector3::CreateAxisZ(), m_rotation);
|
||||
AZ::TransformBus::Event(m_iblEntityId, &AZ::TransformBus::Events::SetLocalRotationQuaternion, rotation);
|
||||
const AZ::Matrix4x4 rotationMatrix = AZ::Matrix4x4::CreateFromQuaternion(rotation);
|
||||
m_skyBoxFeatureProcessorInterface->SetCubemapRotationMatrix(rotationMatrix);
|
||||
}
|
||||
|
||||
float RotateEnvironmentBehavior::GetSensitivityX()
|
||||
{
|
||||
return SensitivityX;
|
||||
}
|
||||
|
||||
float RotateEnvironmentBehavior::GetSensitivityY()
|
||||
{
|
||||
return SensitivityY;
|
||||
}
|
||||
} // namespace MaterialEditor
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Viewport/InputController/Behavior.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
class SkyBoxFeatureProcessorInterface;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
//! Rotates lighting and skybox around vertical axis
|
||||
class RotateEnvironmentBehavior final
|
||||
: public Behavior
|
||||
{
|
||||
public:
|
||||
RotateEnvironmentBehavior() = default;
|
||||
virtual ~RotateEnvironmentBehavior() = default;
|
||||
|
||||
void Start() override;
|
||||
|
||||
protected:
|
||||
void TickInternal(float x, float y, float z) override;
|
||||
float GetSensitivityX() override;
|
||||
float GetSensitivityY() override;
|
||||
|
||||
private:
|
||||
static constexpr float SensitivityX = 0.01f;
|
||||
static constexpr float SensitivityY = 0;
|
||||
|
||||
AZ::EntityId m_iblEntityId;
|
||||
AZ::Render::SkyBoxFeatureProcessorInterface* m_skyBoxFeatureProcessorInterface = nullptr;
|
||||
float m_rotation = 0;
|
||||
};
|
||||
} // namespace MaterialEditor
|
||||
-59
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <Viewport/InputController/MaterialEditorViewportInputController.h>
|
||||
#include <Viewport/InputController/RotateModelBehavior.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
void RotateModelBehavior::Start()
|
||||
{
|
||||
Behavior::Start();
|
||||
|
||||
MaterialEditorViewportInputControllerRequestBus::BroadcastResult(
|
||||
m_targetEntityId,
|
||||
&MaterialEditorViewportInputControllerRequestBus::Handler::GetTargetEntityId);
|
||||
AZ_Assert(m_targetEntityId.IsValid(), "Failed to find m_targetEntityId");
|
||||
AZ::EntityId cameraEntityId;
|
||||
MaterialEditorViewportInputControllerRequestBus::BroadcastResult(
|
||||
cameraEntityId,
|
||||
&MaterialEditorViewportInputControllerRequestBus::Handler::GetCameraEntityId);
|
||||
AZ_Assert(cameraEntityId.IsValid(), "Failed to find cameraEntityId");
|
||||
AZ::Transform transform = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::EventResult(transform, cameraEntityId, &AZ::TransformBus::Events::GetLocalTM);
|
||||
m_cameraRight = transform.GetBasisX();
|
||||
}
|
||||
|
||||
void RotateModelBehavior::TickInternal(float x, float y, float z)
|
||||
{
|
||||
Behavior::TickInternal(x, y, z);
|
||||
|
||||
AZ::Transform transform = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::EventResult(transform, m_targetEntityId, &AZ::TransformBus::Events::GetLocalTM);
|
||||
|
||||
AZ::Quaternion rotation = transform.GetRotation();
|
||||
rotation =
|
||||
AZ::Quaternion::CreateFromAxisAngle(AZ::Vector3::CreateAxisZ(), x) *
|
||||
AZ::Quaternion::CreateFromAxisAngle(m_cameraRight, y) *
|
||||
rotation;
|
||||
rotation.Normalize();
|
||||
|
||||
AZ::TransformBus::Event(m_targetEntityId, &AZ::TransformBus::Events::SetLocalRotationQuaternion, rotation);
|
||||
}
|
||||
|
||||
float RotateModelBehavior::GetSensitivityX()
|
||||
{
|
||||
return SensitivityX;
|
||||
}
|
||||
|
||||
float RotateModelBehavior::GetSensitivityY()
|
||||
{
|
||||
return SensitivityY;
|
||||
}
|
||||
} // namespace MaterialEditor
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Viewport/InputController/Behavior.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
//! Rotates target model in viewport
|
||||
class RotateModelBehavior final
|
||||
: public Behavior
|
||||
{
|
||||
public:
|
||||
RotateModelBehavior() = default;
|
||||
virtual ~RotateModelBehavior() = default;
|
||||
|
||||
void Start() override;
|
||||
|
||||
protected:
|
||||
void TickInternal(float x, float y, float z) override;
|
||||
float GetSensitivityX() override;
|
||||
float GetSensitivityY() override;
|
||||
|
||||
private:
|
||||
static constexpr float SensitivityX = 0.01f;
|
||||
static constexpr float SensitivityY = 0.01f;
|
||||
|
||||
AZ::EntityId m_targetEntityId;
|
||||
AZ::Vector3 m_cameraRight = AZ::Vector3::CreateAxisX();
|
||||
};
|
||||
} // namespace MaterialEditor
|
||||
@@ -394,7 +394,7 @@ namespace MaterialEditor
|
||||
return m_viewportSettings->m_displayMapperOperationType;
|
||||
}
|
||||
|
||||
inline void MaterialViewportComponent::OnAssetReady(AZ::Data::Asset<AZ::Data::AssetData> asset)
|
||||
void MaterialViewportComponent::OnAssetReady(AZ::Data::Asset<AZ::Data::AssetData> asset)
|
||||
{
|
||||
if (AZ::Data::Asset<AZ::RPI::AnyAsset> anyAsset = asset)
|
||||
{
|
||||
|
||||
@@ -40,6 +40,12 @@
|
||||
#include <AtomLyIntegration/CommonFeatures/PostProcess/ExposureControl/ExposureControlBus.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/PostProcess/ExposureControl/ExposureControlComponentConstants.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/PostProcess/PostFxLayerComponentConstants.h>
|
||||
#include <AtomToolsFramework/Viewport/ViewportInputBehaviorController/DollyCameraBehavior.h>
|
||||
#include <AtomToolsFramework/Viewport/ViewportInputBehaviorController/MoveCameraBehavior.h>
|
||||
#include <AtomToolsFramework/Viewport/ViewportInputBehaviorController/OrbitCameraBehavior.h>
|
||||
#include <AtomToolsFramework/Viewport/ViewportInputBehaviorController/PanCameraBehavior.h>
|
||||
#include <AtomToolsFramework/Viewport/ViewportInputBehaviorController/RotateEnvironmentBehavior.h>
|
||||
#include <AtomToolsFramework/Viewport/ViewportInputBehaviorController/RotateModelBehavior.h>
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzFramework/Components/NonUniformScaleComponent.h>
|
||||
@@ -64,7 +70,6 @@ namespace MaterialEditor
|
||||
: AtomToolsFramework::RenderViewportWidget(parent)
|
||||
, m_ui(new Ui::MaterialViewportWidget)
|
||||
, m_toolId(toolId)
|
||||
, m_viewportController(AZStd::make_shared<MaterialEditorViewportInputController>())
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
@@ -117,31 +122,24 @@ namespace MaterialEditor
|
||||
entityContextId, &AzFramework::GameEntityContextRequestBus::Events::GetGameEntityContextId);
|
||||
|
||||
// Configure camera
|
||||
AzFramework::EntityContextRequestBus::EventResult(
|
||||
m_cameraEntity, entityContextId, &AzFramework::EntityContextRequestBus::Events::CreateEntity, "Cameraentity");
|
||||
AZ_Assert(m_cameraEntity != nullptr, "Failed to create camera entity.");
|
||||
m_cameraEntity =
|
||||
CreateEntity("Cameraentity", { azrtti_typeid<AzFramework::TransformComponent>(), azrtti_typeid<AZ::Debug::CameraComponent>() });
|
||||
|
||||
// Add debug camera and controller components
|
||||
AZ::Debug::CameraComponentConfig cameraConfig(GetViewportContext()->GetWindowContext());
|
||||
cameraConfig.m_fovY = AZ::Constants::HalfPi;
|
||||
cameraConfig.m_depthNear = DepthNear;
|
||||
m_cameraComponent = m_cameraEntity->CreateComponent(azrtti_typeid<AZ::Debug::CameraComponent>());
|
||||
m_cameraComponent->SetConfiguration(cameraConfig);
|
||||
m_cameraEntity->CreateComponent(azrtti_typeid<AzFramework::TransformComponent>());
|
||||
m_cameraEntity->Deactivate();
|
||||
m_cameraEntity->FindComponent(azrtti_typeid<AZ::Debug::CameraComponent>())->SetConfiguration(cameraConfig);
|
||||
m_cameraEntity->Activate();
|
||||
|
||||
// Connect camera to pipeline's default view after camera entity activated
|
||||
m_renderPipeline->SetDefaultViewFromEntity(m_cameraEntity->GetId());
|
||||
|
||||
// Configure tone mapper
|
||||
AzFramework::EntityContextRequestBus::EventResult(
|
||||
m_postProcessEntity, entityContextId, &AzFramework::EntityContextRequestBus::Events::CreateEntity, "postProcessEntity");
|
||||
AZ_Assert(m_postProcessEntity != nullptr, "Failed to create post process entity.");
|
||||
|
||||
m_postProcessEntity->CreateComponent(AZ::Render::PostFxLayerComponentTypeId);
|
||||
m_postProcessEntity->CreateComponent(AZ::Render::ExposureControlComponentTypeId);
|
||||
m_postProcessEntity->CreateComponent(azrtti_typeid<AzFramework::TransformComponent>());
|
||||
m_postProcessEntity->Activate();
|
||||
m_postProcessEntity = CreateEntity(
|
||||
"PostProcessEntity",
|
||||
{ AZ::Render::PostFxLayerComponentTypeId, AZ::Render::ExposureControlComponentTypeId,
|
||||
azrtti_typeid<AzFramework::TransformComponent>() });
|
||||
|
||||
// Init directional light processor
|
||||
m_directionalLightFeatureProcessor = m_scene->GetFeatureProcessor<AZ::Render::DirectionalLightFeatureProcessorInterface>();
|
||||
@@ -155,33 +153,19 @@ namespace MaterialEditor
|
||||
m_skyboxFeatureProcessor->SetSkyboxMode(AZ::Render::SkyBoxMode::Cubemap);
|
||||
|
||||
// Create IBL
|
||||
AzFramework::EntityContextRequestBus::EventResult(
|
||||
m_iblEntity, entityContextId, &AzFramework::EntityContextRequestBus::Events::CreateEntity, "IblEntity");
|
||||
AZ_Assert(m_iblEntity != nullptr, "Failed to create ibl entity.");
|
||||
|
||||
m_iblEntity->CreateComponent(AZ::Render::ImageBasedLightComponentTypeId);
|
||||
m_iblEntity->CreateComponent(azrtti_typeid<AzFramework::TransformComponent>());
|
||||
m_iblEntity->Activate();
|
||||
m_iblEntity =
|
||||
CreateEntity("IblEntity", { AZ::Render::ImageBasedLightComponentTypeId, azrtti_typeid<AzFramework::TransformComponent>() });
|
||||
|
||||
// Create model
|
||||
AzFramework::EntityContextRequestBus::EventResult(
|
||||
m_modelEntity, entityContextId, &AzFramework::EntityContextRequestBus::Events::CreateEntity, "ViewportModel");
|
||||
AZ_Assert(m_modelEntity != nullptr, "Failed to create model entity.");
|
||||
|
||||
m_modelEntity->CreateComponent(AZ::Render::MeshComponentTypeId);
|
||||
m_modelEntity->CreateComponent(AZ::Render::MaterialComponentTypeId);
|
||||
m_modelEntity->CreateComponent(azrtti_typeid<AzFramework::TransformComponent>());
|
||||
m_modelEntity->Activate();
|
||||
m_modelEntity = CreateEntity(
|
||||
"ViewportModel",
|
||||
{ AZ::Render::MeshComponentTypeId, AZ::Render::MaterialComponentTypeId, azrtti_typeid<AzFramework::TransformComponent>() });
|
||||
|
||||
// Create shadow catcher
|
||||
AzFramework::EntityContextRequestBus::EventResult(
|
||||
m_shadowCatcherEntity, entityContextId, &AzFramework::EntityContextRequestBus::Events::CreateEntity, "ViewportShadowCatcher");
|
||||
AZ_Assert(m_shadowCatcherEntity != nullptr, "Failed to create shadow catcher entity.");
|
||||
m_shadowCatcherEntity->CreateComponent(AZ::Render::MeshComponentTypeId);
|
||||
m_shadowCatcherEntity->CreateComponent(AZ::Render::MaterialComponentTypeId);
|
||||
m_shadowCatcherEntity->CreateComponent(azrtti_typeid<AzFramework::TransformComponent>());
|
||||
m_shadowCatcherEntity->CreateComponent(azrtti_typeid<AzFramework::NonUniformScaleComponent>());
|
||||
m_shadowCatcherEntity->Activate();
|
||||
m_shadowCatcherEntity = CreateEntity(
|
||||
"ViewportShadowCatcher",
|
||||
{ AZ::Render::MeshComponentTypeId, AZ::Render::MaterialComponentTypeId, azrtti_typeid<AzFramework::TransformComponent>(),
|
||||
azrtti_typeid<AzFramework::NonUniformScaleComponent>() });
|
||||
|
||||
AZ::NonUniformScaleRequestBus::Event(
|
||||
m_shadowCatcherEntity->GetId(), &AZ::NonUniformScaleRequests::SetScale, AZ::Vector3{ 100, 100, 1.0 });
|
||||
@@ -214,21 +198,19 @@ namespace MaterialEditor
|
||||
}
|
||||
|
||||
// Create grid
|
||||
AzFramework::EntityContextRequestBus::EventResult(
|
||||
m_gridEntity, entityContextId, &AzFramework::EntityContextRequestBus::Events::CreateEntity, "ViewportGrid");
|
||||
AZ_Assert(m_gridEntity != nullptr, "Failed to create grid entity.");
|
||||
m_gridEntity = CreateEntity("ViewportGrid", { AZ::Render::GridComponentTypeId, azrtti_typeid<AzFramework::TransformComponent>() });
|
||||
|
||||
AZ::Render::GridComponentConfig gridConfig;
|
||||
gridConfig.m_gridSize = 4.0f;
|
||||
gridConfig.m_axisColor = AZ::Color(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
gridConfig.m_primaryColor = AZ::Color(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
gridConfig.m_secondaryColor = AZ::Color(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
auto gridComponent = m_gridEntity->CreateComponent(AZ::Render::GridComponentTypeId);
|
||||
gridComponent->SetConfiguration(gridConfig);
|
||||
|
||||
m_gridEntity->CreateComponent(azrtti_typeid<AzFramework::TransformComponent>());
|
||||
m_gridEntity->Deactivate();
|
||||
m_gridEntity->FindComponent(AZ::Render::GridComponentTypeId)->SetConfiguration(gridConfig);
|
||||
m_gridEntity->Activate();
|
||||
|
||||
SetupInputController();
|
||||
|
||||
OnDocumentOpened(AZ::Uuid::CreateNull());
|
||||
|
||||
// Attempt to apply the default lighting preset
|
||||
@@ -241,8 +223,6 @@ namespace MaterialEditor
|
||||
MaterialViewportRequestBus::BroadcastResult(modelPreset, &MaterialViewportRequestBus::Events::GetModelPresetSelection);
|
||||
OnModelPresetSelected(modelPreset);
|
||||
|
||||
m_viewportController->Init(m_cameraEntity->GetId(), m_modelEntity->GetId(), m_iblEntity->GetId());
|
||||
|
||||
// Apply user settinngs restored since last run
|
||||
AZStd::intrusive_ptr<MaterialViewportSettings> viewportSettings =
|
||||
AZ::UserSettings::CreateFind<MaterialViewportSettings>(AZ::Crc32("MaterialViewportSettings"), AZ::UserSettings::CT_GLOBAL);
|
||||
@@ -257,8 +237,6 @@ namespace MaterialEditor
|
||||
MaterialViewportNotificationBus::Handler::BusConnect();
|
||||
AZ::TickBus::Handler::BusConnect();
|
||||
AZ::TransformNotificationBus::MultiHandler::BusConnect(m_cameraEntity->GetId());
|
||||
|
||||
GetControllerList()->Add(m_viewportController);
|
||||
}
|
||||
|
||||
MaterialViewportWidget::~MaterialViewportWidget()
|
||||
@@ -269,33 +247,12 @@ namespace MaterialEditor
|
||||
MaterialViewportNotificationBus::Handler::BusDisconnect();
|
||||
AZ::Data::AssetBus::Handler::BusDisconnect();
|
||||
|
||||
AzFramework::EntityContextId entityContextId;
|
||||
AzFramework::GameEntityContextRequestBus::BroadcastResult(
|
||||
entityContextId, &AzFramework::GameEntityContextRequestBus::Events::GetGameEntityContextId);
|
||||
|
||||
AzFramework::EntityContextRequestBus::Event(
|
||||
entityContextId, &AzFramework::EntityContextRequestBus::Events::DestroyEntity, m_iblEntity);
|
||||
m_iblEntity = nullptr;
|
||||
|
||||
AzFramework::EntityContextRequestBus::Event(
|
||||
entityContextId, &AzFramework::EntityContextRequestBus::Events::DestroyEntity, m_modelEntity);
|
||||
m_modelEntity = nullptr;
|
||||
|
||||
AzFramework::EntityContextRequestBus::Event(
|
||||
entityContextId, &AzFramework::EntityContextRequestBus::Events::DestroyEntity, m_shadowCatcherEntity);
|
||||
m_shadowCatcherEntity = nullptr;
|
||||
|
||||
AzFramework::EntityContextRequestBus::Event(
|
||||
entityContextId, &AzFramework::EntityContextRequestBus::Events::DestroyEntity, m_gridEntity);
|
||||
m_gridEntity = nullptr;
|
||||
|
||||
AzFramework::EntityContextRequestBus::Event(
|
||||
entityContextId, &AzFramework::EntityContextRequestBus::Events::DestroyEntity, m_cameraEntity);
|
||||
m_cameraEntity = nullptr;
|
||||
|
||||
AzFramework::EntityContextRequestBus::Event(
|
||||
entityContextId, &AzFramework::EntityContextRequestBus::Events::DestroyEntity, m_postProcessEntity);
|
||||
m_postProcessEntity = nullptr;
|
||||
DestroyEntity(m_iblEntity);
|
||||
DestroyEntity(m_modelEntity);
|
||||
DestroyEntity(m_shadowCatcherEntity);
|
||||
DestroyEntity(m_gridEntity);
|
||||
DestroyEntity(m_cameraEntity);
|
||||
DestroyEntity(m_postProcessEntity);
|
||||
|
||||
for (DirectionalLightHandle& handle : m_lightHandles)
|
||||
{
|
||||
@@ -315,6 +272,74 @@ namespace MaterialEditor
|
||||
m_scene = nullptr;
|
||||
}
|
||||
|
||||
AZ::Entity* MaterialViewportWidget::CreateEntity(const AZStd::string& name, const AZStd::vector<AZ::Uuid>& componentTypeIds)
|
||||
{
|
||||
AzFramework::EntityContextId entityContextId;
|
||||
AzFramework::GameEntityContextRequestBus::BroadcastResult(
|
||||
entityContextId, &AzFramework::GameEntityContextRequestBus::Events::GetGameEntityContextId);
|
||||
|
||||
AZ::Entity* entity = {};
|
||||
AzFramework::EntityContextRequestBus::EventResult(
|
||||
entity, entityContextId, &AzFramework::EntityContextRequestBus::Events::CreateEntity, name.c_str());
|
||||
AZ_Assert(entity != nullptr, "Failed to create post process entity: %s.", name.c_str());
|
||||
|
||||
if (entity)
|
||||
{
|
||||
for (const auto& componentTypeId : componentTypeIds)
|
||||
{
|
||||
entity->CreateComponent(componentTypeId);
|
||||
}
|
||||
entity->Activate();
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
void MaterialViewportWidget::DestroyEntity(AZ::Entity*& entity)
|
||||
{
|
||||
AzFramework::EntityContextId entityContextId;
|
||||
AzFramework::GameEntityContextRequestBus::BroadcastResult(
|
||||
entityContextId, &AzFramework::GameEntityContextRequestBus::Events::GetGameEntityContextId);
|
||||
|
||||
AzFramework::EntityContextRequestBus::Event(entityContextId, &AzFramework::EntityContextRequestBus::Events::DestroyEntity, entity);
|
||||
entity = nullptr;
|
||||
}
|
||||
|
||||
void MaterialViewportWidget::SetupInputController()
|
||||
{
|
||||
using namespace AtomToolsFramework;
|
||||
|
||||
// Create viewport input controller and regioster its behaviors
|
||||
m_viewportController.reset(
|
||||
aznew ViewportInputBehaviorController(m_cameraEntity->GetId(), m_modelEntity->GetId(), m_iblEntity->GetId()));
|
||||
m_viewportController->AddBehavior(
|
||||
ViewportInputBehaviorController::Lmb, AZStd::make_shared<PanCameraBehavior>(m_viewportController.get()));
|
||||
m_viewportController->AddBehavior(
|
||||
ViewportInputBehaviorController::Mmb, AZStd::make_shared<MoveCameraBehavior>(m_viewportController.get()));
|
||||
m_viewportController->AddBehavior(
|
||||
ViewportInputBehaviorController::Rmb, AZStd::make_shared<OrbitCameraBehavior>(m_viewportController.get()));
|
||||
m_viewportController->AddBehavior(
|
||||
ViewportInputBehaviorController::Alt ^ ViewportInputBehaviorController::Lmb,
|
||||
AZStd::make_shared<OrbitCameraBehavior>(m_viewportController.get()));
|
||||
m_viewportController->AddBehavior(
|
||||
ViewportInputBehaviorController::Alt ^ ViewportInputBehaviorController::Mmb,
|
||||
AZStd::make_shared<MoveCameraBehavior>(m_viewportController.get()));
|
||||
m_viewportController->AddBehavior(
|
||||
ViewportInputBehaviorController::Alt ^ ViewportInputBehaviorController::Rmb,
|
||||
AZStd::make_shared<DollyCameraBehavior>(m_viewportController.get()));
|
||||
m_viewportController->AddBehavior(
|
||||
ViewportInputBehaviorController::Lmb ^ ViewportInputBehaviorController::Rmb,
|
||||
AZStd::make_shared<DollyCameraBehavior>(m_viewportController.get()));
|
||||
m_viewportController->AddBehavior(
|
||||
ViewportInputBehaviorController::Ctrl ^ ViewportInputBehaviorController::Lmb,
|
||||
AZStd::make_shared<RotateModelBehavior>(m_viewportController.get()));
|
||||
m_viewportController->AddBehavior(
|
||||
ViewportInputBehaviorController::Shift ^ ViewportInputBehaviorController::Lmb,
|
||||
AZStd::make_shared<RotateEnvironmentBehavior>(m_viewportController.get()));
|
||||
|
||||
GetControllerList()->Add(m_viewportController);
|
||||
}
|
||||
|
||||
void MaterialViewportWidget::OnDocumentOpened(const AZ::Uuid& documentId)
|
||||
{
|
||||
AZ::Data::Instance<AZ::RPI::Material> materialInstance;
|
||||
@@ -436,8 +461,7 @@ namespace MaterialEditor
|
||||
|
||||
void MaterialViewportWidget::OnFieldOfViewChanged(float fieldOfView)
|
||||
{
|
||||
MaterialEditorViewportInputControllerRequestBus::Broadcast(
|
||||
&MaterialEditorViewportInputControllerRequestBus::Handler::SetFieldOfView, fieldOfView);
|
||||
m_viewportController->SetFieldOfView(fieldOfView);
|
||||
}
|
||||
|
||||
void MaterialViewportWidget::OnDisplayMapperOperationTypeChanged(AZ::Render::DisplayMapperOperationType operationType)
|
||||
@@ -451,7 +475,9 @@ namespace MaterialEditor
|
||||
{
|
||||
if (m_modelAssetId == asset.GetId())
|
||||
{
|
||||
MaterialEditorViewportInputControllerRequestBus::Broadcast(&MaterialEditorViewportInputControllerRequestBus::Handler::Reset);
|
||||
AZ::Data::Asset<AZ::RPI::ModelAsset> modelAsset = asset;
|
||||
m_viewportController->SetTargetBounds(modelAsset->GetAabb());
|
||||
m_viewportController->Reset();
|
||||
AZ::Data::AssetBus::Handler::BusDisconnect(asset.GetId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
#include <AtomCore/Instance/Instance.h>
|
||||
#include <AtomToolsFramework/Document/AtomToolsDocumentNotificationBus.h>
|
||||
#include <AtomToolsFramework/Viewport/RenderViewportWidget.h>
|
||||
#include <AtomToolsFramework/Viewport/ViewportInputBehaviorController/ViewportInputBehaviorController.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzFramework/Windowing/WindowBus.h>
|
||||
#include <Viewport/InputController/MaterialEditorViewportInputController.h>
|
||||
#include <Viewport/MaterialViewportNotificationBus.h>
|
||||
|
||||
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT
|
||||
@@ -61,6 +61,10 @@ namespace MaterialEditor
|
||||
~MaterialViewportWidget();
|
||||
|
||||
private:
|
||||
AZ::Entity* CreateEntity(const AZStd::string& name, const AZStd::vector<AZ::Uuid>& componentTypeIds);
|
||||
void DestroyEntity(AZ::Entity*& entity);
|
||||
void SetupInputController();
|
||||
|
||||
// AtomToolsFramework::AtomToolsDocumentNotificationBus::Handler interface overrides...
|
||||
void OnDocumentOpened(const AZ::Uuid& documentId) override;
|
||||
|
||||
@@ -96,8 +100,6 @@ namespace MaterialEditor
|
||||
AZ::Render::DisplayMapperFeatureProcessorInterface* m_displayMapperFeatureProcessor = {};
|
||||
|
||||
AZ::Entity* m_cameraEntity = {};
|
||||
AZ::Component* m_cameraComponent = {};
|
||||
|
||||
AZ::Entity* m_postProcessEntity = {};
|
||||
|
||||
AZ::Entity* m_modelEntity = {};
|
||||
@@ -114,7 +116,7 @@ namespace MaterialEditor
|
||||
AZ::Entity* m_iblEntity = {};
|
||||
AZ::Render::SkyBoxFeatureProcessorInterface* m_skyboxFeatureProcessor = {};
|
||||
|
||||
AZStd::shared_ptr<MaterialEditorViewportInputController> m_viewportController;
|
||||
AZStd::shared_ptr<AtomToolsFramework::ViewportInputBehaviorController> m_viewportController;
|
||||
|
||||
QScopedPointer<Ui::MaterialViewportWidget> m_ui;
|
||||
};
|
||||
|
||||
@@ -17,28 +17,9 @@ set(FILES
|
||||
|
||||
Source/Viewport/MaterialViewportModule.h
|
||||
Source/Viewport/MaterialViewportModule.cpp
|
||||
Source/Viewport/InputController/MaterialEditorViewportInputControllerBus.h
|
||||
Source/Viewport/MaterialViewportSettings.h
|
||||
Source/Viewport/MaterialViewportRequestBus.h
|
||||
Source/Viewport/MaterialViewportNotificationBus.h
|
||||
Source/Viewport/InputController/MaterialEditorViewportInputController.cpp
|
||||
Source/Viewport/InputController/MaterialEditorViewportInputController.h
|
||||
Source/Viewport/InputController/Behavior.cpp
|
||||
Source/Viewport/InputController/Behavior.h
|
||||
Source/Viewport/InputController/DollyCameraBehavior.cpp
|
||||
Source/Viewport/InputController/DollyCameraBehavior.h
|
||||
Source/Viewport/InputController/IdleBehavior.cpp
|
||||
Source/Viewport/InputController/IdleBehavior.h
|
||||
Source/Viewport/InputController/MoveCameraBehavior.cpp
|
||||
Source/Viewport/InputController/MoveCameraBehavior.h
|
||||
Source/Viewport/InputController/PanCameraBehavior.cpp
|
||||
Source/Viewport/InputController/PanCameraBehavior.h
|
||||
Source/Viewport/InputController/OrbitCameraBehavior.cpp
|
||||
Source/Viewport/InputController/OrbitCameraBehavior.h
|
||||
Source/Viewport/InputController/RotateEnvironmentBehavior.cpp
|
||||
Source/Viewport/InputController/RotateEnvironmentBehavior.h
|
||||
Source/Viewport/InputController/RotateModelBehavior.cpp
|
||||
Source/Viewport/InputController/RotateModelBehavior.h
|
||||
Source/Viewport/MaterialViewportSettings.cpp
|
||||
Source/Viewport/MaterialViewportComponent.cpp
|
||||
Source/Viewport/MaterialViewportComponent.h
|
||||
|
||||
Reference in New Issue
Block a user