Merge branch 'main' into SpawnablePriorityQueue

This commit is contained in:
AMZN-koppersr
2021-06-01 09:57:27 -07:00
581 changed files with 13617 additions and 12612 deletions
@@ -483,6 +483,8 @@ namespace AzToolsFramework
}
}
m_dirty = false;
AddRecentPath(targetFilePath);
SetStatusText(Status::assetCreated);
@@ -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()
@@ -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.GetUniformScale());
result.SetUniformScale(m_space.GetUniformScale() * localTransform.GetUniformScale());
return result;
}
@@ -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:
@@ -64,7 +64,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;
@@ -76,6 +76,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
@@ -144,7 +146,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)
{
@@ -254,7 +257,7 @@ namespace AzToolsFramework
}
// Save Template to file
m_prefabLoaderInterface->SaveTemplate(instanceToCreate->get().GetTemplateId());
m_prefabLoaderInterface->SaveTemplateToFile(instanceToCreate->get().GetTemplateId(), absolutePath);
return AZ::Success();
}
@@ -318,7 +321,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,
@@ -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
@@ -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());
@@ -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();
}
@@ -599,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()
@@ -1141,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)->
@@ -1202,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)
;
@@ -1230,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();
@@ -115,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;
@@ -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;
};
@@ -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
@@ -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
@@ -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,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())
{
@@ -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());
@@ -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);
@@ -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;
@@ -293,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