Merge branch 'main' into LY-113714
This commit is contained in:
@@ -13,6 +13,12 @@
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
struct BehaviorParameter;
|
||||
}
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
@@ -40,6 +46,8 @@ namespace AzToolsFramework
|
||||
};
|
||||
using GlobalFunctionCollection = AZStd::vector<GlobalFunction>;
|
||||
virtual void GetGlobalFunctionList(GlobalFunctionCollection& globalFunctionCollection) const = 0;
|
||||
|
||||
virtual AZStd::string FetchPythonTypeName(const AZ::BehaviorParameter& param) = 0;
|
||||
};
|
||||
|
||||
//! Interface to signal the phases for the Python virtual machine
|
||||
|
||||
@@ -31,6 +31,10 @@ namespace AzToolsFramework
|
||||
//! Allows a component to get the list of selected entities
|
||||
//! \param selectedEntityIds the return vector holding the entities required
|
||||
virtual void GetSelectedEntities(EntityIdList& selectedEntityIds) = 0;
|
||||
|
||||
//! Explicitly sets a component as having been the most recently added.
|
||||
//! This means that the next time the UI refreshes, that component will be ensured to be visible.
|
||||
virtual void SetNewComponentId(AZ::ComponentId componentId) = 0;
|
||||
};
|
||||
|
||||
using EntityPropertyEditorRequestBus = AZ::EBus<EntityPropertyEditorRequests>;
|
||||
|
||||
@@ -117,8 +117,6 @@ namespace AzToolsFramework
|
||||
{
|
||||
EditorEntityModel::EditorEntityModel()
|
||||
{
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(m_isPrefabEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
EntityCompositionNotificationBus::Handler::BusConnect();
|
||||
EditorOnlyEntityComponentNotificationBus::Handler::BusConnect();
|
||||
EditorEntityRuntimeActivationChangeNotificationBus::Handler::BusConnect();
|
||||
@@ -565,7 +563,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
//retrieve or add an entity entry to the table
|
||||
//the entry must exist, even if not connected, so children and other data can be assigned
|
||||
[[maybe_unused]] auto [it, inserted] = m_entityInfoTable.try_emplace(entityId, m_isPrefabEnabled);
|
||||
[[maybe_unused]] auto [it, inserted] = m_entityInfoTable.try_emplace(entityId);
|
||||
auto& entityInfo = it->second;
|
||||
|
||||
//the entity id defaults to invalid and must be set to match the requested id
|
||||
@@ -882,11 +880,6 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
EditorEntityModel::EditorEntityModelEntry::EditorEntityModelEntry(bool isPrefabEnabled)
|
||||
: m_isPrefabEnabled(isPrefabEnabled)
|
||||
{
|
||||
}
|
||||
|
||||
EditorEntityModel::EditorEntityModelEntry::~EditorEntityModelEntry()
|
||||
{
|
||||
Disconnect();
|
||||
@@ -1213,29 +1206,15 @@ namespace AzToolsFramework
|
||||
auto childItr = m_childIndexCache.find(childId);
|
||||
if (childItr != m_childIndexCache.end())
|
||||
{
|
||||
if (m_isPrefabEnabled)
|
||||
{
|
||||
// Take the last entry and move it into the removed spot instead of deleting the entry and having to move all
|
||||
// following entries one step down.
|
||||
AZ::EntityId backEntity = m_children.back();
|
||||
m_children[childItr->second] = backEntity;
|
||||
// Update cached index for the moved id to the new index.
|
||||
m_childIndexCache[backEntity] = childItr->second;
|
||||
// Now remove the deleted id from the children and cache.
|
||||
m_childIndexCache.erase(childId);
|
||||
m_children.erase(m_children.end() - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_children.erase(m_children.begin() + childItr->second);
|
||||
|
||||
// rebuild index cache for faster lookup
|
||||
m_childIndexCache.clear();
|
||||
for (auto childIdToCache : m_children)
|
||||
{
|
||||
m_childIndexCache[childIdToCache] = static_cast<AZ::u64>(m_childIndexCache.size());
|
||||
}
|
||||
}
|
||||
// Take the last entry and move it into the removed spot instead of deleting the entry and having to move all
|
||||
// following entries one step down.
|
||||
AZ::EntityId backEntity = m_children.back();
|
||||
m_children[childItr->second] = backEntity;
|
||||
// Update cached index for the moved id to the new index.
|
||||
m_childIndexCache[backEntity] = childItr->second;
|
||||
// Now remove the deleted id from the children and cache.
|
||||
m_childIndexCache.erase(childId);
|
||||
m_children.erase(m_children.end() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -171,7 +171,6 @@ namespace AzToolsFramework
|
||||
, public PropertyEditorEntityChangeNotificationBus::Handler
|
||||
{
|
||||
public:
|
||||
explicit EditorEntityModelEntry(bool isPrefabEnabled);
|
||||
~EditorEntityModelEntry();
|
||||
|
||||
// Separately connect to EditorEntityInfoRequestBus and refresh Entity
|
||||
@@ -336,7 +335,6 @@ namespace AzToolsFramework
|
||||
bool m_visible = true;
|
||||
bool m_locked = false;
|
||||
bool m_connected = false;
|
||||
bool m_isPrefabEnabled = false;
|
||||
AZStd::string m_name;
|
||||
AZStd::string m_sliceAssetName;
|
||||
AZStd::unordered_map<AZ::EntityId, AZ::u64> m_childIndexCache;
|
||||
@@ -375,6 +373,5 @@ namespace AzToolsFramework
|
||||
AZ::EntityId m_postInstantiateBeforeEntity;
|
||||
AZ::EntityId m_postInstantiateSliceParent;
|
||||
bool m_gotInstantiateSliceDetails = false;
|
||||
bool m_isPrefabEnabled = false;
|
||||
};
|
||||
}
|
||||
|
||||
+3
-4
@@ -127,8 +127,7 @@ namespace AzToolsFramework
|
||||
ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult(
|
||||
worldSurfacePosition, viewportId,
|
||||
&ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain,
|
||||
ViewportInteraction::QPointFromScreenPoint(
|
||||
mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates));
|
||||
mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates);
|
||||
|
||||
AZ::Transform worldFromLocal;
|
||||
AZ::TransformBus::EventResult(worldFromLocal, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM);
|
||||
@@ -402,10 +401,10 @@ namespace AzToolsFramework
|
||||
vertexIndex, localVertex);
|
||||
|
||||
const AZ::Vector3 worldVertex = worldFromLocal.TransformPoint(AZ::AdaptVertexOut<Vertex>(localVertex));
|
||||
const QPoint screenPosition = GetScreenPosition(viewportId, worldVertex);
|
||||
const AzFramework::ScreenPoint screenPosition = GetScreenPosition(viewportId, worldVertex);
|
||||
|
||||
// check if a vertex is inside the box select region
|
||||
if (editorBoxSelect.BoxRegion()->contains(screenPosition))
|
||||
if (editorBoxSelect.BoxRegion()->contains(ViewportInteraction::QPointFromScreenPoint(screenPosition)))
|
||||
{
|
||||
// see if vertexIndex is in active selection
|
||||
auto vertexIt = AZStd::find(
|
||||
|
||||
+3
-6
@@ -103,8 +103,7 @@ namespace AzToolsFramework
|
||||
ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult(
|
||||
worldSurfacePosition, interaction.m_interactionId.m_viewportId,
|
||||
&ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain,
|
||||
ViewportInteraction::QPointFromScreenPoint(
|
||||
interaction.m_mousePick.m_screenCoordinates));
|
||||
interaction.m_mousePick.m_screenCoordinates);
|
||||
|
||||
m_startInternal = CalculateManipulationDataStart(
|
||||
worldFromLocalUniformScale, worldSurfacePosition, GetLocalPosition(),
|
||||
@@ -129,8 +128,7 @@ namespace AzToolsFramework
|
||||
ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult(
|
||||
worldSurfacePosition, interaction.m_interactionId.m_viewportId,
|
||||
&ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain,
|
||||
ViewportInteraction::QPointFromScreenPoint(
|
||||
interaction.m_mousePick.m_screenCoordinates));
|
||||
interaction.m_mousePick.m_screenCoordinates);
|
||||
|
||||
const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId);
|
||||
|
||||
@@ -150,8 +148,7 @@ namespace AzToolsFramework
|
||||
ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult(
|
||||
worldSurfacePosition, interaction.m_interactionId.m_viewportId,
|
||||
&ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain,
|
||||
ViewportInteraction::QPointFromScreenPoint(
|
||||
interaction.m_mousePick.m_screenCoordinates));
|
||||
interaction.m_mousePick.m_screenCoordinates);
|
||||
|
||||
const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId);
|
||||
|
||||
|
||||
@@ -96,9 +96,7 @@ namespace AzToolsFramework
|
||||
// target templates of the other instances.
|
||||
for (auto& nestedInstance : instances)
|
||||
{
|
||||
PrefabUndoHelpers::RemoveLink(
|
||||
nestedInstance->GetTemplateId(), commonRootEntityOwningInstance->get().GetTemplateId(),
|
||||
nestedInstance->GetInstanceAlias(), nestedInstance->GetLinkId(), undoBatch.GetUndoBatch());
|
||||
RemoveLink(nestedInstance, commonRootEntityOwningInstance->get().GetTemplateId(), undoBatch.GetUndoBatch());
|
||||
}
|
||||
|
||||
PrefabUndoHelpers::UpdatePrefabInstance(
|
||||
@@ -184,6 +182,22 @@ namespace AzToolsFramework
|
||||
instanceToParentUnder = prefabEditorEntityOwnershipInterface->GetRootPrefabInstance();
|
||||
parent = instanceToParentUnder->get().GetContainerEntityId();
|
||||
}
|
||||
|
||||
//Detect whether this instantiation would produce a cyclical dependency
|
||||
auto relativePath = m_prefabLoaderInterface->GetRelativePathToProject(filePath);
|
||||
Prefab::TemplateId templateId = m_prefabSystemComponentInterface->GetTemplateIdFromFilePath(relativePath);
|
||||
|
||||
// If the template isn't currently loaded, there's no way for it to be in the hierarchy so we just skip the check.
|
||||
if (templateId != Prefab::InvalidTemplateId && IsPrefabInInstanceAncestorHierarchy(templateId, instanceToParentUnder->get()))
|
||||
{
|
||||
return AZ::Failure(
|
||||
AZStd::string::format(
|
||||
"Instantiate Prefab operation aborted - Cyclical dependency detected\n(%s depends on %s).",
|
||||
relativePath.Native().c_str(),
|
||||
instanceToParentUnder->get().GetTemplateSourcePath().Native().c_str()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
// Initialize Undo Batch object
|
||||
@@ -194,7 +208,7 @@ namespace AzToolsFramework
|
||||
instanceToParentUnderDomBeforeCreate, instanceToParentUnder->get());
|
||||
|
||||
// Instantiate the Prefab
|
||||
auto instanceToCreate = prefabEditorEntityOwnershipInterface->InstantiatePrefab(filePath, instanceToParentUnder);
|
||||
auto instanceToCreate = prefabEditorEntityOwnershipInterface->InstantiatePrefab(relativePath, instanceToParentUnder);
|
||||
|
||||
if (!instanceToCreate)
|
||||
{
|
||||
@@ -238,17 +252,29 @@ namespace AzToolsFramework
|
||||
|
||||
// Retrieve the owning instance of the common root entity, which will be our new instance's parent instance.
|
||||
commonRootEntityOwningInstance = GetOwnerInstanceByEntityId(commonRootEntityId);
|
||||
if (!commonRootEntityOwningInstance)
|
||||
{
|
||||
AZ_Assert(
|
||||
false,
|
||||
"Failed to create prefab : Couldn't get a valid owning instance for the common root entity of the enities provided");
|
||||
return AZ::Failure(AZStd::string(
|
||||
"Failed to create prefab : Couldn't get a valid owning instance for the common root entity of the enities provided"));
|
||||
}
|
||||
AZ_Assert(
|
||||
commonRootEntityOwningInstance.has_value(),
|
||||
"Failed to create prefab : Couldn't get a valid owning instance for the common root entity of the enities provided");
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
bool PrefabPublicHandler::IsPrefabInInstanceAncestorHierarchy(TemplateId prefabTemplateId, InstanceOptionalConstReference instance)
|
||||
{
|
||||
InstanceOptionalConstReference currentInstance = instance;
|
||||
|
||||
while (currentInstance.has_value())
|
||||
{
|
||||
if (currentInstance->get().GetTemplateId() == prefabTemplateId)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
currentInstance = currentInstance->get().GetParentInstance();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void PrefabPublicHandler::CreateLink(
|
||||
const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId,
|
||||
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId)
|
||||
@@ -287,6 +313,34 @@ namespace AzToolsFramework
|
||||
m_prefabUndoCache.Store(containerEntityId, AZStd::move(containerEntityDomAfter));
|
||||
}
|
||||
|
||||
void PrefabPublicHandler::RemoveLink(
|
||||
AZStd::unique_ptr<Instance>& sourceInstance, TemplateId targetTemplateId, UndoSystem::URSequencePoint* undoBatch)
|
||||
{
|
||||
LinkReference nestedInstanceLink = m_prefabSystemComponentInterface->FindLink(sourceInstance->GetLinkId());
|
||||
AZ_Assert(
|
||||
nestedInstanceLink.has_value(),
|
||||
"A valid link was not found for one of the instances provided as input for the CreatePrefab operation.");
|
||||
|
||||
PrefabDomReference nestedInstanceLinkDom = nestedInstanceLink->get().GetLinkDom();
|
||||
AZ_Assert(
|
||||
nestedInstanceLinkDom.has_value(),
|
||||
"A valid DOM was not found for the link corresponding to one of the instances provided as input for the "
|
||||
"CreatePrefab operation.");
|
||||
|
||||
PrefabDomValueReference nestedInstanceLinkPatches =
|
||||
PrefabDomUtils::FindPrefabDomValue(nestedInstanceLinkDom->get(), PrefabDomUtils::PatchesName);
|
||||
AZ_Assert(
|
||||
nestedInstanceLinkPatches.has_value(),
|
||||
"A valid DOM for patches was not found for the link corresponding to one of the instances provided as input for the "
|
||||
"CreatePrefab operation.");
|
||||
|
||||
PrefabDom patchesCopyForUndoSupport;
|
||||
patchesCopyForUndoSupport.CopyFrom(nestedInstanceLinkPatches->get(), patchesCopyForUndoSupport.GetAllocator());
|
||||
PrefabUndoHelpers::RemoveLink(
|
||||
sourceInstance->GetTemplateId(), targetTemplateId, sourceInstance->GetInstanceAlias(), sourceInstance->GetLinkId(),
|
||||
patchesCopyForUndoSupport, undoBatch);
|
||||
}
|
||||
|
||||
PrefabOperationResult PrefabPublicHandler::SavePrefab(AZ::IO::Path filePath)
|
||||
{
|
||||
auto templateId = m_prefabSystemComponentInterface->GetTemplateIdFromFilePath(filePath.c_str());
|
||||
|
||||
@@ -82,6 +82,16 @@ namespace AzToolsFramework
|
||||
const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId,
|
||||
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId);
|
||||
|
||||
/**
|
||||
* Removes the link between template of the sourceInstance and the template corresponding to targetTemplateId.
|
||||
*
|
||||
* \param sourceInstance The instance corresponding to the source template of the link to be removed.
|
||||
* \param targetTemplateId The id of the target template of the link to be removed.
|
||||
* \param undoBatch The undo batch to set as parent for this remove link action.
|
||||
*/
|
||||
void RemoveLink(
|
||||
AZStd::unique_ptr<Instance>& sourceInstance, TemplateId targetTemplateId, UndoSystem::URSequencePoint* undoBatch);
|
||||
|
||||
/**
|
||||
* Given a list of entityIds, finds the prefab instance that owns the common root entity of the entityIds.
|
||||
*
|
||||
@@ -96,6 +106,14 @@ namespace AzToolsFramework
|
||||
const AZStd::vector<AZ::EntityId>& entityIds, EntityList& inputEntityList, EntityList& topLevelEntities,
|
||||
AZ::EntityId& commonRootEntityId, InstanceOptionalReference& commonRootEntityOwningInstance);
|
||||
|
||||
/* Detects whether an instance of prefabTemplateId is present in the hierarchy of ancestors of instance.
|
||||
*
|
||||
* \param prefabTemplateId The template id to test for
|
||||
* \param instance The instance whose ancestor hierarchy prefabTemplateId will be tested against.
|
||||
* \return true if an instance of the template of id prefabTemplateId could be found in the ancestor hierarchy of instance, false otherwise.
|
||||
*/
|
||||
bool IsPrefabInInstanceAncestorHierarchy(TemplateId prefabTemplateId, InstanceOptionalConstReference instance);
|
||||
|
||||
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);
|
||||
|
||||
@@ -663,8 +663,9 @@ namespace AzToolsFramework
|
||||
newLink.SetSourceTemplateId(linkSourceId);
|
||||
newLink.SetInstanceName(instanceAlias.c_str());
|
||||
newLink.GetLinkDom().SetObject();
|
||||
newLink.GetLinkDom().AddMember(rapidjson::StringRef(PrefabDomUtils::SourceName),
|
||||
rapidjson::StringRef(sourceTemplate.GetFilePath().c_str()), newLink.GetLinkDom().GetAllocator());
|
||||
newLink.GetLinkDom().AddMember(
|
||||
rapidjson::StringRef(PrefabDomUtils::SourceName), rapidjson::StringRef(sourceTemplate.GetFilePath().c_str()),
|
||||
newLink.GetLinkDom().GetAllocator());
|
||||
|
||||
if (linkPatch && linkPatch->get().IsArray() && !(linkPatch->get().Empty()))
|
||||
{
|
||||
@@ -720,6 +721,8 @@ namespace AzToolsFramework
|
||||
|
||||
TemplateId PrefabSystemComponent::GetTemplateIdFromFilePath(AZ::IO::PathView filePath) const
|
||||
{
|
||||
AZ_Assert(!filePath.IsAbsolute(), "Prefab - GetTemplateIdFromFilePath was passed an absolute path. Prefabs use paths relative to the project folder.");
|
||||
|
||||
auto found = m_templateFilePathToIdMap.find(filePath);
|
||||
if (found != m_templateFilePathToIdMap.end())
|
||||
{
|
||||
|
||||
@@ -113,7 +113,7 @@ namespace AzToolsFramework
|
||||
, m_sourceId(InvalidTemplateId)
|
||||
, m_instanceAlias("")
|
||||
, m_linkId(InvalidLinkId)
|
||||
, m_linkDom(PrefabDom())
|
||||
, m_linkPatches(PrefabDom())
|
||||
, m_linkStatus(LinkStatus::LINKSTATUS)
|
||||
{
|
||||
m_prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
|
||||
@@ -124,7 +124,7 @@ namespace AzToolsFramework
|
||||
const TemplateId& targetId,
|
||||
const TemplateId& sourceId,
|
||||
const InstanceAlias& instanceAlias,
|
||||
PrefabDomReference linkDom,
|
||||
PrefabDomReference linkPatches,
|
||||
const LinkId linkId)
|
||||
{
|
||||
m_targetId = targetId;
|
||||
@@ -132,9 +132,9 @@ namespace AzToolsFramework
|
||||
m_instanceAlias = instanceAlias;
|
||||
m_linkId = linkId;
|
||||
|
||||
if (linkDom.has_value())
|
||||
if (linkPatches.has_value())
|
||||
{
|
||||
m_linkDom = AZStd::move(linkDom->get());
|
||||
m_linkPatches = AZStd::move(linkPatches->get());
|
||||
}
|
||||
|
||||
//if linkId is invalid, set as ADD
|
||||
@@ -193,7 +193,7 @@ namespace AzToolsFramework
|
||||
|
||||
void PrefabUndoInstanceLink::AddLink()
|
||||
{
|
||||
m_linkId = m_prefabSystemComponentInterface->CreateLink(m_targetId, m_sourceId, m_instanceAlias, m_linkDom, m_linkId);
|
||||
m_linkId = m_prefabSystemComponentInterface->CreateLink(m_targetId, m_sourceId, m_instanceAlias, m_linkPatches, m_linkId);
|
||||
}
|
||||
|
||||
void PrefabUndoInstanceLink::RemoveLink()
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace AzToolsFramework
|
||||
const TemplateId& targetId,
|
||||
const TemplateId& sourceId,
|
||||
const InstanceAlias& instanceAlias,
|
||||
PrefabDomReference linkDom = PrefabDomReference(),
|
||||
PrefabDomReference linkPatches = PrefabDomReference(),
|
||||
const LinkId linkId = InvalidLinkId);
|
||||
|
||||
void Undo() override;
|
||||
@@ -120,7 +120,7 @@ namespace AzToolsFramework
|
||||
InstanceAlias m_instanceAlias;
|
||||
|
||||
LinkId m_linkId;
|
||||
PrefabDom m_linkDom; //data for delete/update
|
||||
PrefabDom m_linkPatches; //data for delete/update
|
||||
LinkStatus m_linkStatus;
|
||||
|
||||
PrefabSystemComponentInterface* m_prefabSystemComponentInterface = nullptr;
|
||||
|
||||
@@ -46,13 +46,11 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
void RemoveLink(
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias,
|
||||
LinkId linkId, UndoSystem::URSequencePoint* undoBatch)
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias, LinkId linkId,
|
||||
PrefabDomReference linkPatches, UndoSystem::URSequencePoint* undoBatch)
|
||||
{
|
||||
auto linkRemoveUndo = aznew PrefabUndoInstanceLink("Remove Link");
|
||||
PrefabDom emptyLinkDom;
|
||||
linkRemoveUndo->Capture(
|
||||
targetTemplateId, sourceTemplateId, instanceAlias, emptyLinkDom, linkId);
|
||||
linkRemoveUndo->Capture(targetTemplateId, sourceTemplateId, instanceAlias, linkPatches, linkId);
|
||||
linkRemoveUndo->SetParent(undoBatch);
|
||||
linkRemoveUndo->Redo();
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@ namespace AzToolsFramework
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, PrefabDomReference patch,
|
||||
const InstanceAlias& instanceAlias, UndoSystem::URSequencePoint* undoBatch);
|
||||
void RemoveLink(
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias,
|
||||
LinkId linkId, UndoSystem::URSequencePoint* undoBatch);
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias, LinkId linkId,
|
||||
PrefabDomReference linkPatches, UndoSystem::URSequencePoint* undoBatch);
|
||||
}
|
||||
} // namespace Prefab
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+6
-3
@@ -39,9 +39,10 @@ namespace AzToolsFramework
|
||||
editContext->Class<EditorNonUniformScaleComponent>("Non-uniform Scale",
|
||||
"Non-uniform scale for this entity only (does not propagate through hierarchy)")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::Category, "Non-uniform Scale")
|
||||
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game"))
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->Attribute(AZ::Edit::Attributes::FixedComponentListIndex, 1)
|
||||
->Attribute(AZ::Edit::Attributes::RemoveableByUser, true)
|
||||
->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/NonUniformScale.svg")
|
||||
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/NonUniformScale.svg")
|
||||
->DataElement(
|
||||
AZ::Edit::UIHandlers::Default, &EditorNonUniformScaleComponent::m_scale, "Non-uniform Scale",
|
||||
"Non-uniform scale for this entity only (does not propagate through hierarchy)")
|
||||
@@ -61,6 +62,8 @@ namespace AzToolsFramework
|
||||
|
||||
void EditorNonUniformScaleComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
|
||||
{
|
||||
incompatible.push_back(AZ_CRC_CE("NonUniformScaleService"));
|
||||
|
||||
incompatible.push_back(AZ_CRC_CE("DebugDrawObbService"));
|
||||
incompatible.push_back(AZ_CRC_CE("DebugDrawService"));
|
||||
incompatible.push_back(AZ_CRC_CE("EMotionFXActorService"));
|
||||
|
||||
+70
@@ -25,11 +25,15 @@
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
#include <AzFramework/Components/TransformComponent.h>
|
||||
#include <AzToolsFramework/API/EntityCompositionRequestBus.h>
|
||||
#include <AzToolsFramework/API/EntityPropertyEditorRequestsBus.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
|
||||
#include <AzToolsFramework/ToolsComponents/TransformComponentBus.h>
|
||||
#include <AzToolsFramework/ToolsComponents/TransformScalePropertyHandler.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorInspectorComponentBus.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorPendingCompositionBus.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
|
||||
@@ -1196,6 +1200,66 @@ namespace AzToolsFramework
|
||||
destinationComponent->SetWorldTM(const_cast<TransformComponent*>(sourceComponent)->GetWorldTM());
|
||||
}
|
||||
|
||||
AZ::Component* TransformComponent::FindPresentOrPendingComponent(AZ::Uuid componentUuid)
|
||||
{
|
||||
// first check if the component is present and valid
|
||||
if (AZ::Component* foundComponent = GetEntity()->FindComponent(componentUuid))
|
||||
{
|
||||
return foundComponent;
|
||||
}
|
||||
|
||||
// then check to see if there's a component pending because it's in an invalid state
|
||||
AZStd::vector<AZ::Component*> pendingComponents;
|
||||
AzToolsFramework::EditorPendingCompositionRequestBus::Event(GetEntityId(),
|
||||
&AzToolsFramework::EditorPendingCompositionRequests::GetPendingComponents, pendingComponents);
|
||||
|
||||
for (const auto pendingComponent : pendingComponents)
|
||||
{
|
||||
if (pendingComponent->RTTI_IsTypeOf(componentUuid))
|
||||
{
|
||||
return pendingComponent;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool TransformComponent::IsAddNonUniformScaleButtonReadOnly()
|
||||
{
|
||||
return FindPresentOrPendingComponent(EditorNonUniformScaleComponent::TYPEINFO_Uuid()) != nullptr;
|
||||
}
|
||||
|
||||
AZ::Crc32 TransformComponent::OnAddNonUniformScaleButtonPressed()
|
||||
{
|
||||
// if there is already a non-uniform scale component, do nothing
|
||||
if (FindPresentOrPendingComponent(EditorNonUniformScaleComponent::TYPEINFO_Uuid()))
|
||||
{
|
||||
return AZ::Edit::PropertyRefreshLevels::None;
|
||||
}
|
||||
|
||||
const AZStd::vector<AZ::EntityId> entityList = { GetEntityId() };
|
||||
const AZ::ComponentTypeList componentsToAdd = { EditorNonUniformScaleComponent::TYPEINFO_Uuid() };
|
||||
|
||||
AzToolsFramework::EntityCompositionRequests::AddComponentsOutcome addComponentsOutcome;
|
||||
AzToolsFramework::EntityCompositionRequestBus::BroadcastResult(addComponentsOutcome,
|
||||
&AzToolsFramework::EntityCompositionRequests::AddComponentsToEntities, entityList, componentsToAdd);
|
||||
|
||||
const auto nonUniformScaleComponent = FindPresentOrPendingComponent(EditorNonUniformScaleComponent::RTTI_Type());
|
||||
AZ::ComponentId nonUniformScaleComponentId =
|
||||
nonUniformScaleComponent ? nonUniformScaleComponent->GetId() : AZ::InvalidComponentId;
|
||||
|
||||
if (!addComponentsOutcome.IsSuccess() || !nonUniformScaleComponent)
|
||||
{
|
||||
AZ_Warning("Transform component", false, "Failed to add non-uniform scale component.");
|
||||
return AZ::Edit::PropertyRefreshLevels::None;
|
||||
}
|
||||
|
||||
AzToolsFramework::EntityPropertyEditorRequestBus::Broadcast(
|
||||
&AzToolsFramework::EntityPropertyEditorRequests::SetNewComponentId, nonUniformScaleComponentId);
|
||||
|
||||
return AZ::Edit::PropertyRefreshLevels::EntireTree;
|
||||
}
|
||||
|
||||
void TransformComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
// reflect data for script, serialization, editing..
|
||||
@@ -1211,6 +1275,7 @@ namespace AzToolsFramework
|
||||
serializeContext->Class<Components::TransformComponent, EditorComponentBase>()->
|
||||
Field("Parent Entity", &TransformComponent::m_parentEntityId)->
|
||||
Field("Transform Data", &TransformComponent::m_editorTransform)->
|
||||
Field("AddNonUniformScaleButton", &TransformComponent::m_addNonUniformScaleButton)->
|
||||
Field("Cached World Transform", &TransformComponent::m_cachedWorldTransform)->
|
||||
Field("Cached World Transform Parent", &TransformComponent::m_cachedWorldTransformParent)->
|
||||
Field("Parent Activation Transform Mode", &TransformComponent::m_parentActivationTransformMode)->
|
||||
@@ -1224,6 +1289,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
ptrEdit->Class<TransformComponent>("Transform", "Controls the placement of the entity in the world in 3d")->
|
||||
ClassElement(AZ::Edit::ClassElements::EditorData, "")->
|
||||
Attribute(AZ::Edit::Attributes::FixedComponentListIndex, 0)->
|
||||
Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Transform.svg")->
|
||||
Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Transform.png")->
|
||||
Attribute(AZ::Edit::Attributes::AutoExpand, true)->
|
||||
@@ -1234,6 +1300,10 @@ namespace AzToolsFramework
|
||||
DataElement(AZ::Edit::UIHandlers::Default, &TransformComponent::m_editorTransform, "Values", "")->
|
||||
Attribute(AZ::Edit::Attributes::ChangeNotify, &TransformComponent::TransformChanged)->
|
||||
Attribute(AZ::Edit::Attributes::AutoExpand, true)->
|
||||
DataElement(AZ::Edit::UIHandlers::Button, &TransformComponent::m_addNonUniformScaleButton, "", "")->
|
||||
Attribute(AZ::Edit::Attributes::ButtonText, "Add non-uniform scale")->
|
||||
Attribute(AZ::Edit::Attributes::ReadOnly, &TransformComponent::IsAddNonUniformScaleButtonReadOnly)->
|
||||
Attribute(AZ::Edit::Attributes::ChangeNotify, &TransformComponent::OnAddNonUniformScaleButtonPressed)->
|
||||
DataElement(AZ::Edit::UIHandlers::ComboBox, &TransformComponent::m_parentActivationTransformMode,
|
||||
"Parent activation", "Configures relative transform behavior when parent activates.")->
|
||||
EnumAttribute(AZ::TransformConfig::ParentActivationTransformMode::MaintainOriginalRelativeTransform, "Original relative transform")->
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <AzToolsFramework/API/ComponentEntitySelectionBus.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/Commands/SelectionCommand.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.h>
|
||||
|
||||
#include "EditorComponentBase.h"
|
||||
#include "TransformComponentBus.h"
|
||||
@@ -228,6 +229,10 @@ namespace AzToolsFramework
|
||||
|
||||
void CheckApplyCachedWorldTransform(const AZ::Transform& parentWorld);
|
||||
|
||||
AZ::Component* FindPresentOrPendingComponent(AZ::Uuid componentUuid);
|
||||
bool IsAddNonUniformScaleButtonReadOnly();
|
||||
AZ::Crc32 OnAddNonUniformScaleButtonPressed();
|
||||
|
||||
// Drives transform behavior when parent activates. See AZ::TransformConfig::ParentActivationTransformMode for details.
|
||||
AZ::TransformConfig::ParentActivationTransformMode m_parentActivationTransformMode;
|
||||
|
||||
@@ -260,6 +265,10 @@ namespace AzToolsFramework
|
||||
bool m_worldTransformDirty = true;
|
||||
bool m_isStatic = false;
|
||||
|
||||
// This is a workaround for a bug which causes the button to appear with incorrect placement if a UI
|
||||
// element is used rather than a data element.
|
||||
bool m_addNonUniformScaleButton = false;
|
||||
|
||||
// Deprecated
|
||||
AZ::InterpolationMode m_interpolatePosition;
|
||||
AZ::InterpolationMode m_interpolateRotation;
|
||||
|
||||
+82
-13
@@ -63,6 +63,7 @@ AZ_POP_DISABLE_WARNING
|
||||
#include <AzToolsFramework/ToolsComponents/EditorOnlyEntityComponentBus.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorOnlyEntityComponent.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorLayerComponent.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.h>
|
||||
#include <AzToolsFramework/ToolsMessaging/EntityHighlightBus.h>
|
||||
#include <AzToolsFramework/UI/ComponentPalette/ComponentPaletteUtil.hxx>
|
||||
#include <AzToolsFramework/UI/ComponentPalette/ComponentPaletteWidget.hxx>
|
||||
@@ -494,6 +495,11 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
void EntityPropertyEditor::SetNewComponentId(AZ::ComponentId componentId)
|
||||
{
|
||||
m_newComponentId = componentId;
|
||||
}
|
||||
|
||||
void EntityPropertyEditor::SetOverrideEntityIds(const AzToolsFramework::EntityIdSet& entities)
|
||||
{
|
||||
m_overrideSelectedEntityIds = entities;
|
||||
@@ -1039,15 +1045,23 @@ namespace AzToolsFramework
|
||||
sortedComponents.end(),
|
||||
[=](const OrderedSortComponentEntry& component1, const OrderedSortComponentEntry& component2)
|
||||
{
|
||||
// Transform component must be first, always
|
||||
// If component 1 is a transform component, it is sorted earlier
|
||||
if (component1.m_component->RTTI_IsTypeOf(AZ::EditorTransformComponentTypeId))
|
||||
AZStd::optional<int> fixedComponentListIndex1 = GetFixedComponentListIndex(component1.m_component);
|
||||
AZStd::optional<int> fixedComponentListIndex2 = GetFixedComponentListIndex(component2.m_component);
|
||||
|
||||
// If both components have fixed list indices, sort based on those indices
|
||||
if (fixedComponentListIndex1.has_value() && fixedComponentListIndex2.has_value())
|
||||
{
|
||||
return fixedComponentListIndex1.value() < fixedComponentListIndex2.value();
|
||||
}
|
||||
|
||||
// If component 1 has a fixed list index, sort it first
|
||||
if (fixedComponentListIndex1.has_value())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// If component 2 is a transform component, component 1 is never sorted earlier
|
||||
if (component2.m_component->RTTI_IsTypeOf(AZ::EditorTransformComponentTypeId))
|
||||
// If component 2 has a fixed list index, component 1 should not be sorted before it
|
||||
if (fixedComponentListIndex2.has_value())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1128,10 +1142,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
if (auto attributeData = azdynamic_cast<AZ::Edit::AttributeData<bool>*>(attribute))
|
||||
{
|
||||
if (!attributeData->Get(nullptr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return attributeData->Get(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1166,6 +1177,36 @@ namespace AzToolsFramework
|
||||
return true;
|
||||
}
|
||||
|
||||
AZStd::optional<int> EntityPropertyEditor::GetFixedComponentListIndex(const AZ::Component* component)
|
||||
{
|
||||
auto componentClassData = component ? GetComponentClassData(component) : nullptr;
|
||||
if (componentClassData && componentClassData->m_editData)
|
||||
{
|
||||
if (auto editorDataElement = componentClassData->m_editData->FindElementData(AZ::Edit::ClassElements::EditorData))
|
||||
{
|
||||
if (auto attribute = editorDataElement->FindAttribute(AZ::Edit::Attributes::FixedComponentListIndex))
|
||||
{
|
||||
if (auto attributeData = azdynamic_cast<AZ::Edit::AttributeData<int>*>(attribute))
|
||||
{
|
||||
return { attributeData->Get(nullptr) };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool EntityPropertyEditor::IsComponentDraggable(const AZ::Component* component)
|
||||
{
|
||||
return !GetFixedComponentListIndex(component).has_value();
|
||||
}
|
||||
|
||||
bool EntityPropertyEditor::AreComponentsDraggable(const AZ::Entity::ComponentArrayType& components) const
|
||||
{
|
||||
return AZStd::all_of(
|
||||
components.begin(), components.end(), [](AZ::Component* component) { return IsComponentDraggable(component); });
|
||||
}
|
||||
|
||||
bool EntityPropertyEditor::AreComponentsCopyable(const AZ::Entity::ComponentArrayType& components) const
|
||||
{
|
||||
return AreComponentsCopyable(components, m_componentFilter);
|
||||
@@ -3367,7 +3408,9 @@ namespace AzToolsFramework
|
||||
sourceComponents.size() == m_selectedEntityIds.size() &&
|
||||
targetComponents.size() == m_selectedEntityIds.size() &&
|
||||
AreComponentsRemovable(sourceComponents) &&
|
||||
AreComponentsRemovable(targetComponents);
|
||||
AreComponentsRemovable(targetComponents) &&
|
||||
AreComponentsDraggable(sourceComponents) &&
|
||||
AreComponentsDraggable(targetComponents);
|
||||
}
|
||||
|
||||
bool EntityPropertyEditor::IsMoveComponentsUpAllowed() const
|
||||
@@ -3681,14 +3724,38 @@ namespace AzToolsFramework
|
||||
|
||||
void EntityPropertyEditor::ScrollToNewComponent()
|
||||
{
|
||||
//force new components to be visible, assuming they are added to the end of the list and layout
|
||||
auto componentEditor = GetComponentEditorsFromIndex(m_componentEditorsUsed - 1);
|
||||
// force new components to be visible
|
||||
// if no component has been explicitly set at the most recently added,
|
||||
// assume new components are added to the end of the list and layout
|
||||
AZ::s32 newComponentIndex = m_componentEditorsUsed - 1;
|
||||
|
||||
// if there is a component id explicitly set as the most recently added, try to find it and make sure it is visible
|
||||
if (m_newComponentId.has_value() && m_newComponentId.value() != AZ::InvalidComponentId)
|
||||
{
|
||||
AZ::ComponentId newComponentId = m_newComponentId.value();
|
||||
for (AZ::s32 componentIndex = 0; componentIndex < m_componentEditorsUsed; ++componentIndex)
|
||||
{
|
||||
if (m_componentEditors[componentIndex])
|
||||
{
|
||||
for (const auto component : m_componentEditors[componentIndex]->GetComponents())
|
||||
{
|
||||
if (component->GetId() == newComponentId)
|
||||
{
|
||||
newComponentIndex = componentIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto componentEditor = GetComponentEditorsFromIndex(newComponentIndex);
|
||||
if (componentEditor)
|
||||
{
|
||||
m_gui->m_componentList->ensureWidgetVisible(componentEditor);
|
||||
}
|
||||
m_shouldScrollToNewComponents = false;
|
||||
m_shouldScrollToNewComponentsQueued = false;
|
||||
m_newComponentId.reset();
|
||||
}
|
||||
|
||||
void EntityPropertyEditor::QueueScrollToNewComponent()
|
||||
@@ -4073,7 +4140,8 @@ namespace AzToolsFramework
|
||||
{
|
||||
if (!componentEditor ||
|
||||
!componentEditor->isVisible() ||
|
||||
!AreComponentsRemovable(componentEditor->GetComponents()))
|
||||
!AreComponentsRemovable(componentEditor->GetComponents()) ||
|
||||
!AreComponentsDraggable(componentEditor->GetComponents()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -4223,6 +4291,7 @@ namespace AzToolsFramework
|
||||
while (targetComponentEditor
|
||||
&& (targetComponentEditor->IsDragged()
|
||||
|| !AreComponentsRemovable(targetComponentEditor->GetComponents())
|
||||
|| !AreComponentsDraggable(targetComponentEditor->GetComponents())
|
||||
|| (globalRect.center().y() > GetWidgetGlobalRect(targetComponentEditor).center().y())))
|
||||
{
|
||||
if (targetItr == m_componentEditors.end() || targetComponentEditor == m_componentEditors.back() || !targetComponentEditor->isVisible())
|
||||
|
||||
+7
@@ -211,6 +211,7 @@ namespace AzToolsFramework
|
||||
// EntityPropertEditorRequestBus
|
||||
void GetSelectedAndPinnedEntities(EntityIdList& selectedEntityIds) override;
|
||||
void GetSelectedEntities(EntityIdList& selectedEntityIds) override;
|
||||
void SetNewComponentId(AZ::ComponentId componentId) override;
|
||||
|
||||
bool IsEntitySelected(const AZ::EntityId& id) const;
|
||||
bool IsSingleEntitySelected(const AZ::EntityId& id) const;
|
||||
@@ -237,6 +238,9 @@ namespace AzToolsFramework
|
||||
static bool DoesComponentPassFilter(const AZ::Component* component, const ComponentFilter& filter);
|
||||
static bool IsComponentRemovable(const AZ::Component* component);
|
||||
bool AreComponentsRemovable(const AZ::Entity::ComponentArrayType& components) const;
|
||||
static AZStd::optional<int> GetFixedComponentListIndex(const AZ::Component* component);
|
||||
static bool IsComponentDraggable(const AZ::Component* component);
|
||||
bool AreComponentsDraggable(const AZ::Entity::ComponentArrayType& components) const;
|
||||
bool AreComponentsCopyable(const AZ::Entity::ComponentArrayType& components) const;
|
||||
|
||||
void AddMenuOptionsForComponents(QMenu& menu, const QPoint& position);
|
||||
@@ -568,6 +572,9 @@ namespace AzToolsFramework
|
||||
void ConnectToEntityBuses(const AZ::EntityId& entityId);
|
||||
void DisconnectFromEntityBuses(const AZ::EntityId& entityId);
|
||||
|
||||
//! Stores a component id to be focused on next time the UI updates.
|
||||
AZStd::optional<AZ::ComponentId> m_newComponentId;
|
||||
|
||||
private slots:
|
||||
void OnPropertyRefreshRequired(); // refresh is needed for a property.
|
||||
void UpdateContents();
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportTypes.h>
|
||||
|
||||
class QPoint; // LYN-2315 in-progress, remove this
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
struct ScreenPoint;
|
||||
@@ -167,19 +165,37 @@ namespace AzToolsFramework
|
||||
/// Return the angle snapping/step size.
|
||||
virtual float AngleStep() = 0;
|
||||
/// Transform a point in world space to screen space coordinates.
|
||||
virtual QPoint ViewportWorldToScreen(const AZ::Vector3& worldPosition) = 0;
|
||||
virtual AzFramework::ScreenPoint ViewportWorldToScreen(const AZ::Vector3& worldPosition) = 0;
|
||||
/// Transform a point in screen space coordinates to a vector in world space based on clip space depth.
|
||||
/// Depth specifies a relative camera depth to project in the range of [0.f, 1.f].
|
||||
/// Returns the world space position if successful.
|
||||
virtual AZStd::optional<AZ::Vector3> ViewportScreenToWorld(const QPoint& screenPosition, float depth) = 0;
|
||||
virtual AZStd::optional<AZ::Vector3> ViewportScreenToWorld(const AzFramework::ScreenPoint& screenPosition, float depth) = 0;
|
||||
/// Casts a point in screen space to a ray in world space originating from the viewport camera frustum's near plane.
|
||||
/// Returns a ray containing the ray's origin and a direction normal, if successful.
|
||||
virtual AZStd::optional<ProjectedViewportRay> ViewportScreenToWorldRay(const QPoint& screenPosition) = 0;
|
||||
virtual AZStd::optional<ProjectedViewportRay> ViewportScreenToWorldRay(const AzFramework::ScreenPoint& screenPosition) = 0;
|
||||
|
||||
protected:
|
||||
~ViewportInteractionRequests() = default;
|
||||
};
|
||||
|
||||
/// Interface to return only viewport specific settings (e.g. snapping).
|
||||
class ViewportSettings
|
||||
{
|
||||
public:
|
||||
virtual ~ViewportSettings() = default;
|
||||
|
||||
/// Return if grid snapping is enabled.
|
||||
virtual bool GridSnappingEnabled() const = 0;
|
||||
/// Return the grid snapping size.
|
||||
virtual float GridSize() const = 0;
|
||||
/// Does the grid currently want to be displayed.
|
||||
virtual bool ShowGrid() const = 0;
|
||||
/// Return if angle snapping is enabled.
|
||||
virtual bool AngleSnappingEnabled() const = 0;
|
||||
/// Return the angle snapping/step size.
|
||||
virtual float AngleStep() const = 0;
|
||||
};
|
||||
|
||||
/// Type to inherit to implement ViewportInteractionRequests.
|
||||
using ViewportInteractionRequestBus = AZ::EBus<ViewportInteractionRequests, ViewportEBusTraits>;
|
||||
|
||||
@@ -207,9 +223,9 @@ namespace AzToolsFramework
|
||||
public:
|
||||
/// Given a point in screen space, return the picked entity (if any).
|
||||
/// Picked EntityId will be returned, InvalidEntityId will be returned on failure.
|
||||
virtual AZ::EntityId PickEntity(const QPoint& point) = 0;
|
||||
virtual AZ::EntityId PickEntity(const AzFramework::ScreenPoint& point) = 0;
|
||||
/// Given a point in screen space, return the terrain position in world space.
|
||||
virtual AZ::Vector3 PickTerrain(const QPoint& point) = 0;
|
||||
virtual AZ::Vector3 PickTerrain(const AzFramework::ScreenPoint& point) = 0;
|
||||
/// Return the terrain height given a world position in 2d (xy plane).
|
||||
virtual float TerrainHeight(const AZ::Vector2& position) = 0;
|
||||
/// Given the current view frustum (viewport) return all visible entities.
|
||||
@@ -246,6 +262,8 @@ namespace AzToolsFramework
|
||||
/// from ViewportCursorScreenPosition. This method will always return the correct position to generate a mouse
|
||||
/// position delta.
|
||||
virtual AZStd::optional<AzFramework::ScreenPoint> PreviousViewportCursorScreenPosition() = 0;
|
||||
/// Is mouse over viewport.
|
||||
virtual bool IsMouseOver() const = 0;
|
||||
|
||||
protected:
|
||||
~ViewportMouseCursorRequests() = default;
|
||||
|
||||
@@ -19,8 +19,6 @@ namespace AzToolsFramework
|
||||
{
|
||||
namespace ViewportInteraction
|
||||
{
|
||||
const AZ::s32 g_mainViewportEntityDebugDisplayId = AZ_CRC("MainViewportEntityDebugDisplayId", 0x58ae7fe8);
|
||||
|
||||
void ViewportInteractionReflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
|
||||
@@ -256,9 +256,5 @@ namespace AzToolsFramework
|
||||
|
||||
/// Reflect all viewport related types.
|
||||
void ViewportInteractionReflect(AZ::ReflectContext* context);
|
||||
|
||||
/// The Id the main DebugDisplayRequestBus will be connected on.
|
||||
extern const AZ::s32 g_mainViewportEntityDebugDisplayId;
|
||||
|
||||
} // namespace ViewportInteraction
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+5
-5
@@ -141,16 +141,16 @@ namespace AzToolsFramework
|
||||
const AZ::Vector3& entityPosition = m_entityDataCache->GetVisibleEntityPosition(entityCacheIndex);
|
||||
|
||||
// selecting based on 2d icon - should only do it when visible and not selected
|
||||
const QPoint screenPosition = GetScreenPosition(viewportId, entityPosition);
|
||||
const AzFramework::ScreenPoint screenPosition = GetScreenPosition(viewportId, entityPosition);
|
||||
|
||||
const float distSqFromCamera = cameraState.m_position.GetDistanceSq(entityPosition);
|
||||
const auto iconRange = static_cast<float>(GetIconScale(distSqFromCamera) * s_iconSize * 0.5f);
|
||||
const auto screenCoords = mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates;
|
||||
|
||||
if ( screenCoords.m_x >= screenPosition.x() - iconRange
|
||||
&& screenCoords.m_x <= screenPosition.x() + iconRange
|
||||
&& screenCoords.m_y >= screenPosition.y() - iconRange
|
||||
&& screenCoords.m_y <= screenPosition.y() + iconRange)
|
||||
if ( screenCoords.m_x >= screenPosition.m_x - iconRange
|
||||
&& screenCoords.m_x <= screenPosition.m_x + iconRange
|
||||
&& screenCoords.m_y >= screenPosition.m_y - iconRange
|
||||
&& screenCoords.m_y <= screenPosition.m_y + iconRange)
|
||||
{
|
||||
entityIdUnderCursor = entityId;
|
||||
break;
|
||||
|
||||
+2
-2
@@ -53,11 +53,11 @@ namespace AzToolsFramework
|
||||
return AZ::GetMax(projectedCameraDistance, cameraState.m_nearClip) / apparentDistance;
|
||||
}
|
||||
|
||||
QPoint GetScreenPosition(const int viewportId, const AZ::Vector3& worldTranslation)
|
||||
AzFramework::ScreenPoint GetScreenPosition(const int viewportId, const AZ::Vector3& worldTranslation)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
|
||||
|
||||
QPoint screenPosition = QPoint();
|
||||
auto screenPosition = AzFramework::ScreenPoint(0, 0);
|
||||
ViewportInteraction::ViewportInteractionRequestBus::EventResult(
|
||||
screenPosition, viewportId,
|
||||
&ViewportInteraction::ViewportInteractionRequestBus::Events::ViewportWorldToScreen,
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ namespace AzToolsFramework
|
||||
const AZ::Vector3& worldPosition, const AzFramework::CameraState& cameraState);
|
||||
|
||||
/// Map from world space to screen space.
|
||||
QPoint GetScreenPosition(int viewportId, const AZ::Vector3& worldTranslation);
|
||||
AzFramework::ScreenPoint GetScreenPosition(int viewportId, const AZ::Vector3& worldTranslation);
|
||||
|
||||
/// Given a mouse interaction, determine if the pick ray from its position
|
||||
/// in screen space intersected an aabb in world space.
|
||||
|
||||
+4
-4
@@ -316,14 +316,14 @@ namespace AzToolsFramework
|
||||
|
||||
template<typename EntitySelectFuncType, typename EntityIdContainer, typename Compare>
|
||||
static void BoxSelectAddRemoveToEntitySelection(
|
||||
const AZStd::optional<QRect>& boxSelect, const QPoint& screenPosition, const AZ::EntityId visibleEntityId,
|
||||
const AZStd::optional<QRect>& boxSelect, const AzFramework::ScreenPoint& screenPosition, const AZ::EntityId visibleEntityId,
|
||||
const EntityIdContainer& incomingEntityIds, EntityIdContainer& outgoingEntityIds,
|
||||
EditorTransformComponentSelection& entityTransformComponentSelection,
|
||||
EntitySelectFuncType selectFunc1, EntitySelectFuncType selectFunc2, Compare outgoingCheck)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
|
||||
|
||||
if (boxSelect->contains(screenPosition))
|
||||
if (boxSelect->contains(ViewportInteraction::QPointFromScreenPoint(screenPosition)))
|
||||
{
|
||||
const auto entityIt = incomingEntityIds.find(visibleEntityId);
|
||||
|
||||
@@ -389,7 +389,7 @@ namespace AzToolsFramework
|
||||
const AZ::EntityId entityId = entityDataCache.GetVisibleEntityId(entityCacheIndex);
|
||||
const AZ::Vector3& entityPosition = entityDataCache.GetVisibleEntityPosition(entityCacheIndex);
|
||||
|
||||
const QPoint screenPosition = GetScreenPosition(viewportId, entityPosition);
|
||||
const AzFramework::ScreenPoint screenPosition = GetScreenPosition(viewportId, entityPosition);
|
||||
|
||||
if (currentKeyboardModifiers.Ctrl())
|
||||
{
|
||||
@@ -927,7 +927,7 @@ namespace AzToolsFramework
|
||||
ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult(
|
||||
worldSurfacePosition, viewportId,
|
||||
&ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain,
|
||||
ViewportInteraction::QPointFromScreenPoint(mouseInteraction.m_mousePick.m_screenCoordinates));
|
||||
mouseInteraction.m_mousePick.m_screenCoordinates);
|
||||
|
||||
// convert to local space - snap if enabled
|
||||
const GridSnapParameters gridSnapParams = GridSnapSettings(viewportId);
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ namespace Benchmark
|
||||
}
|
||||
BENCHMARK_REGISTER_F(BM_PrefabUpdateInstances, UpdateInstances_SingeEntityInstances)
|
||||
->RangeMultiplier(10)
|
||||
->Range(100, 1000)
|
||||
->Range(100, 10000)
|
||||
->Unit(benchmark::kMillisecond)
|
||||
->Complexity();
|
||||
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
#include <AzToolsFramework/Application/ToolsApplication.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorInteractionSystemViewportSelectionRequestBus.h>
|
||||
#include <AzToolsFramework/ToolsComponents/TransformComponent.h>
|
||||
#include <AzToolsFramework/ToolsComponents/ScriptEditorComponent.h>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx>
|
||||
#include <AzToolsFramework/API/EntityPropertyEditorRequestsBus.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorLockComponent.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorVisibilityComponent.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorDefaultSelection.h>
|
||||
|
||||
#include <AzCore/IO/Streamer/StreamerComponent.h>
|
||||
#include <AzCore/Asset/AssetManagerComponent.h>
|
||||
#include <AzCore/std/sort.h>
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace UnitTest
|
||||
|
||||
TEST(EntityPropertyEditorTests, PrioritySort_NonTransformAsFirstItem_TransformMovesToTopRemainderUnchanged)
|
||||
{
|
||||
ComponentApplication app;
|
||||
ToolsApplication app;
|
||||
|
||||
AZ::Entity::ComponentArrayType unorderedComponents;
|
||||
AZ::Entity::ComponentArrayType orderedComponents;
|
||||
@@ -68,12 +68,18 @@ namespace UnitTest
|
||||
|
||||
Entity* systemEntity = app.Create(desc, startupParams);
|
||||
|
||||
// Need to reflect the components so that edit attribute used for sorting, such as FixedComponentListIndex, get set.
|
||||
app.RegisterComponentDescriptor(AzToolsFramework::Components::TransformComponent::CreateDescriptor());
|
||||
app.RegisterComponentDescriptor(AzToolsFramework::Components::ScriptEditorComponent::CreateDescriptor());
|
||||
app.RegisterComponentDescriptor(AZ::AssetManagerComponent::CreateDescriptor());
|
||||
|
||||
// Add more than 31 components, as we are testing the case where the sort fails when there are 32 or more items.
|
||||
const int numFillerItems = 32;
|
||||
|
||||
for (int commentIndex = 0; commentIndex < numFillerItems; commentIndex++)
|
||||
{
|
||||
unorderedComponents.insert(unorderedComponents.begin(), systemEntity->CreateComponent(AZ::StreamerComponent::RTTI_Type()));
|
||||
unorderedComponents.insert(unorderedComponents.begin(), systemEntity->CreateComponent(
|
||||
AzToolsFramework::Components::ScriptEditorComponent::RTTI_Type()));
|
||||
}
|
||||
|
||||
// Add a TransformComponent at the end which should be sorted to the beginning by the priority sort.
|
||||
|
||||
Reference in New Issue
Block a user