Merge branch 'main' into transform-float-scale-3

This commit is contained in:
greerdv
2021-05-28 19:14:45 +01:00
192 changed files with 3065 additions and 2090 deletions
@@ -18,6 +18,7 @@
#include <AzCore/RTTI/RTTI.h>
#include <AzCore/std/containers/variant.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/limits.h>
#include <AzFramework/Physics/Common/PhysicsSimulatedBodyEvents.h>
#include <AzFramework/Physics/Common/PhysicsSceneQueries.h>
#include <AzFramework/Physics/Common/PhysicsTypes.h>
@@ -68,6 +69,22 @@ namespace AzPhysics
return m_customUserData;
}
//! Helper functions for setting frame ID.
//! @param frameId Optionally set frame ID for the systems moving the actors back in time.
void SetFrameId(uint32_t frameId)
{
m_frameId = frameId;
}
//! Helper functions for getting the set frame ID.
//! @return Will return the frame ID.
uint32_t GetFrameId() const
{
return m_frameId;
}
static constexpr uint32_t UndefinedFrameId = AZStd::numeric_limits<uint32_t>::max();
//! Perform a ray cast on this Simulated Body.
//! @param request The request to make.
//! @return Returns the closest hit, if any, against this simulated body.
@@ -126,6 +143,7 @@ namespace AzPhysics
SimulatedBodyEvents::OnTriggerExit m_triggerExitEvent;
void* m_customUserData = nullptr;
uint32_t m_frameId = UndefinedFrameId;
// helpers for reflecting to behavior context
SimulatedBodyEvents::OnCollisionBegin* GetOnCollisionBeginEvent();
@@ -12,6 +12,7 @@
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzFramework/Entity/EntityContextBus.h>
#include <AzFramework/Render/GeometryIntersectionStructures.h>
namespace AzFramework
@@ -35,12 +36,12 @@ namespace AzFramework
AzFramework::EntityContextId m_contextId;
};
//! Interface for intersection requests, implement this interface for making your component
//! render geometry intersectable.
//! Interface for intersection requests.
//! Implement this interface to make your component 'intersectable'.
class IntersectionRequests
: public AZ::EBusTraits
{
//! Policy for notifying the Intersector bus of entities connected/disconnected to this ebus
//! Policy for notifying the Intersector bus of entities connected/disconnected to this EBus
//! so it updates the internal data of the entities
template<class Bus>
struct IntersectionRequestsConnectionPolicy
@@ -144,7 +144,7 @@ namespace AzFramework
z = AZStd::atan2(-orientation.GetElement(1, 2), orientation.GetElement(1, 1));
}
return {x, y, z};
return { x, y, z };
}
void UpdateCameraFromTransform(Camera& camera, const AZ::Transform& transform)
@@ -179,7 +179,7 @@ namespace AzFramework
{
const auto nextCamera = m_cameras.StepCamera(targetCamera, m_motionDelta, m_scrollDelta, deltaTime);
m_motionDelta = ScreenVector{0, 0};
m_motionDelta = ScreenVector{ 0, 0 };
m_scrollDelta = 0.0f;
return nextCamera;
@@ -213,7 +213,10 @@ namespace AzFramework
auto& cameraInput = m_idleCameraInputs[i];
const bool canBegin = cameraInput->Beginning() &&
AZStd::all_of(m_activeCameraInputs.cbegin(), m_activeCameraInputs.cend(),
[](const auto& input) { return !input->Exclusive(); }) &&
[](const auto& input)
{
return !input->Exclusive();
}) &&
(!cameraInput->Exclusive() || (cameraInput->Exclusive() && m_activeCameraInputs.empty()));
if (canBegin)
@@ -231,7 +234,8 @@ namespace AzFramework
const Camera nextCamera = AZStd::accumulate(
AZStd::begin(m_activeCameraInputs), AZStd::end(m_activeCameraInputs), targetCamera,
[cursorDelta, scrollDelta, deltaTime](Camera acc, auto& camera) {
[cursorDelta, scrollDelta, deltaTime](Camera acc, auto& camera)
{
acc = camera->StepCamera(acc, cursorDelta, scrollDelta, deltaTime);
return acc;
});
@@ -284,7 +288,8 @@ namespace AzFramework
bool RotateCameraInput::HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta)
{
const ClickDetector::ClickEvent clickEvent = [&event, this] {
const ClickDetector::ClickEvent clickEvent = [&event, this]
{
if (const auto& input = AZStd::get_if<DiscreteInputEvent>(&event))
{
if (input->m_channelId == m_rotateChannelId)
@@ -330,7 +335,10 @@ namespace AzFramework
nextCamera.m_pitch -= float(cursorDelta.m_y) * ed_cameraSystemRotateSpeed;
nextCamera.m_yaw -= float(cursorDelta.m_x) * ed_cameraSystemRotateSpeed;
const auto clampRotation = [](const float angle) { return AZStd::fmod(angle + AZ::Constants::TwoPi, AZ::Constants::TwoPi); };
const auto clampRotation = [](const float angle)
{
return AZStd::fmod(angle + AZ::Constants::TwoPi, AZ::Constants::TwoPi);
};
nextCamera.m_yaw = clampRotation(nextCamera.m_yaw);
// clamp pitch to be +-90 degrees
@@ -377,9 +385,10 @@ namespace AzFramework
const auto deltaPanX = float(cursorDelta.m_x) * panAxes.m_horizontalAxis * ed_cameraSystemPanSpeed;
const auto deltaPanY = float(cursorDelta.m_y) * panAxes.m_verticalAxis * ed_cameraSystemPanSpeed;
const auto inv = [](const bool invert) {
constexpr float Dir[] = {1.0f, -1.0f};
return Dir[static_cast<int>(invert)];
const auto inv = [](const bool invert)
{
constexpr float Dir[] = { 1.0f, -1.0f };
return Dir[aznumeric_cast<int>(invert)];
};
nextCamera.m_lookAt += deltaPanX * inv(ed_cameraSystemPanInvertX);
@@ -475,7 +484,8 @@ namespace AzFramework
const auto axisY = translationBasis.GetBasisY();
const auto axisZ = translationBasis.GetBasisZ();
const float speed = [boost = m_boost]() {
const float speed = [boost = m_boost]()
{
return ed_cameraSystemTranslateSpeed * (boost ? ed_cameraSystemBoostMultiplier : 1.0f);
}();
@@ -555,10 +565,12 @@ namespace AzFramework
if (Beginning())
{
const auto hasLookAt = [&nextCamera, &targetCamera, &lookAtFn = m_lookAtFn] {
const auto hasLookAt = [&nextCamera, &targetCamera, &lookAtFn = m_lookAtFn]
{
if (lookAtFn)
{
if (const auto lookAt = lookAtFn())
// pass through the camera's position and look vector for use in the lookAt function
if (const auto lookAt = lookAtFn(targetCamera.Translation(), targetCamera.Rotation().GetBasisY()))
{
auto transform = AZ::Transform::CreateLookAt(targetCamera.m_lookAt, *lookAt);
nextCamera.m_lookDist = -lookAt->GetDistance(targetCamera.m_lookAt);
@@ -692,14 +704,20 @@ namespace AzFramework
Camera SmoothCamera(const Camera& currentCamera, const Camera& targetCamera, const float deltaTime)
{
const auto clamp_rotation = [](const float angle) { return AZStd::fmod(angle + AZ::Constants::TwoPi, AZ::Constants::TwoPi); };
const auto clamp_rotation = [](const float angle)
{
return AZStd::fmod(angle + AZ::Constants::TwoPi, AZ::Constants::TwoPi);
};
// keep yaw in 0 - 360 range
float targetYaw = clamp_rotation(targetCamera.m_yaw);
const float currentYaw = clamp_rotation(currentCamera.m_yaw);
// return the sign of the float input (-1, 0, 1)
const auto sign = [](const float value) { return aznumeric_cast<float>((0.0f < value) - (value < 0.0f)); };
const auto sign = [](const float value)
{
return aznumeric_cast<float>((0.0f < value) - (value < 0.0f));
};
// ensure smooth transition when moving across 0 - 360 boundary
const float yawDelta = targetYaw - currentYaw;
@@ -727,26 +745,28 @@ namespace AzFramework
const auto& inputChannelId = inputChannel.GetInputChannelId();
const auto& inputDeviceId = inputChannel.GetInputDevice().GetInputDeviceId();
const bool wasMouseButton =
AZStd::any_of(InputDeviceMouse::Button::All.begin(), InputDeviceMouse::Button::All.end(), [inputChannelId](const auto& button) {
const bool wasMouseButton = AZStd::any_of(
InputDeviceMouse::Button::All.begin(), InputDeviceMouse::Button::All.end(),
[inputChannelId](const auto& button)
{
return button == inputChannelId;
});
if (inputChannelId == InputDeviceMouse::Movement::X)
{
return HorizontalMotionEvent{(int)inputChannel.GetValue()};
return HorizontalMotionEvent{ aznumeric_cast<int>(inputChannel.GetValue()) };
}
else if (inputChannelId == InputDeviceMouse::Movement::Y)
{
return VerticalMotionEvent{(int)inputChannel.GetValue()};
return VerticalMotionEvent{ aznumeric_cast<int>(inputChannel.GetValue()) };
}
else if (inputChannelId == InputDeviceMouse::Movement::Z)
{
return ScrollEvent{inputChannel.GetValue()};
return ScrollEvent{ inputChannel.GetValue() };
}
else if (wasMouseButton || InputDeviceKeyboard::IsKeyboardDevice(inputDeviceId))
{
return DiscreteInputEvent{inputChannelId, inputChannel.GetState()};
return DiscreteInputEvent{ inputChannelId, inputChannel.GetState() };
}
return AZStd::monostate{};
@@ -34,9 +34,9 @@ namespace AzFramework
AZ::Vector3 m_lookAt = AZ::Vector3::CreateZero(); //!< Position of camera when m_lookDist is zero,
//!< or position of m_lookAt when m_lookDist is greater
//!< than zero.
float m_yaw{0.0};
float m_pitch{0.0};
float m_lookDist{0.0}; //!< Zero gives first person free look, otherwise orbit about m_lookAt
float m_yaw{ 0.0 };
float m_pitch{ 0.0 };
float m_lookDist{ 0.0 }; //!< Zero gives first person free look, otherwise orbit about m_lookAt
//! View camera transform (v in MVP).
AZ::Transform View() const;
@@ -195,7 +195,11 @@ namespace AzFramework
inline bool Cameras::Exclusive() const
{
return AZStd::any_of(
m_activeCameraInputs.begin(), m_activeCameraInputs.end(), [](const auto& cameraInput) { return cameraInput->Exclusive(); });
m_activeCameraInputs.begin(), m_activeCameraInputs.end(),
[](const auto& cameraInput)
{
return cameraInput->Exclusive();
});
}
//! Responsible for updating a series of cameras given various inputs.
@@ -209,7 +213,7 @@ namespace AzFramework
private:
ScreenVector m_motionDelta; //!< The delta used for look/orbit/pan (rotation + translation) - two dimensional.
float m_scrollDelta = 0.0f; //!< The delta used for dolly/movement (translation) - one dimensional.
float m_scrollDelta = 0.0f; //!< The delta used for dolly/movement (translation) - one dimensional.
};
class RotateCameraInput : public CameraInput
@@ -237,7 +241,7 @@ namespace AzFramework
inline PanAxes LookPan(const Camera& camera)
{
const AZ::Matrix3x3 orientation = camera.Rotation();
return {orientation.GetBasisX(), orientation.GetBasisZ()};
return { orientation.GetBasisX(), orientation.GetBasisZ() };
}
inline PanAxes OrbitPan(const Camera& camera)
@@ -245,12 +249,13 @@ namespace AzFramework
const AZ::Matrix3x3 orientation = camera.Rotation();
const auto basisX = orientation.GetBasisX();
const auto basisY = [&orientation] {
const auto basisY = [&orientation]
{
const auto forward = orientation.GetBasisY();
return AZ::Vector3(forward.GetX(), forward.GetY(), 0.0f).GetNormalized();
}();
return {basisX, basisY};
return { basisX, basisY };
}
class PanCameraInput : public CameraInput
@@ -285,7 +290,8 @@ namespace AzFramework
const AZ::Matrix3x3 orientation = camera.Rotation();
const auto basisX = orientation.GetBasisX();
const auto basisY = [&orientation] {
const auto basisY = [&orientation]
{
const auto forward = orientation.GetBasisY();
return AZ::Vector3(forward.GetX(), forward.GetY(), 0.0f).GetNormalized();
}();
@@ -398,7 +404,7 @@ namespace AzFramework
class OrbitCameraInput : public CameraInput
{
public:
using LookAtFn = AZStd::function<AZStd::optional<AZ::Vector3>()>;
using LookAtFn = AZStd::function<AZStd::optional<AZ::Vector3>(const AZ::Vector3& position, const AZ::Vector3& direction)>;
// CameraInput overrides ...
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
@@ -41,6 +41,7 @@ namespace AzManipulatorTestFramework
AZStd::optional<AZ::Vector3> ViewportScreenToWorld(const AzFramework::ScreenPoint& screenPosition, float depth) override;
AZStd::optional<AzToolsFramework::ViewportInteraction::ProjectedViewportRay> ViewportScreenToWorldRay(
const AzFramework::ScreenPoint& screenPosition) override;
float DeviceScalingFactor() override;
private:
// ViewportInteractionRequestBus ...
bool GridSnappingEnabled();
@@ -127,4 +127,9 @@ namespace AzManipulatorTestFramework
{
return {};
}
} // namespace AzManipulatorTestFramework
float ViewportInteraction::DeviceScalingFactor()
{
return 1.0f;
}
}// namespace AzManipulatorTestFramework
@@ -49,7 +49,7 @@ QMenu::right-arrow
QMenu::icon
{
right: 8px;
right: 20px;
}
QMenu::indicator:checked
@@ -0,0 +1,4 @@
<svg width="13" height="13" viewBox="0 0 13 13" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.0708 0.87087L11.0708 0.87074C10.4286 0.371024 9.61107 0.13517 8.79265 0.213464C7.97422 0.291757 7.21961 0.678004 6.6897 1.28985L5.76756 2.36366C5.63378 2.51944 5.56909 2.72055 5.58771 2.92273C5.60634 3.12492 5.70675 3.31163 5.86686 3.44178C6.02698 3.57194 6.23368 3.63488 6.44149 3.61676C6.6493 3.59864 6.8412 3.50094 6.97498 3.34516L7.89716 2.27122C8.03184 2.11488 8.19736 1.98639 8.38395 1.89334C8.57053 1.8003 8.7744 1.74459 8.98349 1.7295C9.19258 1.71442 9.40266 1.74027 9.60131 1.80552C9.79996 1.87078 9.98315 1.97411 10.1401 2.10942C10.4422 2.38256 10.6244 2.75851 10.6488 3.15904C10.6732 3.55957 10.5379 3.95383 10.2711 4.25978L8.35381 6.49309L8.33616 6.51209C8.23375 6.62767 8.11374 6.72729 7.98031 6.80749C7.67189 6.99364 7.30661 7.06983 6.94686 7.02305C6.58711 6.97626 6.25522 6.8094 6.00789 6.55097C5.86556 6.40288 5.66865 6.31578 5.46039 6.30879C5.25213 6.30179 5.04952 6.37546 4.89703 6.51365C4.74453 6.65183 4.65462 6.84323 4.64701 7.04584C4.6394 7.24845 4.71472 7.44572 4.85645 7.59436C5.21222 7.96578 5.65746 8.24515 6.15198 8.40726C6.6465 8.56937 7.17473 8.60911 7.68898 8.52289C7.84983 8.49539 8.00828 8.45599 8.16298 8.40505C8.70939 8.22568 9.19408 7.90261 9.56335 7.47165L11.4758 5.24457C11.7478 4.92529 11.9523 4.55683 12.0773 4.16038C12.2024 3.76394 12.2457 3.34735 12.2046 2.93457C12.1671 2.53429 12.0475 2.1454 11.8527 1.79092C11.658 1.43644 11.3921 1.12358 11.0708 0.87087Z" fill="white"/>
<path d="M5.40958 9.14055L4.58546 10.1003C4.32342 10.4101 3.94867 10.6097 3.53919 10.6576C3.12972 10.7054 2.71706 10.5977 2.3871 10.357C2.22234 10.2309 2.08525 10.0738 1.98392 9.89526C1.8826 9.71668 1.81911 9.52014 1.79719 9.31727C1.77528 9.1144 1.79539 8.90932 1.85634 8.71414C1.91729 8.51896 2.01784 8.33765 2.15204 8.18093L4.10231 5.90975L4.11666 5.89415C4.21908 5.77861 4.3391 5.67903 4.47254 5.59887C4.75216 5.42921 5.07976 5.34988 5.4085 5.37222C5.73725 5.39457 6.05033 5.51745 6.30299 5.72329C6.3635 5.77246 6.42015 5.82595 6.47246 5.88333C6.54738 5.9658 6.63971 6.03156 6.74316 6.07611C6.84661 6.12066 6.95872 6.14295 7.07184 6.14146C7.18361 6.13992 7.29372 6.11492 7.39465 6.06817C7.49558 6.02143 7.58495 5.95403 7.65666 5.8706L7.66607 5.85958C7.78641 5.72083 7.85132 5.54454 7.8489 5.36301C7.84647 5.18148 7.77687 5.00689 7.65286 4.87124C7.35341 4.54132 6.98422 4.27825 6.57057 4.10003C6.15692 3.92182 5.70858 3.83266 5.25623 3.83866C4.80388 3.84467 4.35821 3.94569 3.94971 4.13482C3.54122 4.32395 3.17954 4.59672 2.88945 4.93446L0.944626 7.19943C0.420065 7.81564 0.163643 8.60683 0.230025 9.40433C0.296406 10.2018 0.68034 10.9426 1.29998 11.4686C1.61272 11.7312 1.97644 11.9301 2.3696 12.0535C2.76277 12.1769 3.17738 12.2223 3.5889 12.187C3.687 12.1793 3.78434 12.1672 3.88093 12.1507C4.62877 12.0232 5.30663 11.6437 5.79562 11.0786L6.617 10.1221C6.75077 9.96628 6.81547 9.76517 6.79684 9.56299C6.77822 9.3608 6.6778 9.17409 6.51769 9.04394C6.35758 8.91378 6.15088 8.85084 5.94306 8.86896C5.73525 8.88708 5.54335 8.98477 5.40957 9.14055H5.40958Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

@@ -13,5 +13,6 @@
<qresource prefix="/Notifications">
<file alias="checkmark.svg">Notifications/checkmark.svg</file>
<file alias="download.svg">Notifications/download.svg</file>
<file alias="link.svg">Notifications/link.svg</file>
</qresource>
</RCC>
@@ -39,4 +39,3 @@
#define AZ_TRAIT_DISABLE_FAILED_EMOTION_FX_EDITOR_TESTS true
#define AZ_TRAIT_DISABLE_FAILED_METRICS_TESTS true
#define AZ_TRAIT_DISABLE_ASSET_JOB_PARALLEL_TESTS true
@@ -57,7 +57,6 @@ namespace AzToolsFramework
"Couldn't get prefab loader interface, it's a requirement for PrefabEntityOwnership system to work");
m_rootInstance = AZStd::unique_ptr<Prefab::Instance>(m_prefabSystemComponent->CreatePrefab({}, {}, "NewLevel.prefab"));
m_sliceOwnershipService.BusConnect(m_entityContextId);
m_sliceOwnershipService.m_shouldAssertForLegacySlicesUsage = m_shouldAssertForLegacySlicesUsage;
m_editorSliceOwnershipService.BusConnect();
@@ -91,14 +90,17 @@ namespace AzToolsFramework
void PrefabEditorEntityOwnershipService::Reset()
{
Prefab::TemplateId templateId = m_rootInstance->GetTemplateId();
if (templateId != Prefab::InvalidTemplateId)
if (m_rootInstance)
{
m_rootInstance->SetTemplateId(Prefab::InvalidTemplateId);
m_prefabSystemComponent->RemoveTemplate(templateId);
Prefab::TemplateId templateId = m_rootInstance->GetTemplateId();
if (templateId != Prefab::InvalidTemplateId)
{
m_rootInstance->SetTemplateId(Prefab::InvalidTemplateId);
m_prefabSystemComponent->RemoveTemplate(templateId);
}
m_rootInstance->Reset();
m_rootInstance->SetContainerEntityName("Level");
}
m_rootInstance->Reset();
m_rootInstance->SetContainerEntityName("Level");
AzFramework::EntityOwnershipServiceNotificationBus::Event(
m_entityContextId, &AzFramework::EntityOwnershipServiceNotificationBus::Events::OnEntityOwnershipServiceReset);
@@ -202,7 +204,7 @@ namespace AzToolsFramework
}
m_rootInstance->SetTemplateId(templateId);
m_rootInstance->SetTemplateSourcePath(m_loaderInterface->GetRelativePathToProject(filename));
m_rootInstance->SetTemplateSourcePath(m_loaderInterface->GenerateRelativePath(filename));
m_rootInstance->SetContainerEntityName("Level");
m_prefabSystemComponent->PropagateTemplateChanges(templateId);
@@ -220,7 +222,7 @@ namespace AzToolsFramework
bool PrefabEditorEntityOwnershipService::SaveToStream(AZ::IO::GenericStream& stream, AZStd::string_view filename)
{
AZ::IO::Path relativePath = m_loaderInterface->GetRelativePathToProject(filename);
AZ::IO::Path relativePath = m_loaderInterface->GenerateRelativePath(filename);
AzToolsFramework::Prefab::TemplateId templateId = m_prefabSystemComponent->GetTemplateIdFromFilePath(relativePath);
m_rootInstance->SetTemplateSourcePath(relativePath);
@@ -267,7 +269,7 @@ namespace AzToolsFramework
void PrefabEditorEntityOwnershipService::CreateNewLevelPrefab(AZStd::string_view filename, const AZStd::string& templateFilename)
{
AZ::IO::Path relativePath = m_loaderInterface->GetRelativePathToProject(filename);
AZ::IO::Path relativePath = m_loaderInterface->GenerateRelativePath(filename);
AzToolsFramework::Prefab::TemplateId templateId = m_prefabSystemComponent->GetTemplateIdFromFilePath(relativePath);
m_rootInstance->SetTemplateSourcePath(relativePath);
@@ -378,7 +380,12 @@ namespace AzToolsFramework
Prefab::InstanceOptionalReference PrefabEditorEntityOwnershipService::GetRootPrefabInstance()
{
AZ_Assert(m_rootInstance, "A valid root prefab instance couldn't be found in PrefabEditorEntityOwnershipService.");
return *m_rootInstance;
if (m_rootInstance)
{
return *m_rootInstance;
}
return AZStd::nullopt;
}
const AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& PrefabEditorEntityOwnershipService::GetPlayInEditorAssetData()
@@ -124,7 +124,7 @@ namespace AzToolsFramework
"PrefabLoaderInterface could not be found. It is required to load Prefab Instances");
// Make sure we have a relative path
instance->m_templateSourcePath = loaderInterface->GetRelativePathToProject(instance->m_templateSourcePath);
instance->m_templateSourcePath = loaderInterface->GenerateRelativePath(instance->m_templateSourcePath);
TemplateId templateId = prefabSystemComponentInterface->GetTemplateIdFromFilePath(instance->GetTemplateSourcePath());
@@ -18,7 +18,9 @@
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzCore/StringFunc/StringFunc.h>
#include <AzFramework/Asset/AssetSystemBus.h>
#include <AzFramework/FileFunc/FileFunc.h>
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
#include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
@@ -112,7 +114,7 @@ namespace AzToolsFramework
return InvalidTemplateId;
}
AZ::IO::Path relativePath = GetRelativePathToProject(originPath);
AZ::IO::Path relativePath = GenerateRelativePath(originPath);
// Cyclical dependency detected if the prefab file is already part of the progressed
// file path set.
@@ -385,21 +387,100 @@ namespace AzToolsFramework
AZ::IO::Path pathWithOSSeparator = AZ::IO::Path(path).MakePreferred();
if (pathWithOSSeparator.IsAbsolute())
{
// If an absolute path was passed in, just return it as-is.
return path;
}
return AZ::IO::Path(m_projectPathWithOsSeparator).Append(pathWithOSSeparator);
// A relative path was passed in, so try to turn it back into an absolute path.
AZ::IO::Path fullPath;
bool pathFound = false;
AZ::Data::AssetInfo assetInfo;
AZStd::string rootFolder;
AZStd::string inputPath(path.Native());
// Given an input path that's expected to exist, try to look it up.
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
pathFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath,
inputPath.c_str(), assetInfo, rootFolder);
if (pathFound)
{
// The asset system provided us with a valid root folder and relative path, so return it.
fullPath = AZ::IO::Path(rootFolder) / assetInfo.m_relativePath;
}
else
{
// If for some reason the Asset system couldn't provide a relative path, provide some fallback logic.
// Check to see if the AssetProcessor is ready. If it *is* and we didn't get a path, print an error then follow
// the fallback logic. If it's *not* ready, we're probably either extremely early in a tool startup flow or inside
// a unit test, so just execute the fallback logic without an error.
[[maybe_unused]] bool assetProcessorReady = false;
AzFramework::AssetSystemRequestBus::BroadcastResult(
assetProcessorReady, &AzFramework::AssetSystemRequestBus::Events::AssetProcessorIsReady);
AZ_Error(
"Prefab", !assetProcessorReady, "Full source path for '%.*s' could not be determined. Using fallback logic.",
AZ_STRING_ARG(path.Native()));
// If a relative path was passed in, make it relative to the project root.
fullPath = AZ::IO::Path(m_projectPathWithOsSeparator).Append(pathWithOSSeparator);
}
return fullPath;
}
AZ::IO::Path PrefabLoader::GetRelativePathToProject(AZ::IO::PathView path)
AZ::IO::Path PrefabLoader::GenerateRelativePath(AZ::IO::PathView path)
{
AZ::IO::Path pathWithOSSeparator = AZ::IO::Path(path.Native()).MakePreferred();
if (!pathWithOSSeparator.IsAbsolute())
bool pathFound = false;
AZStd::string relativePath;
AZStd::string rootFolder;
AZ::IO::Path finalPath;
// The asset system allows for paths to be relative to multiple root folders, using a priority system.
// This request will make the input path relative to the most appropriate, highest-priority root folder.
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
pathFound, &AzToolsFramework::AssetSystemRequestBus::Events::GenerateRelativeSourcePath, path.Native(),
relativePath, rootFolder);
if (pathFound && !relativePath.empty())
{
return path;
// A relative path was generated successfully, so return it.
finalPath = relativePath;
}
else
{
// If for some reason the Asset system couldn't provide a relative path, provide some fallback logic.
// Check to see if the AssetProcessor is ready. If it *is* and we didn't get a path, print an error then follow
// the fallback logic. If it's *not* ready, we're probably either extremely early in a tool startup flow or inside
// a unit test, so just execute the fallback logic without an error.
[[maybe_unused]] bool assetProcessorReady = false;
AzFramework::AssetSystemRequestBus::BroadcastResult(
assetProcessorReady, &AzFramework::AssetSystemRequestBus::Events::AssetProcessorIsReady);
AZ_Error("Prefab", !assetProcessorReady,
"Relative source path for '%.*s' could not be determined. Using project path as relative root.",
AZ_STRING_ARG(path.Native()));
AZ::IO::Path pathWithOSSeparator = AZ::IO::Path(path.Native()).MakePreferred();
if (pathWithOSSeparator.IsAbsolute())
{
// If an absolute path was passed in, make it relative to the project path.
finalPath = AZ::IO::Path(path.Native(), '/').MakePreferred().LexicallyRelative(m_projectPathWithSlashSeparator);
}
else
{
// If a relative path was passed in, just return it.
finalPath = path;
}
}
return AZ::IO::Path(path.Native(), '/').MakePreferred().LexicallyRelative(m_projectPathWithSlashSeparator);
return finalPath;
}
AZ::IO::Path PrefabLoaderInterface::GeneratePath()
@@ -91,9 +91,11 @@ namespace AzToolsFramework
//! The path will always have the correct separator for the current OS
AZ::IO::Path GetFullPath(AZ::IO::PathView path) override;
//! Converts path into a relative path to the project, this will be the paths in .prefab file.
//! The path will always have '/' separator.
AZ::IO::Path GetRelativePathToProject(AZ::IO::PathView path) override;
//! Converts path into a path that's relative to the highest-priority containing folder of all the folders registered
//! with the engine.
//! This path will be the path that appears in the .prefab file.
//! The path will always use the '/' separator.
AZ::IO::Path GenerateRelativePath(AZ::IO::PathView path) override;
//! Returns if the path is a valid path for a prefab
static bool IsValidPrefabPath(AZ::IO::PathView path);
@@ -74,9 +74,11 @@ namespace AzToolsFramework
//! The path will always have the correct separator for the current OS
virtual AZ::IO::Path GetFullPath(AZ::IO::PathView path) = 0;
//! Converts path into a relative path to the current project, this will be the paths in .prefab file.
//! The path will always have '/' separator.
virtual AZ::IO::Path GetRelativePathToProject(AZ::IO::PathView path) = 0;
//! Converts path into a path that's relative to the highest-priority containing folder of all the folders registered
//! with the engine.
//! This path will be the path that appears in the .prefab file.
//! The path will always use the '/' separator.
virtual AZ::IO::Path GenerateRelativePath(AZ::IO::PathView path) = 0;
protected:
@@ -318,7 +318,7 @@ namespace AzToolsFramework
}
//Detect whether this instantiation would produce a cyclical dependency
auto relativePath = m_prefabLoaderInterface->GetRelativePathToProject(filePath);
auto relativePath = m_prefabLoaderInterface->GenerateRelativePath(filePath);
Prefab::TemplateId templateId = m_prefabSystemComponentInterface->GetTemplateIdFromFilePath(relativePath);
if (templateId == InvalidTemplateId)
@@ -95,7 +95,7 @@ namespace AzToolsFramework
const AZStd::vector<AZ::Entity*>& entities, AZStd::vector<AZStd::unique_ptr<Instance>>&& instancesToConsume,
AZ::IO::PathView filePath, AZStd::unique_ptr<AZ::Entity> containerEntity, bool shouldCreateLinks)
{
AZ::IO::Path relativeFilePath = m_prefabLoader.GetRelativePathToProject(filePath);
AZ::IO::Path relativeFilePath = m_prefabLoader.GenerateRelativePath(filePath);
if (GetTemplateIdFromFilePath(relativeFilePath) != InvalidTemplateId)
{
AZ_Error("Prefab", false,
@@ -172,7 +172,7 @@ namespace AzToolsFramework
const int autoExpandDelayMilliseconds = 2500;
m_gui->m_objectTree->setSelectionMode(QAbstractItemView::ExtendedSelection);
m_gui->m_objectTree->setEditTriggers(QAbstractItemView::EditKeyPressed);
SetDefaultTreeViewEditTriggers();
m_gui->m_objectTree->setAutoExpandDelay(autoExpandDelayMilliseconds);
m_gui->m_objectTree->setDragEnabled(true);
m_gui->m_objectTree->setDropIndicatorShown(true);
@@ -850,6 +850,11 @@ namespace AzToolsFramework
addAction(m_actionGoToEntitiesInViewport);
}
void EntityOutlinerWidget::SetDefaultTreeViewEditTriggers()
{
m_gui->m_objectTree->setEditTriggers(QAbstractItemView::SelectedClicked | QAbstractItemView::EditKeyPressed);
}
void EntityOutlinerWidget::OnEntityPickModeStarted()
{
m_gui->m_objectTree->setDragEnabled(false);
@@ -862,7 +867,7 @@ namespace AzToolsFramework
{
m_gui->m_objectTree->setDragEnabled(true);
m_gui->m_objectTree->setSelectionMode(QAbstractItemView::ExtendedSelection);
m_gui->m_objectTree->setEditTriggers(QAbstractItemView::SelectedClicked | QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed);
SetDefaultTreeViewEditTriggers();
m_inObjectPickMode = false;
}
@@ -166,6 +166,8 @@ namespace AzToolsFramework
// to a given entity
void QueueScrollToNewContent(const AZ::EntityId& entityId) override;
void SetDefaultTreeViewEditTriggers();
void ScrollToNewContent();
bool m_scrollToNewContentQueued;
bool m_scrollToSelectedEntity;
@@ -333,7 +333,8 @@ namespace AzToolsFramework
}
}
auto createPrefabOutcome = s_prefabPublicInterface->CreatePrefab(selectedEntities, s_prefabLoaderInterface->GetRelativePathToProject(prefabFilePath.data()));
auto createPrefabOutcome = s_prefabPublicInterface->CreatePrefab(
selectedEntities, s_prefabLoaderInterface->GenerateRelativePath(prefabFilePath.data()));
if (!createPrefabOutcome.IsSuccess())
{
@@ -165,15 +165,18 @@ namespace AzToolsFramework
virtual bool AngleSnappingEnabled() = 0;
/// Return the angle snapping/step size.
virtual float AngleStep() = 0;
/// Transform a point in world space to screen space coordinates.
/// 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 in screen space coordinates to a vector in world space based on clip space depth.
/// 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.
virtual AZStd::optional<ProjectedViewportRay> ViewportScreenToWorldRay(const AzFramework::ScreenPoint& screenPosition) = 0;
/// Gets the DPI scaling factor that translates Qt widget space into viewport pixel space.
virtual float DeviceScalingFactor() = 0;
protected:
~ViewportInteractionRequests() = default;