Merge branch 'main' into DetachPrefab
This commit is contained in:
@@ -60,10 +60,20 @@ namespace AzToolsFramework
|
||||
//! and is generally checked into source control.
|
||||
virtual const char* GetAbsoluteDevRootFolderPath() = 0;
|
||||
|
||||
/// Convert a full source path like "c:\\dev\gamename\\blah\\test.tga" into a relative product path.
|
||||
/// Convert a full source path like "c:\\dev\\gamename\\blah\\test.tga" into a relative product path.
|
||||
/// asset paths never mention their alias and are relative to the asset cache root
|
||||
virtual bool GetRelativeProductPathFromFullSourceOrProductPath(const AZStd::string& fullPath, AZStd::string& relativeProductPath) = 0;
|
||||
|
||||
/** Convert a source path like "c:\\dev\\gamename\\blah\\test.tga" into a relative source path, like "blah/test.tga".
|
||||
* If no valid relative path could be created, the input source path will be returned in relativePath.
|
||||
* @param sourcePath partial or full path to a source file. (The file doesn't need to exist)
|
||||
* @param relativePath the output relative path for the source file, if a valid one could be created
|
||||
* @param rootFilePath the root path that relativePath is relative to
|
||||
* @return true if a valid relative path was created, false if it wasn't
|
||||
*/
|
||||
virtual bool GenerateRelativeSourcePath(
|
||||
const AZStd::string& sourcePath, AZStd::string& relativePath, AZStd::string& rootFilePath) = 0;
|
||||
|
||||
/// Convert a relative asset path like "blah/test.tga" to a full source path path.
|
||||
/// Once the asset processor has finished building, this function is capable of handling even when the extension changes
|
||||
/// or when the source is in a different folder or in a different location (such as inside gems)
|
||||
@@ -110,14 +120,14 @@ namespace AzToolsFramework
|
||||
|
||||
/**
|
||||
* Query to see if a specific asset platform is enabled
|
||||
* @param platform the asset platform to check e.g. es3, ios, etc.
|
||||
* @param platform the asset platform to check e.g. android, ios, etc.
|
||||
* @return true if enabled, false otherwise
|
||||
*/
|
||||
virtual bool IsAssetPlatformEnabled(const char* platform) = 0;
|
||||
|
||||
/**
|
||||
* Get the total number of pending assets left to process for a specific asset platform
|
||||
* @param platform the asset platform to check e.g. es3, ios, etc.
|
||||
* @param platform the asset platform to check e.g. android, ios, etc.
|
||||
* @return -1 if the process fails, a positive number otherwise
|
||||
*/
|
||||
virtual int GetPendingAssetsForPlatform(const char* platform) = 0;
|
||||
@@ -302,7 +312,7 @@ namespace AzToolsFramework
|
||||
inline const char* GetHostAssetPlatform()
|
||||
{
|
||||
#if defined(AZ_PLATFORM_MAC)
|
||||
return "osx_gl";
|
||||
return "mac";
|
||||
#elif defined(AZ_PLATFORM_WINDOWS)
|
||||
return "pc";
|
||||
#elif defined(AZ_PLATFORM_LINUX)
|
||||
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/RTTI/RTTI.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Math/Color.h>
|
||||
|
||||
#include <AzFramework/Viewport/ViewportId.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
//! An interface for loading simple icon assets and rendering them to screen on a per-viewport basis.
|
||||
class EditorViewportIconDisplayInterface
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(EditorViewportIconDisplayInterface, "{D5190B58-2561-4F3F-B793-F1E7D454CDF2}");
|
||||
|
||||
using IconId = AZ::s32;
|
||||
static constexpr IconId InvalidIconId = -1;
|
||||
|
||||
enum class CoordinateSpace : AZ::u8
|
||||
{
|
||||
ScreenSpace,
|
||||
WorldSpace
|
||||
};
|
||||
|
||||
//! These draw parameters control rendering for a single icon to a single viewport.
|
||||
struct DrawParameters
|
||||
{
|
||||
//! The ViewportId to render to.
|
||||
AzFramework::ViewportId m_viewport = AzFramework::InvalidViewportId;
|
||||
//! The icon ID, retrieved from GetOrLoadIconForPath, to render to screen.
|
||||
IconId m_icon = InvalidIconId;
|
||||
//! The color, including opacity, to render the icon with. White will render the icon as opaque in its original color.
|
||||
AZ::Color m_color = AZ::Colors::White;
|
||||
//! The position to render the icon to, in world or screen space depending on m_positionSpace.
|
||||
AZ::Vector3 m_position;
|
||||
//! The coordinate system to use for m_position.
|
||||
//! ScreenSpace will accept m_position in the form of [X, Y, Depth], where X & Y are screen coordinates in
|
||||
//! pixels and Depth is a z-ordering depth value from 0.0f to 1.0f.
|
||||
//! WorldSpace will accept a 3D vector in world space coordinates that will be translated back into screen
|
||||
//! space when the icon is rendered.
|
||||
CoordinateSpace m_positionSpace = CoordinateSpace::ScreenSpace;
|
||||
//! The size to render the icon as, in pixels.
|
||||
AZ::Vector2 m_size;
|
||||
};
|
||||
|
||||
//! The current load status of an icon retrieved by GetOrLoadIconForPath.
|
||||
enum class IconLoadStatus : AZ::u8
|
||||
{
|
||||
Unloaded,
|
||||
Loading,
|
||||
Loaded,
|
||||
Error
|
||||
};
|
||||
|
||||
//! Draws an icon to a viewport given a set of draw parameters.
|
||||
//! Requires an IconId retrieved from GetOrLoadIconForPath.
|
||||
virtual void DrawIcon(const DrawParameters& drawParameters) = 0;
|
||||
//! Retrieves a reusable IconId for an icon at a given path.
|
||||
//! This will load the icon, if it has not already been loaded.
|
||||
//! @param path should be a relative asset path to an icon image asset.
|
||||
//! png and svg icons are currently supported.
|
||||
virtual IconId GetOrLoadIconForPath(AZStd::string_view path) = 0;
|
||||
//! Gets the current load status of an icon retrieved via GetOrLoadIconForPath.
|
||||
virtual IconLoadStatus GetIconLoadStatus(IconId icon) = 0;
|
||||
};
|
||||
|
||||
using EditorViewportIconDisplay = AZ::Interface<EditorViewportIconDisplayInterface>;
|
||||
} //namespace AzToolsFramework
|
||||
@@ -265,6 +265,30 @@ namespace AzToolsFramework
|
||||
return response.m_resolved;
|
||||
}
|
||||
|
||||
bool AssetSystemComponent::GenerateRelativeSourcePath(
|
||||
const AZStd::string& sourcePath, AZStd::string& relativePath, AZStd::string& rootFilePath)
|
||||
{
|
||||
AzFramework::SocketConnection* engineConnection = AzFramework::SocketConnection::GetInstance();
|
||||
if (!engineConnection || !engineConnection->IsConnected())
|
||||
{
|
||||
relativePath = sourcePath;
|
||||
return false;
|
||||
}
|
||||
|
||||
AzFramework::AssetSystem::GenerateRelativeSourcePathRequest request(sourcePath);
|
||||
AzFramework::AssetSystem::GenerateRelativeSourcePathResponse response;
|
||||
if (!SendRequest(request, response))
|
||||
{
|
||||
AZ_Error("Editor", false, "Failed to send GenerateRelativeSourcePath request for %s", sourcePath.c_str());
|
||||
relativePath = sourcePath;
|
||||
return false;
|
||||
}
|
||||
|
||||
relativePath = response.m_relativeSourcePath;
|
||||
rootFilePath = response.m_rootFolder;
|
||||
return response.m_resolved;
|
||||
}
|
||||
|
||||
bool AssetSystemComponent::GetFullSourcePathFromRelativeProductPath(const AZStd::string& relPath, AZStd::string& fullPath)
|
||||
{
|
||||
auto foundIt = m_assetSourceRelativePathToFullPathCache.find(relPath);
|
||||
|
||||
@@ -63,6 +63,8 @@ namespace AzToolsFramework
|
||||
const char* GetAbsoluteDevGameFolderPath() override;
|
||||
const char* GetAbsoluteDevRootFolderPath() override;
|
||||
bool GetRelativeProductPathFromFullSourceOrProductPath(const AZStd::string& fullPath, AZStd::string& outputPath) override;
|
||||
bool GenerateRelativeSourcePath(
|
||||
const AZStd::string& sourcePath, AZStd::string& outputPath, AZStd::string& watchFolder) override;
|
||||
bool GetFullSourcePathFromRelativeProductPath(const AZStd::string& relPath, AZStd::string& fullPath) override;
|
||||
bool GetAssetInfoById(const AZ::Data::AssetId& assetId, const AZ::Data::AssetType& assetType, const AZStd::string& platformName, AZ::Data::AssetInfo& assetInfo, AZStd::string& rootFilePath) override;
|
||||
bool GetSourceInfoBySourcePath(const char* sourcePath, AZ::Data::AssetInfo& assetInfo, AZStd::string& watchFolder) override;
|
||||
|
||||
@@ -483,6 +483,8 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
m_dirty = false;
|
||||
|
||||
AddRecentPath(targetFilePath);
|
||||
|
||||
SetStatusText(Status::assetCreated);
|
||||
|
||||
+2
@@ -56,5 +56,7 @@ namespace AzToolsFramework
|
||||
|
||||
virtual void StartPlayInEditor() = 0;
|
||||
virtual void StopPlayInEditor() = 0;
|
||||
|
||||
virtual void CreateNewLevelPrefab(AZStd::string_view filename, const AZStd::string& templateFilename) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
+90
-56
@@ -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,55 +222,24 @@ 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);
|
||||
|
||||
bool newLevelFromTemplate = false;
|
||||
|
||||
if (templateId == AzToolsFramework::Prefab::InvalidTemplateId)
|
||||
{
|
||||
AZStd::string watchFolder;
|
||||
AZ::Data::AssetInfo assetInfo;
|
||||
bool sourceInfoFound = false;
|
||||
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
|
||||
sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, DefaultLevelTemplateName,
|
||||
assetInfo, watchFolder);
|
||||
m_rootInstance->m_containerEntity->AddComponent(aznew Prefab::EditorPrefabComponent());
|
||||
HandleEntitiesAdded({ m_rootInstance->m_containerEntity.get() });
|
||||
|
||||
if (sourceInfoFound)
|
||||
AzToolsFramework::Prefab::PrefabDom dom;
|
||||
bool success = AzToolsFramework::Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*m_rootInstance, dom);
|
||||
if (!success)
|
||||
{
|
||||
AZStd::string fullPath;
|
||||
AZ::StringFunc::Path::Join(watchFolder.c_str(), assetInfo.m_relativePath.c_str(), fullPath);
|
||||
|
||||
// Get the default prefab and copy the Dom over to the new template being saved
|
||||
Prefab::TemplateId defaultId = m_loaderInterface->LoadTemplateFromFile(fullPath.c_str());
|
||||
Prefab::PrefabDom& dom = m_prefabSystemComponent->FindTemplateDom(defaultId);
|
||||
|
||||
Prefab::PrefabDom levelDefaultDom;
|
||||
levelDefaultDom.CopyFrom(dom, levelDefaultDom.GetAllocator());
|
||||
|
||||
Prefab::PrefabDomPath sourcePath("/Source");
|
||||
sourcePath.Set(levelDefaultDom, relativePath.c_str());
|
||||
|
||||
templateId = m_prefabSystemComponent->AddTemplate(relativePath, std::move(levelDefaultDom));
|
||||
newLevelFromTemplate = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create an empty level since we couldn't find the default template
|
||||
m_rootInstance->m_containerEntity->AddComponent(aznew Prefab::EditorPrefabComponent());
|
||||
HandleEntitiesAdded({ m_rootInstance->m_containerEntity.get() });
|
||||
|
||||
AzToolsFramework::Prefab::PrefabDom dom;
|
||||
bool success = AzToolsFramework::Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*m_rootInstance, dom);
|
||||
if (!success)
|
||||
{
|
||||
AZ_Error("Prefab", false, "Failed to convert current root instance into a DOM when saving file '%.*s'", AZ_STRING_ARG(filename));
|
||||
return false;
|
||||
}
|
||||
templateId = m_prefabSystemComponent->AddTemplate(relativePath, std::move(dom));
|
||||
AZ_Error("Prefab", false, "Failed to convert current root instance into a DOM when saving file '%.*s'", AZ_STRING_ARG(filename));
|
||||
return false;
|
||||
}
|
||||
templateId = m_prefabSystemComponent->AddTemplate(relativePath, AZStd::move(dom));
|
||||
|
||||
if (templateId == AzToolsFramework::Prefab::InvalidTemplateId)
|
||||
{
|
||||
@@ -286,13 +257,6 @@ namespace AzToolsFramework
|
||||
m_prefabSystemComponent->RemoveTemplate(prevTemplateId);
|
||||
}
|
||||
|
||||
// If we have a new level from a template, we need to make sure to propagate the changes here otherwise
|
||||
// the entities from the new template won't show up
|
||||
if (newLevelFromTemplate)
|
||||
{
|
||||
m_prefabSystemComponent->PropagateTemplateChanges(templateId);
|
||||
}
|
||||
|
||||
AZStd::string out;
|
||||
if (m_loaderInterface->SaveTemplateToString(m_rootInstance->GetTemplateId(), out))
|
||||
{
|
||||
@@ -303,6 +267,71 @@ namespace AzToolsFramework
|
||||
return false;
|
||||
}
|
||||
|
||||
void PrefabEditorEntityOwnershipService::CreateNewLevelPrefab(AZStd::string_view filename, const AZStd::string& templateFilename)
|
||||
{
|
||||
AZ::IO::Path relativePath = m_loaderInterface->GenerateRelativePath(filename);
|
||||
AzToolsFramework::Prefab::TemplateId templateId = m_prefabSystemComponent->GetTemplateIdFromFilePath(relativePath);
|
||||
|
||||
m_rootInstance->SetTemplateSourcePath(relativePath);
|
||||
|
||||
AZStd::string watchFolder;
|
||||
AZ::Data::AssetInfo assetInfo;
|
||||
bool sourceInfoFound = false;
|
||||
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
|
||||
sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, templateFilename.c_str(),
|
||||
assetInfo, watchFolder);
|
||||
|
||||
if (sourceInfoFound)
|
||||
{
|
||||
AZStd::string fullPath;
|
||||
AZ::StringFunc::Path::Join(watchFolder.c_str(), assetInfo.m_relativePath.c_str(), fullPath);
|
||||
|
||||
// Get the default prefab and copy the Dom over to the new template being saved
|
||||
Prefab::TemplateId defaultId = m_loaderInterface->LoadTemplateFromFile(fullPath.c_str());
|
||||
Prefab::PrefabDom& dom = m_prefabSystemComponent->FindTemplateDom(defaultId);
|
||||
|
||||
Prefab::PrefabDom levelDefaultDom;
|
||||
levelDefaultDom.CopyFrom(dom, levelDefaultDom.GetAllocator());
|
||||
|
||||
Prefab::PrefabDomPath sourcePath("/Source");
|
||||
sourcePath.Set(levelDefaultDom, relativePath.c_str());
|
||||
|
||||
templateId = m_prefabSystemComponent->AddTemplate(relativePath, AZStd::move(levelDefaultDom));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rootInstance->m_containerEntity->AddComponent(aznew Prefab::EditorPrefabComponent());
|
||||
HandleEntitiesAdded({ m_rootInstance->m_containerEntity.get() });
|
||||
|
||||
AzToolsFramework::Prefab::PrefabDom dom;
|
||||
bool success = AzToolsFramework::Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*m_rootInstance, dom);
|
||||
if (!success)
|
||||
{
|
||||
AZ_Error(
|
||||
"Prefab", false, "Failed to convert current root instance into a DOM when saving file '%.*s'", AZ_STRING_ARG(filename));
|
||||
return;
|
||||
}
|
||||
templateId = m_prefabSystemComponent->AddTemplate(relativePath, std::move(dom));
|
||||
}
|
||||
|
||||
if (templateId == AzToolsFramework::Prefab::InvalidTemplateId)
|
||||
{
|
||||
AZ_Error("Prefab", false, "Couldn't create new template id '%i' when creating new level '%.*s'", templateId, AZ_STRING_ARG(filename));
|
||||
return;
|
||||
}
|
||||
|
||||
Prefab::TemplateId prevTemplateId = m_rootInstance->GetTemplateId();
|
||||
m_rootInstance->SetTemplateId(templateId);
|
||||
|
||||
if (prevTemplateId != Prefab::InvalidTemplateId && templateId != prevTemplateId)
|
||||
{
|
||||
// Make sure we only have one level template loaded at a time
|
||||
m_prefabSystemComponent->RemoveTemplate(prevTemplateId);
|
||||
}
|
||||
|
||||
m_prefabSystemComponent->PropagateTemplateChanges(templateId);
|
||||
}
|
||||
|
||||
Prefab::InstanceOptionalReference PrefabEditorEntityOwnershipService::CreatePrefab(
|
||||
const AZStd::vector<AZ::Entity*>& entities, AZStd::vector<AZStd::unique_ptr<Prefab::Instance>>&& nestedPrefabInstances,
|
||||
AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder)
|
||||
@@ -351,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()
|
||||
|
||||
+2
-2
@@ -170,6 +170,8 @@ namespace AzToolsFramework
|
||||
void StartPlayInEditor() override;
|
||||
void StopPlayInEditor() override;
|
||||
|
||||
void CreateNewLevelPrefab(AZStd::string_view filename, const AZStd::string& templateFilename) override;
|
||||
|
||||
protected:
|
||||
|
||||
AZ::SliceComponent::SliceInstanceAddress GetOwningSlice() override;
|
||||
@@ -216,7 +218,5 @@ namespace AzToolsFramework
|
||||
Prefab::PrefabLoaderInterface* m_loaderInterface;
|
||||
AzFramework::EntityContextId m_entityContextId;
|
||||
AZ::SerializeContext m_serializeContext;
|
||||
|
||||
static inline constexpr const char* DefaultLevelTemplateName = "Prefabs/Default_Level.prefab";
|
||||
};
|
||||
}
|
||||
|
||||
+1
-1
@@ -614,7 +614,7 @@ namespace AzToolsFramework
|
||||
|
||||
AZ::Quaternion oldEntityRotation;
|
||||
AZ::TransformBus::EventResult(oldEntityRotation, id, &AZ::TransformBus::Events::GetWorldRotationQuaternion);
|
||||
transformComponent->SetRotationQuaternion(oldEntityRotation);
|
||||
transformComponent->SetWorldRotationQuaternion(oldEntityRotation);
|
||||
|
||||
// Ensure the existing hierarchy is maintained
|
||||
AZ::EntityId oldParentEntityId;
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ namespace AzToolsFramework
|
||||
rayProportion, lineSegmentProportion, worldClosestPositionRay, worldClosestPositionLineSegment);
|
||||
|
||||
AZ::Transform worldFromLocalNormalized = worldFromLocal;
|
||||
const AZ::Vector3 scale = worldFromLocalNormalized.ExtractScale() * nonUniformScale;
|
||||
const AZ::Vector3 scale = worldFromLocalNormalized.ExtractUniformScale() * nonUniformScale;
|
||||
const AZ::Transform localFromWorldNormalized = worldFromLocalNormalized.GetInverse();
|
||||
|
||||
return { (localFromWorldNormalized.TransformPoint(worldClosestPositionLineSegment)) / scale };
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace AzToolsFramework
|
||||
? CalculateSnappedOffset(localTransform.GetTranslation(), axis, gridSize * scaleRecip)
|
||||
: AZ::Vector3::CreateZero();
|
||||
|
||||
const AZ::Vector3 localScale = localTransform.GetScale();
|
||||
const AZ::Vector3 localScale = AZ::Vector3(localTransform.GetUniformScale());
|
||||
const AZ::Quaternion localRotation = QuaternionFromTransformNoScaling(localTransform);
|
||||
// calculate scale amount to snap, to align to round scale value
|
||||
const AZ::Vector3 scaleSnapOffset = snapping && !gridSnapAction.m_localSnapping
|
||||
|
||||
@@ -113,7 +113,7 @@ namespace AzToolsFramework
|
||||
/// noise in the value returned when dealing with values far from the origin.
|
||||
inline float ScaleReciprocal(const AZ::Transform& transform)
|
||||
{
|
||||
return Round3(transform.GetScale().GetReciprocal().GetMinElement());
|
||||
return Round3(1.0f / transform.GetUniformScale());
|
||||
}
|
||||
|
||||
/// Find the reciprocal of the non-uniform scale.
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace AzToolsFramework
|
||||
AZ::Transform result;
|
||||
result.SetRotation(m_space.GetRotation() * localTransform.GetRotation());
|
||||
result.SetTranslation(m_space.TransformPoint(m_nonUniformScale * localTransform.GetTranslation()));
|
||||
result.SetScale(m_space.GetScale() * localTransform.GetScale());
|
||||
result.SetUniformScale(m_space.GetUniformScale() * localTransform.GetUniformScale());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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.
|
||||
@@ -301,6 +303,45 @@ namespace AzToolsFramework
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PrefabLoader::SaveTemplateToFile(TemplateId templateId, AZ::IO::PathView absolutePath)
|
||||
{
|
||||
AZ_Assert(absolutePath.IsAbsolute(), "SaveTemplateToFile requires an absolute path for saving the initial prefab file.");
|
||||
|
||||
const auto& domAndFilepath = StoreTemplateIntoFileFormat(templateId);
|
||||
if (!domAndFilepath)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify that the absolute path provided to this matches the relative path saved in the template.
|
||||
// Otherwise, the saved prefab won't be able to be loaded.
|
||||
auto relativePath = GenerateRelativePath(absolutePath);
|
||||
if (relativePath != domAndFilepath->second)
|
||||
{
|
||||
AZ_Error(
|
||||
"Prefab", false,
|
||||
"PrefabLoader::SaveTemplateToFile - "
|
||||
"Failed to save template '%s' to location '%.*s'."
|
||||
"Error: Relative path '%.*s' for location didn't match template name.",
|
||||
domAndFilepath->second.c_str(), AZ_STRING_ARG(absolutePath.Native()), AZ_STRING_ARG(relativePath.Native()));
|
||||
return false;
|
||||
}
|
||||
|
||||
auto outcome = AzFramework::FileFunc::WriteJsonFile(domAndFilepath->first, absolutePath);
|
||||
if (!outcome.IsSuccess())
|
||||
{
|
||||
AZ_Error(
|
||||
"Prefab", false,
|
||||
"PrefabLoader::SaveTemplateToFile - "
|
||||
"Failed to save template '%s' to location '%.*s'."
|
||||
"Error: %s",
|
||||
domAndFilepath->second.c_str(), AZ_STRING_ARG(absolutePath.Native()), outcome.GetError().c_str());
|
||||
return false;
|
||||
}
|
||||
m_prefabSystemComponentInterface->SetTemplateDirtyFlag(templateId, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PrefabLoader::SaveTemplateToString(TemplateId templateId, AZStd::string& output)
|
||||
{
|
||||
const auto& domAndFilepath = StoreTemplateIntoFileFormat(templateId);
|
||||
@@ -385,21 +426,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()
|
||||
|
||||
@@ -72,6 +72,16 @@ namespace AzToolsFramework
|
||||
*/
|
||||
bool SaveTemplate(TemplateId templateId) override;
|
||||
|
||||
/**
|
||||
* Saves a Prefab Template to the provided absolute source path, which needs to match the relative path in the template.
|
||||
* Converts Prefab Template form into .prefab form by collapsing nested Template info
|
||||
* into a source path and patches.
|
||||
* @param templateId Id of the template to be saved
|
||||
* @param absolutePath Absolute path to save the file to
|
||||
* @return bool on whether the operation succeeded or not
|
||||
*/
|
||||
bool SaveTemplateToFile(TemplateId templateId, AZ::IO::PathView absolutePath) override;
|
||||
|
||||
/**
|
||||
* Saves a Prefab Template into the provided output string.
|
||||
* Converts Prefab Template form into .prefab form by collapsing nested Template info
|
||||
@@ -91,9 +101,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);
|
||||
|
||||
@@ -60,6 +60,16 @@ namespace AzToolsFramework
|
||||
*/
|
||||
virtual bool SaveTemplate(TemplateId templateId) = 0;
|
||||
|
||||
/**
|
||||
* Saves a Prefab Template to the provided absolute source path, which needs to match the relative path in the template.
|
||||
* Converts Prefab Template form into .prefab form by collapsing nested Template info
|
||||
* into a source path and patches.
|
||||
* @param templateId Id of the template to be saved
|
||||
* @param absolutePath Absolute path to save the file to
|
||||
* @return bool on whether the operation succeeded or not
|
||||
*/
|
||||
virtual bool SaveTemplateToFile(TemplateId templateId, AZ::IO::PathView absolutePath) = 0;
|
||||
|
||||
/**
|
||||
* Saves a Prefab Template into the provided output string.
|
||||
* Converts Prefab Template form into .prefab form by collapsing nested Template info
|
||||
@@ -74,9 +84,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:
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace AzToolsFramework
|
||||
m_prefabUndoCache.Destroy();
|
||||
}
|
||||
|
||||
PrefabOperationResult PrefabPublicHandler::CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView filePath)
|
||||
PrefabOperationResult PrefabPublicHandler::CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView absolutePath)
|
||||
{
|
||||
EntityList inputEntityList, topLevelEntities;
|
||||
AZ::EntityId commonRootEntityId;
|
||||
@@ -77,6 +77,8 @@ namespace AzToolsFramework
|
||||
return findCommonRootOutcome;
|
||||
}
|
||||
|
||||
AZ_Assert(absolutePath.IsAbsolute(), "CreatePrefab requires an absolute path for saving the initial prefab file.");
|
||||
|
||||
InstanceOptionalReference instanceToCreate;
|
||||
{
|
||||
// Initialize Undo Batch object
|
||||
@@ -145,7 +147,8 @@ namespace AzToolsFramework
|
||||
|
||||
// Create the Prefab
|
||||
instanceToCreate = prefabEditorEntityOwnershipInterface->CreatePrefab(
|
||||
entities, AZStd::move(instancePtrs), filePath, commonRootEntityOwningInstance);
|
||||
entities, AZStd::move(instancePtrs), m_prefabLoaderInterface->GenerateRelativePath(absolutePath),
|
||||
commonRootEntityOwningInstance);
|
||||
|
||||
if (!instanceToCreate)
|
||||
{
|
||||
@@ -238,7 +241,7 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
// Save Template to file
|
||||
m_prefabLoaderInterface->SaveTemplate(instanceToCreate->get().GetTemplateId());
|
||||
m_prefabLoaderInterface->SaveTemplateToFile(instanceToCreate->get().GetTemplateId(), absolutePath);
|
||||
|
||||
return AZ::Success();
|
||||
}
|
||||
@@ -302,7 +305,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)
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace AzToolsFramework
|
||||
void UnregisterPrefabPublicHandlerInterface();
|
||||
|
||||
// PrefabPublicInterface...
|
||||
PrefabOperationResult CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView filePath) override;
|
||||
PrefabOperationResult CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView absolutePath) override;
|
||||
PrefabOperationResult InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position) override;
|
||||
PrefabOperationResult SavePrefab(AZ::IO::Path filePath) override;
|
||||
PrefabEntityResult CreateEntity(AZ::EntityId parentId, const AZ::Vector3& position) override;
|
||||
|
||||
@@ -46,10 +46,10 @@ namespace AzToolsFramework
|
||||
* Create a prefab out of the entities provided, at the path provided.
|
||||
* Automatically detects descendants of entities, and discerns between entities and child instances.
|
||||
* @param entityIds The entities that should form the new prefab (along with their descendants).
|
||||
* @param filePath The path for the new prefab file.
|
||||
* @param filePath The absolute path for the new prefab file.
|
||||
* @return An outcome object; on failure, it comes with an error message detailing the cause of the error.
|
||||
*/
|
||||
virtual PrefabOperationResult CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView filePath) = 0;
|
||||
virtual PrefabOperationResult CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView absolutePath) = 0;
|
||||
|
||||
/**
|
||||
* Instantiate a prefab from a prefab file.
|
||||
|
||||
@@ -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,
|
||||
|
||||
+2
-3
@@ -10,7 +10,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Casting/lossy_cast.h>
|
||||
#include <AzFramework/Spawnable/SpawnableAssetHandler.h>
|
||||
#include <AzToolsFramework/Prefab/Spawnable/ProcesedObjectStore.h>
|
||||
|
||||
namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
@@ -73,8 +73,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
|
||||
uint32_t ProcessedObjectStore::BuildSubId(AZStd::string_view id)
|
||||
{
|
||||
AZ::Uuid subIdHash = AZ::Uuid::CreateData(id.data(), id.size());
|
||||
return azlossy_caster(subIdHash.GetHash());
|
||||
return AzFramework::SpawnableAssetHandler::BuildSubId(id);
|
||||
}
|
||||
|
||||
const AZStd::string& ProcessedObjectStore::GetId() const
|
||||
|
||||
+19
-20
@@ -1,22 +1,22 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzToolsFramework/ToolsComponents/EditorComponentBase.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorVisibilityBus.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/EditContextConstants.inl>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorComponentBase.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorVisibilityBus.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
@@ -31,7 +31,7 @@ namespace AzToolsFramework
|
||||
To use the EditorComponentAdapter, 3 classes are required:
|
||||
- a class that implements the functions required for TController (see below)
|
||||
- a configuration struct/class which extends AZ::ComponentConfig
|
||||
- A runtime component that will be generated by the editor comoinent on export
|
||||
- A runtime component that will be generated by the editor component on export
|
||||
|
||||
The concrete component extends the adapter and implements behavior which is unique to the component.
|
||||
|
||||
@@ -64,15 +64,15 @@ namespace AzToolsFramework
|
||||
the EditContext. TController can friend itself to the editor component to make this work if required.
|
||||
*/
|
||||
template<typename TController, typename TRuntimeComponent, typename TConfiguration = AZ::ComponentConfig>
|
||||
class EditorComponentAdapter
|
||||
: public EditorComponentBase
|
||||
class EditorComponentAdapter : public EditorComponentBase
|
||||
{
|
||||
public:
|
||||
|
||||
AZ_RTTI((EditorComponentAdapter, "{2F5A3669-FFE9-4CD7-B9E2-7FC8100CF1A2}", TController, TRuntimeComponent, TConfiguration), EditorComponentBase);
|
||||
AZ_RTTI(
|
||||
(EditorComponentAdapter, "{2F5A3669-FFE9-4CD7-B9E2-7FC8100CF1A2}", TController, TRuntimeComponent, TConfiguration),
|
||||
EditorComponentBase);
|
||||
|
||||
EditorComponentAdapter() = default;
|
||||
EditorComponentAdapter(const TConfiguration& configuration);
|
||||
explicit EditorComponentAdapter(const TConfiguration& configuration);
|
||||
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services);
|
||||
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services);
|
||||
@@ -86,7 +86,6 @@ namespace AzToolsFramework
|
||||
void BuildGameEntity(AZ::Entity* gameEntity) override;
|
||||
|
||||
protected:
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
// AZ::Component overrides ...
|
||||
|
||||
+39
-30
@@ -1,14 +1,14 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzFramework/Components/ComponentAdapterHelpers.h>
|
||||
|
||||
@@ -28,23 +28,21 @@ namespace AzToolsFramework
|
||||
template<typename TController, typename TRuntimeComponent, typename TConfiguration>
|
||||
void EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<EditorComponentAdapter, EditorComponentBase>()
|
||||
->Version(1)
|
||||
->Field("Controller", &EditorComponentAdapter::m_controller)
|
||||
;
|
||||
serializeContext->Class<EditorComponentAdapter, EditorComponentBase>()->Version(1)->Field(
|
||||
"Controller", &EditorComponentAdapter::m_controller);
|
||||
|
||||
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
|
||||
{
|
||||
editContext->Class<EditorComponentAdapter>(
|
||||
"EditorComponentAdapter", "")
|
||||
// clang-format off
|
||||
editContext->Class<EditorComponentAdapter>("EditorComponentAdapter", "")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &EditorComponentAdapter::m_controller, "Controller", "")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorComponentAdapter::OnConfigurationChanged)
|
||||
;
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorComponentAdapter::OnConfigurationChanged);
|
||||
// clang-format on
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,27 +51,35 @@ namespace AzToolsFramework
|
||||
// Get*Services functions
|
||||
|
||||
template<typename TController, typename TRuntimeComponent, typename TConfiguration>
|
||||
void EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services)
|
||||
void EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>::GetProvidedServices(
|
||||
AZ::ComponentDescriptor::DependencyArrayType& services)
|
||||
{
|
||||
AzFramework::Components::GetProvidedServicesHelper<TController>(services, typename AZ::HasComponentProvidedServices<TController>::type());
|
||||
AzFramework::Components::GetProvidedServicesHelper<TController>(
|
||||
services, typename AZ::HasComponentProvidedServices<TController>::type());
|
||||
}
|
||||
|
||||
template<typename TController, typename TRuntimeComponent, typename TConfiguration>
|
||||
void EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& services)
|
||||
void EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>::GetRequiredServices(
|
||||
AZ::ComponentDescriptor::DependencyArrayType& services)
|
||||
{
|
||||
AzFramework::Components::GetRequiredServicesHelper<TController>(services, typename AZ::HasComponentRequiredServices<TController>::type());
|
||||
AzFramework::Components::GetRequiredServicesHelper<TController>(
|
||||
services, typename AZ::HasComponentRequiredServices<TController>::type());
|
||||
}
|
||||
|
||||
template<typename TController, typename TRuntimeComponent, typename TConfiguration>
|
||||
void EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services)
|
||||
void EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>::GetIncompatibleServices(
|
||||
AZ::ComponentDescriptor::DependencyArrayType& services)
|
||||
{
|
||||
AzFramework::Components::GetIncompatibleServicesHelper<TController>(services, typename AZ::HasComponentIncompatibleServices<TController>::type());
|
||||
AzFramework::Components::GetIncompatibleServicesHelper<TController>(
|
||||
services, typename AZ::HasComponentIncompatibleServices<TController>::type());
|
||||
}
|
||||
|
||||
template<typename TController, typename TRuntimeComponent, typename TConfiguration>
|
||||
void EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& services)
|
||||
void EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>::GetDependentServices(
|
||||
AZ::ComponentDescriptor::DependencyArrayType& services)
|
||||
{
|
||||
AzFramework::Components::GetDependentServicesHelper<TController>(services, typename AZ::HasComponentDependentServices<TController>::type());
|
||||
AzFramework::Components::GetDependentServicesHelper<TController>(
|
||||
services, typename AZ::HasComponentDependentServices<TController>::type());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -99,7 +105,8 @@ namespace AzToolsFramework
|
||||
|
||||
if (ShouldActivateController())
|
||||
{
|
||||
m_controller.Activate(GetEntityId());
|
||||
AzFramework::Components::ComponentActivateHelper<TController>::Activate(
|
||||
m_controller, AZ::EntityComponentIdPair(GetEntityId(), GetId()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +129,8 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
template<typename TController, typename TRuntimeComponent, typename TConfiguration>
|
||||
bool EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>::WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const
|
||||
bool EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>::WriteOutConfig(
|
||||
AZ::ComponentConfig* outBaseConfig) const
|
||||
{
|
||||
if (auto config = azrtti_cast<TConfiguration*>(outBaseConfig))
|
||||
{
|
||||
@@ -139,7 +147,8 @@ namespace AzToolsFramework
|
||||
|
||||
if (ShouldActivateController())
|
||||
{
|
||||
m_controller.Activate(GetEntityId());
|
||||
AzFramework::Components::ComponentActivateHelper<TController>::Activate(
|
||||
m_controller, AZ::EntityComponentIdPair(GetEntityId(), GetId()));
|
||||
}
|
||||
|
||||
return AZ::Edit::PropertyRefreshLevels::None;
|
||||
|
||||
+2
-2
@@ -17,6 +17,7 @@
|
||||
#include <AzCore/Asset/AssetManagerBus.h>
|
||||
|
||||
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
#include <AzToolsFramework/API/EditorViewportIconDisplayInterface.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorVisibilityBus.h>
|
||||
#include <AzToolsFramework/ToolsComponents/GenericComponentWrapper.h>
|
||||
@@ -313,8 +314,7 @@ namespace AzToolsFramework
|
||||
// if we do not yet have a valid texture id, request it using the entity icon path
|
||||
if (m_entityIconTextureId == 0)
|
||||
{
|
||||
EditorRequestBus::BroadcastResult(
|
||||
m_entityIconTextureId, &EditorRequests::GetIconTextureIdFromEntityIconPath, m_entityIconPath);
|
||||
m_entityIconTextureId = EditorViewportIconDisplay::Get()->GetOrLoadIconForPath(m_entityIconPath);
|
||||
}
|
||||
|
||||
return m_entityIconTextureId;
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ namespace AzToolsFramework
|
||||
|
||||
AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::EventResult(worldFromLocal, m_entityComponentIdPair.GetEntityId(), &AZ::TransformBus::Events::GetWorldTM);
|
||||
worldFromLocal.ExtractScale();
|
||||
worldFromLocal.ExtractUniformScale();
|
||||
m_manipulators = AZStd::make_unique<ScaleManipulators>(worldFromLocal);
|
||||
m_manipulators->Register(g_mainManipulatorManagerId);
|
||||
m_manipulators->SetAxes(AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY(), AZ::Vector3::CreateAxisZ());
|
||||
|
||||
+37
-106
@@ -32,7 +32,6 @@
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
|
||||
#include <AzToolsFramework/ToolsComponents/TransformComponentBus.h>
|
||||
#include <AzToolsFramework/ToolsComponents/TransformScalePropertyHandler.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorInspectorComponentBus.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorPendingCompositionBus.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
|
||||
@@ -50,10 +49,10 @@ namespace AzToolsFramework
|
||||
{
|
||||
const AZ::u32 ParentEntityCRC = AZ_CRC("Parent Entity", 0x5b1b276c);
|
||||
|
||||
// Decompose a transform into euler angles in degrees, scale (along basis, any shear will be dropped), and translation.
|
||||
void DecomposeTransform(const AZ::Transform& transform, AZ::Vector3& translation, AZ::Vector3& rotation, AZ::Vector3& scale)
|
||||
// Decompose a transform into euler angles in degrees, uniform scale, and translation.
|
||||
void DecomposeTransform(const AZ::Transform& transform, AZ::Vector3& translation, AZ::Vector3& rotation, float& scale)
|
||||
{
|
||||
scale = transform.GetScale();
|
||||
scale = transform.GetUniformScale();
|
||||
translation = transform.GetTranslation();
|
||||
rotation = transform.GetRotation().GetEulerDegrees();
|
||||
}
|
||||
@@ -120,7 +119,7 @@ namespace AzToolsFramework
|
||||
// Decompose the old slice-relative transform and set it as a our editor transform,
|
||||
// since the entity is now our parent.
|
||||
EditorTransform editorTransform;
|
||||
DecomposeTransform(sliceRelTransform, editorTransform.m_translate, editorTransform.m_rotate, editorTransform.m_scale);
|
||||
DecomposeTransform(sliceRelTransform, editorTransform.m_translate, editorTransform.m_rotate, editorTransform.m_uniformScale);
|
||||
editorTransformElement.Convert<EditorTransform>(context);
|
||||
editorTransformElement.SetData(context, editorTransform);
|
||||
}
|
||||
@@ -170,6 +169,23 @@ namespace AzToolsFramework
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EditorTransformDataConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement)
|
||||
{
|
||||
if (classElement.GetVersion() < 3)
|
||||
{
|
||||
// version 3 replaces vector scale with uniform scale but does not yet delete the legacy scale data
|
||||
// in order to allow for migration
|
||||
AZ::Vector3 vectorScale;
|
||||
if (classElement.FindSubElementAndGetData<AZ::Vector3>(AZ_CRC_CE("Scale"), vectorScale))
|
||||
{
|
||||
const float uniformScale = vectorScale.GetMaxElement();
|
||||
classElement.AddElementWithData(context, "UniformScale", uniformScale);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace Internal
|
||||
|
||||
TransformComponent::TransformComponent()
|
||||
@@ -357,7 +373,7 @@ namespace AzToolsFramework
|
||||
|
||||
AZ::Transform TransformComponent::GetLocalScaleTM() const
|
||||
{
|
||||
return AZ::Transform::CreateUniformScale(m_editorTransform.m_scale.GetMaxElement());
|
||||
return AZ::Transform::CreateUniformScale(m_editorTransform.m_uniformScale);
|
||||
}
|
||||
|
||||
const AZ::Transform& TransformComponent::GetLocalTM()
|
||||
@@ -374,12 +390,13 @@ namespace AzToolsFramework
|
||||
// given a local transform, update local transform.
|
||||
void TransformComponent::SetLocalTM(const AZ::Transform& finalTx)
|
||||
{
|
||||
AZ::Vector3 tx, rot, scale;
|
||||
Internal::DecomposeTransform(finalTx, tx, rot, scale);
|
||||
AZ::Vector3 tx, rot;
|
||||
float uniformScale;
|
||||
Internal::DecomposeTransform(finalTx, tx, rot, uniformScale);
|
||||
|
||||
m_editorTransform.m_translate = tx;
|
||||
m_editorTransform.m_rotate = rot;
|
||||
m_editorTransform.m_scale = scale;
|
||||
m_editorTransform.m_uniformScale = uniformScale;
|
||||
|
||||
TransformChanged();
|
||||
}
|
||||
@@ -520,91 +537,13 @@ namespace AzToolsFramework
|
||||
return m_editorTransform.m_translate.GetZ();
|
||||
}
|
||||
|
||||
void TransformComponent::SetRotation(const AZ::Vector3& eulerAnglesRadians)
|
||||
void TransformComponent::SetWorldRotationQuaternion(const AZ::Quaternion& quaternion)
|
||||
{
|
||||
AZ_Warning("AzToolsFramework::TransformComponent", false, "SetRotation is deprecated, please use SetLocalRotation");
|
||||
AZ::Transform newWorldTransform = GetWorldTM();
|
||||
newWorldTransform.SetRotation(AZ::ConvertEulerRadiansToQuaternion(eulerAnglesRadians));
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
|
||||
void TransformComponent::SetRotationQuaternion(const AZ::Quaternion& quaternion)
|
||||
{
|
||||
AZ_Warning("AzToolsFramework::TransformComponent", false, "SetRotationQuaternion is deprecated, please use SetLocalRotation");
|
||||
AZ::Transform newWorldTransform = GetWorldTM();
|
||||
newWorldTransform.SetRotation(quaternion);
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
|
||||
void TransformComponent::SetRotationX(float eulerAngleRadians)
|
||||
{
|
||||
AZ_Warning("AzToolsFramework::TransformComponent", false, "SetRotationX is deprecated, please use SetLocalRotation");
|
||||
AZ::Transform newWorldTransform = GetWorldTM();
|
||||
newWorldTransform.SetRotation(AZ::Quaternion::CreateRotationX(eulerAngleRadians));
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
|
||||
void TransformComponent::SetRotationY(float eulerAngleRadians)
|
||||
{
|
||||
AZ_Warning("AzToolsFramework::TransformComponent", false, "SetRotationY is deprecated, please use SetLocalRotation");
|
||||
AZ::Transform newWorldTransform = GetWorldTM();
|
||||
newWorldTransform.SetRotation(AZ::Quaternion::CreateRotationY(eulerAngleRadians));
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
|
||||
void TransformComponent::SetRotationZ(float eulerAngleRadians)
|
||||
{
|
||||
AZ_Warning("AzToolsFramework::TransformComponent", false, "SetRotationZ is deprecated, please use SetLocalRotation");
|
||||
AZ::Transform newWorldTransform = GetWorldTM();
|
||||
newWorldTransform.SetRotation(AZ::Quaternion::CreateRotationZ(eulerAngleRadians));
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
|
||||
void TransformComponent::RotateByX(float eulerAngleRadians)
|
||||
{
|
||||
AZ_Warning("AzToolsFramework::TransformComponent", false, "RotateByX is deprecated, please use RotateAroundLocalX");
|
||||
SetWorldTM(GetWorldTM() * AZ::Transform::CreateRotationX(eulerAngleRadians));
|
||||
}
|
||||
|
||||
void TransformComponent::RotateByY(float eulerAngleRadians)
|
||||
{
|
||||
AZ_Warning("AzToolsFramework::TransformComponent", false, "RotateByY is deprecated, please use RotateAroundLocalY");
|
||||
SetWorldTM(GetWorldTM() * AZ::Transform::CreateRotationY(eulerAngleRadians));
|
||||
}
|
||||
|
||||
void TransformComponent::RotateByZ(float eulerAngleRadians)
|
||||
{
|
||||
AZ_Warning("AzToolsFramework::TransformComponent", false, "RotateByZ is deprecated, please use RotateAroundLocalZ");
|
||||
SetWorldTM(GetWorldTM() * AZ::Transform::CreateRotationZ(eulerAngleRadians));
|
||||
}
|
||||
|
||||
AZ::Vector3 TransformComponent::GetRotationEulerRadians()
|
||||
{
|
||||
AZ_Warning("AzToolsFramework::TransformComponent", false, "GetRotationEulerRadians is deprecated, please use GetWorldRotation");
|
||||
return GetWorldTM().GetRotation().GetEulerRadians();
|
||||
}
|
||||
|
||||
AZ::Quaternion TransformComponent::GetRotationQuaternion()
|
||||
{
|
||||
AZ_Warning("AzToolsFramework::TransformComponent", false, "GetRotationQuaternion is deprecated, please use GetWorldRotationQuaternion");
|
||||
return GetWorldTM().GetRotation();
|
||||
}
|
||||
|
||||
float TransformComponent::GetRotationX()
|
||||
{
|
||||
return GetRotationEulerRadians().GetX();
|
||||
}
|
||||
|
||||
float TransformComponent::GetRotationY()
|
||||
{
|
||||
return GetRotationEulerRadians().GetY();
|
||||
}
|
||||
|
||||
float TransformComponent::GetRotationZ()
|
||||
{
|
||||
return GetRotationEulerRadians().GetZ();
|
||||
}
|
||||
|
||||
AZ::Vector3 TransformComponent::GetWorldRotation()
|
||||
{
|
||||
return GetWorldTM().GetRotation().GetEulerRadians();
|
||||
@@ -677,31 +616,21 @@ namespace AzToolsFramework
|
||||
return result;
|
||||
}
|
||||
|
||||
void TransformComponent::SetLocalScale(const AZ::Vector3& scale)
|
||||
{
|
||||
m_editorTransform.m_scale = scale;
|
||||
TransformChanged();
|
||||
}
|
||||
|
||||
AZ::Vector3 TransformComponent::GetLocalScale()
|
||||
{
|
||||
return m_editorTransform.m_scale;
|
||||
}
|
||||
|
||||
AZ::Vector3 TransformComponent::GetWorldScale()
|
||||
{
|
||||
return GetWorldTM().GetScale();
|
||||
AZ_WarningOnce("TransformComponent", false, "GetLocalScale is deprecated, please use GetLocalUniformScale instead");
|
||||
return m_editorTransform.m_legacyScale;
|
||||
}
|
||||
|
||||
void TransformComponent::SetLocalUniformScale(float scale)
|
||||
{
|
||||
m_editorTransform.m_scale = AZ::Vector3(scale);
|
||||
m_editorTransform.m_uniformScale = scale;
|
||||
TransformChanged();
|
||||
}
|
||||
|
||||
float TransformComponent::GetLocalUniformScale()
|
||||
{
|
||||
return m_editorTransform.m_scale.GetMaxElement();
|
||||
return m_editorTransform.m_uniformScale;
|
||||
}
|
||||
|
||||
float TransformComponent::GetWorldUniformScale()
|
||||
@@ -1219,9 +1148,10 @@ namespace AzToolsFramework
|
||||
serializeContext->Class<EditorTransform>()->
|
||||
Field("Translate", &EditorTransform::m_translate)->
|
||||
Field("Rotate", &EditorTransform::m_rotate)->
|
||||
Field("Scale", &EditorTransform::m_scale)->
|
||||
Field("Scale", &EditorTransform::m_legacyScale)->
|
||||
Field("Locked", &EditorTransform::m_locked)->
|
||||
Version(2);
|
||||
Field("UniformScale", &EditorTransform::m_uniformScale)->
|
||||
Version(3, &Internal::EditorTransformDataConverter);
|
||||
|
||||
serializeContext->Class<Components::TransformComponent, EditorComponentBase>()->
|
||||
Field("Parent Entity", &TransformComponent::m_parentEntityId)->
|
||||
@@ -1280,7 +1210,7 @@ namespace AzToolsFramework
|
||||
Attribute(AZ::Edit::Attributes::Suffix, " deg")->
|
||||
Attribute(AZ::Edit::Attributes::ReadOnly, &EditorTransform::m_locked)->
|
||||
Attribute(AZ::Edit::Attributes::SliceFlags, AZ::Edit::SliceFlags::NotPushableOnSliceRoot)->
|
||||
DataElement(TransformScaleHandler, &EditorTransform::m_scale, "Scale", "Local Scale")->
|
||||
DataElement(AZ::Edit::UIHandlers::Default, &EditorTransform::m_uniformScale, "Uniform Scale", "Local Uniform Scale")->
|
||||
Attribute(AZ::Edit::Attributes::Step, 0.1f)->
|
||||
Attribute(AZ::Edit::Attributes::ReadOnly, &EditorTransform::m_locked)
|
||||
;
|
||||
@@ -1308,7 +1238,8 @@ namespace AzToolsFramework
|
||||
{
|
||||
AzToolsFramework::ScopedUndoBatch undo("Reset transform values");
|
||||
m_editorTransform.m_translate = AZ::Vector3::CreateZero();
|
||||
m_editorTransform.m_scale = AZ::Vector3::CreateOne();
|
||||
m_editorTransform.m_legacyScale = AZ::Vector3::CreateOne();
|
||||
m_editorTransform.m_uniformScale = 1.0f;
|
||||
m_editorTransform.m_rotate = AZ::Vector3::CreateZero();
|
||||
OnTransformChanged();
|
||||
SetDirty();
|
||||
|
||||
+1
-18
@@ -99,22 +99,7 @@ namespace AzToolsFramework
|
||||
float GetLocalZ() override;
|
||||
|
||||
// Rotation modifiers
|
||||
void SetRotation(const AZ::Vector3& eulerAnglesRadians) override;
|
||||
void SetRotationQuaternion(const AZ::Quaternion& quaternion) override;
|
||||
void SetRotationX(float eulerAngleRadians) override;
|
||||
void SetRotationY(float eulerAngleRadians) override;
|
||||
void SetRotationZ(float eulerAngleRadians) override;
|
||||
|
||||
void RotateByX(float eulerAngleRadians) override;
|
||||
void RotateByY(float eulerAngleRadians) override;
|
||||
void RotateByZ(float eulerAngleRadians) override;
|
||||
|
||||
AZ::Vector3 GetRotationEulerRadians() override;
|
||||
AZ::Quaternion GetRotationQuaternion() override;
|
||||
|
||||
float GetRotationX() override;
|
||||
float GetRotationY() override;
|
||||
float GetRotationZ() override;
|
||||
void SetWorldRotationQuaternion(const AZ::Quaternion& quaternion) override;
|
||||
|
||||
AZ::Vector3 GetWorldRotation() override;
|
||||
AZ::Quaternion GetWorldRotationQuaternion() override;
|
||||
@@ -130,9 +115,7 @@ namespace AzToolsFramework
|
||||
AZ::Quaternion GetLocalRotationQuaternion() override;
|
||||
|
||||
// Scale Modifiers
|
||||
void SetLocalScale(const AZ::Vector3& scale) override;
|
||||
AZ::Vector3 GetLocalScale() override;
|
||||
AZ::Vector3 GetWorldScale() override;
|
||||
|
||||
void SetLocalUniformScale(float scale) override;
|
||||
float GetLocalUniformScale() override;
|
||||
|
||||
+6
-4
@@ -30,7 +30,8 @@ namespace AzToolsFramework
|
||||
EditorTransform()
|
||||
{
|
||||
m_translate = AZ::Vector3::CreateZero();
|
||||
m_scale = AZ::Vector3::CreateOne();
|
||||
m_legacyScale = AZ::Vector3::CreateOne();
|
||||
m_uniformScale = 1.0f;
|
||||
m_rotate = AZ::Vector3::CreateZero();
|
||||
m_locked = false;
|
||||
}
|
||||
@@ -40,9 +41,10 @@ namespace AzToolsFramework
|
||||
return EditorTransform();
|
||||
}
|
||||
|
||||
AZ::Vector3 m_translate; //! Translation in engine units (meters)
|
||||
AZ::Vector3 m_scale;
|
||||
AZ::Vector3 m_rotate; //! Rotation in degrees
|
||||
AZ::Vector3 m_translate; //!< Translation in engine units (meters)
|
||||
AZ::Vector3 m_legacyScale; //!< Legacy vector scale value, retained only for migration.
|
||||
float m_uniformScale; //!< Single scale value applied uniformly.
|
||||
AZ::Vector3 m_rotate; //!< Rotation in degrees
|
||||
bool m_locked;
|
||||
};
|
||||
|
||||
|
||||
-82
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "AzToolsFramework_precompiled.h"
|
||||
#include <ToolsComponents/TransformScalePropertyHandler.h>
|
||||
#include <AzCore/Math/Transform.h>
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
void RegisterTransformScaleHandler()
|
||||
{
|
||||
PropertyTypeRegistrationMessages::Bus::Broadcast(&PropertyTypeRegistrationMessages::RegisterPropertyType, aznew Components::TransformScalePropertyHandler());
|
||||
}
|
||||
|
||||
namespace Components
|
||||
{
|
||||
AZ::u32 TransformScalePropertyHandler::GetHandlerName(void) const
|
||||
{
|
||||
return TransformScaleHandler;
|
||||
}
|
||||
|
||||
QWidget* TransformScalePropertyHandler::CreateGUI(QWidget* parent)
|
||||
{
|
||||
AzQtComponents::DoubleSpinBox* newCtrl = new AzQtComponents::DoubleSpinBox(parent);
|
||||
connect(newCtrl, QOverload<double>::of(&AzQtComponents::DoubleSpinBox::valueChanged), newCtrl, [newCtrl]()
|
||||
{
|
||||
AzToolsFramework::PropertyEditorGUIMessages::Bus::Broadcast(&AzToolsFramework::PropertyEditorGUIMessages::RequestWrite, newCtrl);
|
||||
});
|
||||
|
||||
newCtrl->setMinimum(AZ::MinTransformScale);
|
||||
newCtrl->setMaximum(AZ::MaxTransformScale);
|
||||
|
||||
return newCtrl;
|
||||
}
|
||||
|
||||
void TransformScalePropertyHandler::ConsumeAttribute(AzQtComponents::DoubleSpinBox* GUI, AZ::u32 attrib,
|
||||
AzToolsFramework::PropertyAttributeReader* attrValue, [[maybe_unused]] const char* debugName)
|
||||
{
|
||||
if (attrib == AZ::Edit::Attributes::Suffix)
|
||||
{
|
||||
AZStd::string label;
|
||||
if (attrValue->Read<AZStd::string>(label))
|
||||
{
|
||||
GUI->setSuffix(label.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TransformScalePropertyHandler::WriteGUIValuesIntoProperty([[maybe_unused]] size_t index, AzQtComponents::DoubleSpinBox* GUI,
|
||||
AZ::Vector3& instance, [[maybe_unused]] AzToolsFramework::InstanceDataNode* node)
|
||||
{
|
||||
const float value = aznumeric_cast<float>(GUI->value());
|
||||
const float currentMaxElement = instance.GetMaxElement();
|
||||
if (currentMaxElement != 0.0f)
|
||||
{
|
||||
instance *= value / currentMaxElement;
|
||||
}
|
||||
else
|
||||
{
|
||||
instance = AZ::Vector3(value);
|
||||
}
|
||||
}
|
||||
|
||||
bool TransformScalePropertyHandler::ReadValuesIntoGUI([[maybe_unused]] size_t index, AzQtComponents::DoubleSpinBox* GUI,
|
||||
const AZ::Vector3& instance, [[maybe_unused]] AzToolsFramework::InstanceDataNode* node)
|
||||
{
|
||||
QSignalBlocker signalBlocker(GUI);
|
||||
GUI->setValue(instance.GetMaxElement());
|
||||
return true;
|
||||
}
|
||||
} // namespace Components
|
||||
} // namespace AzToolsFramework
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzQtComponents/Components/Widgets/SpinBox.h>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#endif
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace Components
|
||||
{
|
||||
static const AZ::Crc32 TransformScaleHandler = AZ_CRC_CE("TransformScale");
|
||||
|
||||
//! Handler to allow the scale field inside the Transform Component to be represented as a single value in
|
||||
//! the editor, but stored internally as a Vector3.
|
||||
//! The purpose for this is to prevent any new entities being created with non-uniform scale on the Transform
|
||||
//! Component, but preserve the data required for migrating any existing entities to use the Non-Uniform Scale
|
||||
//! Component, until all migration work is completed.
|
||||
//! The value shown in the editor will be the maximum value from the scale vector, and changing the value in
|
||||
//! the editor will update the vector so that its maximum value matches the newly edited value, but its
|
||||
//! components retain their existing proportion.
|
||||
//! For example, if the current vector scale is (2, 3, 4), the value in the editor will appear as 4. If the value
|
||||
//! in the editor is updated to 2, then the vector scale will update to (1, 1.5, 2), keeping the same proportion
|
||||
//! between the x, y and z components.
|
||||
class TransformScalePropertyHandler
|
||||
: public QObject
|
||||
, public AzToolsFramework::PropertyHandler<AZ::Vector3, AzQtComponents::DoubleSpinBox>
|
||||
{
|
||||
Q_OBJECT //AUTOMOC
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(TransformScalePropertyHandler, AZ::SystemAllocator, 0);
|
||||
|
||||
AZ::u32 GetHandlerName(void) const override;
|
||||
QWidget* CreateGUI(QWidget* parent) override;
|
||||
void ConsumeAttribute(AzQtComponents::DoubleSpinBox* GUI, AZ::u32 attrib,
|
||||
AzToolsFramework::PropertyAttributeReader* attrValue, const char* debugName) override;
|
||||
void WriteGUIValuesIntoProperty(size_t index, AzQtComponents::DoubleSpinBox* GUI,
|
||||
AZ::Vector3& instance, AzToolsFramework::InstanceDataNode* node) override;
|
||||
bool ReadValuesIntoGUI(size_t index, AzQtComponents::DoubleSpinBox* GUI,
|
||||
const AZ::Vector3& instance, AzToolsFramework::InstanceDataNode* node) override;
|
||||
};
|
||||
} // namespace Components
|
||||
} // namespace AzToolsFramework
|
||||
+7
-2
@@ -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;
|
||||
|
||||
+1
-1
@@ -351,7 +351,7 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
auto createPrefabOutcome = s_prefabPublicInterface->CreatePrefab(selectedEntities, s_prefabLoaderInterface->GetRelativePathToProject(prefabFilePath.data()));
|
||||
auto createPrefabOutcome = s_prefabPublicInterface->CreatePrefab(selectedEntities, prefabFilePath.data());
|
||||
|
||||
if (!createPrefabOutcome.IsSuccess())
|
||||
{
|
||||
|
||||
+45
-5
@@ -777,6 +777,23 @@ namespace AzToolsFramework
|
||||
selection.SetDefaultDirectory(defaultDirectory);
|
||||
}
|
||||
|
||||
if (m_hideProductFilesInAssetPicker)
|
||||
{
|
||||
FilterConstType displayFilter = selection.GetDisplayFilter();
|
||||
|
||||
EntryTypeFilter* productsFilter = new EntryTypeFilter();
|
||||
productsFilter->SetEntryType(AssetBrowserEntry::AssetEntryType::Product);
|
||||
|
||||
InverseFilter* noProductsFilter = new InverseFilter();
|
||||
noProductsFilter->SetFilter(FilterConstType(productsFilter));
|
||||
|
||||
CompositeFilter* compFilter = new CompositeFilter(CompositeFilter::LogicOperatorType::AND);
|
||||
compFilter->AddFilter(FilterConstType(displayFilter));
|
||||
compFilter->AddFilter(FilterConstType(noProductsFilter));
|
||||
|
||||
selection.SetDisplayFilter(FilterConstType(compFilter));
|
||||
}
|
||||
|
||||
AssetBrowserComponentRequestBus::Broadcast(&AssetBrowserComponentRequests::PickAssets, selection, parentWidget());
|
||||
if (selection.IsValid())
|
||||
{
|
||||
@@ -936,11 +953,16 @@ namespace AzToolsFramework
|
||||
return;
|
||||
}
|
||||
|
||||
const AZ::Data::AssetId assetID = GetCurrentAssetID();
|
||||
m_currentAssetHint = "";
|
||||
|
||||
if (!m_unnamedType)
|
||||
const AZStd::string& folderPath = GetFolderSelection();
|
||||
if (!folderPath.empty())
|
||||
{
|
||||
m_currentAssetHint = folderPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
const AZ::Data::AssetId assetID = GetCurrentAssetID();
|
||||
m_currentAssetHint = "";
|
||||
|
||||
AZ::Outcome<AssetSystem::JobInfoContainer> jobOutcome = AZ::Failure();
|
||||
AssetSystemJobRequestBus::BroadcastResult(jobOutcome, &AssetSystemJobRequestBus::Events::GetAssetJobsInfoByAssetID, assetID, false, false);
|
||||
|
||||
@@ -954,7 +976,7 @@ namespace AzToolsFramework
|
||||
|
||||
if (!jobs.empty())
|
||||
{
|
||||
// The default behavior is show to the source filename.
|
||||
// The default behavior is to show the source filename.
|
||||
assetPath = jobs[0].m_sourceFile;
|
||||
|
||||
AZStd::string errorLog;
|
||||
@@ -1172,6 +1194,16 @@ namespace AzToolsFramework
|
||||
return m_showProductAssetName;
|
||||
}
|
||||
|
||||
void PropertyAssetCtrl::SetHideProductFilesInAssetPicker(bool hide)
|
||||
{
|
||||
m_hideProductFilesInAssetPicker = hide;
|
||||
}
|
||||
|
||||
bool PropertyAssetCtrl::GetHideProductFilesInAssetPicker() const
|
||||
{
|
||||
return m_hideProductFilesInAssetPicker;
|
||||
}
|
||||
|
||||
void PropertyAssetCtrl::SetShowThumbnail(bool enable)
|
||||
{
|
||||
m_showThumbnail = enable;
|
||||
@@ -1297,6 +1329,14 @@ namespace AzToolsFramework
|
||||
GUI->SetShowProductAssetName(showProductAssetName);
|
||||
}
|
||||
}
|
||||
else if(attrib == AZ::Edit::Attributes::HideProductFilesInAssetPicker)
|
||||
{
|
||||
bool hideProductFilesInAssetPicker = false;
|
||||
if (attrValue->Read<bool>(hideProductFilesInAssetPicker))
|
||||
{
|
||||
GUI->SetHideProductFilesInAssetPicker(hideProductFilesInAssetPicker);
|
||||
}
|
||||
}
|
||||
else if (attrib == AZ::Edit::Attributes::ClearNotify)
|
||||
{
|
||||
PropertyAssetCtrl::ClearCallbackType* func = azdynamic_cast<PropertyAssetCtrl::ClearCallbackType*>(attrValue->GetAttribute());
|
||||
|
||||
+7
@@ -158,6 +158,10 @@ namespace AzToolsFramework
|
||||
//! Assets can be either source or product assets generated from source assets. By default, source assets are shown in the property asset. You can override that with this flag.
|
||||
bool m_showProductAssetName = true;
|
||||
|
||||
//! Assets can be either source or product assets generated from source assets.
|
||||
//! By default the asset picker shows both on an AZ::Asset<> property. You can hide product assets with this flag.
|
||||
bool m_hideProductFilesInAssetPicker = false;
|
||||
|
||||
bool m_showThumbnail = false;
|
||||
bool m_showThumbnailDropDownButton = false;
|
||||
EditCallbackType* m_thumbnailCallback = nullptr;
|
||||
@@ -211,6 +215,9 @@ namespace AzToolsFramework
|
||||
void SetShowProductAssetName(bool enable);
|
||||
bool GetShowProductAssetName() const;
|
||||
|
||||
void SetHideProductFilesInAssetPicker(bool hide);
|
||||
bool GetHideProductFilesInAssetPicker() const;
|
||||
|
||||
void SetShowThumbnail(bool enable);
|
||||
bool GetShowThumbnail() const;
|
||||
void SetShowThumbnailDropDownButton(bool enable);
|
||||
|
||||
-3
@@ -16,7 +16,6 @@
|
||||
#include <AzToolsFramework/ToolsComponents/EditorEntityIdContainer.h>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/PropertyAudioCtrlTypes.h>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/GenericComboBoxCtrl.h>
|
||||
#include <AzToolsFramework/ToolsComponents/TransformScalePropertyHandler.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
@@ -38,7 +37,6 @@ namespace AzToolsFramework
|
||||
void RegisterButtonPropertyHandlers();
|
||||
void RegisterMultiLineEditHandler();
|
||||
void RegisterCrcHandler();
|
||||
void RegisterTransformScaleHandler();
|
||||
void ReflectPropertyEditor(AZ::ReflectContext* context);
|
||||
|
||||
namespace Components
|
||||
@@ -192,7 +190,6 @@ namespace AzToolsFramework
|
||||
RegisterVectorHandlers();
|
||||
RegisterButtonPropertyHandlers();
|
||||
RegisterMultiLineEditHandler();
|
||||
RegisterTransformScaleHandler();
|
||||
|
||||
// GenericComboBoxHandlers
|
||||
RegisterGenericComboBoxHandler<AZ::Crc32>();
|
||||
|
||||
@@ -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;
|
||||
|
||||
+9
-4
@@ -21,6 +21,7 @@
|
||||
#include <AzToolsFramework/Viewport/ViewportTypes.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorVisibleEntityDataCache.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
|
||||
#include <AzToolsFramework/API/EditorViewportIconDisplayInterface.h>
|
||||
|
||||
AZ_CVAR(
|
||||
bool, ed_visibility_showAggregateEntitySelectionBounds, false, nullptr, AZ::ConsoleFunctorFlags::Null,
|
||||
@@ -232,10 +233,14 @@ namespace AzToolsFramework
|
||||
return AZ::Color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}();
|
||||
|
||||
debugDisplay.SetColor(iconHighlight);
|
||||
// debugDisplay.DrawTextureLabel(
|
||||
// iconTextureId, entityPosition, iconSize, iconSize,
|
||||
// /*DisplayContext::ETextureIconFlags::TEXICON_ON_TOP=*/ 0x0008);
|
||||
EditorViewportIconDisplay::Get()->DrawIcon({
|
||||
viewportInfo.m_viewportId,
|
||||
iconTextureId,
|
||||
iconHighlight,
|
||||
entityPosition,
|
||||
EditorViewportIconDisplayInterface::CoordinateSpace::WorldSpace,
|
||||
AZ::Vector2{iconSize, iconSize}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+17
-22
@@ -809,14 +809,12 @@ namespace AzToolsFramework
|
||||
EntityIdManipulators& entityIdManipulators,
|
||||
OptionalFrame& pivotOverrideFrame,
|
||||
ViewportInteraction::KeyboardModifiers& prevModifiers,
|
||||
bool& transformChangedInternally, SpaceCluster spaceCluster)
|
||||
bool& transformChangedInternally, const AZStd::optional<ReferenceFrame> spaceLock)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
|
||||
|
||||
entityIdManipulators.m_manipulators->SetLocalPosition(action.LocalPosition());
|
||||
|
||||
const ReferenceFrame referenceFrame = spaceCluster.m_spaceLock ? spaceCluster.m_currentSpace : ReferenceFrameFromModifiers(action.m_modifiers);
|
||||
|
||||
if (action.m_modifiers.Ctrl())
|
||||
{
|
||||
// moving with ctrl - setting override
|
||||
@@ -826,6 +824,8 @@ namespace AzToolsFramework
|
||||
}
|
||||
else
|
||||
{
|
||||
const ReferenceFrame referenceFrame = spaceLock.value_or(ReferenceFrameFromModifiers(action.m_modifiers));
|
||||
|
||||
// note: used for parent and world depending on the current reference frame
|
||||
const auto pivotOrientation =
|
||||
ETCS::CalculateSelectionPivotOrientation(
|
||||
@@ -1298,7 +1298,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
UpdateTranslationManipulator(
|
||||
action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators, m_pivotOverrideFrame, prevModifiers,
|
||||
m_transformChangedInternally, m_spaceCluster);
|
||||
m_transformChangedInternally, m_spaceCluster.m_spaceLock);
|
||||
});
|
||||
|
||||
translationManipulators->InstallLinearManipulatorMouseUpCallback(
|
||||
@@ -1329,7 +1329,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
UpdateTranslationManipulator(
|
||||
action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators, m_pivotOverrideFrame, prevModifiers,
|
||||
m_transformChangedInternally, m_spaceCluster);
|
||||
m_transformChangedInternally, m_spaceCluster.m_spaceLock);
|
||||
});
|
||||
|
||||
translationManipulators->InstallPlanarManipulatorMouseUpCallback(
|
||||
@@ -1359,7 +1359,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
UpdateTranslationManipulator(
|
||||
action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators, m_pivotOverrideFrame, prevModifiers,
|
||||
m_transformChangedInternally, m_spaceCluster);
|
||||
m_transformChangedInternally, m_spaceCluster.m_spaceLock);
|
||||
});
|
||||
|
||||
translationManipulators->InstallSurfaceManipulatorMouseUpCallback(
|
||||
@@ -1437,8 +1437,7 @@ namespace AzToolsFramework
|
||||
[this, prevModifiers, sharedRotationState]
|
||||
(const AngularManipulator::Action& action) mutable -> void
|
||||
{
|
||||
const ReferenceFrame referenceFrame = m_spaceCluster.m_spaceLock ? m_spaceCluster.m_currentSpace : ReferenceFrameFromModifiers(action.m_modifiers);
|
||||
|
||||
const ReferenceFrame referenceFrame = m_spaceCluster.m_spaceLock.value_or(ReferenceFrameFromModifiers(action.m_modifiers));
|
||||
const AZ::Quaternion manipulatorOrientation = action.m_start.m_rotation * action.m_current.m_delta;
|
||||
// store the pivot override frame when positioning the manipulator manually (ctrl)
|
||||
// so we don't lose the orientation when adding/removing entities from the selection
|
||||
@@ -2605,40 +2604,37 @@ namespace AzToolsFramework
|
||||
if (buttonId == m_spaceCluster.m_localButtonId)
|
||||
{
|
||||
// Unlock
|
||||
if (m_spaceCluster.m_spaceLock && m_spaceCluster.m_currentSpace == ReferenceFrame::Local)
|
||||
if (m_spaceCluster.m_spaceLock.has_value() && m_spaceCluster.m_spaceLock.value() == ReferenceFrame::Local)
|
||||
{
|
||||
m_spaceCluster.m_spaceLock = false;
|
||||
m_spaceCluster.m_spaceLock = AZStd::nullopt;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spaceCluster.m_spaceLock = true;
|
||||
m_spaceCluster.m_currentSpace = ReferenceFrame::Local;
|
||||
m_spaceCluster.m_spaceLock = ReferenceFrame::Local;
|
||||
}
|
||||
}
|
||||
else if (buttonId == m_spaceCluster.m_parentButtonId)
|
||||
{
|
||||
// Unlock
|
||||
if (m_spaceCluster.m_spaceLock && m_spaceCluster.m_currentSpace == ReferenceFrame::Parent)
|
||||
if (m_spaceCluster.m_spaceLock.has_value() && m_spaceCluster.m_spaceLock.value() == ReferenceFrame::Parent)
|
||||
{
|
||||
m_spaceCluster.m_spaceLock = false;
|
||||
m_spaceCluster.m_spaceLock = AZStd::nullopt;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spaceCluster.m_spaceLock = true;
|
||||
m_spaceCluster.m_currentSpace = ReferenceFrame::Parent;
|
||||
m_spaceCluster.m_spaceLock = ReferenceFrame::Parent;
|
||||
}
|
||||
}
|
||||
else if (buttonId == m_spaceCluster.m_worldButtonId)
|
||||
{
|
||||
// Unlock
|
||||
if (m_spaceCluster.m_spaceLock && m_spaceCluster.m_currentSpace == ReferenceFrame::World)
|
||||
if (m_spaceCluster.m_spaceLock.has_value() && m_spaceCluster.m_spaceLock.value() == ReferenceFrame::World)
|
||||
{
|
||||
m_spaceCluster.m_spaceLock = false;
|
||||
m_spaceCluster.m_spaceLock = AZStd::nullopt;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spaceCluster.m_spaceLock = true;
|
||||
m_spaceCluster.m_currentSpace = ReferenceFrame::World;
|
||||
m_spaceCluster.m_spaceLock = ReferenceFrame::World;
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -3361,8 +3357,7 @@ namespace AzToolsFramework
|
||||
ViewportInteraction::BuildMouseButtons(
|
||||
QGuiApplication::mouseButtons()), m_boxSelect.Active());
|
||||
|
||||
const ReferenceFrame referenceFrame =
|
||||
m_spaceCluster.m_spaceLock ? m_spaceCluster.m_currentSpace : ReferenceFrameFromModifiers(modifiers);
|
||||
const ReferenceFrame referenceFrame = m_spaceCluster.m_spaceLock.value_or(ReferenceFrameFromModifiers(modifiers));
|
||||
|
||||
UpdateSpaceCluster(referenceFrame);
|
||||
|
||||
|
||||
+16
-10
@@ -106,15 +106,20 @@ namespace AzToolsFramework
|
||||
World, //!< World space (space aligned to world axes - identity).
|
||||
};
|
||||
|
||||
//! Grouping of viewport ui related state for controlling the current reference space of the Editor.
|
||||
struct SpaceCluster
|
||||
{
|
||||
ViewportUi::ClusterId m_spaceClusterId;
|
||||
ViewportUi::ButtonId m_localButtonId;
|
||||
ViewportUi::ButtonId m_parentButtonId;
|
||||
ViewportUi::ButtonId m_worldButtonId;
|
||||
AZ::Event<ViewportUi::ButtonId>::Handler m_spaceSelectionHandler;
|
||||
ReferenceFrame m_currentSpace = ReferenceFrame::Parent;
|
||||
bool m_spaceLock = false;
|
||||
SpaceCluster() = default;
|
||||
// disable copying and moving (implicit)
|
||||
SpaceCluster(const SpaceCluster&) = delete;
|
||||
SpaceCluster& operator=(const SpaceCluster&) = delete;
|
||||
|
||||
ViewportUi::ClusterId m_spaceClusterId; //!< The id identifying the reference space cluster.
|
||||
ViewportUi::ButtonId m_localButtonId; //!< Local reference space button id.
|
||||
ViewportUi::ButtonId m_parentButtonId; //!< Parent reference space button id.
|
||||
ViewportUi::ButtonId m_worldButtonId; //!< World reference space button id.
|
||||
AZ::Event<ViewportUi::ButtonId>::Handler m_spaceSelectionHandler; //!< Callback for when a space cluster button is pressed.
|
||||
AZStd::optional<ReferenceFrame> m_spaceLock; //!< Locked reference frame to use if set.
|
||||
};
|
||||
|
||||
//! Entity selection/interaction handling.
|
||||
@@ -265,6 +270,9 @@ namespace AzToolsFramework
|
||||
void SetEntityLocalScale(AZ::EntityId entityId, float localScale);
|
||||
void SetEntityLocalRotation(AZ::EntityId entityId, const AZ::Vector3& localRotation);
|
||||
|
||||
// Responsible for keeping the space cluster in sync with the current reference frame.
|
||||
void UpdateSpaceCluster(ReferenceFrame referenceFrame);
|
||||
|
||||
AZ::EntityId m_hoveredEntityId; //!< What EntityId is the mouse currently hovering over (if any).
|
||||
AZ::EntityId m_cachedEntityIdUnderCursor; //!< Store the EntityId on each mouse move for use in Display.
|
||||
AZ::EntityId m_editorCameraComponentEntityId; //!< The EditorCameraComponent EntityId if it is set.
|
||||
@@ -297,9 +305,7 @@ namespace AzToolsFramework
|
||||
AZ::Event<ViewportUi::ButtonId>::Handler m_transformModeSelectionHandler; //!< Event handler for the Viewport UI cluster.
|
||||
AzFramework::ClickDetector m_clickDetector; //!< Detect different types of mouse click.
|
||||
AzFramework::CursorState m_cursorState; //!< Track the mouse position and delta movement each frame.
|
||||
|
||||
SpaceCluster m_spaceCluster;
|
||||
void UpdateSpaceCluster(ReferenceFrame referenceFrame);
|
||||
SpaceCluster m_spaceCluster; //!< Related viewport ui state for controlling the current reference space.
|
||||
};
|
||||
|
||||
//! The ETCS (EntityTransformComponentSelection) namespace contains functions and data used exclusively by
|
||||
|
||||
@@ -46,6 +46,7 @@ set(FILES
|
||||
API/EditorWindowRequestBus.h
|
||||
API/EntityCompositionRequestBus.h
|
||||
API/EntityCompositionNotificationBus.h
|
||||
API/EditorViewportIconDisplayInterface.h
|
||||
API/ViewPaneOptions.h
|
||||
Application/Ticker.h
|
||||
Application/Ticker.cpp
|
||||
@@ -292,8 +293,6 @@ set(FILES
|
||||
ToolsComponents/TransformComponent.h
|
||||
ToolsComponents/TransformComponent.cpp
|
||||
ToolsComponents/TransformComponentBus.h
|
||||
ToolsComponents/TransformScalePropertyHandler.cpp
|
||||
ToolsComponents/TransformScalePropertyHandler.h
|
||||
ToolsComponents/ScriptEditorComponent.cpp
|
||||
ToolsComponents/ScriptEditorComponent.h
|
||||
ToolsComponents/ToolsAssetCatalogComponent.cpp
|
||||
|
||||
Reference in New Issue
Block a user