Merge branch 'main' of https://github.com/aws-lumberyard/o3de into Spawnable/ScriptCanvas/Integration
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)
|
||||
|
||||
+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
|
||||
@@ -239,6 +239,11 @@ namespace AzToolsFramework
|
||||
*/
|
||||
virtual int RemoveDirtyEntity(AZ::EntityId target) = 0;
|
||||
|
||||
/*!
|
||||
* Clears the dirty entity set.
|
||||
*/
|
||||
virtual void ClearDirtyEntities() = 0;
|
||||
|
||||
/*!
|
||||
* \return true if an undo/redo operation is in progress.
|
||||
*/
|
||||
|
||||
@@ -1354,6 +1354,11 @@ namespace AzToolsFramework
|
||||
return static_cast<int>(m_dirtyEntities.erase(entityId));
|
||||
}
|
||||
|
||||
void ToolsApplication::ClearDirtyEntities()
|
||||
{
|
||||
m_dirtyEntities.clear();
|
||||
}
|
||||
|
||||
void ToolsApplication::UndoPressed()
|
||||
{
|
||||
if (m_undoStack)
|
||||
|
||||
@@ -85,6 +85,7 @@ namespace AzToolsFramework
|
||||
|
||||
void AddDirtyEntity(AZ::EntityId entityId) override;
|
||||
int RemoveDirtyEntity(AZ::EntityId entityId) override;
|
||||
void ClearDirtyEntities() override;
|
||||
bool IsDuringUndoRedo() override { return m_isDuringUndoRedo; }
|
||||
void UndoPressed() override;
|
||||
void RedoPressed() override;
|
||||
|
||||
@@ -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;
|
||||
|
||||
+2
@@ -56,5 +56,7 @@ namespace AzToolsFramework
|
||||
|
||||
virtual void StartPlayInEditor() = 0;
|
||||
virtual void StopPlayInEditor() = 0;
|
||||
|
||||
virtual void CreateNewLevelPrefab(AZStd::string_view filename) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
+71
-4
@@ -14,9 +14,11 @@
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Script/ScriptSystemBus.h>
|
||||
#include <AzCore/Serialization/Utils.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
#include <AzFramework/Entity/GameEntityContextBus.h>
|
||||
#include <AzFramework/Spawnable/RootSpawnableInterface.h>
|
||||
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h>
|
||||
#include <AzToolsFramework/Prefab/EditorPrefabComponent.h>
|
||||
@@ -222,12 +224,11 @@ namespace AzToolsFramework
|
||||
AzToolsFramework::Prefab::TemplateId templateId = m_prefabSystemComponent->GetTemplateIdFromFilePath(relativePath);
|
||||
|
||||
m_rootInstance->SetTemplateSourcePath(relativePath);
|
||||
|
||||
if (templateId == AzToolsFramework::Prefab::InvalidTemplateId)
|
||||
{
|
||||
// This has not been loaded yet, this is the case of being saved with a different name.
|
||||
// Create it
|
||||
m_rootInstance->m_containerEntity->AddComponent(aznew Prefab::EditorPrefabComponent());
|
||||
HandleEntitiesAdded({m_rootInstance->m_containerEntity.get()});
|
||||
HandleEntitiesAdded({ m_rootInstance->m_containerEntity.get() });
|
||||
|
||||
AzToolsFramework::Prefab::PrefabDom dom;
|
||||
bool success = AzToolsFramework::Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*m_rootInstance, dom);
|
||||
@@ -236,7 +237,8 @@ namespace AzToolsFramework
|
||||
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));
|
||||
templateId = m_prefabSystemComponent->AddTemplate(relativePath, AZStd::move(dom));
|
||||
|
||||
if (templateId == AzToolsFramework::Prefab::InvalidTemplateId)
|
||||
{
|
||||
AZ_Error("Prefab", false, "Couldn't add new template id '%i' when saving file '%.*s'", templateId, AZ_STRING_ARG(filename));
|
||||
@@ -263,6 +265,71 @@ namespace AzToolsFramework
|
||||
return false;
|
||||
}
|
||||
|
||||
void PrefabEditorEntityOwnershipService::CreateNewLevelPrefab(AZStd::string_view filename)
|
||||
{
|
||||
AZ::IO::Path relativePath = m_loaderInterface->GetRelativePathToProject(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, DefaultLevelTemplateName,
|
||||
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, assetInfo.m_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)
|
||||
|
||||
+4
@@ -170,6 +170,8 @@ namespace AzToolsFramework
|
||||
void StartPlayInEditor() override;
|
||||
void StopPlayInEditor() override;
|
||||
|
||||
void CreateNewLevelPrefab(AZStd::string_view filename) override;
|
||||
|
||||
protected:
|
||||
|
||||
AZ::SliceComponent::SliceInstanceAddress GetOwningSlice() override;
|
||||
@@ -216,5 +218,7 @@ namespace AzToolsFramework
|
||||
Prefab::PrefabLoaderInterface* m_loaderInterface;
|
||||
AzFramework::EntityContextId m_entityContextId;
|
||||
AZ::SerializeContext m_serializeContext;
|
||||
|
||||
static inline constexpr const char* DefaultLevelTemplateName = "Prefabs/Default_Level.prefab";
|
||||
};
|
||||
}
|
||||
|
||||
@@ -82,9 +82,7 @@ namespace AzToolsFramework
|
||||
|
||||
m_uniformScaleManipulator->SetVisualOrientationOverride(
|
||||
QuaternionFromTransformNoScaling(localTransform));
|
||||
m_uniformScaleManipulator->SetLocalTransform(
|
||||
AZ::Transform::CreateTranslation(localTransform.GetTranslation()) *
|
||||
AZ::Transform::CreateScale(localTransform.GetScale()));
|
||||
m_uniformScaleManipulator->SetLocalOrientation(AZ::Quaternion::CreateIdentity());
|
||||
}
|
||||
|
||||
void ScaleManipulators::SetLocalPositionImpl(const AZ::Vector3& localPosition)
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace AzToolsFramework
|
||||
inline AZ::Transform TransformNormalizedScale(const AZ::Transform& transform)
|
||||
{
|
||||
AZ::Transform transformNormalizedScale = transform;
|
||||
transformNormalizedScale.SetScale(AZ::Vector3::CreateOne());
|
||||
transformNormalizedScale.SetUniformScale(1.0f);
|
||||
return transformNormalizedScale;
|
||||
}
|
||||
|
||||
@@ -33,8 +33,7 @@ namespace AzToolsFramework
|
||||
inline AZ::Transform TransformUniformScale(const AZ::Transform& transform)
|
||||
{
|
||||
AZ::Transform transformUniformScale = transform;
|
||||
const float maxScale = transformUniformScale.GetScale().GetMaxElement();
|
||||
transformUniformScale.SetScale(AZ::Vector3(maxScale));
|
||||
transformUniformScale.SetUniformScale(transformUniformScale.GetUniformScale());
|
||||
return transformUniformScale;
|
||||
}
|
||||
|
||||
|
||||
+8
-12
@@ -276,18 +276,14 @@ namespace AzToolsFramework
|
||||
PrefabDomValueReference linkPatchesReference =
|
||||
PrefabDomUtils::FindPrefabDomValue(linkDom, PrefabDomUtils::PatchesName);
|
||||
|
||||
// This logic only covers addition of patches. If patches already exists, the given list of patches must be appended to them.
|
||||
if (!linkPatchesReference.has_value())
|
||||
{
|
||||
/*
|
||||
If the original allocator the patches were created with gets destroyed, then the patches would become garbage in the
|
||||
linkDom. Since we cannot guarantee the lifecycle of the patch allocators, we are doing a copy of the patches here to
|
||||
associate them with the linkDom's allocator.
|
||||
*/
|
||||
PrefabDom patchesCopy;
|
||||
patchesCopy.CopyFrom(patches, linkDom.GetAllocator());
|
||||
linkDom.AddMember(rapidjson::StringRef(PrefabDomUtils::PatchesName), patchesCopy, linkDom.GetAllocator());
|
||||
}
|
||||
/*
|
||||
If the original allocator the patches were created with gets destroyed, then the patches would become garbage in the
|
||||
linkDom. Since we cannot guarantee the lifecycle of the patch allocators, we are doing a copy of the patches here to
|
||||
associate them with the linkDom's allocator.
|
||||
*/
|
||||
PrefabDom patchesCopy;
|
||||
patchesCopy.CopyFrom(patches, linkDom.GetAllocator());
|
||||
linkDom.AddMember(rapidjson::StringRef(PrefabDomUtils::PatchesName), patchesCopy, linkDom.GetAllocator());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,5 +234,10 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
PrefabDomValueReference Link::GetLinkPatches()
|
||||
{
|
||||
return PrefabDomUtils::FindPrefabDomValue(m_linkDom, PrefabDomUtils::PatchesName);
|
||||
}
|
||||
|
||||
} // namespace Prefab
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -79,6 +79,8 @@ namespace AzToolsFramework
|
||||
*/
|
||||
void AddLinkIdToInstanceDom(PrefabDomValue& instanceDomValue);
|
||||
|
||||
PrefabDomValueReference GetLinkPatches();
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace AzToolsFramework
|
||||
|
||||
[[maybe_unused]] bool result =
|
||||
settingsRegistry->Get(m_projectPathWithOsSeparator.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectPath);
|
||||
AZ_Assert(result, "Couldn't retrieve project root path");
|
||||
AZ_Warning("Prefab", result, "Couldn't retrieve project root path");
|
||||
m_projectPathWithSlashSeparator = AZ::IO::Path(m_projectPathWithOsSeparator.Native(), '/').MakePreferred();
|
||||
|
||||
AZ::Interface<PrefabLoaderInterface>::Register(this);
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzToolsFramework/Prefab/PrefabPublicHandler.h>
|
||||
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/JSON/stringbuffer.h>
|
||||
#include <AzCore/JSON/writer.h>
|
||||
@@ -28,6 +26,7 @@
|
||||
#include <AzToolsFramework/Prefab/Instance/InstanceToTemplateInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabLoaderInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabPublicHandler.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabUndo.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabUndoHelpers.h>
|
||||
@@ -98,9 +97,13 @@ namespace AzToolsFramework
|
||||
AZStd::string("Could not create a new prefab out of the entities provided - invalid selection."));
|
||||
}
|
||||
|
||||
AZStd::unordered_map<AZ::EntityId, AZStd::string> oldEntityAliases;
|
||||
|
||||
// Detach the retrieved entities
|
||||
for (AZ::Entity* entity : entities)
|
||||
{
|
||||
AZ::EntityId entityId = entity->GetId();
|
||||
oldEntityAliases.emplace(entityId, commonRootEntityOwningInstance->get().GetEntityAlias(entityId)->get());
|
||||
commonRootEntityOwningInstance->get().DetachEntity(entity->GetId()).release();
|
||||
}
|
||||
|
||||
@@ -110,15 +113,18 @@ namespace AzToolsFramework
|
||||
{
|
||||
AZStd::unique_ptr<Instance> outInstance = commonRootEntityOwningInstance->get().DetachNestedInstance(nestedInstance->GetInstanceAlias());
|
||||
|
||||
auto linkRef = m_prefabSystemComponentInterface->FindLink(nestedInstance->GetLinkId());
|
||||
LinkId detachingInstanceLinkId = nestedInstance->GetLinkId();
|
||||
auto linkRef = m_prefabSystemComponentInterface->FindLink(detachingInstanceLinkId);
|
||||
AZ_Assert(linkRef.has_value(), "Unable to find link with id '%llu' during prefab creation.", detachingInstanceLinkId);
|
||||
|
||||
if (linkRef.has_value())
|
||||
{
|
||||
PrefabDom oldLinkPatches;
|
||||
oldLinkPatches.CopyFrom(linkRef->get().GetLinkDom(), oldLinkPatches.GetAllocator());
|
||||
PrefabDomValueReference linkPatches = linkRef->get().GetLinkPatches();
|
||||
AZ_Assert(
|
||||
linkPatches.has_value(), "Unable to get patches on link with id '%llu' during prefab creation.",
|
||||
detachingInstanceLinkId);
|
||||
|
||||
nestedInstanceLinkPatchesMap.emplace(nestedInstance, AZStd::move(oldLinkPatches));
|
||||
}
|
||||
PrefabDom linkPatchesCopy;
|
||||
linkPatchesCopy.CopyFrom(linkPatches->get(), linkPatchesCopy.GetAllocator());
|
||||
nestedInstanceLinkPatchesMap.emplace(nestedInstance, AZStd::move(linkPatchesCopy));
|
||||
|
||||
RemoveLink(outInstance, commonRootEntityOwningInstance->get().GetTemplateId(), undoBatch.GetUndoBatch());
|
||||
|
||||
@@ -182,6 +188,24 @@ namespace AzToolsFramework
|
||||
if (nestedInstanceLinkPatchesMap.contains(nestedInstance.get()))
|
||||
{
|
||||
previousPatch = AZStd::move(nestedInstanceLinkPatchesMap[nestedInstance.get()]);
|
||||
rapidjson::StringBuffer buffer;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
|
||||
previousPatch.Accept(writer);
|
||||
QString previousPatchString(buffer.GetString());
|
||||
|
||||
for (AZ::Entity* entity : entities)
|
||||
{
|
||||
AZ::EntityId entityId = entity->GetId();
|
||||
AZStd::string oldEntityAlias = oldEntityAliases[entityId];
|
||||
EntityAliasOptionalReference newEntityAlias = instanceToCreate->get().GetEntityAlias(entityId);
|
||||
AZ_Assert(
|
||||
newEntityAlias.has_value(),
|
||||
"Could not fetch entity alias for entity with id '%llu' during prefab creation.",
|
||||
static_cast<AZ::u64>(entityId));
|
||||
ReplaceOldAliases(previousPatchString, oldEntityAlias, newEntityAlias->get());
|
||||
}
|
||||
|
||||
previousPatch.Parse(previousPatchString.toUtf8().constData());
|
||||
}
|
||||
|
||||
// These link creations shouldn't be undone because that would put the template in a non-usable state if a user
|
||||
@@ -203,36 +227,23 @@ namespace AzToolsFramework
|
||||
m_instanceToTemplateInterface->GeneratePatch(reparentPatch, containerEntityDomBefore, containerEntityDomAfter);
|
||||
m_instanceToTemplateInterface->AppendEntityAliasToPatchPaths(reparentPatch, nestedInstanceContainerEntityId);
|
||||
|
||||
// Update the cache - this prevents these changes from being stored in the regular undo/redo nodes as a separate step
|
||||
m_prefabUndoCache.Store(nestedInstanceContainerEntityId, AZStd::move(containerEntityDomAfter));
|
||||
|
||||
// Save these changes as patches to the link
|
||||
PrefabUndoLinkUpdate* linkUpdate = aznew PrefabUndoLinkUpdate(AZStd::to_string(static_cast<AZ::u64>(nestedInstanceContainerEntityId)));
|
||||
linkUpdate->SetParent(undoBatch.GetUndoBatch());
|
||||
linkUpdate->Capture(reparentPatch, nestedInstance->GetLinkId());
|
||||
|
||||
linkUpdate->Redo();
|
||||
// We won't parent this undo node to the undo batch so that the newly created template and link will remain
|
||||
// unaffected by undo actions. This is needed so that any future instantiations of the template will work.
|
||||
PrefabUndoLinkUpdate linkUpdate = PrefabUndoLinkUpdate(AZStd::to_string(static_cast<AZ::u64>(nestedInstanceContainerEntityId)));
|
||||
linkUpdate.Capture(reparentPatch, nestedInstance->GetLinkId());
|
||||
linkUpdate.Redo();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Create a link between the templates of the newly created instance and the instance it's being parented under.
|
||||
CreateLink(
|
||||
instanceToCreate->get(), commonRootEntityOwningInstance->get().GetTemplateId(), undoBatch.GetUndoBatch(),
|
||||
AZStd::move(patch));
|
||||
|
||||
for (AZ::Entity* topLevelEntity : topLevelEntities)
|
||||
{
|
||||
AZ::EntityId topLevelEntityId = topLevelEntity->GetId();
|
||||
if (topLevelEntityId.IsValid())
|
||||
{
|
||||
m_prefabUndoCache.UpdateCache(topLevelEntity->GetId());
|
||||
|
||||
// Parenting entities would mark entities as dirty. But we want to unmark the top level entities as dirty because
|
||||
// if we don't, the template created would be updated and cause issues with undo operation followed by instantiation.
|
||||
ToolsApplicationRequests::Bus::Broadcast(
|
||||
&ToolsApplicationRequests::Bus::Events::RemoveDirtyEntity, topLevelEntity->GetId());
|
||||
}
|
||||
}
|
||||
// This clears any entities marked as dirty due to reparenting of entities during the process of creating a prefab.
|
||||
// We are doing this so that the changes in those enities are not queued up twice for propagation.
|
||||
AzToolsFramework::ToolsApplicationRequestBus::Broadcast(
|
||||
&AzToolsFramework::ToolsApplicationRequestBus::Events::ClearDirtyEntities);
|
||||
|
||||
// Select Container Entity
|
||||
{
|
||||
@@ -824,15 +835,7 @@ namespace AzToolsFramework
|
||||
// This will cover both cases where an alias could be used in a normal entity vs. an instance
|
||||
for (auto aliasMapIter : oldAliasToNewAliasMap)
|
||||
{
|
||||
QString oldAliasQuotes = QString("\"%1\"").arg(aliasMapIter.first.c_str());
|
||||
QString newAliasQuotes = QString("\"%1\"").arg(aliasMapIter.second.c_str());
|
||||
|
||||
newEntityDomString.replace(oldAliasQuotes, newAliasQuotes);
|
||||
|
||||
QString oldAliasPathRef = QString("/%1").arg(aliasMapIter.first.c_str());
|
||||
QString newAliasPathRef = QString("/%1").arg(aliasMapIter.second.c_str());
|
||||
|
||||
newEntityDomString.replace(oldAliasPathRef, newAliasPathRef);
|
||||
ReplaceOldAliases(newEntityDomString, aliasMapIter.first, aliasMapIter.second);
|
||||
}
|
||||
|
||||
// Create the new Entity DOM from parsing the JSON string
|
||||
@@ -1233,5 +1236,18 @@ namespace AzToolsFramework
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PrefabPublicHandler::ReplaceOldAliases(QString& stringToReplace, AZStd::string_view oldAlias, AZStd::string_view newAlias)
|
||||
{
|
||||
QString oldAliasQuotes = QString("\"%1\"").arg(oldAlias.data());
|
||||
QString newAliasQuotes = QString("\"%1\"").arg(newAlias.data());
|
||||
|
||||
stringToReplace.replace(oldAliasQuotes, newAliasQuotes);
|
||||
|
||||
QString oldAliasPathRef = QString("/%1").arg(oldAlias.data());
|
||||
QString newAliasPathRef = QString("/%1").arg(newAlias.data());
|
||||
|
||||
stringToReplace.replace(oldAliasPathRef, newAliasPathRef);
|
||||
}
|
||||
} // namespace Prefab
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -14,12 +14,15 @@
|
||||
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabUndoCache.h>
|
||||
|
||||
class QString;
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
using EntityList = AZStd::vector<AZ::Entity*>;
|
||||
@@ -27,7 +30,6 @@ namespace AzToolsFramework
|
||||
namespace Prefab
|
||||
{
|
||||
class Instance;
|
||||
|
||||
class InstanceEntityMapperInterface;
|
||||
class InstanceToTemplateInterface;
|
||||
class PrefabLoaderInterface;
|
||||
@@ -130,6 +132,8 @@ namespace AzToolsFramework
|
||||
bool IsCyclicalDependencyFound(
|
||||
InstanceOptionalConstReference instance, const AZStd::unordered_set<AZ::IO::Path>& templateSourcePaths);
|
||||
|
||||
void ReplaceOldAliases(QString& stringToReplace, AZStd::string_view oldAlias, AZStd::string_view newAlias);
|
||||
|
||||
static Instance* GetParentInstance(Instance* instance);
|
||||
static Instance* GetAncestorOfInstanceThatIsChildOfRoot(const Instance* ancestor, Instance* descendant);
|
||||
static void GenerateContainerEntityTransform(const EntityList& topLevelEntities, AZ::Vector3& translation, AZ::Quaternion& rotation);
|
||||
|
||||
@@ -1475,10 +1475,8 @@ namespace AzToolsFramework
|
||||
// to avoid pushing them to the slice.
|
||||
// Only scale is preserved on the root entity of a slice.
|
||||
transformComponent->SetParent(AZ::EntityId());
|
||||
AZ::Vector3 scale = transformComponent->GetLocalScale();
|
||||
transformComponent->SetWorldTranslation(AZ::Vector3::CreateZero());
|
||||
transformComponent->SetLocalRotation(AZ::Vector3::CreateZero());
|
||||
transformComponent->SetLocalScale(scale);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+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;
|
||||
|
||||
+17
-95
@@ -357,7 +357,7 @@ namespace AzToolsFramework
|
||||
|
||||
AZ::Transform TransformComponent::GetLocalScaleTM() const
|
||||
{
|
||||
return AZ::Transform::CreateScale(m_editorTransform.m_scale);
|
||||
return AZ::Transform::CreateUniformScale(m_editorTransform.m_scale.GetMaxElement());
|
||||
}
|
||||
|
||||
const AZ::Transform& TransformComponent::GetLocalTM()
|
||||
@@ -677,100 +677,12 @@ namespace AzToolsFramework
|
||||
return result;
|
||||
}
|
||||
|
||||
void TransformComponent::SetScale(const AZ::Vector3& newScale)
|
||||
{
|
||||
AZ_Warning("AzToolsFramework::TransformComponent", false, "SetScale is deprecated, please use SetLocalScale");
|
||||
|
||||
AZ::Transform newWorldTransform = GetWorldTM();
|
||||
AZ::Vector3 prevScale = newWorldTransform.ExtractScale();
|
||||
if (!prevScale.IsClose(newScale))
|
||||
{
|
||||
newWorldTransform.MultiplyByScale(newScale);
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
}
|
||||
|
||||
void TransformComponent::SetScaleX(float newScale)
|
||||
{
|
||||
AZ_Warning("AzToolsFramework::TransformComponent", false, "SetScaleX is deprecated, please use SetLocalScaleX");
|
||||
|
||||
AZ::Transform newWorldTransform = GetWorldTM();
|
||||
AZ::Vector3 scale = newWorldTransform.ExtractScale();
|
||||
scale.SetX(newScale);
|
||||
newWorldTransform.MultiplyByScale(scale);
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
|
||||
void TransformComponent::SetScaleY(float newScale)
|
||||
{
|
||||
AZ_Warning("AzToolsFramework::TransformComponent", false, "SetScaleY is deprecated, please use SetLocalScaleY");
|
||||
|
||||
AZ::Transform newWorldTransform = GetWorldTM();
|
||||
AZ::Vector3 scale = newWorldTransform.ExtractScale();
|
||||
scale.SetY(newScale);
|
||||
newWorldTransform.MultiplyByScale(scale);
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
|
||||
void TransformComponent::SetScaleZ(float newScale)
|
||||
{
|
||||
AZ_Warning("AzToolsFramework::TransformComponent", false, "SetScaleZ is deprecated, please use SetLocalScaleZ");
|
||||
|
||||
AZ::Transform newWorldTransform = GetWorldTM();
|
||||
AZ::Vector3 scale = newWorldTransform.ExtractScale();
|
||||
scale.SetZ(newScale);
|
||||
newWorldTransform.MultiplyByScale(scale);
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
|
||||
AZ::Vector3 TransformComponent::GetScale()
|
||||
{
|
||||
AZ_Warning("AzToolsFramework::TransformComponent", false, "GetScale is deprecated, please use GetLocalScale");
|
||||
return GetWorldTM().GetScale();
|
||||
}
|
||||
|
||||
float TransformComponent::GetScaleX()
|
||||
{
|
||||
AZ_Warning("AzToolsFramework::TransformComponent", false, "GetScaleX is deprecated, please use GetLocalScale");
|
||||
return GetWorldTM().GetScale().GetX();
|
||||
}
|
||||
|
||||
float TransformComponent::GetScaleY()
|
||||
{
|
||||
AZ_Warning("AzToolsFramework::TransformComponent", false, "GetScaleY is deprecated, please use GetLocalScale");
|
||||
return GetWorldTM().GetScale().GetY();
|
||||
}
|
||||
|
||||
float TransformComponent::GetScaleZ()
|
||||
{
|
||||
AZ_Warning("AzToolsFramework::TransformComponent", false, "GetScaleZ is deprecated, please use GetLocalScale");
|
||||
return GetWorldTM().GetScale().GetZ();
|
||||
}
|
||||
|
||||
void TransformComponent::SetLocalScale(const AZ::Vector3& scale)
|
||||
{
|
||||
m_editorTransform.m_scale = scale;
|
||||
TransformChanged();
|
||||
}
|
||||
|
||||
void TransformComponent::SetLocalScaleX(float scaleX)
|
||||
{
|
||||
m_editorTransform.m_scale.SetX(scaleX);
|
||||
TransformChanged();
|
||||
}
|
||||
|
||||
void TransformComponent::SetLocalScaleY(float scaleY)
|
||||
{
|
||||
m_editorTransform.m_scale.SetY(scaleY);
|
||||
TransformChanged();
|
||||
}
|
||||
|
||||
void TransformComponent::SetLocalScaleZ(float scaleZ)
|
||||
{
|
||||
m_editorTransform.m_scale.SetZ(scaleZ);
|
||||
TransformChanged();
|
||||
}
|
||||
|
||||
AZ::Vector3 TransformComponent::GetLocalScale()
|
||||
{
|
||||
return m_editorTransform.m_scale;
|
||||
@@ -781,6 +693,22 @@ namespace AzToolsFramework
|
||||
return GetWorldTM().GetScale();
|
||||
}
|
||||
|
||||
void TransformComponent::SetLocalUniformScale(float scale)
|
||||
{
|
||||
m_editorTransform.m_scale = AZ::Vector3(scale);
|
||||
TransformChanged();
|
||||
}
|
||||
|
||||
float TransformComponent::GetLocalUniformScale()
|
||||
{
|
||||
return m_editorTransform.m_scale.GetMaxElement();
|
||||
}
|
||||
|
||||
float TransformComponent::GetWorldUniformScale()
|
||||
{
|
||||
return GetWorldTM().GetUniformScale();
|
||||
}
|
||||
|
||||
const AZ::Transform& TransformComponent::GetParentWorldTM() const
|
||||
{
|
||||
auto parent = GetParentTransformComponent();
|
||||
@@ -1183,12 +1111,6 @@ namespace AzToolsFramework
|
||||
ModifyEditorTransform(m_editorTransform.m_rotate, data, parent);
|
||||
}
|
||||
|
||||
void TransformComponent::ScaleBy(const AZ::Vector3& data)
|
||||
{
|
||||
//scale is always local
|
||||
ModifyEditorTransform(m_editorTransform.m_scale, data, AZ::Transform::Identity());
|
||||
}
|
||||
|
||||
AZ::EntityId TransformComponent::GetSliceEntityParentId()
|
||||
{
|
||||
return GetParentId();
|
||||
|
||||
+4
-15
@@ -130,24 +130,14 @@ namespace AzToolsFramework
|
||||
AZ::Quaternion GetLocalRotationQuaternion() override;
|
||||
|
||||
// Scale Modifiers
|
||||
void SetScale(const AZ::Vector3& newScale) override;
|
||||
void SetScaleX(float newScale) override;
|
||||
void SetScaleY(float newScale) override;
|
||||
void SetScaleZ(float newScale) override;
|
||||
|
||||
AZ::Vector3 GetScale() override;
|
||||
float GetScaleX() override;
|
||||
float GetScaleY() override;
|
||||
float GetScaleZ() override;
|
||||
|
||||
void SetLocalScale(const AZ::Vector3& scale) override;
|
||||
void SetLocalScaleX(float scaleX) override;
|
||||
void SetLocalScaleY(float scaleY) override;
|
||||
void SetLocalScaleZ(float scaleZ) override;
|
||||
|
||||
AZ::Vector3 GetLocalScale() override;
|
||||
AZ::Vector3 GetWorldScale() override;
|
||||
|
||||
void SetLocalUniformScale(float scale) override;
|
||||
float GetLocalUniformScale() override;
|
||||
float GetWorldUniformScale() override;
|
||||
|
||||
AZ::EntityId GetParentId() override;
|
||||
AZ::TransformInterface* GetParent() override;
|
||||
void SetParent(AZ::EntityId parentId) override;
|
||||
@@ -161,7 +151,6 @@ namespace AzToolsFramework
|
||||
// TransformComponentMessages::Bus
|
||||
void TranslateBy(const AZ::Vector3&) override;
|
||||
void RotateBy(const AZ::Vector3&) override; // euler in degrees
|
||||
void ScaleBy(const AZ::Vector3&) override;
|
||||
const EditorTransform& GetLocalEditorTransform() override;
|
||||
void SetLocalEditorTransform(const EditorTransform& dest) override;
|
||||
bool IsTransformLocked() override;
|
||||
|
||||
-1
@@ -65,7 +65,6 @@ namespace AzToolsFramework
|
||||
|
||||
virtual void TranslateBy(const AZ::Vector3&) = 0;
|
||||
virtual void RotateBy(const AZ::Vector3&) = 0;
|
||||
virtual void ScaleBy(const AZ::Vector3&) = 0;
|
||||
|
||||
virtual bool IsTransformLocked() = 0;
|
||||
};
|
||||
|
||||
+7
-2
@@ -83,7 +83,7 @@ namespace AzToolsFramework
|
||||
protected:
|
||||
QWidget* GetFirstInTabOrder() override;
|
||||
QWidget* GetLastInTabOrder() override;
|
||||
void UpdateTabOrder() override;
|
||||
void UpdateTabOrder() override;
|
||||
|
||||
void onChildComboBoxValueChange(int comboBoxIndex) override;
|
||||
|
||||
@@ -93,7 +93,7 @@ namespace AzToolsFramework
|
||||
|
||||
void addElementImpl(const AZStd::pair<T, AZStd::string>& genericValue);
|
||||
|
||||
QLabel* m_warningLabel = nullptr;
|
||||
QLabel* m_warningLabel = nullptr;
|
||||
DHQComboBox* m_pComboBox;
|
||||
AZStd::vector<AZStd::pair<T, AZStd::string>> m_values;
|
||||
AZ::AttributeFunction <void(const T&)>* m_postChangeNotifyCB{};
|
||||
@@ -131,6 +131,11 @@ namespace AzToolsFramework
|
||||
template<typename T>
|
||||
AzToolsFramework::PropertyHandlerBase* RegisterGenericComboBoxHandler()
|
||||
{
|
||||
if (!AzToolsFramework::PropertyTypeRegistrationMessages::Bus::FindFirstHandler())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto propertyHandler = aznew GenericComboBoxHandler<T>();
|
||||
AzToolsFramework::PropertyTypeRegistrationMessages::Bus::Broadcast(&AzToolsFramework::PropertyTypeRegistrationMessages::RegisterPropertyType, propertyHandler);
|
||||
return propertyHandler;
|
||||
|
||||
+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}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+118
-32
@@ -435,7 +435,7 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
static void DestroyTransformModeSelectionCluster(const ViewportUi::ClusterId clusterId)
|
||||
static void DestroyCluster(const ViewportUi::ClusterId clusterId)
|
||||
{
|
||||
ViewportUi::ViewportUiRequestBus::Event(
|
||||
ViewportUi::DefaultViewportId,
|
||||
@@ -483,6 +483,26 @@ namespace AzToolsFramework
|
||||
return worldFromLocal.TransformPoint(CalculateCenterOffset(entityId, pivot));
|
||||
}
|
||||
|
||||
void EditorTransformComponentSelection::UpdateSpaceCluster(const ReferenceFrame referenceFrame)
|
||||
{
|
||||
auto buttonIdFromFrameFn = [this](const ReferenceFrame referenceFrame) {
|
||||
switch (referenceFrame)
|
||||
{
|
||||
case ReferenceFrame::Local:
|
||||
return m_spaceCluster.m_localButtonId;
|
||||
case ReferenceFrame::Parent:
|
||||
return m_spaceCluster.m_parentButtonId;
|
||||
case ReferenceFrame::World:
|
||||
return m_spaceCluster.m_worldButtonId;
|
||||
}
|
||||
return m_spaceCluster.m_parentButtonId;
|
||||
};
|
||||
|
||||
ViewportUi::ViewportUiRequestBus::Event(
|
||||
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::SetClusterActiveButton, m_spaceCluster.m_spaceClusterId,
|
||||
buttonIdFromFrameFn(referenceFrame));
|
||||
}
|
||||
|
||||
namespace ETCS
|
||||
{
|
||||
PivotOrientationResult CalculatePivotOrientation(
|
||||
@@ -789,13 +809,13 @@ namespace AzToolsFramework
|
||||
EntityIdManipulators& entityIdManipulators,
|
||||
OptionalFrame& pivotOverrideFrame,
|
||||
ViewportInteraction::KeyboardModifiers& prevModifiers,
|
||||
bool& transformChangedInternally)
|
||||
bool& transformChangedInternally, SpaceCluster spaceCluster)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
|
||||
|
||||
entityIdManipulators.m_manipulators->SetLocalPosition(action.LocalPosition());
|
||||
|
||||
const ReferenceFrame referenceFrame = ReferenceFrameFromModifiers(action.m_modifiers);
|
||||
const ReferenceFrame referenceFrame = spaceCluster.m_spaceLock ? spaceCluster.m_currentSpace : ReferenceFrameFromModifiers(action.m_modifiers);
|
||||
|
||||
if (action.m_modifiers.Ctrl())
|
||||
{
|
||||
@@ -1027,6 +1047,7 @@ namespace AzToolsFramework
|
||||
EditorManipulatorCommandUndoRedoRequestBus::Handler::BusConnect(entityContextId);
|
||||
|
||||
CreateTransformModeSelectionCluster();
|
||||
CreateSpaceSelectionCluster();
|
||||
RegisterActions();
|
||||
SetupBoxSelect();
|
||||
RefreshSelectedEntityIdsAndRegenerateManipulators();
|
||||
@@ -1037,7 +1058,9 @@ namespace AzToolsFramework
|
||||
m_selectedEntityIds.clear();
|
||||
DestroyManipulators(m_entityIdManipulators);
|
||||
|
||||
DestroyTransformModeSelectionCluster(m_transformModeClusterId);
|
||||
DestroyCluster(m_transformModeClusterId);
|
||||
DestroyCluster(m_spaceCluster.m_spaceClusterId);
|
||||
|
||||
UnregisterActions();
|
||||
|
||||
m_pivotOverrideFrame.Reset();
|
||||
@@ -1274,8 +1297,8 @@ namespace AzToolsFramework
|
||||
[this, prevModifiers, manipulatorEntityIds](const LinearManipulator::Action& action) mutable -> void
|
||||
{
|
||||
UpdateTranslationManipulator(
|
||||
action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators,
|
||||
m_pivotOverrideFrame, prevModifiers, m_transformChangedInternally);
|
||||
action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators, m_pivotOverrideFrame, prevModifiers,
|
||||
m_transformChangedInternally, m_spaceCluster);
|
||||
});
|
||||
|
||||
translationManipulators->InstallLinearManipulatorMouseUpCallback(
|
||||
@@ -1305,8 +1328,8 @@ namespace AzToolsFramework
|
||||
[this, prevModifiers, manipulatorEntityIds](const PlanarManipulator::Action& action) mutable -> void
|
||||
{
|
||||
UpdateTranslationManipulator(
|
||||
action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators,
|
||||
m_pivotOverrideFrame, prevModifiers, m_transformChangedInternally);
|
||||
action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators, m_pivotOverrideFrame, prevModifiers,
|
||||
m_transformChangedInternally, m_spaceCluster);
|
||||
});
|
||||
|
||||
translationManipulators->InstallPlanarManipulatorMouseUpCallback(
|
||||
@@ -1335,8 +1358,8 @@ namespace AzToolsFramework
|
||||
[this, prevModifiers, manipulatorEntityIds](const SurfaceManipulator::Action& action) mutable -> void
|
||||
{
|
||||
UpdateTranslationManipulator(
|
||||
action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators,
|
||||
m_pivotOverrideFrame, prevModifiers, m_transformChangedInternally);
|
||||
action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators, m_pivotOverrideFrame, prevModifiers,
|
||||
m_transformChangedInternally, m_spaceCluster);
|
||||
});
|
||||
|
||||
translationManipulators->InstallSurfaceManipulatorMouseUpCallback(
|
||||
@@ -1414,7 +1437,7 @@ namespace AzToolsFramework
|
||||
[this, prevModifiers, sharedRotationState]
|
||||
(const AngularManipulator::Action& action) mutable -> void
|
||||
{
|
||||
const ReferenceFrame referenceFrame = ReferenceFrameFromModifiers(action.m_modifiers);
|
||||
const ReferenceFrame referenceFrame = m_spaceCluster.m_spaceLock ? m_spaceCluster.m_currentSpace : 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)
|
||||
@@ -1474,7 +1497,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
const AZ::Quaternion rotation = entityIdLookupIt->second.m_initial.GetRotation().GetNormalized();
|
||||
const AZ::Vector3 position = entityIdLookupIt->second.m_initial.GetTranslation();
|
||||
const AZ::Vector3 scale = entityIdLookupIt->second.m_initial.GetScale();
|
||||
const float scale = entityIdLookupIt->second.m_initial.GetUniformScale();
|
||||
|
||||
const AZ::Vector3 centerOffset = CalculateCenterOffset(entityId, m_pivotMode);
|
||||
|
||||
@@ -1485,7 +1508,7 @@ namespace AzToolsFramework
|
||||
AZ::Transform::CreateFromQuaternion(rotation) *
|
||||
AZ::Transform::CreateTranslation(centerOffset) * offsetRotation *
|
||||
AZ::Transform::CreateTranslation(-centerOffset) *
|
||||
AZ::Transform::CreateScale(scale));
|
||||
AZ::Transform::CreateUniformScale(scale));
|
||||
}
|
||||
break;
|
||||
case ReferenceFrame::Parent:
|
||||
@@ -1597,16 +1620,15 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
const AZ::Transform initial = entityIdLookupIt->second.m_initial;
|
||||
const AZ::Vector3 initialScale = initial.GetScale();
|
||||
const float initialScale = initial.GetUniformScale();
|
||||
|
||||
const auto sumVectorElements = [](const AZ::Vector3& vec) {
|
||||
return vec.GetX() + vec.GetY() + vec.GetZ();
|
||||
};
|
||||
|
||||
const AZ::Vector3 uniformScale = AZ::Vector3(action.m_start.m_sign * sumVectorElements(action.LocalScaleOffset()));
|
||||
const AZ::Vector3 scale = (AZ::Vector3::CreateOne() +
|
||||
(uniformScale / initialScale)).GetClamp(AZ::Vector3(AZ::MinTransformScale), AZ::Vector3(AZ::MaxTransformScale));
|
||||
const AZ::Transform scaleTransform = AZ::Transform::CreateScale(scale);
|
||||
const float uniformScale = action.m_start.m_sign * sumVectorElements(action.LocalScaleOffset());
|
||||
const float scale = AZ::GetClamp(1.0f + uniformScale / initialScale, AZ::MinTransformScale, AZ::MaxTransformScale);
|
||||
const AZ::Transform scaleTransform = AZ::Transform::CreateUniformScale(scale);
|
||||
|
||||
if (action.m_modifiers.Alt())
|
||||
{
|
||||
@@ -1872,7 +1894,7 @@ namespace AzToolsFramework
|
||||
CopyOrientationToSelectedEntitiesGroup(QuaternionFromTransformNoScaling(worldFromLocal));
|
||||
break;
|
||||
case Mode::Scale:
|
||||
CopyScaleToSelectedEntitiesIndividualWorld(worldFromLocal.GetScale());
|
||||
CopyScaleToSelectedEntitiesIndividualWorld(worldFromLocal.GetUniformScale());
|
||||
break;
|
||||
case Mode::Translation:
|
||||
CopyTranslationToSelectedEntitiesGroup(worldFromLocal.GetTranslation());
|
||||
@@ -1901,7 +1923,7 @@ namespace AzToolsFramework
|
||||
CopyOrientationToSelectedEntitiesIndividual(QuaternionFromTransformNoScaling(worldFromLocal));
|
||||
break;
|
||||
case Mode::Scale:
|
||||
CopyScaleToSelectedEntitiesIndividualWorld(worldFromLocal.GetScale());
|
||||
CopyScaleToSelectedEntitiesIndividualWorld(worldFromLocal.GetUniformScale());
|
||||
break;
|
||||
case Mode::Translation:
|
||||
CopyTranslationToSelectedEntitiesIndividual(worldFromLocal.GetTranslation());
|
||||
@@ -2394,7 +2416,7 @@ namespace AzToolsFramework
|
||||
ResetOrientationForSelectedEntitiesLocal();
|
||||
break;
|
||||
case Mode::Scale:
|
||||
CopyScaleToSelectedEntitiesIndividualLocal(AZ::Vector3::CreateOne());
|
||||
CopyScaleToSelectedEntitiesIndividualLocal(1.0f);
|
||||
break;
|
||||
case Mode::Translation:
|
||||
ResetTranslationForSelectedEntitiesLocal();
|
||||
@@ -2420,7 +2442,7 @@ namespace AzToolsFramework
|
||||
ResetOrientationForSelectedEntitiesLocal();
|
||||
break;
|
||||
case Mode::Scale:
|
||||
CopyScaleToSelectedEntitiesIndividualWorld(AZ::Vector3::CreateOne());
|
||||
CopyScaleToSelectedEntitiesIndividualWorld(1.0f);
|
||||
break;
|
||||
case Mode::Translation:
|
||||
// do nothing
|
||||
@@ -2567,6 +2589,67 @@ namespace AzToolsFramework
|
||||
m_transformModeSelectionHandler);
|
||||
}
|
||||
|
||||
void EditorTransformComponentSelection::CreateSpaceSelectionCluster()
|
||||
{
|
||||
// create the cluster for switching spaces/reference frames
|
||||
ViewportUi::ViewportUiRequestBus::EventResult(
|
||||
m_spaceCluster.m_spaceClusterId, ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateCluster,
|
||||
ViewportUi::Alignment::TopRight);
|
||||
|
||||
// create and register the buttons (strings correspond to icons even if the values appear different)
|
||||
m_spaceCluster.m_worldButtonId = RegisterClusterButton(m_spaceCluster.m_spaceClusterId, "World");
|
||||
m_spaceCluster.m_parentButtonId = RegisterClusterButton(m_spaceCluster.m_spaceClusterId, "Parent");
|
||||
m_spaceCluster.m_localButtonId = RegisterClusterButton(m_spaceCluster.m_spaceClusterId, "Local");
|
||||
|
||||
auto onButtonClicked = [this](ViewportUi::ButtonId buttonId) {
|
||||
if (buttonId == m_spaceCluster.m_localButtonId)
|
||||
{
|
||||
// Unlock
|
||||
if (m_spaceCluster.m_spaceLock && m_spaceCluster.m_currentSpace == ReferenceFrame::Local)
|
||||
{
|
||||
m_spaceCluster.m_spaceLock = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spaceCluster.m_spaceLock = true;
|
||||
m_spaceCluster.m_currentSpace = ReferenceFrame::Local;
|
||||
}
|
||||
}
|
||||
else if (buttonId == m_spaceCluster.m_parentButtonId)
|
||||
{
|
||||
// Unlock
|
||||
if (m_spaceCluster.m_spaceLock && m_spaceCluster.m_currentSpace == ReferenceFrame::Parent)
|
||||
{
|
||||
m_spaceCluster.m_spaceLock = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spaceCluster.m_spaceLock = true;
|
||||
m_spaceCluster.m_currentSpace = ReferenceFrame::Parent;
|
||||
}
|
||||
}
|
||||
else if (buttonId == m_spaceCluster.m_worldButtonId)
|
||||
{
|
||||
// Unlock
|
||||
if (m_spaceCluster.m_spaceLock && m_spaceCluster.m_currentSpace == ReferenceFrame::World)
|
||||
{
|
||||
m_spaceCluster.m_spaceLock = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spaceCluster.m_spaceLock = true;
|
||||
m_spaceCluster.m_currentSpace = ReferenceFrame::World;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
m_spaceCluster.m_spaceSelectionHandler = AZ::Event<ViewportUi::ButtonId>::Handler(onButtonClicked);
|
||||
|
||||
ViewportUi::ViewportUiRequestBus::Event(
|
||||
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::RegisterClusterEventHandler,
|
||||
m_spaceCluster.m_spaceClusterId, m_spaceCluster.m_spaceSelectionHandler);
|
||||
}
|
||||
|
||||
EditorTransformComponentSelectionRequests::Mode EditorTransformComponentSelection::GetTransformMode()
|
||||
{
|
||||
return m_mode;
|
||||
@@ -2940,7 +3023,7 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
void EditorTransformComponentSelection::CopyScaleToSelectedEntitiesIndividualWorld(const AZ::Vector3& scale)
|
||||
void EditorTransformComponentSelection::CopyScaleToSelectedEntitiesIndividualWorld(float scale)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
|
||||
|
||||
@@ -2955,7 +3038,7 @@ namespace AzToolsFramework
|
||||
const auto transformsBefore = RecordTransformsBefore(manipulatorEntityIds.m_entityIds);
|
||||
|
||||
// update scale relative to initial
|
||||
const AZ::Transform scaleTransform = AZ::Transform::CreateScale(scale);
|
||||
const AZ::Transform scaleTransform = AZ::Transform::CreateUniformScale(scale);
|
||||
for (AZ::EntityId entityId : manipulatorEntityIds.m_entityIds)
|
||||
{
|
||||
ScopedUndoBatch::MarkEntityDirty(entityId);
|
||||
@@ -2964,7 +3047,7 @@ namespace AzToolsFramework
|
||||
if (transformIt != transformsBefore.end())
|
||||
{
|
||||
AZ::Transform transformBefore = transformIt->second;
|
||||
transformBefore.ExtractScale();
|
||||
transformBefore.ExtractUniformScale();
|
||||
AZ::Transform newWorldFromLocal = transformBefore * scaleTransform;
|
||||
|
||||
SetEntityWorldTransform(entityId, newWorldFromLocal);
|
||||
@@ -2974,7 +3057,7 @@ namespace AzToolsFramework
|
||||
RefreshUiAfterChange(manipulatorEntityIds.m_entityIds);
|
||||
}
|
||||
|
||||
void EditorTransformComponentSelection::CopyScaleToSelectedEntitiesIndividualLocal(const AZ::Vector3& scale)
|
||||
void EditorTransformComponentSelection::CopyScaleToSelectedEntitiesIndividualLocal(float scale)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
|
||||
|
||||
@@ -3020,9 +3103,9 @@ namespace AzToolsFramework
|
||||
if (transformIt != transformsBefore.end())
|
||||
{
|
||||
AZ::Transform newWorldFromLocal = transformIt->second;
|
||||
const AZ::Vector3 scale = newWorldFromLocal.GetScale();
|
||||
const float scale = newWorldFromLocal.GetUniformScale();
|
||||
newWorldFromLocal.SetRotation(orientation);
|
||||
newWorldFromLocal *= AZ::Transform::CreateScale(scale);
|
||||
newWorldFromLocal *= AZ::Transform::CreateUniformScale(scale);
|
||||
|
||||
SetEntityWorldTransform(entityId, newWorldFromLocal);
|
||||
}
|
||||
@@ -3278,7 +3361,10 @@ namespace AzToolsFramework
|
||||
ViewportInteraction::BuildMouseButtons(
|
||||
QGuiApplication::mouseButtons()), m_boxSelect.Active());
|
||||
|
||||
const ReferenceFrame referenceFrame = ReferenceFrameFromModifiers(modifiers);
|
||||
const ReferenceFrame referenceFrame =
|
||||
m_spaceCluster.m_spaceLock ? m_spaceCluster.m_currentSpace : ReferenceFrameFromModifiers(modifiers);
|
||||
|
||||
UpdateSpaceCluster(referenceFrame);
|
||||
|
||||
bool refresh = false;
|
||||
if (referenceFrame != m_referenceFrame)
|
||||
@@ -3669,7 +3755,7 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
void EditorTransformComponentSelection::SetEntityLocalScale(
|
||||
const AZ::EntityId entityId, const AZ::Vector3& localScale)
|
||||
const AZ::EntityId entityId, const float localScale)
|
||||
{
|
||||
ETCS::SetEntityLocalScale(entityId, localScale, m_transformChangedInternally);
|
||||
}
|
||||
@@ -3722,11 +3808,11 @@ namespace AzToolsFramework
|
||||
entityId, &AZ::TransformBus::Events::SetWorldTM, worldTransform);
|
||||
}
|
||||
|
||||
void SetEntityLocalScale(AZ::EntityId entityId, const AZ::Vector3& localScale, bool& internal)
|
||||
void SetEntityLocalScale(AZ::EntityId entityId, float localScale, bool& internal)
|
||||
{
|
||||
ScopeSwitch sw(internal);
|
||||
AZ::TransformBus::Event(
|
||||
entityId, &AZ::TransformBus::Events::SetLocalScale, localScale);
|
||||
entityId, &AZ::TransformBus::Events::SetLocalUniformScale, localScale);
|
||||
}
|
||||
|
||||
void SetEntityLocalRotation(AZ::EntityId entityId, const AZ::Vector3& localRotation, bool& internal)
|
||||
|
||||
+19
-4
@@ -106,6 +106,17 @@ namespace AzToolsFramework
|
||||
World, //!< World space (space aligned to world axes - identity).
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
//! Entity selection/interaction handling.
|
||||
//! Provide a suite of functionality for manipulating entities, primarily through their TransformComponent.
|
||||
class EditorTransformComponentSelection
|
||||
@@ -160,6 +171,7 @@ namespace AzToolsFramework
|
||||
void RegenerateManipulators();
|
||||
|
||||
void CreateTransformModeSelectionCluster();
|
||||
void CreateSpaceSelectionCluster();
|
||||
|
||||
void ClearManipulatorTranslationOverride();
|
||||
void ClearManipulatorOrientationOverride();
|
||||
@@ -214,8 +226,8 @@ namespace AzToolsFramework
|
||||
void CopyOrientationToSelectedEntitiesIndividual(const AZ::Quaternion& orientation);
|
||||
void CopyOrientationToSelectedEntitiesGroup(const AZ::Quaternion& orientation);
|
||||
void ResetOrientationForSelectedEntitiesLocal();
|
||||
void CopyScaleToSelectedEntitiesIndividualLocal(const AZ::Vector3& scale);
|
||||
void CopyScaleToSelectedEntitiesIndividualWorld(const AZ::Vector3& scale);
|
||||
void CopyScaleToSelectedEntitiesIndividualLocal(float scale);
|
||||
void CopyScaleToSelectedEntitiesIndividualWorld(float scale);
|
||||
|
||||
// EditorManipulatorCommandUndoRedoRequestBus ...
|
||||
void UndoRedoEntityManipulatorCommand(
|
||||
@@ -250,7 +262,7 @@ namespace AzToolsFramework
|
||||
void SetEntityWorldTranslation(AZ::EntityId entityId, const AZ::Vector3& worldTranslation);
|
||||
void SetEntityLocalTranslation(AZ::EntityId entityId, const AZ::Vector3& localTranslation);
|
||||
void SetEntityWorldTransform(AZ::EntityId entityId, const AZ::Transform& worldTransform);
|
||||
void SetEntityLocalScale(AZ::EntityId entityId, const AZ::Vector3& localScale);
|
||||
void SetEntityLocalScale(AZ::EntityId entityId, float localScale);
|
||||
void SetEntityLocalRotation(AZ::EntityId entityId, const AZ::Vector3& localRotation);
|
||||
|
||||
AZ::EntityId m_hoveredEntityId; //!< What EntityId is the mouse currently hovering over (if any).
|
||||
@@ -285,6 +297,9 @@ 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);
|
||||
};
|
||||
|
||||
//! The ETCS (EntityTransformComponentSelection) namespace contains functions and data used exclusively by
|
||||
@@ -320,7 +335,7 @@ namespace AzToolsFramework
|
||||
void SetEntityWorldTranslation(AZ::EntityId entityId, const AZ::Vector3& worldTranslation, bool& internal);
|
||||
void SetEntityLocalTranslation(AZ::EntityId entityId, const AZ::Vector3& localTranslation, bool& internal);
|
||||
void SetEntityWorldTransform(AZ::EntityId entityId, const AZ::Transform& worldTransform, bool& internal);
|
||||
void SetEntityLocalScale(AZ::EntityId entityId, const AZ::Vector3& localScale, bool& internal);
|
||||
void SetEntityLocalScale(AZ::EntityId entityId, float localScale, bool& internal);
|
||||
void SetEntityLocalRotation(AZ::EntityId entityId, const AZ::Vector3& localRotation, bool& internal);
|
||||
} // namespace ETCS
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+2
-2
@@ -101,10 +101,10 @@ namespace AzToolsFramework
|
||||
virtual void ResetOrientationForSelectedEntitiesLocal() = 0;
|
||||
|
||||
/// Copy scale to each individual entity in local space without moving position.
|
||||
virtual void CopyScaleToSelectedEntitiesIndividualLocal(const AZ::Vector3& scale) = 0;
|
||||
virtual void CopyScaleToSelectedEntitiesIndividualLocal(float scale) = 0;
|
||||
|
||||
/// Copy scale to to each individual entity in world (absolute) space.
|
||||
virtual void CopyScaleToSelectedEntitiesIndividualWorld(const AZ::Vector3& scale) = 0;
|
||||
virtual void CopyScaleToSelectedEntitiesIndividualWorld(float scale) = 0;
|
||||
|
||||
protected:
|
||||
~EditorTransformComponentSelectionRequests() = default;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user