Merge branch 'development' of https://github.com/o3de/o3de into daimini/FocusMode/breadcrumbs
This commit is contained in:
+10
@@ -151,6 +151,10 @@ namespace AzToolsFramework
|
||||
m_ui->m_assetBrowserTableViewWidget, &AssetBrowserTableView::ClearTypeFilter, m_ui->m_searchWidget,
|
||||
&SearchWidget::ClearTypeFilter);
|
||||
|
||||
connect(
|
||||
this, &AssetPickerDialog::SizeChangedSignal, m_ui->m_assetBrowserTableViewWidget,
|
||||
&AssetBrowserTableView::UpdateSizeSlot);
|
||||
|
||||
m_ui->m_assetBrowserTableViewWidget->SetName("AssetBrowserTableView_main");
|
||||
m_tableModel->UpdateTableModelMaps();
|
||||
}
|
||||
@@ -206,6 +210,12 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
void AssetPickerDialog::resizeEvent(QResizeEvent* resizeEvent)
|
||||
{
|
||||
emit SizeChangedSignal(m_ui->verticalLayout_4->geometry().width());
|
||||
QDialog::resizeEvent(resizeEvent);
|
||||
}
|
||||
|
||||
void AssetPickerDialog::keyPressEvent(QKeyEvent* e)
|
||||
{
|
||||
// Until search widget is revised, Return key should not close the dialog,
|
||||
|
||||
+4
@@ -46,6 +46,9 @@ namespace AzToolsFramework
|
||||
explicit AssetPickerDialog(AssetSelectionModel& selection, QWidget* parent = nullptr);
|
||||
virtual ~AssetPickerDialog();
|
||||
|
||||
Q_SIGNALS:
|
||||
void SizeChangedSignal(int newWidth);
|
||||
|
||||
protected:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// QDialog
|
||||
@@ -53,6 +56,7 @@ namespace AzToolsFramework
|
||||
void accept() override;
|
||||
void reject() override;
|
||||
void keyPressEvent(QKeyEvent* e) override;
|
||||
void resizeEvent(QResizeEvent* resizeEvent) override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void DoubleClickedSlot(const QModelIndex& index);
|
||||
|
||||
+3
-3
@@ -117,6 +117,9 @@
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="AzToolsFramework::AssetBrowser::AssetBrowserTableView" name="m_assetBrowserTableViewWidget"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="AzToolsFramework::AssetBrowser::AssetBrowserTreeView" name="m_assetBrowserTreeViewWidget">
|
||||
<property name="sizePolicy">
|
||||
@@ -142,9 +145,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="AzToolsFramework::AssetBrowser::AssetBrowserTableView" name="m_assetBrowserTableViewWidget"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="verticalLayoutWidget">
|
||||
|
||||
+18
-3
@@ -20,13 +20,17 @@ AZ_PUSH_DISABLE_WARNING(
|
||||
#include <QCoreApplication>
|
||||
#include <QHeaderView>
|
||||
#include <QMenu>
|
||||
|
||||
#include <QResizeEvent>
|
||||
#include <QTimer>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace AssetBrowser
|
||||
{
|
||||
const float MinHeaderResizeProportion = .25f;
|
||||
const float MaxHeaderResizeProportion = .75f;
|
||||
const float DefaultHeaderResizeProportion = .5f;
|
||||
|
||||
AssetBrowserTableView::AssetBrowserTableView(QWidget* parent)
|
||||
: AzQtComponents::TableView(parent)
|
||||
, m_delegate(new SearchEntryDelegate(this))
|
||||
@@ -65,8 +69,10 @@ namespace AzToolsFramework
|
||||
AzQtComponents::TableView::setModel(model);
|
||||
connect(m_tableModel, &AssetBrowserTableModel::layoutChanged, this, &AssetBrowserTableView::layoutChangedSlot);
|
||||
|
||||
header()->setSectionResizeMode(0, QHeaderView::ResizeMode::Stretch);
|
||||
header()->setSectionResizeMode(1, QHeaderView::ResizeMode::Stretch);
|
||||
header()->setStretchLastSection(true);
|
||||
header()->setSectionResizeMode(0, QHeaderView::ResizeMode::Interactive);
|
||||
header()->setSectionResizeMode(1, QHeaderView::ResizeMode::Interactive);
|
||||
UpdateSizeSlot(parentWidget()->width());
|
||||
header()->setSortIndicatorShown(false);
|
||||
header()->setSectionsClickable(false);
|
||||
}
|
||||
@@ -148,8 +154,17 @@ namespace AzToolsFramework
|
||||
|
||||
void AssetBrowserTableView::OnAssetBrowserComponentReady()
|
||||
{
|
||||
UpdateSizeSlot(parentWidget()->width());
|
||||
}
|
||||
|
||||
void AssetBrowserTableView::UpdateSizeSlot(int newWidth)
|
||||
{
|
||||
setColumnWidth(0, aznumeric_cast<int>(newWidth * DefaultHeaderResizeProportion));
|
||||
header()->setMinimumSectionSize(aznumeric_cast<int>(newWidth * MinHeaderResizeProportion));
|
||||
header()->setMaximumSectionSize(aznumeric_cast<int>(newWidth * MaxHeaderResizeProportion));
|
||||
}
|
||||
|
||||
|
||||
void AssetBrowserTableView::OnContextMenu([[maybe_unused]] const QPoint& point)
|
||||
{
|
||||
const auto& selectedAssets = GetSelectedAssets();
|
||||
|
||||
+3
-1
@@ -59,12 +59,14 @@ namespace AzToolsFramework
|
||||
void ClearStringFilter();
|
||||
void ClearTypeFilter();
|
||||
|
||||
public Q_SLOTS:
|
||||
void UpdateSizeSlot(int newWidth);
|
||||
|
||||
protected Q_SLOTS:
|
||||
void selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) override;
|
||||
void rowsAboutToBeRemoved(const QModelIndex& parent, int start, int end) override;
|
||||
void layoutChangedSlot(const QList<QPersistentModelIndex> &parents = QList<QPersistentModelIndex>(),
|
||||
QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint);
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
QPointer<AssetBrowserTableModel> m_tableModel;
|
||||
|
||||
@@ -381,12 +381,22 @@ namespace AzToolsFramework
|
||||
return;
|
||||
}
|
||||
|
||||
//orphan any children that remain attached to the entity
|
||||
auto children = entityInfo.GetChildren();
|
||||
for (auto childId : children)
|
||||
bool isPrefabSystemEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
isPrefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
// For slices, orphan any children that remain attached to the entity
|
||||
// For prefabs, this is an unneeded operation because the prefab system handles the orphans
|
||||
// and the extra reparenting operation can be problematic for consumers subscribed to entity
|
||||
// events, such as the entity outliner.
|
||||
if (!isPrefabSystemEnabled)
|
||||
{
|
||||
ReparentChild(childId, AZ::EntityId(), entityId);
|
||||
m_entityOrphanTable[entityId].insert(childId);
|
||||
auto children = entityInfo.GetChildren();
|
||||
for (auto childId : children)
|
||||
{
|
||||
ReparentChild(childId, AZ::EntityId(), entityId);
|
||||
m_entityOrphanTable[entityId].insert(childId);
|
||||
}
|
||||
}
|
||||
|
||||
m_savedOrderInfo[entityId] = AZStd::make_pair(entityInfo.GetParent(), entityInfo.GetIndexForSorting());
|
||||
|
||||
+2
@@ -56,5 +56,7 @@ namespace AzToolsFramework
|
||||
virtual void StopPlayInEditor() = 0;
|
||||
|
||||
virtual void CreateNewLevelPrefab(AZStd::string_view filename, const AZStd::string& templateFilename) = 0;
|
||||
|
||||
virtual bool IsRootPrefabAssigned() const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
+9
@@ -79,6 +79,8 @@ namespace AzToolsFramework
|
||||
|
||||
void PrefabEditorEntityOwnershipService::Reset()
|
||||
{
|
||||
m_isRootPrefabAssigned = false;
|
||||
|
||||
if (m_rootInstance)
|
||||
{
|
||||
AzToolsFramework::ToolsApplicationRequestBus::Broadcast(
|
||||
@@ -203,6 +205,7 @@ namespace AzToolsFramework
|
||||
m_rootInstance->SetTemplateSourcePath(m_loaderInterface->GenerateRelativePath(filename));
|
||||
m_rootInstance->SetContainerEntityName("Level");
|
||||
m_prefabSystemComponent->PropagateTemplateChanges(templateId);
|
||||
m_isRootPrefabAssigned = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -302,6 +305,12 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
m_prefabSystemComponent->PropagateTemplateChanges(templateId);
|
||||
m_isRootPrefabAssigned = true;
|
||||
}
|
||||
|
||||
bool PrefabEditorEntityOwnershipService::IsRootPrefabAssigned() const
|
||||
{
|
||||
return m_isRootPrefabAssigned;
|
||||
}
|
||||
|
||||
Prefab::InstanceOptionalReference PrefabEditorEntityOwnershipService::CreatePrefab(
|
||||
|
||||
+2
@@ -167,6 +167,7 @@ namespace AzToolsFramework
|
||||
void StopPlayInEditor() override;
|
||||
|
||||
void CreateNewLevelPrefab(AZStd::string_view filename, const AZStd::string& templateFilename) override;
|
||||
bool IsRootPrefabAssigned() const override;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -215,5 +216,6 @@ namespace AzToolsFramework
|
||||
Prefab::PrefabLoaderInterface* m_loaderInterface;
|
||||
AzFramework::EntityContextId m_entityContextId;
|
||||
AZ::SerializeContext m_serializeContext;
|
||||
bool m_isRootPrefabAssigned = false;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
m_uniformScaleManipulator->SetVisualOrientationOverride(QuaternionFromTransformNoScaling(localTransform));
|
||||
m_uniformScaleManipulator->SetLocalPosition(localTransform.GetTranslation());
|
||||
m_uniformScaleManipulator->SetLocalOrientation(AZ::Quaternion::CreateIdentity());
|
||||
}
|
||||
|
||||
|
||||
+14
-13
@@ -13,14 +13,14 @@
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
static const float s_surfaceManipulatorTransparency = 0.75f;
|
||||
static const float s_axisLength = 2.0f;
|
||||
static const float s_surfaceManipulatorRadius = 0.1f;
|
||||
static const float SurfaceManipulatorTransparency = 0.75f;
|
||||
static const float LinearManipulatorAxisLength = 2.0f;
|
||||
static const float SurfaceManipulatorRadius = 0.1f;
|
||||
|
||||
static const AZ::Color s_xAxisColor = AZ::Color(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
static const AZ::Color s_yAxisColor = AZ::Color(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
static const AZ::Color s_zAxisColor = AZ::Color(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
static const AZ::Color s_surfaceManipulatorColor = AZ::Color(1.0f, 1.0f, 0.0f, 0.5f);
|
||||
static const AZ::Color LinearManipulatorXAxisColor = AZ::Color(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
static const AZ::Color LinearManipulatorYAxisColor = AZ::Color(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
static const AZ::Color LinearManipulatorZAxisColor = AZ::Color(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
static const AZ::Color SurfaceManipulatorColor = AZ::Color(1.0f, 1.0f, 0.0f, 0.5f);
|
||||
|
||||
TranslationManipulators::TranslationManipulators(
|
||||
const Dimensions dimensions, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale)
|
||||
@@ -291,7 +291,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
const AZ::Color color[2] = {
|
||||
defaultColor,
|
||||
Vector3ToVector4(BaseManipulator::s_defaultMouseOverColor.GetAsVector3(), s_surfaceManipulatorTransparency)
|
||||
Vector3ToVector4(BaseManipulator::s_defaultMouseOverColor.GetAsVector3(), SurfaceManipulatorTransparency)
|
||||
};
|
||||
|
||||
return color[mouseOver];
|
||||
@@ -325,15 +325,16 @@ namespace AzToolsFramework
|
||||
void ConfigureTranslationManipulatorAppearance3d(TranslationManipulators* translationManipulators)
|
||||
{
|
||||
translationManipulators->SetAxes(AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY(), AZ::Vector3::CreateAxisZ());
|
||||
translationManipulators->ConfigurePlanarView(s_xAxisColor, s_yAxisColor, s_zAxisColor);
|
||||
translationManipulators->ConfigureLinearView(s_axisLength, s_xAxisColor, s_yAxisColor, s_zAxisColor);
|
||||
translationManipulators->ConfigureSurfaceView(s_surfaceManipulatorRadius, s_surfaceManipulatorColor);
|
||||
translationManipulators->ConfigurePlanarView(LinearManipulatorXAxisColor, LinearManipulatorYAxisColor, LinearManipulatorZAxisColor);
|
||||
translationManipulators->ConfigureLinearView(
|
||||
LinearManipulatorAxisLength, LinearManipulatorXAxisColor, LinearManipulatorYAxisColor, LinearManipulatorZAxisColor);
|
||||
translationManipulators->ConfigureSurfaceView(SurfaceManipulatorRadius, SurfaceManipulatorColor);
|
||||
}
|
||||
|
||||
void ConfigureTranslationManipulatorAppearance2d(TranslationManipulators* translationManipulators)
|
||||
{
|
||||
translationManipulators->SetAxes(AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY());
|
||||
translationManipulators->ConfigurePlanarView(s_xAxisColor);
|
||||
translationManipulators->ConfigureLinearView(s_axisLength, s_xAxisColor, s_yAxisColor);
|
||||
translationManipulators->ConfigurePlanarView(LinearManipulatorXAxisColor);
|
||||
translationManipulators->ConfigureLinearView(LinearManipulatorAxisLength, LinearManipulatorXAxisColor, LinearManipulatorYAxisColor);
|
||||
}
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -329,6 +329,11 @@ namespace AzToolsFramework
|
||||
return AZ::Failure(AZStd::string("Could not instantiate prefab - internal error "
|
||||
"(PrefabEditorEntityOwnershipInterface unavailable)."));
|
||||
}
|
||||
if (!prefabEditorEntityOwnershipInterface->IsRootPrefabAssigned())
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Could not instantiate prefab - no root prefab assigned. "
|
||||
"Currently, prefabs can only be instantiated inside a level"));
|
||||
}
|
||||
|
||||
InstanceOptionalReference instanceToParentUnder;
|
||||
|
||||
|
||||
+7
-7
@@ -82,6 +82,8 @@ namespace AzToolsFramework
|
||||
, m_entityExpansionState()
|
||||
, m_entityFilteredState()
|
||||
{
|
||||
m_focusModeInterface = AZ::Interface<FocusModeInterface>::Get();
|
||||
AZ_Assert(m_focusModeInterface != nullptr, "EntityOutlinerListModel requires a FocusModeInterface instance on construction.");
|
||||
}
|
||||
|
||||
EntityOutlinerListModel::~EntityOutlinerListModel()
|
||||
@@ -106,11 +108,6 @@ namespace AzToolsFramework
|
||||
m_editorEntityUiInterface = AZ::Interface<AzToolsFramework::EditorEntityUiInterface>::Get();
|
||||
AZ_Assert(m_editorEntityUiInterface != nullptr,
|
||||
"EntityOutlinerListModel requires a EditorEntityUiInterface instance on Initialize.");
|
||||
|
||||
m_focusModeInterface = AZ::Interface<FocusModeInterface>::Get();
|
||||
AZ_Assert(
|
||||
m_focusModeInterface != nullptr,
|
||||
"EntityOutlinerListModel requires a FocusModeInterface instance on Initialize.");
|
||||
}
|
||||
|
||||
int EntityOutlinerListModel::rowCount(const QModelIndex& parent) const
|
||||
@@ -1347,7 +1344,10 @@ namespace AzToolsFramework
|
||||
//add/remove operations trigger selection change signals which assert and break undo/redo operations in progress in inspector etc.
|
||||
//so disallow selection updates until change is complete
|
||||
emit EnableSelectionUpdates(false);
|
||||
beginResetModel();
|
||||
|
||||
auto parentIndex = GetIndexFromEntity(parentId);
|
||||
auto childIndex = GetIndexFromEntity(childId);
|
||||
beginRemoveRows(parentIndex, childIndex.row(), childIndex.row());
|
||||
}
|
||||
|
||||
void EntityOutlinerListModel::OnEntityInfoUpdatedRemoveChildEnd(AZ::EntityId parentId, AZ::EntityId childId)
|
||||
@@ -1355,7 +1355,7 @@ namespace AzToolsFramework
|
||||
(void)childId;
|
||||
AZ_PROFILE_FUNCTION(AzToolsFramework);
|
||||
|
||||
endResetModel();
|
||||
endRemoveRows();
|
||||
|
||||
//must refresh partial lock/visibility of parents
|
||||
m_isFilterDirty = true;
|
||||
|
||||
@@ -232,6 +232,9 @@ namespace AzToolsFramework
|
||||
m_gui->m_objectTree->header()->setSortIndicatorShown(false);
|
||||
m_gui->m_objectTree->header()->setStretchLastSection(false);
|
||||
|
||||
// Always expand root entity (level entity) - needed if the widget is re-created while a level is already open.
|
||||
m_gui->m_objectTree->expand(m_proxyModel->index(0, 0));
|
||||
|
||||
// resize the icon columns so that the Visibility and Lock toggle icon columns stay right-justified
|
||||
m_gui->m_objectTree->header()->setStretchLastSection(false);
|
||||
m_gui->m_objectTree->header()->setMinimumSectionSize(0);
|
||||
|
||||
+92
-87
@@ -700,13 +700,6 @@ namespace AzToolsFramework
|
||||
switch (referenceFrame)
|
||||
{
|
||||
case ReferenceFrame::Local:
|
||||
// if we have a group selection, always use the pivot override if one
|
||||
// is set when moving to local space (can't pick individual local space)
|
||||
if (entityIdMap.size() > 1)
|
||||
{
|
||||
pivot.m_worldOrientation = pivotOverrideFrame.m_orientationOverride.value();
|
||||
}
|
||||
break;
|
||||
case ReferenceFrame::Parent:
|
||||
pivot.m_worldOrientation = pivotOverrideFrame.m_orientationOverride.value();
|
||||
break;
|
||||
@@ -784,7 +777,7 @@ namespace AzToolsFramework
|
||||
SortEntitiesByLocationInHierarchy(sortedEntityIdsOut);
|
||||
}
|
||||
|
||||
static void UpdateInitialRotation(EntityIdManipulators& entityManipulators)
|
||||
static void UpdateInitialTransform(EntityIdManipulators& entityManipulators)
|
||||
{
|
||||
// save new start orientation (if moving rotation axes separate from object
|
||||
// or switching type of rotation (modifier keys change))
|
||||
@@ -797,22 +790,17 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
// utility function to immediately return the current reference frame
|
||||
// based on the state of the modifiers
|
||||
// utility function to immediately return the current reference frame based on the state of the modifiers
|
||||
static ReferenceFrame ReferenceFrameFromModifiers(const ViewportInteraction::KeyboardModifiers modifiers)
|
||||
{
|
||||
if (modifiers.Shift() && !modifiers.Alt())
|
||||
{
|
||||
return ReferenceFrame::World;
|
||||
}
|
||||
else if (modifiers.Alt() && !modifiers.Shift())
|
||||
{
|
||||
return ReferenceFrame::Local;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ReferenceFrame::Parent;
|
||||
}
|
||||
return modifiers.Shift() ? ReferenceFrame::World : ReferenceFrame::Local;
|
||||
}
|
||||
|
||||
// utility function to immediately return the current sphere of influence of the manipulators based on the
|
||||
// state of the modifiers
|
||||
static Influence InfluenceFromModifiers(const ViewportInteraction::KeyboardModifiers modifiers)
|
||||
{
|
||||
return modifiers.Alt() ? Influence::Individual : Influence::Group;
|
||||
}
|
||||
|
||||
template<typename Action, typename EntityIdContainer>
|
||||
@@ -838,6 +826,7 @@ namespace AzToolsFramework
|
||||
else
|
||||
{
|
||||
const ReferenceFrame referenceFrame = spaceLock.value_or(ReferenceFrameFromModifiers(action.m_modifiers));
|
||||
const Influence influence = InfluenceFromModifiers(action.m_modifiers);
|
||||
|
||||
// note: used for parent and world depending on the current reference frame
|
||||
const auto pivotOrientation =
|
||||
@@ -854,9 +843,9 @@ namespace AzToolsFramework
|
||||
|
||||
const AZ::Vector3 worldTranslation = GetWorldTranslation(entityId);
|
||||
|
||||
switch (referenceFrame)
|
||||
switch (influence)
|
||||
{
|
||||
case ReferenceFrame::Local:
|
||||
case Influence::Individual:
|
||||
{
|
||||
// move in each entities local space at once
|
||||
AZ::Quaternion worldOrientation = AZ::Quaternion::CreateIdentity();
|
||||
@@ -876,10 +865,9 @@ namespace AzToolsFramework
|
||||
entityId, entityItLookupIt->second.m_initial.GetTranslation() + localOffset, transformChangedInternally);
|
||||
}
|
||||
break;
|
||||
case ReferenceFrame::Parent:
|
||||
case ReferenceFrame::World:
|
||||
case Influence::Group:
|
||||
{
|
||||
AZ::Quaternion offsetRotation = pivotOrientation.m_worldOrientation *
|
||||
const AZ::Quaternion offsetRotation = pivotOrientation.m_worldOrientation *
|
||||
QuaternionFromTransformNoScaling(entityIdManipulators.m_manipulators->GetLocalTransform().GetInverse());
|
||||
|
||||
const AZ::Vector3 localOffset = offsetRotation.TransformVector(action.LocalPositionOffset());
|
||||
@@ -1062,7 +1050,8 @@ namespace AzToolsFramework
|
||||
{
|
||||
AZStd::chrono::milliseconds timeNow;
|
||||
AzToolsFramework::ViewportInteraction::EditorViewportInputTimeNowRequestBus::BroadcastResult(
|
||||
timeNow, &AzToolsFramework::ViewportInteraction::EditorViewportInputTimeNowRequestBus::Events::EditorViewportInputTimeNow);
|
||||
timeNow,
|
||||
&AzToolsFramework::ViewportInteraction::EditorViewportInputTimeNowRequestBus::Events::EditorViewportInputTimeNow);
|
||||
return timeNow;
|
||||
});
|
||||
}
|
||||
@@ -1263,7 +1252,7 @@ namespace AzToolsFramework
|
||||
|
||||
AZStd::unique_ptr<TranslationManipulators> translationManipulators = AZStd::make_unique<TranslationManipulators>(
|
||||
TranslationManipulators::Dimensions::Three, AZ::Transform::CreateIdentity(), AZ::Vector3::CreateOne());
|
||||
translationManipulators->SetLineBoundWidth(ManipulatorLineBoundWidth(ViewportUi::DefaultViewportId));
|
||||
translationManipulators->SetLineBoundWidth(ManipulatorLineBoundWidth());
|
||||
|
||||
InitializeManipulators(*translationManipulators);
|
||||
|
||||
@@ -1297,7 +1286,7 @@ namespace AzToolsFramework
|
||||
|
||||
ViewportInteraction::KeyboardModifiers prevModifiers{};
|
||||
translationManipulators->InstallLinearManipulatorMouseMoveCallback(
|
||||
[this, prevModifiers, manipulatorEntityIds](const LinearManipulator::Action& action) mutable -> void
|
||||
[this, prevModifiers, manipulatorEntityIds](const LinearManipulator::Action& action) mutable
|
||||
{
|
||||
UpdateTranslationManipulator(
|
||||
action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators, m_pivotOverrideFrame, prevModifiers,
|
||||
@@ -1331,7 +1320,7 @@ namespace AzToolsFramework
|
||||
});
|
||||
|
||||
translationManipulators->InstallPlanarManipulatorMouseMoveCallback(
|
||||
[this, prevModifiers, manipulatorEntityIds](const PlanarManipulator::Action& action) mutable -> void
|
||||
[this, prevModifiers, manipulatorEntityIds](const PlanarManipulator::Action& action) mutable
|
||||
{
|
||||
UpdateTranslationManipulator(
|
||||
action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators, m_pivotOverrideFrame, prevModifiers,
|
||||
@@ -1364,7 +1353,7 @@ namespace AzToolsFramework
|
||||
});
|
||||
|
||||
translationManipulators->InstallSurfaceManipulatorMouseMoveCallback(
|
||||
[this, prevModifiers, manipulatorEntityIds](const SurfaceManipulator::Action& action) mutable -> void
|
||||
[this, prevModifiers, manipulatorEntityIds](const SurfaceManipulator::Action& action) mutable
|
||||
{
|
||||
UpdateTranslationManipulator(
|
||||
action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators, m_pivotOverrideFrame, prevModifiers,
|
||||
@@ -1391,7 +1380,7 @@ namespace AzToolsFramework
|
||||
|
||||
AZStd::unique_ptr<RotationManipulators> rotationManipulators =
|
||||
AZStd::make_unique<RotationManipulators>(AZ::Transform::CreateIdentity());
|
||||
rotationManipulators->SetCircleBoundWidth(ManipulatorCicleBoundWidth(ViewportUi::DefaultViewportId));
|
||||
rotationManipulators->SetCircleBoundWidth(ManipulatorCicleBoundWidth());
|
||||
|
||||
InitializeManipulators(*rotationManipulators);
|
||||
|
||||
@@ -1415,7 +1404,7 @@ namespace AzToolsFramework
|
||||
AZStd::shared_ptr<SharedRotationState> sharedRotationState = AZStd::make_shared<SharedRotationState>();
|
||||
|
||||
rotationManipulators->InstallLeftMouseDownCallback(
|
||||
[this, sharedRotationState]([[maybe_unused]] const AngularManipulator::Action& action) mutable -> void
|
||||
[this, sharedRotationState]([[maybe_unused]] const AngularManipulator::Action& action) mutable
|
||||
{
|
||||
sharedRotationState->m_savedOrientation = AZ::Quaternion::CreateIdentity();
|
||||
sharedRotationState->m_referenceFrameAtMouseDown = m_referenceFrame;
|
||||
@@ -1437,11 +1426,13 @@ namespace AzToolsFramework
|
||||
BeginRecordManipulatorCommand();
|
||||
});
|
||||
|
||||
ViewportInteraction::KeyboardModifiers prevModifiers{};
|
||||
rotationManipulators->InstallMouseMoveCallback(
|
||||
[this, prevModifiers, sharedRotationState](const AngularManipulator::Action& action) mutable -> void
|
||||
[this, prevModifiers = ViewportInteraction::KeyboardModifiers(),
|
||||
sharedRotationState](const AngularManipulator::Action& action) mutable
|
||||
{
|
||||
const ReferenceFrame referenceFrame = m_spaceCluster.m_spaceLock.value_or(ReferenceFrameFromModifiers(action.m_modifiers));
|
||||
const Influence influence = InfluenceFromModifiers(action.m_modifiers);
|
||||
|
||||
const AZ::Quaternion manipulatorOrientation = action.m_start.m_rotation * action.m_current.m_delta;
|
||||
// store the pivot override frame when positioning the manipulator manually (ctrl)
|
||||
// so we don't lose the orientation when adding/removing entities from the selection
|
||||
@@ -1452,9 +1443,7 @@ namespace AzToolsFramework
|
||||
|
||||
// only update the manipulator orientation if we're rotating in a local reference frame or we're
|
||||
// manually modifying the manipulator orientation independent of the entity by holding ctrl
|
||||
if ((sharedRotationState->m_referenceFrameAtMouseDown == ReferenceFrame::Local &&
|
||||
m_entityIdManipulators.m_lookups.size() == 1) ||
|
||||
action.m_modifiers.Ctrl())
|
||||
if (sharedRotationState->m_referenceFrameAtMouseDown == ReferenceFrame::Local || action.m_modifiers.Ctrl())
|
||||
{
|
||||
m_entityIdManipulators.m_manipulators->SetLocalTransform(AZ::Transform::CreateFromQuaternionAndTranslation(
|
||||
manipulatorOrientation, m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation()));
|
||||
@@ -1463,20 +1452,24 @@ namespace AzToolsFramework
|
||||
// save state if we change the type of rotation we're doing to to prevent snapping
|
||||
if (prevModifiers != action.m_modifiers)
|
||||
{
|
||||
UpdateInitialRotation(m_entityIdManipulators);
|
||||
UpdateInitialTransform(m_entityIdManipulators);
|
||||
sharedRotationState->m_savedOrientation = action.m_current.m_delta.GetInverseFull();
|
||||
}
|
||||
|
||||
// allow the user to modify the orientation without moving the object if ctrl is held
|
||||
if (action.m_modifiers.Ctrl())
|
||||
{
|
||||
UpdateInitialRotation(m_entityIdManipulators);
|
||||
UpdateInitialTransform(m_entityIdManipulators);
|
||||
sharedRotationState->m_savedOrientation = action.m_current.m_delta.GetInverseFull();
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto pivotOrientation = ETCS::CalculateSelectionPivotOrientation(
|
||||
m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, ReferenceFrame::Parent);
|
||||
// only update the pivot override if the orientation is being modified in local space and we have
|
||||
// more than one entity selected (so rotating a single entity does not set the orientation override)
|
||||
if (referenceFrame == ReferenceFrame::Local && sharedRotationState->m_entityIds.size() > 1)
|
||||
{
|
||||
m_pivotOverrideFrame.m_orientationOverride = manipulatorOrientation;
|
||||
}
|
||||
|
||||
// note: must use sorted entityIds based on hierarchy order when updating transforms
|
||||
for (AZ::EntityId entityId : sharedRotationState->m_entityIds)
|
||||
@@ -1492,9 +1485,9 @@ namespace AzToolsFramework
|
||||
const AZ::Transform offsetRotation =
|
||||
AZ::Transform::CreateFromQuaternion(sharedRotationState->m_savedOrientation * action.m_current.m_delta);
|
||||
|
||||
switch (referenceFrame)
|
||||
switch (influence)
|
||||
{
|
||||
case ReferenceFrame::Local:
|
||||
case Influence::Individual:
|
||||
{
|
||||
const AZ::Quaternion rotation = entityIdLookupIt->second.m_initial.GetRotation().GetNormalized();
|
||||
const AZ::Vector3 position = entityIdLookupIt->second.m_initial.GetTranslation();
|
||||
@@ -1510,23 +1503,10 @@ namespace AzToolsFramework
|
||||
AZ::Transform::CreateTranslation(-centerOffset) * AZ::Transform::CreateUniformScale(scale));
|
||||
}
|
||||
break;
|
||||
case ReferenceFrame::Parent:
|
||||
case Influence::Group:
|
||||
{
|
||||
const AZ::Transform pivotTransform = AZ::Transform::CreateFromQuaternionAndTranslation(
|
||||
pivotOrientation.m_worldOrientation,
|
||||
m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation());
|
||||
|
||||
const AZ::Transform transformInPivotSpace =
|
||||
pivotTransform.GetInverse() * entityIdLookupIt->second.m_initial;
|
||||
|
||||
SetEntityWorldTransform(entityId, pivotTransform * offsetRotation * transformInPivotSpace);
|
||||
}
|
||||
break;
|
||||
case ReferenceFrame::World:
|
||||
{
|
||||
const AZ::Transform pivotTransform = AZ::Transform::CreateFromQuaternionAndTranslation(
|
||||
AZ::Quaternion::CreateIdentity(),
|
||||
m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation());
|
||||
manipulatorOrientation, m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation());
|
||||
const AZ::Transform transformInPivotSpace =
|
||||
pivotTransform.GetInverse() * entityIdLookupIt->second.m_initial;
|
||||
|
||||
@@ -1561,7 +1541,7 @@ namespace AzToolsFramework
|
||||
AZ_PROFILE_FUNCTION(AzToolsFramework);
|
||||
|
||||
AZStd::unique_ptr<ScaleManipulators> scaleManipulators = AZStd::make_unique<ScaleManipulators>(AZ::Transform::CreateIdentity());
|
||||
scaleManipulators->SetLineBoundWidth(ManipulatorLineBoundWidth(ViewportUi::DefaultViewportId));
|
||||
scaleManipulators->SetLineBoundWidth(ManipulatorLineBoundWidth());
|
||||
|
||||
InitializeManipulators(*scaleManipulators);
|
||||
|
||||
@@ -1571,13 +1551,20 @@ namespace AzToolsFramework
|
||||
scaleManipulators->SetAxes(AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY(), AZ::Vector3::CreateAxisZ());
|
||||
scaleManipulators->ConfigureView(2.0f, AZ::Color::CreateOne(), AZ::Color::CreateOne(), AZ::Color::CreateOne());
|
||||
|
||||
// lambdas capture shared_ptr by value to increment ref count
|
||||
auto manipulatorEntityIds = AZStd::make_shared<ManipulatorEntityIds>();
|
||||
|
||||
auto uniformLeftMouseDownCallback = [this, manipulatorEntityIds]([[maybe_unused]] const LinearManipulator::Action& action)
|
||||
struct SharedScaleState
|
||||
{
|
||||
AZ::Vector3 m_savedScaleOffset = AZ::Vector3::CreateZero();
|
||||
EntityIdList m_entityIds;
|
||||
};
|
||||
|
||||
// lambdas capture shared_ptr by value to increment ref count
|
||||
auto sharedScaleState = AZStd::make_shared<SharedScaleState>();
|
||||
|
||||
auto uniformLeftMouseDownCallback = [this, sharedScaleState]([[maybe_unused]] const LinearManipulator::Action& action)
|
||||
{
|
||||
sharedScaleState->m_savedScaleOffset = AZ::Vector3::CreateZero();
|
||||
// important to sort entityIds based on hierarchy order when updating transforms
|
||||
BuildSortedEntityIdVectorFromEntityIdMap(m_entityIdManipulators.m_lookups, manipulatorEntityIds->m_entityIds);
|
||||
BuildSortedEntityIdVectorFromEntityIdMap(m_entityIdManipulators.m_lookups, sharedScaleState->m_entityIds);
|
||||
|
||||
for (auto& entityIdLookup : m_entityIdManipulators.m_lookups)
|
||||
{
|
||||
@@ -1591,20 +1578,32 @@ namespace AzToolsFramework
|
||||
m_axisPreview.m_orientation = QuaternionFromTransformNoScaling(m_entityIdManipulators.m_manipulators->GetLocalTransform());
|
||||
};
|
||||
|
||||
auto uniformLeftMouseUpCallback = [this, manipulatorEntityIds]([[maybe_unused]] const LinearManipulator::Action& action)
|
||||
auto uniformLeftMouseUpCallback = [this, sharedScaleState]([[maybe_unused]] const LinearManipulator::Action& action)
|
||||
{
|
||||
AzToolsFramework::EditorTransformChangeNotificationBus::Broadcast(
|
||||
&AzToolsFramework::EditorTransformChangeNotificationBus::Events::OnEntityTransformChanged,
|
||||
manipulatorEntityIds->m_entityIds);
|
||||
&AzToolsFramework::EditorTransformChangeNotificationBus::Events::OnEntityTransformChanged, sharedScaleState->m_entityIds);
|
||||
|
||||
m_entityIdManipulators.m_manipulators->SetLocalTransform(RecalculateAverageManipulatorTransform(
|
||||
m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, m_pivotMode, m_referenceFrame));
|
||||
};
|
||||
|
||||
auto uniformLeftMouseMoveCallback = [this, manipulatorEntityIds](const LinearManipulator::Action& action)
|
||||
auto uniformLeftMouseMoveCallback = [this, sharedScaleState, prevModifiers = ViewportInteraction::KeyboardModifiers()](
|
||||
const LinearManipulator::Action& action) mutable
|
||||
{
|
||||
// do nothing to modify the manipulator
|
||||
if (action.m_modifiers.Ctrl())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (prevModifiers != action.m_modifiers)
|
||||
{
|
||||
UpdateInitialTransform(m_entityIdManipulators);
|
||||
sharedScaleState->m_savedScaleOffset = action.LocalScaleOffset();
|
||||
}
|
||||
|
||||
// note: must use sorted entityIds based on hierarchy order when updating transforms
|
||||
for (AZ::EntityId entityId : manipulatorEntityIds->m_entityIds)
|
||||
for (AZ::EntityId entityId : sharedScaleState->m_entityIds)
|
||||
{
|
||||
auto entityIdLookupIt = m_entityIdManipulators.m_lookups.find(entityId);
|
||||
if (entityIdLookupIt == m_entityIdManipulators.m_lookups.end())
|
||||
@@ -1620,26 +1619,33 @@ namespace AzToolsFramework
|
||||
return vec.GetX() + vec.GetY() + vec.GetZ();
|
||||
};
|
||||
|
||||
const float uniformScale = action.m_start.m_sign * sumVectorElements(action.LocalScaleOffset());
|
||||
const float uniformScale =
|
||||
action.m_start.m_sign * sumVectorElements(action.LocalScaleOffset() - sharedScaleState->m_savedScaleOffset);
|
||||
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())
|
||||
switch (InfluenceFromModifiers(action.m_modifiers))
|
||||
{
|
||||
const AZ::Transform pivotTransform = TransformNormalizedScale(entityIdLookupIt->second.m_initial);
|
||||
const AZ::Transform transformInPivotSpace = pivotTransform.GetInverse() * initial;
|
||||
case Influence::Individual:
|
||||
{
|
||||
const AZ::Transform pivotTransform = TransformNormalizedScale(entityIdLookupIt->second.m_initial);
|
||||
const AZ::Transform transformInPivotSpace = pivotTransform.GetInverse() * initial;
|
||||
|
||||
SetEntityWorldTransform(entityId, pivotTransform * scaleTransform * transformInPivotSpace);
|
||||
}
|
||||
else
|
||||
{
|
||||
const AZ::Transform pivotTransform =
|
||||
TransformNormalizedScale(m_entityIdManipulators.m_manipulators->GetLocalTransform());
|
||||
const AZ::Transform transformInPivotSpace = pivotTransform.GetInverse() * initial;
|
||||
SetEntityWorldTransform(entityId, pivotTransform * scaleTransform * transformInPivotSpace);
|
||||
}
|
||||
break;
|
||||
case Influence::Group:
|
||||
{
|
||||
const AZ::Transform pivotTransform =
|
||||
TransformNormalizedScale(m_entityIdManipulators.m_manipulators->GetLocalTransform());
|
||||
const AZ::Transform transformInPivotSpace = pivotTransform.GetInverse() * initial;
|
||||
|
||||
SetEntityWorldTransform(entityId, pivotTransform * scaleTransform * transformInPivotSpace);
|
||||
SetEntityWorldTransform(entityId, pivotTransform * scaleTransform * transformInPivotSpace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prevModifiers = action.m_modifiers;
|
||||
};
|
||||
|
||||
scaleManipulators->InstallAxisLeftMouseDownCallback(uniformLeftMouseDownCallback);
|
||||
@@ -2729,8 +2735,7 @@ namespace AzToolsFramework
|
||||
|
||||
if (m_pivotOverrideFrame.m_orientationOverride && m_entityIdManipulators.m_manipulators)
|
||||
{
|
||||
m_pivotOverrideFrame.m_orientationOverride =
|
||||
QuaternionFromTransformNoScaling(m_entityIdManipulators.m_manipulators->GetLocalTransform());
|
||||
m_pivotOverrideFrame.m_orientationOverride = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetRotation();
|
||||
}
|
||||
|
||||
if (m_pivotOverrideFrame.m_translationOverride && m_entityIdManipulators.m_manipulators)
|
||||
@@ -3337,7 +3342,7 @@ namespace AzToolsFramework
|
||||
|
||||
display.SetLineWidth(4.0f);
|
||||
|
||||
const auto axisFlip = [&transform, &cameraState](const AZ::Vector3& axis) -> float
|
||||
const auto axisFlip = [&transform, &cameraState](const AZ::Vector3& axis)
|
||||
{
|
||||
return ShouldFlipCameraAxis(
|
||||
AZ::Transform::CreateIdentity(), transform.GetTranslation(), TransformDirectionNoScaling(transform, axis),
|
||||
@@ -3554,7 +3559,7 @@ namespace AzToolsFramework
|
||||
// screen space
|
||||
const auto calculateGizmoAxis = [&cameraView, &cameraProjection, &screenOffset](const AZ::Vector3& axis)
|
||||
{
|
||||
auto result = AZ::Vector2(AzFramework::WorldToScreenNDC(axis, cameraView, cameraProjection));
|
||||
auto result = AZ::Vector2(AzFramework::WorldToScreenNdc(axis, cameraView, cameraProjection));
|
||||
result.SetY(1.0f - result.GetY());
|
||||
return result + screenOffset;
|
||||
};
|
||||
|
||||
+10
-1
@@ -96,6 +96,14 @@ namespace AzToolsFramework
|
||||
AZ::u8 m_pickTypes = PickType::None; //!< What mode(s) were we in when picking an EntityId override.
|
||||
};
|
||||
|
||||
//! How a manipulator should treat an adjustment.
|
||||
//! @note Determines if a transform is applied to an individual entity or the whole group.
|
||||
enum class Influence
|
||||
{
|
||||
Group,
|
||||
Individual
|
||||
};
|
||||
|
||||
//! What frame/space is the manipulator currently operating in.
|
||||
enum class ReferenceFrame
|
||||
{
|
||||
@@ -328,7 +336,8 @@ namespace AzToolsFramework
|
||||
OptionalFrame m_pivotOverrideFrame; //!< Has a pivot override been set.
|
||||
Mode m_mode = Mode::Translation; //!< Manipulator mode - default to translation.
|
||||
Pivot m_pivotMode = Pivot::Object; //!< Entity pivot mode - default to object (authored root).
|
||||
ReferenceFrame m_referenceFrame = ReferenceFrame::Parent; //!< What reference frame is the Manipulator currently operating in.
|
||||
ReferenceFrame m_referenceFrame = ReferenceFrame::Local; //!< What reference frame is the Manipulator currently operating in.
|
||||
Influence m_influence = Influence::Group; //!< What sphere of influence does the Manipulator have.
|
||||
Frame m_axisPreview; //!< Axes of entity at the time of mouse down to indicate delta of translation.
|
||||
bool m_triedToRefresh = false; //!< Did a refresh event occur to recalculate the current Manipulator transform.
|
||||
//! Was EditorTransformComponentSelection responsible for the most recent entity selection change.
|
||||
|
||||
Reference in New Issue
Block a user