Merge branch 'main' into Prefab/RemoveUndoCacheDependency
This commit is contained in:
+12
-1
@@ -81,9 +81,20 @@ namespace AzToolsFramework
|
||||
|
||||
m_ui->m_assetBrowserTreeViewWidget->SetName("AssetBrowserTreeView_" + name);
|
||||
|
||||
bool selectedAsset = false;
|
||||
|
||||
for (auto& assetId : selection.GetSelectedAssetIds())
|
||||
{
|
||||
m_ui->m_assetBrowserTreeViewWidget->SelectProduct(assetId);
|
||||
if (assetId.IsValid())
|
||||
{
|
||||
selectedAsset = true;
|
||||
m_ui->m_assetBrowserTreeViewWidget->SelectProduct(assetId);
|
||||
}
|
||||
}
|
||||
|
||||
if (!selectedAsset)
|
||||
{
|
||||
m_ui->m_assetBrowserTreeViewWidget->SelectFolder(selection.GetDefaultDirectory());
|
||||
}
|
||||
|
||||
setWindowTitle(tr("Pick %1").arg(m_selection.GetTitle()));
|
||||
|
||||
@@ -93,6 +93,16 @@ namespace AzToolsFramework
|
||||
m_selectedAssetIds.push_back(selectedAssetId);
|
||||
}
|
||||
|
||||
void AssetSelectionModel::SetDefaultDirectory(AZStd::string_view defaultDirectory)
|
||||
{
|
||||
m_defaultDirectory = defaultDirectory;
|
||||
}
|
||||
|
||||
AZStd::string_view AssetSelectionModel::GetDefaultDirectory() const
|
||||
{
|
||||
return m_defaultDirectory;
|
||||
}
|
||||
|
||||
AZStd::vector<const AssetBrowserEntry*>& AssetSelectionModel::GetResults()
|
||||
{
|
||||
return m_results;
|
||||
|
||||
@@ -47,6 +47,9 @@ namespace AzToolsFramework
|
||||
const AZStd::vector<AZ::Data::AssetId>& GetSelectedAssetIds() const;
|
||||
void SetSelectedAssetIds(const AZStd::vector<AZ::Data::AssetId>& selectedAssetIds);
|
||||
void SetSelectedAssetId(const AZ::Data::AssetId& selectedAssetId);
|
||||
|
||||
void SetDefaultDirectory(AZStd::string_view defaultDirectory);
|
||||
AZStd::string_view GetDefaultDirectory() const;
|
||||
|
||||
AZStd::vector<const AssetBrowserEntry*>& GetResults();
|
||||
const AssetBrowserEntry* GetResult();
|
||||
@@ -72,6 +75,7 @@ namespace AzToolsFramework
|
||||
|
||||
AZStd::vector<AZ::Data::AssetId> m_selectedAssetIds;
|
||||
AZStd::vector<const AssetBrowserEntry*> m_results;
|
||||
AZStd::string m_defaultDirectory;
|
||||
|
||||
QString m_title;
|
||||
};
|
||||
|
||||
+45
-18
@@ -14,6 +14,7 @@
|
||||
#include <AzCore/Asset/AssetManagerBus.h>
|
||||
#include <AzCore/Math/Crc.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
|
||||
@@ -270,7 +271,20 @@ namespace AzToolsFramework
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AssetBrowserTreeView::SelectEntry(const QModelIndex& idxParent, const AZStd::vector<AZStd::string>& entries, const uint32_t entryPathIndex)
|
||||
void AssetBrowserTreeView::SelectFolder(AZStd::string_view folderPath)
|
||||
{
|
||||
if (folderPath.size() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AZStd::vector<AZStd::string> entries;
|
||||
AZ::StringFunc::Tokenize(folderPath, entries, "/");
|
||||
|
||||
SelectEntry(QModelIndex(), entries, 0, true);
|
||||
}
|
||||
|
||||
bool AssetBrowserTreeView::SelectEntry(const QModelIndex& idxParent, const AZStd::vector<AZStd::string>& entries, const uint32_t entryPathIndex, bool useDisplayName)
|
||||
{
|
||||
if (entries.empty())
|
||||
{
|
||||
@@ -285,30 +299,43 @@ namespace AzToolsFramework
|
||||
auto rowIdx = model()->index(idx, 0, idxParent);
|
||||
auto rowEntry = GetEntryFromIndex<AssetBrowserEntry>(rowIdx);
|
||||
|
||||
// Check if this entry name matches the query
|
||||
if (rowEntry && AzFramework::StringFunc::Equal(entry.c_str(), rowEntry->GetName().c_str(), true))
|
||||
if (rowEntry)
|
||||
{
|
||||
// Final entry found - set it as the selected element
|
||||
if (entryPathIndex == entries.size() - 1)
|
||||
{
|
||||
selectionModel()->clear();
|
||||
selectionModel()->select(rowIdx, QItemSelectionModel::Select);
|
||||
setCurrentIndex(rowIdx);
|
||||
return true;
|
||||
}
|
||||
// Check if this entry name matches the query
|
||||
AZStd::string_view compareName = useDisplayName ? (const char*)(rowEntry->GetDisplayName().toUtf8()) : rowEntry->GetName().c_str();
|
||||
|
||||
// If this isn't the final entry, it needs to be a folder for the path to be valid (otherwise, early out)
|
||||
if (rowEntry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Folder)
|
||||
if (AzFramework::StringFunc::Equal(entry.c_str(), compareName, true))
|
||||
{
|
||||
// Folder found - if the final entry is found, expand this folder so the final entry is viewable in the Asset Browser (otherwise, early out)
|
||||
if (SelectEntry(rowIdx, entries, entryPathIndex + 1))
|
||||
// Final entry found - set it as the selected element
|
||||
if (entryPathIndex == entries.size() - 1)
|
||||
{
|
||||
expand(rowIdx);
|
||||
if (rowEntry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Folder)
|
||||
{
|
||||
// Expand the item itself if it is a folder
|
||||
expand(rowIdx);
|
||||
}
|
||||
|
||||
selectionModel()->clear();
|
||||
selectionModel()->select(rowIdx, QItemSelectionModel::Select);
|
||||
setCurrentIndex(rowIdx);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// If this isn't the final entry, it needs to be a folder for the path to be valid (otherwise, early out)
|
||||
if (rowEntry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Folder)
|
||||
{
|
||||
// Folder found - if the final entry is found, expand this folder so the final entry is viewable in the Asset
|
||||
// Browser (otherwise, early out)
|
||||
if (SelectEntry(rowIdx, entries, entryPathIndex + 1, useDisplayName))
|
||||
{
|
||||
expand(rowIdx);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -60,6 +60,8 @@ namespace AzToolsFramework
|
||||
|
||||
AZStd::vector<AssetBrowserEntry*> GetSelectedAssets() const;
|
||||
|
||||
void SelectFolder(AZStd::string_view folderPath);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// AssetBrowserViewRequestBus
|
||||
void SelectProduct(AZ::Data::AssetId assetID) override;
|
||||
@@ -67,6 +69,7 @@ namespace AzToolsFramework
|
||||
void ClearFilter() override;
|
||||
|
||||
void Update() override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -105,7 +108,7 @@ namespace AzToolsFramework
|
||||
QString m_name;
|
||||
|
||||
bool SelectProduct(const QModelIndex& idxParent, AZ::Data::AssetId assetID);
|
||||
bool SelectEntry(const QModelIndex& idxParent, const AZStd::vector<AZStd::string>& entryPathTokens, const uint32_t entryPathIndex = 0);
|
||||
bool SelectEntry(const QModelIndex& idxParent, const AZStd::vector<AZStd::string>& entryPathTokens, const uint32_t entryPathIndex = 0, bool useDisplayName = false);
|
||||
|
||||
//! Grab one entry from the source thumbnail list and update it
|
||||
void UpdateSCThumbnails();
|
||||
|
||||
+50
-10
@@ -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,21 +224,52 @@ namespace AzToolsFramework
|
||||
AzToolsFramework::Prefab::TemplateId templateId = m_prefabSystemComponent->GetTemplateIdFromFilePath(relativePath);
|
||||
|
||||
m_rootInstance->SetTemplateSourcePath(relativePath);
|
||||
|
||||
bool newLevelFromTemplate = false;
|
||||
|
||||
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()});
|
||||
AZStd::string watchFolder;
|
||||
AZ::Data::AssetInfo assetInfo;
|
||||
bool sourceInfoFound = false;
|
||||
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
|
||||
sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, DefaultLevelTemplateName,
|
||||
assetInfo, watchFolder);
|
||||
|
||||
AzToolsFramework::Prefab::PrefabDom dom;
|
||||
bool success = AzToolsFramework::Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*m_rootInstance, dom);
|
||||
if (!success)
|
||||
if (sourceInfoFound)
|
||||
{
|
||||
AZ_Error("Prefab", false, "Failed to convert current root instance into a DOM when saving file '%.*s'", AZ_STRING_ARG(filename));
|
||||
return false;
|
||||
AZStd::string fullPath;
|
||||
AZ::StringFunc::Path::Join(watchFolder.c_str(), assetInfo.m_relativePath.c_str(), fullPath);
|
||||
|
||||
// Get the default prefab and copy the Dom over to the new template being saved
|
||||
Prefab::TemplateId defaultId = m_loaderInterface->LoadTemplateFromFile(fullPath.c_str());
|
||||
Prefab::PrefabDom& dom = m_prefabSystemComponent->FindTemplateDom(defaultId);
|
||||
|
||||
Prefab::PrefabDom levelDefaultDom;
|
||||
levelDefaultDom.CopyFrom(dom, levelDefaultDom.GetAllocator());
|
||||
|
||||
Prefab::PrefabDomPath sourcePath("/Source");
|
||||
sourcePath.Set(levelDefaultDom, relativePath.c_str());
|
||||
|
||||
templateId = m_prefabSystemComponent->AddTemplate(relativePath, std::move(levelDefaultDom));
|
||||
newLevelFromTemplate = true;
|
||||
}
|
||||
templateId = m_prefabSystemComponent->AddTemplate(relativePath, std::move(dom));
|
||||
else
|
||||
{
|
||||
// Create an empty level since we couldn't find the default template
|
||||
m_rootInstance->m_containerEntity->AddComponent(aznew Prefab::EditorPrefabComponent());
|
||||
HandleEntitiesAdded({ m_rootInstance->m_containerEntity.get() });
|
||||
|
||||
AzToolsFramework::Prefab::PrefabDom dom;
|
||||
bool success = AzToolsFramework::Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*m_rootInstance, dom);
|
||||
if (!success)
|
||||
{
|
||||
AZ_Error("Prefab", false, "Failed to convert current root instance into a DOM when saving file '%.*s'", AZ_STRING_ARG(filename));
|
||||
return false;
|
||||
}
|
||||
templateId = m_prefabSystemComponent->AddTemplate(relativePath, std::move(dom));
|
||||
}
|
||||
|
||||
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));
|
||||
@@ -253,6 +286,13 @@ namespace AzToolsFramework
|
||||
m_prefabSystemComponent->RemoveTemplate(prevTemplateId);
|
||||
}
|
||||
|
||||
// If we have a new level from a template, we need to make sure to propagate the changes here otherwise
|
||||
// the entities from the new template won't show up
|
||||
if (newLevelFromTemplate)
|
||||
{
|
||||
m_prefabSystemComponent->PropagateTemplateChanges(templateId);
|
||||
}
|
||||
|
||||
AZStd::string out;
|
||||
if (m_loaderInterface->SaveTemplateToString(m_rootInstance->GetTemplateId(), out))
|
||||
{
|
||||
|
||||
+2
@@ -216,5 +216,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";
|
||||
};
|
||||
}
|
||||
|
||||
@@ -447,17 +447,14 @@ namespace AzToolsFramework
|
||||
m_radius * viewScale);
|
||||
|
||||
debugDisplay.SetColor(ViewColor(manipulatorState.m_mouseOver, m_color, m_mouseOverColor).GetAsVector4());
|
||||
|
||||
// show wireframe if the axis has been corrected/flipped
|
||||
// note: please see IRenderAuxGeom.h for the definition of e_FillModeWireframe and e_FillModeSolid.
|
||||
// it is not possible to include IRenderAuxGeom from here and we also don't want to introduce that dependency.
|
||||
// these legacy enums should be wrapped so set SetFillMode can be used in a type safe way, until then,
|
||||
// use the values directly until the API has been updated.
|
||||
const AZ::u32 prevFillMode = debugDisplay.SetFillMode(
|
||||
m_shouldCorrect ? /*e_FillModeWireframe =*/ 0x1 << 26 : /*e_FillModeSolid =*/ 0);
|
||||
|
||||
debugDisplay.DrawCone(coneBound.m_base, coneBound.m_axis, coneBound.m_radius, coneBound.m_height, false);
|
||||
debugDisplay.SetFillMode(prevFillMode);
|
||||
if (m_shouldCorrect)
|
||||
{
|
||||
debugDisplay.DrawWireCone(coneBound.m_base, coneBound.m_axis, coneBound.m_radius, coneBound.m_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
debugDisplay.DrawSolidCone(coneBound.m_base, coneBound.m_axis, coneBound.m_radius, coneBound.m_height, false);
|
||||
}
|
||||
|
||||
RefreshBoundInternal(managerId, manipulatorId, coneBound);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+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;
|
||||
|
||||
+1
-2
@@ -140,8 +140,7 @@ namespace AzToolsFramework
|
||||
ProductAssetBrowserEntry* productEntry = static_cast<ProductAssetBrowserEntry*>(childEntry);
|
||||
AZStd::string assetName;
|
||||
AzFramework::StringFunc::Path::GetFileName(productEntry->GetFullPath().c_str(), assetName);
|
||||
m_assets.push_back({
|
||||
assetName, productEntry->GetFullPath(), productEntry->GetAssetId()
|
||||
m_assets.push_back({ productEntry->GetName(), productEntry->GetFullPath(), productEntry->GetAssetId()
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+18
@@ -769,6 +769,14 @@ namespace AzToolsFramework
|
||||
// Request the AssetBrowser Dialog and set a type filter
|
||||
AssetSelectionModel selection = GetAssetSelectionModel();
|
||||
selection.SetSelectedAssetId(m_selectedAssetID);
|
||||
|
||||
AZStd::string defaultDirectory;
|
||||
if (m_defaultDirectoryCallback)
|
||||
{
|
||||
m_defaultDirectoryCallback->Invoke(m_editNotifyTarget, defaultDirectory);
|
||||
selection.SetDefaultDirectory(defaultDirectory);
|
||||
}
|
||||
|
||||
AssetBrowserComponentRequestBus::Broadcast(&AssetBrowserComponentRequests::PickAssets, selection, parentWidget());
|
||||
if (selection.IsValid())
|
||||
{
|
||||
@@ -1080,6 +1088,11 @@ namespace AzToolsFramework
|
||||
m_editNotifyCallback = editNotifyCallback;
|
||||
}
|
||||
|
||||
void PropertyAssetCtrl::SetDefaultDirectoryCallback(DefaultDirectoryCallbackType* callback)
|
||||
{
|
||||
m_defaultDirectoryCallback = callback;
|
||||
}
|
||||
|
||||
void PropertyAssetCtrl::SetClearNotifyCallback(ClearCallbackType* clearNotifyCallback)
|
||||
{
|
||||
m_clearNotifyCallback = clearNotifyCallback;
|
||||
@@ -1214,6 +1227,11 @@ namespace AzToolsFramework
|
||||
GUI->SetTitle(title.c_str());
|
||||
}
|
||||
}
|
||||
else if (attrib == AZ_CRC_CE("DefaultStartingDirectoryCallback"))
|
||||
{
|
||||
// This is assumed to be an Asset Browser path to a specific folder to be used as a default by the asset picker if provided
|
||||
GUI->SetDefaultDirectoryCallback(azdynamic_cast<PropertyAssetCtrl::DefaultDirectoryCallbackType*>(attrValue->GetAttribute()));
|
||||
}
|
||||
else if (attrib == AZ_CRC("EditCallback", 0xb74f2ee1))
|
||||
{
|
||||
PropertyAssetCtrl::EditCallbackType* func = azdynamic_cast<PropertyAssetCtrl::EditCallbackType*>(attrValue->GetAttribute());
|
||||
|
||||
+3
@@ -68,6 +68,7 @@ namespace AzToolsFramework
|
||||
// This is meant to be used with the "EditCallback" Attribute
|
||||
using EditCallbackType = AZ::Edit::AttributeFunction<void(const AZ::Data::AssetId&, const AZ::Data::AssetType&)>;
|
||||
using ClearCallbackType = AZ::Edit::AttributeFunction<void()>;
|
||||
using DefaultDirectoryCallbackType = AZ::Edit::AttributeFunction<void(AZStd::string&)>;
|
||||
|
||||
PropertyAssetCtrl(QWidget *pParent = NULL, QString optionalValidDragDropExtensions = QString());
|
||||
virtual ~PropertyAssetCtrl();
|
||||
@@ -119,6 +120,7 @@ namespace AzToolsFramework
|
||||
EditCallbackType* m_editNotifyCallback = nullptr;
|
||||
ClearCallbackType* m_clearNotifyCallback = nullptr;
|
||||
QString m_optionalValidDragDropExtensions;
|
||||
DefaultDirectoryCallbackType* m_defaultDirectoryCallback = nullptr;
|
||||
|
||||
//! The number of characters after which the autocompleter dropdown will be shown.
|
||||
// Prevents showing too many options.
|
||||
@@ -196,6 +198,7 @@ namespace AzToolsFramework
|
||||
void SetEditNotifyTarget(void* editNotifyTarget);
|
||||
void SetEditNotifyCallback(EditCallbackType* editNotifyCallback); // This is meant to be used with the "EditCallback" Attribute
|
||||
void SetClearNotifyCallback(ClearCallbackType* clearNotifyCallback); // This is meant to be used with the "ClearNotify" Attribute
|
||||
void SetDefaultDirectoryCallback(DefaultDirectoryCallbackType* callback); // This is meant to be used with the "DefaultStartingDirectoryCallback" Attribute
|
||||
void SetEditButtonEnabled(bool enabled);
|
||||
void SetEditButtonVisible(bool visible);
|
||||
void SetEditButtonIcon(const QIcon& icon);
|
||||
|
||||
+3
-3
@@ -233,9 +233,9 @@ namespace AzToolsFramework
|
||||
}();
|
||||
|
||||
debugDisplay.SetColor(iconHighlight);
|
||||
debugDisplay.DrawTextureLabel(
|
||||
iconTextureId, entityPosition, iconSize, iconSize,
|
||||
/*DisplayContext::ETextureIconFlags::TEXICON_ON_TOP=*/ 0x0008);
|
||||
// debugDisplay.DrawTextureLabel(
|
||||
// iconTextureId, entityPosition, iconSize, iconSize,
|
||||
// /*DisplayContext::ETextureIconFlags::TEXICON_ON_TOP=*/ 0x0008);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+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;
|
||||
|
||||
Reference in New Issue
Block a user