Merge branch 'main' into genewalt_emfx_ReleaseUnusedRawAssetDataAfterInit

This commit is contained in:
Gene Walters
2021-04-21 16:19:53 -07:00
407 changed files with 25585 additions and 23427 deletions
@@ -157,7 +157,7 @@ endif()
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
ly_add_pytest(
NAME AutomatedTesting::BlastTests
TEST_SUITE sandbox
TEST_SUITE periodic
TEST_SERIAL TRUE
PATH ${CMAKE_CURRENT_LIST_DIR}/Blast/TestSuite_Active.py
TIMEOUT 3600
+2 -1
View File
@@ -22,6 +22,7 @@ if(CMAKE_VERSION VERSION_EQUAL 3.19)
endif()
include(cmake/Version.cmake)
include(cmake/OutputDirectory.cmake)
if(NOT PROJECT_NAME)
project(O3DE
@@ -30,7 +31,7 @@ if(NOT PROJECT_NAME)
)
endif()
include(cmake/Initialize.cmake)
include(cmake/GeneralSettings.cmake)
include(cmake/FileUtil.cmake)
include(cmake/PAL.cmake)
include(cmake/PALTools.cmake)
@@ -28,7 +28,7 @@ namespace Physics
class CharacterColliderNodeConfiguration
{
public:
AZ_RTTI(CharacterColliderNodeConfiguration, "{C16F3301-0979-400C-B734-692D83755C39}");
AZ_RTTI(Physics::CharacterColliderNodeConfiguration, "{C16F3301-0979-400C-B734-692D83755C39}");
AZ_CLASS_ALLOCATOR_DECL
virtual ~CharacterColliderNodeConfiguration() = default;
@@ -42,7 +42,7 @@ namespace Physics
class CharacterColliderConfiguration
{
public:
AZ_RTTI(CharacterColliderConfiguration, "{4DFF1434-DF5B-4ED5-BE0F-D3E66F9B331A}");
AZ_RTTI(Physics::CharacterColliderConfiguration, "{4DFF1434-DF5B-4ED5-BE0F-D3E66F9B331A}");
AZ_CLASS_ALLOCATOR_DECL
virtual ~CharacterColliderConfiguration() = default;
@@ -63,21 +63,23 @@ namespace Physics
{
public:
AZ_CLASS_ALLOCATOR(CharacterConfiguration, AZ::SystemAllocator, 0);
AZ_RTTI(CharacterConfiguration, "{58D5A6CA-113B-4AC3-8D53-239DB0C4E240}", AzPhysics::SimulatedBodyConfiguration);
AZ_RTTI(Physics::CharacterConfiguration, "{58D5A6CA-113B-4AC3-8D53-239DB0C4E240}", AzPhysics::SimulatedBodyConfiguration);
virtual ~CharacterConfiguration() = default;
static void Reflect(AZ::ReflectContext* context);
AzPhysics::CollisionGroups::Id m_collisionGroupId; ///< Which layers does this character collide with.
AzPhysics::CollisionLayer m_collisionLayer; ///< Which collision layer is this character on.
MaterialSelection m_materialSelection; ///< Material selected from library for the body associated with the character.
AZ::Vector3 m_upDirection = AZ::Vector3::CreateAxisZ(); ///< Up direction for character orientation and step behavior.
float m_maximumSlopeAngle = 30.0f; ///< The maximum slope on which the character can move, in degrees.
float m_stepHeight = 0.5f; ///< Affects what size steps the character can climb.
float m_minimumMovementDistance = 0.001f; ///< To avoid jittering, the controller will not attempt to move distances below this.
float m_maximumSpeed = 100.0f; ///< If the accumulated requested velocity for a tick exceeds this magnitude, it will be clamped.
AZStd::string m_colliderTag; ///< Used to identify the collider associated with the character controller.
AzPhysics::CollisionGroups::Id m_collisionGroupId; //!< Which layers does this character collide with.
AzPhysics::CollisionLayer m_collisionLayer; //!< Which collision layer is this character on.
MaterialSelection m_materialSelection; //!< Material selected from library for the body associated with the character.
AZ::Vector3 m_upDirection = AZ::Vector3::CreateAxisZ(); //!< Up direction for character orientation and step behavior.
float m_maximumSlopeAngle = 30.0f; //!< The maximum slope on which the character can move, in degrees.
float m_stepHeight = 0.5f; //!< Affects what size steps the character can climb.
float m_minimumMovementDistance = 0.001f; //!< To avoid jittering, the controller will not attempt to move distances below this.
float m_maximumSpeed = 100.0f; //!< If the accumulated requested velocity for a tick exceeds this magnitude, it will be clamped.
AZStd::string m_colliderTag; //!< Used to identify the collider associated with the character controller.
AZStd::shared_ptr<Physics::ShapeConfiguration> m_shapeConfig = nullptr; //!< The shape to use when creating the character controller.
AZStd::vector<AZStd::shared_ptr<Physics::Shape>> m_colliders; //!< The list of colliders to attach to the character controller.
};
/// Basic implementation of common character-style needs as a WorldBody. Is not a full-functional ship-ready
@@ -88,7 +90,7 @@ namespace Physics
{
public:
AZ_CLASS_ALLOCATOR(Character, AZ::SystemAllocator, 0);
AZ_RTTI(Character, "{962E37A1-3401-4672-B896-0A6157CFAC97}", AzPhysics::SimulatedBody);
AZ_RTTI(Physics::Character, "{962E37A1-3401-4672-B896-0A6157CFAC97}", AzPhysics::SimulatedBody);
~Character() override = default;
@@ -29,7 +29,7 @@ namespace AzPhysics
struct SimulatedBodyConfiguration
{
AZ_CLASS_ALLOCATOR_DECL;
AZ_RTTI(SimulatedBodyConfiguration, "{52844E3D-79C8-4F34-AF63-5C45ADE77F85}");
AZ_RTTI(AzPhysics::SimulatedBodyConfiguration, "{52844E3D-79C8-4F34-AF63-5C45ADE77F85}");
static void Reflect(AZ::ReflectContext* context);
SimulatedBodyConfiguration() = default;
@@ -246,26 +246,6 @@ namespace Physics
using SystemRequests = System;
using SystemRequestBus = AZ::EBus<SystemRequests, SystemRequestsTraits>;
/// Physics character system global requests.
class CharacterSystemRequests
: public AZ::EBusTraits
{
public:
// EBusTraits
// singleton pattern
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
virtual ~CharacterSystemRequests() = default;
/// Creates the physics representation used to handle basic character interactions (also known as a character
/// controller).
virtual AZStd::unique_ptr<Character> CreateCharacter(const CharacterConfiguration& characterConfig,
const ShapeConfiguration& shapeConfig, AzPhysics::SceneHandle& sceneHandle) = 0;
};
typedef AZ::EBus<CharacterSystemRequests> CharacterSystemRequestBus;
/// Physics system global debug requests.
class SystemDebugRequests
: public AZ::EBusTraits
@@ -37,6 +37,7 @@ namespace AzFramework
// ViewportControllerInterface ...
bool HandleInputChannelEvent(const ViewportControllerInputEvent& event) override;
void ResetInputChannels() override;
void UpdateViewport(const ViewportControllerUpdateEvent& event) override;
void RegisterViewportContext(ViewportId viewport) override;
void UnregisterViewportContext(ViewportId viewport) override;
@@ -58,6 +59,7 @@ namespace AzFramework
ViewportId GetViewportId() const { return m_viewportId; }
virtual bool HandleInputChannelEvent([[maybe_unused]]const ViewportControllerInputEvent& event) { return false; }
virtual void ResetInputChannels() {}
virtual void UpdateViewport([[maybe_unused]]const ViewportControllerUpdateEvent& event) {}
private:
@@ -30,6 +30,15 @@ namespace AzFramework
return instanceIt->second->HandleInputChannelEvent(event);
}
template <class TViewportControllerInstance, ViewportControllerPriority Priority>
void MultiViewportController<TViewportControllerInstance, Priority>::ResetInputChannels()
{
for (auto instanceIt = m_instances.begin(); instanceIt != m_instances.end(); ++instanceIt)
{
instanceIt->second->ResetInputChannels();
}
}
template <class TViewportControllerInstance, ViewportControllerPriority Priority>
void MultiViewportController<TViewportControllerInstance, Priority>::UpdateViewport(const ViewportControllerUpdateEvent& event)
{
@@ -49,6 +49,11 @@ namespace AzFramework
bool ViewportControllerList::HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event)
{
if (!IsEnabled())
{
return false;
}
// If our event priority is "custom", we should dispatch at all priority levels in order
using AzFramework::ViewportControllerPriority;
if (event.m_priority == AzFramework::ViewportControllerPriority::DispatchToAllPriorities)
@@ -76,6 +81,23 @@ namespace AzFramework
}
}
void ViewportControllerList::ResetInputChannels()
{
// We don't need to send this while we're disabled, we're guaranteed to call ResetInputChannels after being re-enabled.
if (!IsEnabled())
{
return;
}
for (const auto& controllerList : m_controllers)
{
for (const auto& controller : controllerList.second)
{
controller->ResetInputChannels();
}
}
}
bool ViewportControllerList::DispatchInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event)
{
if (auto priorityListIt = m_controllers.find(event.m_priority); priorityListIt != m_controllers.end())
@@ -106,6 +128,11 @@ namespace AzFramework
void ViewportControllerList::UpdateViewport(const AzFramework::ViewportControllerUpdateEvent& event)
{
if (!IsEnabled())
{
return;
}
// If our event priority is "custom", we should dispatch at all priority levels in reverse order
// Reverse order lets high priority controllers get the last say in viewport update operations
using AzFramework::ViewportControllerPriority;
@@ -174,4 +201,22 @@ namespace AzFramework
}
}
}
bool ViewportControllerList::IsEnabled() const
{
return m_enabled;
}
void ViewportControllerList::SetEnabled(bool enabled)
{
if (m_enabled != enabled)
{
m_enabled = enabled;
// If we've been re-enabled, reset our input channels as they may have missed state changes.
if (m_enabled)
{
ResetInputChannels();
}
}
}
} //namespace AzFramework
@@ -37,6 +37,9 @@ namespace AzFramework
//! either a controller returns true to consume the event in OnInputChannelEvent or the controller list is exhausted.
//! InputChannelEvents are sent to controllers in priority order (from the lowest priority value to the highest).
bool HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event) override;
//! Dispatches a ResetInputChannels call to all controllers registered to this list.
//! Calls to controllers are made in an undefined order.
void ResetInputChannels() override;
//! Dispatches an update tick to all controllers registered to this list.
//! This occurs in *reverse* priority order (i.e. from the highest priority value to the lowest) so that
//! controllers with the highest registration priority may override the transforms of the controllers with the
@@ -50,6 +53,12 @@ namespace AzFramework
//! All ViewportControllerLists have a priority of Custom to ensure
//! that they receive events at all priorities from any parent controllers.
AzFramework::ViewportControllerPriority GetPriority() const { return ViewportControllerPriority::DispatchToAllPriorities; }
//! Returns true if this controller list is enabled, i.e.
//! it is accepting and forwarding input and update events to its children.
bool IsEnabled() const;
//! Set this controller list's enabled state.
//! If a controller list is disabled, it will ignore all input and update events rather than dispatching them to its children.
void SetEnabled(bool enabled);
private:
void SortControllers();
@@ -58,5 +67,6 @@ namespace AzFramework
AZStd::unordered_map<AzFramework::ViewportControllerPriority, AZStd::vector<ViewportControllerPtr>> m_controllers;
AZStd::unordered_set<ViewportId> m_viewports;
bool m_enabled = true;
};
} //namespace AzFramework
@@ -18,6 +18,8 @@
#include <AzCore/std/typetraits/is_enum.h>
#include <AzCore/RTTI/TypeInfo.h>
#include <AzCore/RTTI/TypeSafeIntegral.h>
#include <AzCore/Name/Name.h>
#include <AzCore/Name/NameDictionary.h>
namespace AzNetworking
{
@@ -173,6 +175,22 @@ namespace AzNetworking
return true;
}
};
template<>
struct SerializeObjectHelper<AZ::Name>
{
static bool SerializeObject(ISerializer& serializer, AZ::Name& value)
{
AZ::Name::Hash nameHash = value.GetHash();
bool result = serializer.Serialize(nameHash, "NameHash");
if (result && serializer.GetSerializerMode() == SerializerMode::WriteToObject)
{
value = AZ::NameDictionary::Instance().FindName(nameHash);
}
return result;
}
};
}
#include <AzNetworking/Serialization/AzContainerSerializers.h>
@@ -2298,6 +2298,12 @@ namespace AzQtComponents
OptimizedSetParent(dock, mainWindow);
mainWindow->addDockWidget(Qt::LeftDockWidgetArea, dock);
dock->show();
// Make sure we listen for events on the dock widget being put into a floating dock window
// because this might be called programmatically, so the dock widget might have never been
// parented to our m_mainWindow initially, so it won't already have an event filter,
// which will prevent the docking functionality from working.
dock->installEventFilter(this);
}
}
@@ -815,8 +815,6 @@ namespace AzToolsFramework
/// Hide or show the circular dependency error when saving slices
virtual void SetShowCircularDependencyError(const bool& /*showCircularDependencyError*/) {}
virtual void SetEditTool(const char* /*tool*/) {}
/// Launches the Lua editor and opens the specified (space separated) files.
virtual void LaunchLuaEditor(const char* /*files*/) {}
@@ -491,6 +491,14 @@ namespace AzToolsFramework
EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::OnStartPlayInEditorBegin);
//cache the current selected entities.
ToolsApplicationRequests::Bus::BroadcastResult(m_selectedBeforeStartingGame, &ToolsApplicationRequests::GetSelectedEntities);
//deselect entities if selected when entering game mode before deactivating the entities in StartPlayInEditor(...)
if (!m_selectedBeforeStartingGame.empty())
{
ToolsApplicationRequests::Bus::Broadcast(&ToolsApplicationRequests::MarkEntitiesDeselected, m_selectedBeforeStartingGame);
}
if (m_isLegacySliceService)
{
SliceEditorEntityOwnershipService* editorEntityOwnershipService =
@@ -507,8 +515,6 @@ namespace AzToolsFramework
m_isRunningGame = true;
ToolsApplicationRequests::Bus::BroadcastResult(m_selectedBeforeStartingGame, &ToolsApplicationRequests::GetSelectedEntities);
EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::OnStartPlayInEditor);
}
@@ -94,6 +94,7 @@ namespace AzToolsFramework
m_prefabSystemComponent->RemoveTemplate(templateId);
}
m_rootInstance->Reset();
m_rootInstance->SetContainerEntityName("Level");
AzFramework::EntityOwnershipServiceNotificationBus::Event(
m_entityContextId, &AzFramework::EntityOwnershipServiceNotificationBus::Events::OnEntityOwnershipServiceReset);
@@ -198,6 +199,7 @@ namespace AzToolsFramework
m_rootInstance->SetTemplateId(templateId);
m_rootInstance->SetTemplateSourcePath(m_loaderInterface->GetRelativePathToProject(filename));
m_rootInstance->SetContainerEntityName("Level");
m_prefabSystemComponent->PropagateTemplateChanges(templateId);
return true;
@@ -279,18 +281,29 @@ namespace AzToolsFramework
AZStd::unique_ptr<Prefab::Instance> createdPrefabInstance =
m_prefabSystemComponent->CreatePrefab(entities, AZStd::move(nestedPrefabInstances), filePath);
if (!instanceToParentUnder)
{
instanceToParentUnder = *m_rootInstance;
}
if (createdPrefabInstance)
{
if (!instanceToParentUnder)
{
instanceToParentUnder = *m_rootInstance;
}
Prefab::Instance& addedInstance = instanceToParentUnder->get().AddInstance(AZStd::move(createdPrefabInstance));
HandleEntitiesAdded({addedInstance.m_containerEntity.get()});
AZ::Entity* containerEntity = addedInstance.m_containerEntity.get();
containerEntity->AddComponent(aznew Prefab::EditorPrefabComponent());
HandleEntitiesAdded({containerEntity});
HandleEntitiesAdded(entities);
// Update the template of the instance since we modified the entities of the instance by calling HandleEntitiesAdded.
Prefab::PrefabDom serializedInstance;
if (Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(addedInstance, serializedInstance))
{
m_prefabSystemComponent->UpdatePrefabTemplate(addedInstance.GetTemplateId(), serializedInstance);
}
return addedInstance;
}
HandleEntitiesAdded(entities);
return AZStd::nullopt;
}
@@ -186,7 +186,7 @@ namespace AzToolsFramework
PlayInEditorData m_playInEditorData;
//////////////////////////////////////////////////////////////////////////
// PrefabSystemComponentInterface interface implementation
// PrefabEditorEntityOwnershipInterface implementation
Prefab::InstanceOptionalReference CreatePrefab(
const AZStd::vector<AZ::Entity*>& entities, AZStd::vector<AZStd::unique_ptr<Prefab::Instance>>&& nestedPrefabInstances,
AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder) override;
@@ -123,7 +123,11 @@ namespace AzToolsFramework
void Instance::SetTemplateSourcePath(AZ::IO::PathView sourcePath)
{
m_templateSourcePath = sourcePath;
m_containerEntity->SetName(sourcePath.Filename().Native());
}
void Instance::SetContainerEntityName(AZStd::string_view containerName)
{
m_containerEntity->SetName(containerName);
}
bool Instance::AddEntity(AZ::Entity& entity)
@@ -563,7 +567,7 @@ namespace AzToolsFramework
AZ::EntityId Instance::GetContainerEntityId() const
{
return m_containerEntity->GetId();
return m_containerEntity ? m_containerEntity->GetId() : AZ::EntityId();
}
bool Instance::HasContainerEntity() const
@@ -80,6 +80,7 @@ namespace AzToolsFramework
const AZ::IO::Path& GetTemplateSourcePath() const;
void SetTemplateSourcePath(AZ::IO::PathView sourcePath);
void SetContainerEntityName(AZStd::string_view containerName);
bool AddEntity(AZ::Entity& entity);
bool AddEntity(AZ::Entity& entity, EntityAlias entityAlias);
@@ -15,6 +15,7 @@
#include <AzCore/Component/TickBus.h>
#include <AzCore/Interface/Interface.h>
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzToolsFramework/Prefab/Instance/Instance.h>
#include <AzToolsFramework/Prefab/Instance/TemplateInstanceMapperInterface.h>
@@ -116,10 +117,24 @@ namespace AzToolsFramework
"Could not find Template using Id '%llu'. Unable to update Instance.",
currentTemplateId);
// Remove the instance from update queue if its corresponding template couldn't be found
isUpdateSuccessful = false;
m_instancesUpdateQueue.pop();
continue;
}
}
auto findInstancesResult = m_templateInstanceMapperInterface->FindInstancesOwnedByTemplate(instanceTemplateId)->get();
if (findInstancesResult.find(instanceToUpdate) == findInstancesResult.end())
{
// Since nested instances get reconstructed during propagation, remove any nested instance that no longer
// maps to a template.
isUpdateSuccessful = false;
m_instancesUpdateQueue.pop();
continue;
}
Template& currentTemplate = currentTemplateReference->get();
Instance::EntityList newEntities;
if (PrefabDomUtils::LoadInstanceFromPrefabDom(*instanceToUpdate, newEntities, currentTemplate.GetPrefabDom()))
@@ -139,9 +154,18 @@ namespace AzToolsFramework
}
m_instancesUpdateQueue.pop();
}
for (auto entityIdIterator = selectedEntityIds.begin(); entityIdIterator != selectedEntityIds.end(); entityIdIterator++)
{
// Since entities get recreated during propagation, we need to check whether the entities correspoding to the list
// of selected entity ids are present or not.
AZ::Entity* entity = GetEntityById(*entityIdIterator);
if (entity == nullptr)
{
selectedEntityIds.erase(entityIdIterator--);
}
}
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, selectedEntityIds);
// Enable the Outliner
@@ -15,15 +15,16 @@
#include <AzCore/Component/TransformBus.h>
#include <AzCore/Utils/TypeHash.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h>
#include <AzToolsFramework/Prefab/EditorPrefabComponent.h>
#include <AzToolsFramework/Prefab/Instance/Instance.h>
#include <AzToolsFramework/Prefab/Instance/InstanceEntityIdMapper.h>
#include <AzToolsFramework/Prefab/Instance/InstanceEntityMapperInterface.h>
#include <AzToolsFramework/Prefab/Instance/InstanceToTemplateInterface.h>
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
#include <AzToolsFramework/Prefab/PrefabLoaderInterface.h>
#include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
#include <AzToolsFramework/Prefab/PrefabUndo.h>
@@ -37,12 +38,14 @@ namespace AzToolsFramework
void PrefabPublicHandler::RegisterPrefabPublicHandlerInterface()
{
m_instanceEntityMapperInterface = AZ::Interface<InstanceEntityMapperInterface>::Get();
AZ_Assert(
m_instanceEntityMapperInterface, "PrefabPublicHandler - Could not retrieve instance of InstanceEntityMapperInterface");
AZ_Assert(m_instanceEntityMapperInterface, "PrefabPublicHandler - Could not retrieve instance of InstanceEntityMapperInterface");
m_instanceToTemplateInterface = AZ::Interface<InstanceToTemplateInterface>::Get();
AZ_Assert(m_instanceToTemplateInterface, "PrefabPublicHandler - Could not retrieve instance of InstanceToTemplateInterface");
m_prefabLoaderInterface = AZ::Interface<PrefabLoaderInterface>::Get();
AZ_Assert(m_prefabLoaderInterface, "Could not get PrefabLoaderInterface on PrefabPublicHandler construction.");
m_prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
AZ_Assert(m_prefabSystemComponentInterface, "Could not get PrefabSystemComponentInterface on PrefabPublicHandler construction.");
@@ -59,91 +62,160 @@ namespace AzToolsFramework
}
PrefabOperationResult PrefabPublicHandler::CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView filePath)
{
EntityList inputEntityList, topLevelEntities;
AZ::EntityId commonRootEntityId;
InstanceOptionalReference commonRootEntityOwningInstance;
PrefabOperationResult findCommonRootOutcome = FindCommonRootOwningInstance(
entityIds, inputEntityList, topLevelEntities, commonRootEntityId, commonRootEntityOwningInstance);
if (!findCommonRootOutcome.IsSuccess())
{
return findCommonRootOutcome;
}
InstanceOptionalReference instanceToCreate;
{
// Initialize Undo Batch object
ScopedUndoBatch undoBatch("Create Prefab");
PrefabDom commonRootInstanceDomBeforeCreate;
m_instanceToTemplateInterface->GenerateDomForInstance(
commonRootInstanceDomBeforeCreate, commonRootEntityOwningInstance->get());
AZStd::vector<AZ::Entity*> entities;
AZStd::vector<AZStd::unique_ptr<Instance>> instances;
// Retrieve all entities affected and identify Instances
if (!RetrieveAndSortPrefabEntitiesAndInstances(inputEntityList, commonRootEntityOwningInstance->get(), entities, instances))
{
return AZ::Failure(
AZStd::string("Could not create a new prefab out of the entities provided - entities do not share a common root."));
}
// When we create a prefab with other prefab instances, we have to remove the existing links between the source and
// target templates of the other instances.
for (auto& nestedInstance : instances)
{
PrefabUndoHelpers::RemoveLink(
nestedInstance->GetTemplateId(), commonRootEntityOwningInstance->get().GetTemplateId(),
nestedInstance->GetInstanceAlias(), nestedInstance->GetLinkId(), undoBatch.GetUndoBatch());
}
auto prefabEditorEntityOwnershipInterface = AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
if (!prefabEditorEntityOwnershipInterface)
{
return AZ::Failure(AZStd::string("Could not create a new prefab out of the entities provided - internal error "
"(PrefabEditorEntityOwnershipInterface unavailable)."));
}
// Create the Prefab
instanceToCreate = prefabEditorEntityOwnershipInterface->CreatePrefab(
entities, AZStd::move(instances), filePath, commonRootEntityOwningInstance);
if (!instanceToCreate)
{
return AZ::Failure(AZStd::string("Could not create a new prefab out of the entities provided - internal error "
"(A null instance is returned)."));
}
PrefabUndoHelpers::UpdatePrefabInstance(
commonRootEntityOwningInstance->get(), "Update prefab instance", commonRootInstanceDomBeforeCreate, undoBatch.GetUndoBatch());
CreateLink(
topLevelEntities, instanceToCreate->get(), commonRootEntityOwningInstance->get().GetTemplateId(), undoBatch.GetUndoBatch(),
commonRootEntityId);
AZ::EntityId containerEntityId = instanceToCreate->get().GetContainerEntityId();
// Change top level entities to be parented to the container entity
// Mark them as dirty so this change is correctly applied to the template
for (AZ::Entity* topLevelEntity : topLevelEntities)
{
m_prefabUndoCache.UpdateCache(topLevelEntity->GetId());
undoBatch.MarkEntityDirty(topLevelEntity->GetId());
AZ::TransformBus::Event(topLevelEntity->GetId(), &AZ::TransformBus::Events::SetParent, containerEntityId);
}
// Select Container Entity
{
auto selectionUndo = aznew SelectionCommand({containerEntityId}, "Select Prefab Container Entity");
selectionUndo->SetParent(undoBatch.GetUndoBatch());
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequestBus::Events::RunRedoSeparately, selectionUndo);
}
}
// Save Template to file
m_prefabLoaderInterface->SaveTemplate(instanceToCreate->get().GetTemplateId());
return AZ::Success();
}
PrefabOperationResult PrefabPublicHandler::FindCommonRootOwningInstance(
const AZStd::vector<AZ::EntityId>& entityIds, EntityList& inputEntityList, EntityList& topLevelEntities,
AZ::EntityId& commonRootEntityId, InstanceOptionalReference& commonRootEntityOwningInstance)
{
// Retrieve entityList from entityIds
EntityList inputEntityList = EntityIdListToEntityList(entityIds);
inputEntityList = EntityIdListToEntityList(entityIds);
// Find common root and top level entities
bool entitiesHaveCommonRoot = false;
AZ::EntityId commonRootEntityId;
EntityList topLevelEntities;
AzToolsFramework::ToolsApplicationRequests::Bus::BroadcastResult(
entitiesHaveCommonRoot,
&AzToolsFramework::ToolsApplicationRequests::FindCommonRootInactive,
inputEntityList,
commonRootEntityId,
&topLevelEntities
);
entitiesHaveCommonRoot, &AzToolsFramework::ToolsApplicationRequests::FindCommonRootInactive, inputEntityList,
commonRootEntityId, &topLevelEntities);
// Bail if entities don't share a common root
if (!entitiesHaveCommonRoot)
{
return AZ::Failure(AZStd::string("Could not create a new prefab out of the entities provided - entities do not share a common root."));
}
AZ::Entity* commonRootEntity = nullptr;
if (commonRootEntityId.IsValid())
{
commonRootEntity = GetEntityById(commonRootEntityId);
return AZ::Failure(AZStd::string("Failed to create a prefab: Provided entities do not share a common root."));
}
// Retrieve the owning instance of the common root entity, which will be our new instance's parent instance.
InstanceOptionalReference commonRootEntityOwningInstance = GetOwnerInstanceByEntityId(commonRootEntityId);
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");
AZStd::vector<AZ::Entity*> entities;
AZStd::vector<AZStd::unique_ptr<Instance>> instances;
// Retrieve all entities affected and identify Instances
if (!RetrieveAndSortPrefabEntitiesAndInstances(inputEntityList, commonRootEntityOwningInstance->get(), entities, instances))
commonRootEntityOwningInstance = GetOwnerInstanceByEntityId(commonRootEntityId);
if (!commonRootEntityOwningInstance)
{
return AZ::Failure(AZStd::string("Could not create a new prefab out of the entities provided - entities do not share a common root."));
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"));
}
return AZ::Success();
}
auto prefabEditorEntityOwnershipInterface = AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
if (!prefabEditorEntityOwnershipInterface)
{
return AZ::Failure(AZStd::string("Could not create a new prefab out of the entities provided - internal error "
"(PrefabEditorEntityOwnershipInterface unavailable)."));
}
void PrefabPublicHandler::CreateLink(
const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId,
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId)
{
AZ::EntityId containerEntityId = sourceInstance.GetContainerEntityId();
AZ::Entity* containerEntity = GetEntityById(containerEntityId);
Prefab::PrefabDom containerEntityDomBefore;
m_instanceToTemplateInterface->GenerateDomForEntity(containerEntityDomBefore, *containerEntity);
InstanceOptionalReference instance = prefabEditorEntityOwnershipInterface->CreatePrefab(
entities, AZStd::move(instances), filePath, commonRootEntityOwningInstance);
if (!instance)
{
return AZ::Failure(AZStd::string("Could not create a new prefab out of the entities provided - internal error "
"(A null instance is returned)."));
}
AZ::EntityId containerEntityId = instance->get().GetContainerEntityId();
AZ::Vector3 containerEntityTranslation(AZ::Vector3::CreateZero());
AZ::Quaternion containerEntityRotation(AZ::Quaternion::CreateZero());
// Set the transform (translation, rotation) of the container entity
GenerateContainerEntityTransform(topLevelEntities, containerEntityTranslation, containerEntityRotation);
// Set container entity to be child of common root
AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetParent, commonRootEntityId);
AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetLocalTranslation, containerEntityTranslation);
AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetLocalRotationQuaternion, containerEntityRotation);
// Set container entity to be child of common root
AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetParent, commonRootEntityId);
// Assign the EditorPrefabComponent to the instance container
EntityCompositionRequests::AddComponentsOutcome outcome;
EntityCompositionRequestBus::BroadcastResult(
outcome, &EntityCompositionRequests::AddComponentsToEntities, EntityIdList{containerEntityId},
AZ::ComponentTypeList{azrtti_typeid<AzToolsFramework::Prefab::EditorPrefabComponent>()});
// Change top level entities to be parented to the container entity
for (AZ::Entity* topLevelEntity : topLevelEntities)
{
AZ::TransformBus::Event(topLevelEntity->GetId(), &AZ::TransformBus::Events::SetParent, containerEntityId);
}
return AZ::Success();
PrefabDom containerEntityDomAfter;
m_instanceToTemplateInterface->GenerateDomForEntity(containerEntityDomAfter, *containerEntity);
PrefabDom patch;
m_instanceToTemplateInterface->GeneratePatch(patch, containerEntityDomBefore, containerEntityDomAfter);
m_instanceToTemplateInterface->AppendEntityAliasToPatchPaths(patch, containerEntityId);
PrefabUndoHelpers::CreateLink(
sourceInstance.GetTemplateId(), targetTemplateId, patch, sourceInstance.GetInstanceAlias(),
undoBatch);
// Update the cache - this prevents these changes from being stored in the regular undo/redo nodes
m_prefabUndoCache.Store(containerEntityId, AZStd::move(containerEntityDomAfter));
}
PrefabOperationResult PrefabPublicHandler::InstantiatePrefab(AZStd::string_view /*filePath*/, AZ::EntityId /*parent*/, AZ::Vector3 /*position*/)
@@ -173,14 +245,7 @@ namespace AzToolsFramework
AZStd::string("SavePrefab - Path error. Path could be invalid, or the prefab may not be loaded in this level."));
}
auto prefabLoaderInterface = AZ::Interface<PrefabLoaderInterface>::Get();
if (prefabLoaderInterface == nullptr)
{
return AZ::Failure(AZStd::string(
"Could not save prefab - internal error (PrefabLoaderInterface unavailable)."));
}
if (!prefabLoaderInterface->SaveTemplate(templateId))
if (!m_prefabLoaderInterface->SaveTemplate(templateId))
{
return AZ::Failure(AZStd::string("Could not save prefab - internal error (Json write operation failure)."));
}
@@ -261,13 +326,13 @@ namespace AzToolsFramework
if (instanceOptionalReference.has_value())
{
PrefabDom beforeState;
m_prefabUndoCache.Retrieve(entityId, beforeState);
PrefabDom afterState;
AZ::Entity* entity = GetEntityById(entityId);
if (entity)
{
PrefabDom beforeState;
m_prefabUndoCache.Retrieve(entityId, beforeState);
m_instanceToTemplateInterface->GenerateDomForEntity(afterState, *entity);
PrefabDom patch;
@@ -286,7 +351,10 @@ namespace AzToolsFramework
// Update the cache
m_prefabUndoCache.Store(entityId, AZStd::move(afterState));
}
else
{
m_prefabUndoCache.PurgeCache(entityId);
}
}
}
@@ -653,7 +721,7 @@ namespace AzToolsFramework
InstanceOptionalReference owningInstance = m_instanceEntityMapperInterface->FindOwningInstance(entity->GetId());
AZ_Assert(
owningInstance.has_value(),
"An error occored while retrieving entities and prefab instances : "
"An error occurred while retrieving entities and prefab instances : "
"Owning instance of entity with id '%llu' couldn't be found",
entity->GetId());
@@ -737,7 +805,7 @@ namespace AzToolsFramework
{
AZ_Assert(
false,
"An error occored in function EntitiesBelongToSameInstance: "
"An error occurred in function EntitiesBelongToSameInstance: "
"Owning instance of entity with id '%llu' couldn't be found",
entityId);
return false;
@@ -27,8 +27,10 @@ namespace AzToolsFramework
namespace Prefab
{
class Instance;
class InstanceEntityMapperInterface;
class InstanceToTemplateInterface;
class PrefabLoaderInterface;
class PrefabSystemComponentInterface;
class PrefabPublicHandler final
@@ -67,12 +69,40 @@ namespace AzToolsFramework
InstanceOptionalReference GetOwnerInstanceByEntityId(AZ::EntityId entityId) const;
bool EntitiesBelongToSameInstance(const EntityIdList& entityIds) const;
/**
* Creates a link between the templates of an instance and its parent.
*
* \param topLevelEntities The list of entities that are immediate children to the container entity of the instance.
* \param sourceInstance The instance that corresponds to the source template of the link.
* \param targetInstance The id of the target template.
* \param undoBatch The undo batch to set as parent for this create link action.
* \param commonRootEntityId The id of the entity that the source instance should be parented under.
*/
void CreateLink(
const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId,
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId);
/**
* Given a list of entityIds, finds the prefab instance that owns the common root entity of the entityIds.
*
* \param entityIds The list of entity ids.
* \param inputEntityList The list of entities corresponding to the entity ids.
* \param topLevelEntities The list of entities that are immediate children of the common root entity.
* \param commonRootEntityId The entity id of the common root entity of all the entityIds.
* \param commonRootEntityOwningInstance The owning instance of the common root entity.
* \return PrefabOperationResult indicating whether the action was successful or not.
*/
PrefabOperationResult FindCommonRootOwningInstance(
const AZStd::vector<AZ::EntityId>& entityIds, EntityList& inputEntityList, EntityList& topLevelEntities,
AZ::EntityId& commonRootEntityId, InstanceOptionalReference& commonRootEntityOwningInstance);
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);
InstanceEntityMapperInterface* m_instanceEntityMapperInterface = nullptr;
InstanceToTemplateInterface* m_instanceToTemplateInterface = nullptr;
PrefabLoaderInterface* m_prefabLoaderInterface = nullptr;
PrefabSystemComponentInterface* m_prefabSystemComponentInterface = nullptr;
// Caches entity states for undo/redo purposes
@@ -104,7 +104,6 @@ namespace AzToolsFramework
return nullptr;
}
AZStd::unique_ptr<Instance> newInstance = AZStd::make_unique<Instance>(AZStd::move(containerEntity));
for (AZ::Entity* entity : entities)
@@ -122,6 +121,7 @@ namespace AzToolsFramework
}
newInstance->SetTemplateSourcePath(relativeFilePath);
newInstance->SetContainerEntityName(relativeFilePath.Stem().Native());
TemplateId newTemplateId = CreateTemplateFromInstance(*newInstance);
if (newTemplateId == InvalidTemplateId)
@@ -142,7 +142,6 @@ namespace AzToolsFramework
void PrefabSystemComponent::PropagateTemplateChanges(TemplateId templateId)
{
UpdatePrefabInstances(templateId);
auto templateIdToLinkIdsIterator = m_templateToLinkIdsMap.find(templateId);
if (templateIdToLinkIdsIterator != m_templateToLinkIdsMap.end())
{
@@ -153,15 +152,24 @@ namespace AzToolsFramework
templateIdToLinkIdsIterator->second.end()));
UpdateLinkedInstances(linkIdsToUpdateQueue);
}
else
{
UpdatePrefabInstances(templateId);
}
}
void PrefabSystemComponent::UpdatePrefabTemplate(TemplateId templateId, const PrefabDom& updatedDom)
{
PrefabDom& templateDomToUpdate = FindTemplateDom(templateId);
if (AZ::JsonSerialization::Compare(templateDomToUpdate, updatedDom) != AZ::JsonSerializerCompareResult::Equal)
auto templateToUpdate = FindTemplate(templateId);
if (templateToUpdate)
{
templateDomToUpdate.CopyFrom(updatedDom, templateDomToUpdate.GetAllocator());
PropagateTemplateChanges(templateId);
PrefabDom& templateDomToUpdate = templateToUpdate->get().GetPrefabDom();
if (AZ::JsonSerialization::Compare(templateDomToUpdate, updatedDom) != AZ::JsonSerializerCompareResult::Equal)
{
templateDomToUpdate.CopyFrom(updatedDom, templateDomToUpdate.GetAllocator());
templateToUpdate->get().MarkAsDirty(true);
PropagateTemplateChanges(templateId);
}
}
}
@@ -615,7 +623,12 @@ namespace AzToolsFramework
instancesValue = memberFound->value;
}
instancesValue->get().AddMember(rapidjson::StringRef(instanceAlias.c_str()), PrefabDomValue(), targetTemplateDom.GetAllocator());
// Only add the instance if it's not there already
if (instancesValue->get().FindMember(rapidjson::StringRef(instanceAlias.c_str())) == instancesValue->get().MemberEnd())
{
instancesValue->get().AddMember(
rapidjson::StringRef(instanceAlias.c_str()), PrefabDomValue(), targetTemplateDom.GetAllocator());
}
Template& sourceTemplate = sourceTemplateRef->get();
@@ -124,7 +124,7 @@ namespace AzToolsFramework
const TemplateId& targetId,
const TemplateId& sourceId,
const InstanceAlias& instanceAlias,
const PrefabDomReference linkDom,
PrefabDomReference linkDom,
const LinkId linkId)
{
m_targetId = targetId;
@@ -101,7 +101,7 @@ namespace AzToolsFramework
const TemplateId& targetId,
const TemplateId& sourceId,
const InstanceAlias& instanceAlias,
const PrefabDomReference linkDom = PrefabDomReference(),
PrefabDomReference linkDom = PrefabDomReference(),
const LinkId linkId = InvalidLinkId);
void Undo() override;
@@ -32,6 +32,28 @@ namespace AzToolsFramework
state->SetParent(undoBatch);
state->Redo();
}
void CreateLink(
TemplateId sourceTemplateId, TemplateId targetTemplateId, PrefabDomReference patch,
const InstanceAlias& instanceAlias, UndoSystem::URSequencePoint* undoBatch)
{
auto linkAddUndo = aznew PrefabUndoInstanceLink("Create Link");
linkAddUndo->Capture(targetTemplateId, sourceTemplateId, instanceAlias, patch, InvalidLinkId);
linkAddUndo->SetParent(undoBatch);
linkAddUndo->Redo();
}
void RemoveLink(
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias,
LinkId linkId, UndoSystem::URSequencePoint* undoBatch)
{
auto linkRemoveUndo = aznew PrefabUndoInstanceLink("Remove Link");
PrefabDom emptyLinkDom;
linkRemoveUndo->Capture(
targetTemplateId, sourceTemplateId, instanceAlias, emptyLinkDom, linkId);
linkRemoveUndo->SetParent(undoBatch);
linkRemoveUndo->Redo();
}
}
} // namespace Prefab
} // namespace AzToolsFramework
@@ -21,6 +21,12 @@ namespace AzToolsFramework
void UpdatePrefabInstance(
const Instance& instance, AZStd::string_view undoMessage, const PrefabDom& instanceDomBeforeUpdate,
UndoSystem::URSequencePoint* undoBatch);
void CreateLink(
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);
}
} // namespace Prefab
} // namespace AzToolsFramework
@@ -61,6 +61,11 @@ namespace AzToolsFramework
return true;
}
bool EditorEntityUiHandlerBase::CanRename(AZ::EntityId /*entityId*/) const
{
return true;
}
void EditorEntityUiHandlerBase::PaintItemBackground(QPainter* /*painter*/, const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/) const
{
}
@@ -47,6 +47,8 @@ namespace AzToolsFramework
virtual QPixmap GenerateItemIcon(AZ::EntityId entityId) const;
//! Returns whether the element's lock and visibility state should be accessible in the Outliner
virtual bool CanToggleLockVisibility(AZ::EntityId entityId) const;
//! Returns whether the element's name should be editable
virtual bool CanRename(AZ::EntityId entityId) const;
//! Paints the background of the item in the Outliner.
virtual void PaintItemBackground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
@@ -945,6 +945,12 @@ namespace AzToolsFramework
return false;
}
// Disable reparenting to the root level
if (!newParentId.IsValid())
{
return false;
}
// Ignore entities not owned by the editor context. It is assumed that all entities belong
// to the same context since multiple selection doesn't span across views.
for (const AZ::EntityId& entityId : selectedEntityIds)
@@ -974,39 +980,33 @@ namespace AzToolsFramework
}
}
if (newParentId.IsValid())
bool isLayerEntity = false;
Layers::EditorLayerComponentRequestBus::EventResult(
isLayerEntity,
entityId,
&Layers::EditorLayerComponentRequestBus::Events::HasLayer);
// Layers can only have other layers as parents, or have no parent.
if (isLayerEntity)
{
bool isLayerEntity = false;
bool newParentIsLayer = false;
Layers::EditorLayerComponentRequestBus::EventResult(
isLayerEntity,
entityId,
newParentIsLayer,
newParentId,
&Layers::EditorLayerComponentRequestBus::Events::HasLayer);
// Layers can only have other layers as parents, or have no parent.
if (isLayerEntity)
if (!newParentIsLayer)
{
bool newParentIsLayer = false;
Layers::EditorLayerComponentRequestBus::EventResult(
newParentIsLayer,
newParentId,
&Layers::EditorLayerComponentRequestBus::Events::HasLayer);
if (!newParentIsLayer)
{
return false;
}
return false;
}
}
}
//Only check the entity pointer if the entity id is valid because
//we want to allow dragging items to unoccupied parts of the tree to un-parent them
if (newParentId.IsValid())
AZ::Entity* newParentEntity = nullptr;
AZ::ComponentApplicationBus::BroadcastResult(newParentEntity, &AZ::ComponentApplicationRequests::FindEntity, newParentId);
if (!newParentEntity)
{
AZ::Entity* newParentEntity = nullptr;
AZ::ComponentApplicationBus::BroadcastResult(newParentEntity, &AZ::ComponentApplicationRequests::FindEntity, newParentId);
if (!newParentEntity)
{
return false;
}
return false;
}
//reject dragging on to yourself or your children
@@ -30,6 +30,7 @@
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
#include <AzToolsFramework/UI/ComponentPalette/ComponentPaletteUtil.hxx>
#include <AzToolsFramework/UI/EditorEntityUi/EditorEntityUiHandlerBase.h>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerDisplayOptionsMenu.h>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerListModel.hxx>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerSortFilterProxyModel.hxx>
@@ -271,6 +272,12 @@ namespace AzToolsFramework
m_listModel->Initialize();
m_editorEntityUiInterface = AZ::Interface<AzToolsFramework::EditorEntityUiInterface>::Get();
AZ_Assert(
m_editorEntityUiInterface != nullptr,
"EntityOutlinerWidget requires a EditorEntityUiInterface instance on Initialize.");
EditorPickModeNotificationBus::Handler::BusConnect(GetEntityContextId());
EntityHighlightMessages::Bus::Handler::BusConnect();
EntityOutlinerModelNotificationBus::Handler::BusConnect();
@@ -562,7 +569,13 @@ namespace AzToolsFramework
if (m_selectedEntityIds.size() == 1)
{
contextMenu->addAction(m_actionToRenameSelection);
auto entityId = m_selectedEntityIds.front();
auto entityUiHandler = m_editorEntityUiInterface->GetHandler(entityId);
if (!entityUiHandler || entityUiHandler->CanRename(entityId))
{
contextMenu->addAction(m_actionToRenameSelection);
}
}
if (m_selectedEntityIds.size() == 1)
@@ -688,11 +701,17 @@ namespace AzToolsFramework
if (m_selectedEntityIds.size() == 1)
{
const QModelIndex proxyIndex = GetIndexFromEntityId(m_selectedEntityIds.front());
if (proxyIndex.isValid())
auto entityId = m_selectedEntityIds.front();
auto entityUiHandler = m_editorEntityUiInterface->GetHandler(entityId);
if (!entityUiHandler || entityUiHandler->CanRename(entityId))
{
m_gui->m_objectTree->setCurrentIndex(proxyIndex);
m_gui->m_objectTree->QTreeView::edit(proxyIndex);
const QModelIndex proxyIndex = GetIndexFromEntityId(entityId);
if (proxyIndex.isValid())
{
m_gui->m_objectTree->setCurrentIndex(proxyIndex);
m_gui->m_objectTree->QTreeView::edit(proxyIndex);
}
}
}
}
@@ -42,6 +42,7 @@ namespace Ui
namespace AzToolsFramework
{
class EditorEntityUiInterface;
class EntityOutlinerListModel;
class EntityOutlinerSortFilterProxyModel;
@@ -193,6 +194,8 @@ namespace AzToolsFramework
EntityIdSet m_entitiesToSort;
EntityOutliner::DisplaySortMode m_sortMode;
bool m_sortContentQueued;
EditorEntityUiInterface* m_editorEntityUiInterface = nullptr;
};
}
@@ -50,11 +50,31 @@ namespace AzToolsFramework
return QPixmap(m_levelRootIconPath);
}
QString LevelRootUiHandler::GenerateItemInfoString(AZ::EntityId entityId) const
{
QString infoString;
AZ::IO::Path path = m_prefabPublicInterface->GetOwningInstancePrefabPath(entityId);
if (!path.empty())
{
infoString =
QObject::tr("<span style=\"font-style: italic; font-weight: 400;\">(%1)</span>").arg(path.Filename().Native().data());
}
return infoString;
}
bool LevelRootUiHandler::CanToggleLockVisibility(AZ::EntityId /*entityId*/) const
{
return false;
}
bool LevelRootUiHandler::CanRename(AZ::EntityId /*entityId*/) const
{
return false;
}
void LevelRootUiHandler::PaintItemBackground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& /*index*/) const
{
if (!painter)
@@ -34,7 +34,9 @@ namespace AzToolsFramework
// EditorEntityUiHandler...
QPixmap GenerateItemIcon(AZ::EntityId entityId) const override;
QString GenerateItemInfoString(AZ::EntityId entityId) const override;
bool CanToggleLockVisibility(AZ::EntityId entityId) const override;
bool CanRename(AZ::EntityId entityId) const override;
void PaintItemBackground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
private:
@@ -310,6 +310,9 @@ namespace AzToolsFramework
{
initEntityPropertyEditorResources();
m_prefabPublicInterface = AZ::Interface<Prefab::PrefabPublicInterface>::Get();
AZ_Assert(m_prefabPublicInterface != nullptr, "EntityPropertyEditor requires a PrefabPublicInterface instance on Initialize.");
setObjectName("EntityPropertyEditor");
setAcceptDrops(true);
@@ -405,8 +408,6 @@ namespace AzToolsFramework
CreateActions();
UpdateContents();
m_prefabPublicInterface = AZ::Interface<Prefab::PrefabPublicInterface>::Get();
EditorEntityContextNotificationBus::Handler::BusConnect();
//forced to register global event filter with application for selection
@@ -693,11 +694,38 @@ namespace AzToolsFramework
m_gui->m_entityIcon->repaint();
}
EntityPropertyEditor::InspectorLayout EntityPropertyEditor::GetCurrentInspectorLayout() const
{
if (!m_prefabsAreEnabled)
{
return m_isLevelEntityEditor ? InspectorLayout::LEVEL : InspectorLayout::ENTITY;
}
AZ::EntityId levelContainerEntityId = m_prefabPublicInterface->GetLevelInstanceContainerEntityId();
if (AZStd::find(m_selectedEntityIds.begin(), m_selectedEntityIds.end(), levelContainerEntityId) != m_selectedEntityIds.end())
{
if (m_selectedEntityIds.size() > 1)
{
return InspectorLayout::INVALID;
}
else
{
return InspectorLayout::LEVEL;
}
}
else
{
return InspectorLayout::ENTITY;
}
}
void EntityPropertyEditor::UpdateEntityDisplay()
{
UpdateStatusComboBox();
if (m_isLevelEntityEditor)
InspectorLayout layout = GetCurrentInspectorLayout();
if (layout == InspectorLayout::LEVEL)
{
AZStd::string levelName;
AzToolsFramework::EditorRequestBus::BroadcastResult(levelName, &AzToolsFramework::EditorRequests::GetLevelName);
@@ -737,13 +765,20 @@ namespace AzToolsFramework
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
SelectionEntityTypeInfo result = SelectionEntityTypeInfo::None;
if (m_isLevelEntityEditor)
InspectorLayout layout = GetCurrentInspectorLayout();
if (layout == InspectorLayout::LEVEL)
{
// The Level Inspector should only have a list of selectable components after the
// level entity itself is valid (i.e. "selected").
return selection.empty() ? SelectionEntityTypeInfo::None : SelectionEntityTypeInfo::LevelEntity;
}
if (layout == InspectorLayout::INVALID)
{
return SelectionEntityTypeInfo::Mixed;
}
for (AZ::EntityId selectedEntityId : selection)
{
bool isLayerEntity = false;
@@ -909,16 +944,18 @@ namespace AzToolsFramework
}
}
bool isLevelLayout = GetCurrentInspectorLayout() == InspectorLayout::LEVEL;
m_gui->m_entityDetailsLabel->setText(entityDetailsLabelText);
m_gui->m_entityDetailsLabel->setVisible(entityDetailsVisible);
m_gui->m_entityNameEditor->setVisible(hasEntitiesDisplayed);
m_gui->m_entityNameLabel->setVisible(hasEntitiesDisplayed);
m_gui->m_entityIcon->setVisible(hasEntitiesDisplayed);
m_gui->m_pinButton->setVisible(m_overrideSelectedEntityIds.empty() && hasEntitiesDisplayed && !m_isSystemEntityEditor && !m_isLevelEntityEditor);
m_gui->m_statusLabel->setVisible(hasEntitiesDisplayed && !m_isSystemEntityEditor && !m_isLevelEntityEditor);
m_gui->m_statusComboBox->setVisible(hasEntitiesDisplayed && !m_isSystemEntityEditor && !m_isLevelEntityEditor);
m_gui->m_entityIdLabel->setVisible(hasEntitiesDisplayed && !m_isSystemEntityEditor && !m_isLevelEntityEditor);
m_gui->m_entityIdText->setVisible(hasEntitiesDisplayed && !m_isSystemEntityEditor && !m_isLevelEntityEditor);
m_gui->m_pinButton->setVisible(m_overrideSelectedEntityIds.empty() && hasEntitiesDisplayed && !m_isSystemEntityEditor);
m_gui->m_statusLabel->setVisible(hasEntitiesDisplayed && !m_isSystemEntityEditor && !isLevelLayout);
m_gui->m_statusComboBox->setVisible(hasEntitiesDisplayed && !m_isSystemEntityEditor && !isLevelLayout);
m_gui->m_entityIdLabel->setVisible(hasEntitiesDisplayed && !m_isSystemEntityEditor && !isLevelLayout);
m_gui->m_entityIdText->setVisible(hasEntitiesDisplayed && !m_isSystemEntityEditor && !isLevelLayout);
bool displayComponentSearchBox = hasEntitiesDisplayed;
if (hasEntitiesDisplayed)
@@ -941,7 +978,7 @@ namespace AzToolsFramework
UpdateEntityDisplay();
}
m_gui->m_darkBox->setVisible(displayComponentSearchBox && !m_isSystemEntityEditor && !m_isLevelEntityEditor);
m_gui->m_darkBox->setVisible(displayComponentSearchBox && !m_isSystemEntityEditor && !isLevelLayout);
m_gui->m_entitySearchBox->setVisible(displayComponentSearchBox);
bool displayAddComponentMenu = CanAddComponentsToSelection(selectionEntityTypeInfo);
@@ -521,6 +521,15 @@ namespace AzToolsFramework
bool m_isSystemEntityEditor;
bool m_isLevelEntityEditor = false;
enum class InspectorLayout
{
ENTITY = 0, // All selected entities are regular entities
LEVEL, // The selected entity is the level prefab container entity
INVALID // Other entities are selected alongside the level prefab container entity
};
InspectorLayout GetCurrentInspectorLayout() const;
// the spacer's job is to make sure that its always at the end of the list of components.
QSpacerItem* m_spacer;
bool m_isAlreadyQueuedRefresh;
-6
View File
@@ -20,7 +20,6 @@
#include "2DViewport.h"
#include "CryEditDoc.h"
#include "DisplaySettings.h"
#include "EditTool.h"
#include "GameEngine.h"
#include "Settings.h"
#include "ViewManager.h"
@@ -1117,11 +1116,6 @@ void Q2DViewport::DrawObjects(DisplayContext& dc)
GetIEditor()->GetObjectManager()->Display(dc);
}
// Display editing tool.
if (GetEditTool())
{
GetEditTool()->Display(dc);
}
dc.PopMatrix();
}
@@ -1,588 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "EditorDefs.h"
#include "QRollupCtrl.h"
// Qt
#include <QMenu>
#include <QStylePainter>
#include <QVBoxLayout>
#include <QSettings>
#include <QToolButton>
#include <QStyleOptionToolButton>
//////////////////////////////////////////////////////////////////////////
class QRollupCtrlButton
: public QToolButton
{
public:
QRollupCtrlButton(QWidget* parent);
inline void setSelected(bool b) { selected = b; update(); }
inline bool isSelected() const { return selected; }
QSize sizeHint() const override;
QSize minimumSizeHint() const override;
protected:
void paintEvent(QPaintEvent*) override;
private:
bool selected;
};
QRollupCtrlButton::QRollupCtrlButton(QWidget* parent)
: QToolButton(parent)
, selected(true)
{
setBackgroundRole(QPalette::Window);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
setFocusPolicy(Qt::NoFocus);
setStyleSheet("* {margin: 2px 5px 2px 5px; border: 1px solid #CBA457;}");
}
QSize QRollupCtrlButton::sizeHint() const
{
QSize iconSize(8, 8);
if (!icon().isNull())
{
int icone = style()->pixelMetric(QStyle::PM_SmallIconSize);
iconSize += QSize(icone + 2, icone);
}
QSize textSize = fontMetrics().size(Qt::TextShowMnemonic, text()) + QSize(0, 8);
QSize total(iconSize.width() + textSize.width(), qMax(iconSize.height(), textSize.height()));
return total.expandedTo(QApplication::globalStrut());
}
QSize QRollupCtrlButton::minimumSizeHint() const
{
if (icon().isNull())
{
return QSize();
}
int icone = style()->pixelMetric(QStyle::PM_SmallIconSize);
return QSize(icone + 8, icone + 8);
}
void QRollupCtrlButton::paintEvent(QPaintEvent*)
{
QStylePainter p(this);
// draw the background manually, not to clash with UI 2.0 style shets
// the numbers here are taken from the stylesheet in the constructor
p.fillRect(QRect(5, 1, width() - 10, height() - 3), QColor(52, 52, 52));
{
QStyleOptionToolButton opt;
initStyleOption(&opt);
if (isSelected())
{
if (opt.state & QStyle::State_MouseOver)
{
opt.state |= QStyle::State_Sunken;
}
opt.state |= QStyle::State_MouseOver;
}
p.drawComplexControl(QStyle::CC_ToolButton, opt);
}
{
p.setPen(QPen(QColor(132, 128, 125)));
int top = height() / 2 - 2;
p.drawLine(2, top, 4, top);
p.drawLine(width() - 5, top, width() - 3, top);
int bottom = !isSelected() ? top + 4 : height();
p.drawLine(2, bottom, 2, top);
p.drawLine(width() - 3, bottom, width() - 3, top);
if (!isSelected())
{
p.drawLine(2, bottom, 4, bottom);
p.drawLine(width() - 5, bottom, width() - 3, bottom);
}
}
}
//////////////////////////////////////////////////////////////////////////
QRollupCtrl::Page* QRollupCtrl::page(QWidget* widget) const
{
if (!widget)
{
return 0;
}
for (PageList::ConstIterator i = m_pageList.constBegin(); i != m_pageList.constEnd(); ++i)
{
if ((*i).widget == widget)
{
return (Page*)&(*i);
}
}
return 0;
}
QRollupCtrl::Page* QRollupCtrl::page(int index)
{
if (index >= 0 && index < m_pageList.size())
{
return &m_pageList[index];
}
return 0;
}
const QRollupCtrl::Page* QRollupCtrl::page(int index) const
{
if (index >= 0 && index < m_pageList.size())
{
return &m_pageList.at(index);
}
return 0;
}
inline void QRollupCtrl::Page::setText(const QString& text) { button->setText(text); }
inline void QRollupCtrl::Page::setIcon(const QIcon& is) { button->setIcon(is); }
inline void QRollupCtrl::Page::setToolTip(const QString& tip) { button->setToolTip(tip); }
inline QString QRollupCtrl::Page::text() const { return button->text(); }
inline QIcon QRollupCtrl::Page::icon() const { return button->icon(); }
inline QString QRollupCtrl::Page::toolTip() const { return button->toolTip(); }
//////////////////////////////////////////////////////////////////////////
QRollupCtrl::QRollupCtrl(QWidget* parent)
: QScrollArea(parent)
, m_layout(0)
{
m_body = new QWidget(this);
m_body->setBackgroundRole(QPalette::Button);
setWidgetResizable(true);
setAlignment(Qt::AlignLeft | Qt::AlignTop);
setWidget(m_body);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
relayout();
}
QRollupCtrl::~QRollupCtrl()
{
foreach(const QRollupCtrl::Page & c, m_pageList)
disconnect(c.widget, &QObject::destroyed, this, &QRollupCtrl::_q_widgetDestroyed);
}
void QRollupCtrl::readSettings(const QString& qSettingsGroup)
{
QSettings settings;
settings.beginGroup(qSettingsGroup);
int i = 0;
foreach(const QRollupCtrl::Page & c, m_pageList) {
QString qObjectName = c.widget->objectName();
bool bHidden = settings.value(qObjectName, true).toBool();
setIndexVisible(i++, !bHidden);
}
settings.endGroup();
}
void QRollupCtrl::writeSettings(const QString& qSettingsGroup)
{
QSettings settings;
settings.beginGroup(qSettingsGroup);
for (int i = 0; i < count(); i++)
{
QString qObjectName;
bool bHidden = isPageHidden(i, qObjectName);
settings.setValue(qObjectName, bHidden);
}
}
void QRollupCtrl::updateTabs()
{
for (auto i = m_pageList.constBegin(); i != m_pageList.constEnd(); ++i)
{
QRollupCtrlButton* tB = (*i).button;
QWidget* tW = (*i).sv;
tB->setSelected(tW->isVisible());
tB->update();
}
}
int QRollupCtrl::insertItem(int index, QWidget* widget, const QIcon& icon, const QString& text)
{
if (!widget)
{
return -1;
}
auto it = std::find_if(m_pageList.cbegin(), m_pageList.cend(), [widget](const Page& page) { return page.widget == widget; });
if (it != m_pageList.cend())
{
return -1;
}
connect(widget, &QObject::destroyed, this, &QRollupCtrl::_q_widgetDestroyed);
QRollupCtrl::Page c;
c.widget = widget;
c.button = new QRollupCtrlButton(m_body);
c.button->setContextMenuPolicy(Qt::CustomContextMenu);
connect(c.button, &QRollupCtrlButton::clicked, this, &QRollupCtrl::_q_buttonClicked);
connect(c.button, &QRollupCtrlButton::customContextMenuRequested, this, &QRollupCtrl::_q_custumButtonMenu);
c.sv = new QFrame(m_body);
c.sv->setObjectName("rollupPaneFrame");
// c.sv->setFixedHeight(qMax(widget->sizeHint().height(), widget->size().height()));
QVBoxLayout* layout = new QVBoxLayout;
layout->setMargin(3);
layout->addWidget(widget);
c.sv->setLayout(layout);
c.sv->setStyleSheet("QFrame#rollupPaneFrame {margin: 0px 2px 2px 2px; border: 1px solid #84807D; border-top:0px;}");
c.sv->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
c.sv->show();
c.setText(text);
c.setIcon(icon);
const int numPages = m_pageList.count();
if (index < 0 || index >= numPages)
{
m_pageList.append(c);
index = numPages - 1;
m_layout->insertWidget(m_layout->count() - 1, c.button);
m_layout->insertWidget(m_layout->count() - 1, c.sv);
}
else
{
m_pageList.insert(index, c);
relayout();
}
c.button->show();
updateTabs();
itemInserted(index);
return index;
}
void QRollupCtrl::_q_buttonClicked()
{
QObject* tb = sender();
QWidget* item = 0;
for (auto i = m_pageList.constBegin(); i != m_pageList.constEnd(); ++i)
{
if ((*i).button == tb)
{
item = (*i).widget;
break;
}
}
if (item)
{
setIndexVisible(indexOf(item), !item->isVisible());
}
}
int QRollupCtrl::count() const
{
return m_pageList.count();
}
bool QRollupCtrl::isPageHidden(int index, QString& qObjectName) const
{
if (index < 0 || index >= m_pageList.size())
{
return true;
}
const QRollupCtrl::Page& c = m_pageList.at(index);
qObjectName = c.widget->objectName();
return c.sv->isHidden();
}
void QRollupCtrl::setIndexVisible(int index, bool visible)
{
QRollupCtrl::Page* c = page(index);
if (!c)
{
return;
}
if (c->sv->isHidden() && visible)
{
c->sv->show();
}
else if (c->sv->isVisible() && !visible)
{
c->sv->hide();
}
updateTabs();
}
void QRollupCtrl::setWidgetVisible(QWidget* widget, bool visible)
{
setIndexVisible(indexOf(widget), visible);
}
void QRollupCtrl::relayout()
{
delete m_layout;
m_layout = new QVBoxLayout(m_body);
m_layout->setMargin(3);
m_layout->setSpacing(0);
for (QRollupCtrl::PageList::ConstIterator i = m_pageList.constBegin(); i != m_pageList.constEnd(); ++i)
{
m_layout->addWidget((*i).button);
m_layout->addWidget((*i).sv);
}
m_layout->addStretch();
updateTabs();
}
void QRollupCtrl::_q_widgetDestroyed(QObject* object)
{
// no verification - vtbl corrupted already
QWidget* p = (QWidget*)object;
QRollupCtrl::Page* c = page(p);
if (!p || !c)
{
return;
}
m_layout->removeWidget(c->sv);
m_layout->removeWidget(c->button);
c->sv->deleteLater(); // page might still be a child of sv
delete c->button;
m_pageList.removeOne(*c);
}
void QRollupCtrl::_q_custumButtonMenu([[maybe_unused]] const QPoint& pos)
{
QMenu menu;
menu.addAction("Expand All")->setData(-1);
menu.addAction("Collapse All")->setData(-2);
menu.addSeparator();
for (int i = 0; i < m_pageList.size(); ++i)
{
QRollupCtrl::Page* c = page(i);
QAction* action = menu.addAction(c->button->text());
action->setCheckable(true);
action->setChecked(c->sv->isVisible());
action->setData(i);
}
QAction* action = menu.exec(QCursor::pos());
if (!action)
{
return;
}
int res = action->data().toInt();
switch (res)
{
case -1: // fall through
case -2:
expandAllPages(res == -1);
break;
default:
{
QRollupCtrl::Page* c = page(res);
if (c)
{
setIndexVisible(res, !c->sv->isVisible());
}
}
break;
}
}
void QRollupCtrl::expandAllPages(bool v)
{
for (int i = 0; i < m_pageList.size(); i++)
{
setIndexVisible(i, v);
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void QRollupCtrl::clear()
{
while (!m_pageList.isEmpty())
{
removeItem(0);
}
}
void QRollupCtrl::removeItem(QWidget* widget)
{
auto it = std::find_if(m_pageList.cbegin(), m_pageList.cend(), [widget](const Page& page) { return page.widget == widget; });
if (it != m_pageList.cend())
{
removeItem(it - m_pageList.cbegin());
}
}
void QRollupCtrl::removeItem(int index)
{
if (QWidget* w = widget(index))
{
disconnect(w, &QObject::destroyed, this, &QRollupCtrl::_q_widgetDestroyed);
w->setParent(this);
// destroy internal data
_q_widgetDestroyed(w);
itemRemoved(index);
}
}
QWidget* QRollupCtrl::widget(int index) const
{
if (index < 0 || index >= (int) m_pageList.size())
{
return 0;
}
return m_pageList.at(index).widget;
}
int QRollupCtrl::indexOf(QWidget* widget) const
{
QRollupCtrl::Page* c = page(widget);
return c ? m_pageList.indexOf(*c) : -1;
}
void QRollupCtrl::setItemEnabled(int index, bool enabled)
{
QRollupCtrl::Page* c = page(index);
if (!c)
{
return;
}
c->button->setEnabled(enabled);
if (!enabled)
{
int curIndexUp = index;
int curIndexDown = curIndexUp;
const int count = m_pageList.count();
while (curIndexUp > 0 || curIndexDown < count - 1)
{
if (curIndexDown < count - 1)
{
if (page(++curIndexDown)->button->isEnabled())
{
index = curIndexDown;
break;
}
}
if (curIndexUp > 0)
{
if (page(--curIndexUp)->button->isEnabled())
{
index = curIndexUp;
break;
}
}
}
}
}
void QRollupCtrl::setItemText(int index, const QString& text)
{
QRollupCtrl::Page* c = page(index);
if (c)
{
c->setText(text);
}
}
void QRollupCtrl::setItemIcon(int index, const QIcon& icon)
{
QRollupCtrl::Page* c = page(index);
if (c)
{
c->setIcon(icon);
}
}
void QRollupCtrl::setItemToolTip(int index, const QString& toolTip)
{
QRollupCtrl::Page* c = page(index);
if (c)
{
c->setToolTip(toolTip);
}
}
bool QRollupCtrl::isItemEnabled(int index) const
{
const QRollupCtrl::Page* c = page(index);
return c && c->button->isEnabled();
}
QString QRollupCtrl::itemText(int index) const
{
const QRollupCtrl::Page* c = page(index);
return (c ? c->text() : QString());
}
QIcon QRollupCtrl::itemIcon(int index) const
{
const QRollupCtrl::Page* c = page(index);
return (c ? c->icon() : QIcon());
}
QString QRollupCtrl::itemToolTip(int index) const
{
const QRollupCtrl::Page* c = page(index);
return (c ? c->toolTip() : QString());
}
void QRollupCtrl::changeEvent(QEvent* ev)
{
if (ev->type() == QEvent::StyleChange)
{
updateTabs();
}
QFrame::changeEvent(ev);
}
void QRollupCtrl::showEvent(QShowEvent* ev)
{
if (isVisible())
{
updateTabs();
}
IEditor* pEditor = GetIEditor();
pEditor->SetEditMode(EEditMode::eEditModeSelect);
QFrame::showEvent(ev);
}
void QRollupCtrl::itemInserted(int index)
{
Q_UNUSED(index)
}
void QRollupCtrl::itemRemoved(int index)
{
Q_UNUSED(index)
}
#include <Controls/moc_QRollupCtrl.cpp>
-126
View File
@@ -1,126 +0,0 @@
#ifndef CRYINCLUDE_EDITOR_CONTROLS_QROLLUPCTRL_H
#define CRYINCLUDE_EDITOR_CONTROLS_QROLLUPCTRL_H
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#if !defined(Q_MOC_RUN)
#include <QFrame>
#include <QScrollArea>
#include <QIcon>
#endif
class QVBoxLayout;
class QRollupCtrlButton;
class QRollupCtrl
: public QScrollArea
{
Q_OBJECT
Q_PROPERTY(int count READ count)
public:
explicit QRollupCtrl(QWidget* parent = 0);
~QRollupCtrl();
int addItem(QWidget* widget, const QString& text);
int addItem(QWidget* widget, const QIcon& icon, const QString& text);
int insertItem(int index, QWidget* widget, const QString& text);
int insertItem(int index, QWidget* widget, const QIcon& icon, const QString& text);
void clear();
void removeItem(QWidget* widget);
void removeItem(int index);
void setItemEnabled(int index, bool enabled);
bool isItemEnabled(int index) const;
void setItemText(int index, const QString& text);
QString itemText(int index) const;
void setItemIcon(int index, const QIcon& icon);
QIcon itemIcon(int index) const;
void setItemToolTip(int index, const QString& toolTip);
QString itemToolTip(int index) const;
QWidget* widget(int index) const;
int indexOf(QWidget* widget) const;
int count() const;
void readSettings (const QString& qSettingsGroup);
void writeSettings(const QString& qSettingsGroup);
public slots:
void setIndexVisible(int index, bool visible);
void setWidgetVisible(QWidget* widget, bool visible);
void expandAllPages(bool v);
protected:
virtual void itemInserted(int index);
virtual void itemRemoved(int index);
void changeEvent(QEvent*) override;
void showEvent(QShowEvent*) override;
private:
Q_DISABLE_COPY(QRollupCtrl)
struct Page
{
QRollupCtrlButton* button;
QFrame* sv;
QWidget* widget;
void setText(const QString& text);
void setIcon(const QIcon& is);
void setToolTip(const QString& tip);
QString text() const;
QIcon icon() const;
QString toolTip() const;
inline bool operator==(const Page& other) const
{
return widget == other.widget;
}
};
typedef QList<Page> PageList;
Page* page(QWidget* widget) const;
const Page* page(int index) const;
Page* page(int index);
void updateTabs();
void relayout();
bool isPageHidden(int index, QString& qObjectName) const;
QWidget* m_body;
PageList m_pageList;
QVBoxLayout* m_layout;
private slots:
void _q_buttonClicked();
void _q_widgetDestroyed(QObject*);
void _q_custumButtonMenu(const QPoint&);
};
//////////////////////////////////////////////////////////////////////////
inline int QRollupCtrl::addItem(QWidget* item, const QString& text)
{ return insertItem(-1, item, QIcon(), text); }
inline int QRollupCtrl::addItem(QWidget* item, const QIcon& iconSet, const QString& text)
{ return insertItem(-1, item, iconSet, text); }
inline int QRollupCtrl::insertItem(int index, QWidget* item, const QString& text)
{ return insertItem(index, item, QIcon(), text); }
#endif
-171
View File
@@ -1,171 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : implementation file
#include "EditorDefs.h"
// Editor
#include "CryEditDoc.h"
#include "EditTool.h"
#include "ToolButton.h"
QEditorToolButton::QEditorToolButton(QWidget* parent /* = nullptr */)
: QPushButton(parent)
, m_styleSheet(styleSheet())
, m_toolClass(nullptr)
, m_toolCreated(nullptr)
, m_needDocument(true)
{
setSizePolicy({ QSizePolicy::Expanding, QSizePolicy::Fixed });
connect(this, &QAbstractButton::clicked, this, &QEditorToolButton::OnClicked);
GetIEditor()->RegisterNotifyListener(this);
}
QEditorToolButton::~QEditorToolButton()
{
GetIEditor()->UnregisterNotifyListener(this);
}
void QEditorToolButton::SetToolName(const QString& editToolName, const QString& userDataKey, void* userData)
{
IClassDesc* klass = GetIEditor()->GetClassFactory()->FindClass(editToolName.toUtf8().data());
if (!klass)
{
Warning(QStringLiteral("Editor Tool %1 not registered.").arg(editToolName).toUtf8().data());
return;
}
if (klass->SystemClassID() != ESYSTEM_CLASS_EDITTOOL)
{
Warning(QStringLiteral("Class name %1 is not a valid Edit Tool class.").arg(editToolName).toUtf8().data());
return;
}
QScopedPointer<QObject> o(klass->CreateQObject());
if (!qobject_cast<CEditTool*>(o.data()))
{
Warning(QStringLiteral("Class name %1 is not a valid Edit Tool class.").arg(editToolName).toUtf8().data());
return;
}
SetToolClass(o->metaObject(), userDataKey, userData);
}
//////////////////////////////////////////////////////////////////////////
void QEditorToolButton::SetToolClass(const QMetaObject* toolClass, const QString& userDataKey, void* userData)
{
m_toolClass = toolClass;
m_userData = userData;
if (!userDataKey.isEmpty())
{
m_userDataKey = userDataKey;
}
}
void QEditorToolButton::OnEditorNotifyEvent(EEditorNotifyEvent event)
{
switch (event)
{
case eNotify_OnBeginNewScene:
case eNotify_OnBeginLoad:
case eNotify_OnBeginSceneOpen:
{
if (m_needDocument)
{
setEnabled(false);
}
break;
}
case eNotify_OnEndNewScene:
case eNotify_OnEndLoad:
case eNotify_OnEndSceneOpen:
{
if (m_needDocument)
{
setEnabled(true);
}
break;
}
case eNotify_OnEditToolChange:
{
CEditTool* tool = GetIEditor()->GetEditTool();
if (!tool || tool != m_toolCreated || tool->metaObject() != m_toolClass)
{
m_toolCreated = nullptr;
SetSelected(false);
}
}
default:
break;
}
}
void QEditorToolButton::OnClicked()
{
if (!m_toolClass)
{
return;
}
if (m_needDocument && !GetIEditor()->GetDocument()->IsDocumentReady())
{
return;
}
CEditTool* tool = GetIEditor()->GetEditTool();
if (tool && tool->IsMoveToObjectModeAfterEnd() && tool->metaObject() == m_toolClass && tool == m_toolCreated)
{
GetIEditor()->SetEditTool(nullptr);
SetSelected(false);
}
else
{
CEditTool* newTool = qobject_cast<CEditTool*>(m_toolClass->newInstance());
if (!newTool)
{
return;
}
m_toolCreated = newTool;
SetSelected(true);
if (m_userData)
{
newTool->SetUserData(m_userDataKey.toUtf8().data(), (void*)m_userData);
}
update();
// Must be last function, can delete this.
GetIEditor()->SetEditTool(newTool);
}
}
void QEditorToolButton::SetSelected(bool selected)
{
if (selected)
{
setStyleSheet(QStringLiteral("QPushButton { background-color: palette(highlight); color: palette(highlighted-text); }"));
}
else
{
setStyleSheet(m_styleSheet);
}
}
#include <Controls/moc_ToolButton.cpp>
-60
View File
@@ -1,60 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_EDITOR_CONTROLS_TOOLBUTTON_H
#define CRYINCLUDE_EDITOR_CONTROLS_TOOLBUTTON_H
#pragma once
// ToolButton.h : header file
//
#if !defined(Q_MOC_RUN)
#include <AzCore/PlatformDef.h>
#include <QPushButton>
#endif
AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING
class SANDBOX_API QEditorToolButton
: public QPushButton
, public IEditorNotifyListener
{
AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
Q_OBJECT
// Construction
public:
QEditorToolButton(QWidget* parent = nullptr);
virtual ~QEditorToolButton();
void SetToolClass(const QMetaObject* toolClass, const QString& userDataKey = 0, void* userData = nullptr);
void SetToolName(const QString& editToolName, const QString& userDataKey = 0, void* userData = nullptr);
// Set if this tool button relies on a loaded level / ready document. By default every tool button only works if a level is loaded.
// However some tools are also used without a loaded level (e.g. UI Emulator)
void SetNeedDocument(bool needDocument) { m_needDocument = needDocument; }
void SetSelected(bool selected);
void OnEditorNotifyEvent(EEditorNotifyEvent event) override;
protected:
void OnClicked();
const QString m_styleSheet;
//! Tool associated with this button.
const QMetaObject* m_toolClass;
CEditTool* m_toolCreated;
QString m_userDataKey;
void* m_userData;
bool m_needDocument;
};
#endif // CRYINCLUDE_EDITOR_CONTROLS_TOOLBUTTON_H
@@ -580,7 +580,6 @@ void LevelEditorMenuHandler::PopulateEditMenu(ActionManager::MenuWrapper& editMe
auto alignMenu = modifyMenu.AddMenu(tr("Align"));
alignMenu.AddAction(ID_OBJECTMODIFY_ALIGNTOGRID);
alignMenu.AddAction(ID_MODIFY_ALIGNOBJTOSURF);
auto constrainMenu = modifyMenu.AddMenu(tr("Constrain"));
constrainMenu.AddAction(ID_SELECT_AXIS_X);
-150
View File
@@ -95,7 +95,6 @@ AZ_POP_DISABLE_WARNING
#include "Core/QtEditorApplication.h"
#include "StringDlg.h"
#include "VoxelAligningTool.h"
#include "NewLevelDialog.h"
#include "GridSettingsDialog.h"
#include "LayoutConfigDialog.h"
@@ -110,7 +109,6 @@ AZ_POP_DISABLE_WARNING
#include "DisplaySettings.h"
#include "GameEngine.h"
#include "ObjectCloneTool.h"
#include "StartupTraceHandler.h"
#include "ThumbnailGenerator.h"
#include "ToolsConfigPage.h"
@@ -153,7 +151,6 @@ AZ_POP_DISABLE_WARNING
#include "LevelIndependentFileMan.h"
#include "WelcomeScreen/WelcomeScreenDialog.h"
#include "Dialogs/DuplicatedObjectsHandlerDlg.h"
#include "EditMode/VertexSnappingModeTool.h"
#include "Controls/ReflectedPropertyControl/PropertyCtrl.h"
#include "Controls/ReflectedPropertyControl/ReflectedVar.h"
@@ -399,11 +396,8 @@ void CCryEditApp::RegisterActionHandlers()
ON_COMMAND(ID_EDITMODE_ROTATE, OnEditmodeRotate)
ON_COMMAND(ID_EDITMODE_SCALE, OnEditmodeScale)
ON_COMMAND(ID_EDITMODE_SELECT, OnEditmodeSelect)
ON_COMMAND(ID_EDIT_ESCAPE, OnEditEscape)
ON_COMMAND(ID_OBJECTMODIFY_SETAREA, OnObjectSetArea)
ON_COMMAND(ID_OBJECTMODIFY_SETHEIGHT, OnObjectSetHeight)
ON_COMMAND(ID_OBJECTMODIFY_VERTEXSNAPPING, OnObjectVertexSnapping)
ON_COMMAND(ID_MODIFY_ALIGNOBJTOSURF, OnAlignToVoxel)
ON_COMMAND(ID_OBJECTMODIFY_FREEZE, OnObjectmodifyFreeze)
ON_COMMAND(ID_OBJECTMODIFY_UNFREEZE, OnObjectmodifyUnfreeze)
ON_COMMAND(ID_EDITMODE_SELECTAREA, OnEditmodeSelectarea)
@@ -413,11 +407,9 @@ void CCryEditApp::RegisterActionHandlers()
ON_COMMAND(ID_SELECT_AXIS_XY, OnSelectAxisXy)
ON_COMMAND(ID_UNDO, OnUndo)
ON_COMMAND(ID_TOOLBAR_WIDGET_REDO, OnUndo) // Can't use the same ID, because for the menu we can't have a QWidgetAction, while for the toolbar we want one
ON_COMMAND(ID_EDIT_CLONE, OnEditClone)
ON_COMMAND(ID_SELECTION_SAVE, OnSelectionSave)
ON_COMMAND(ID_IMPORT_ASSET, OnOpenAssetImporter)
ON_COMMAND(ID_SELECTION_LOAD, OnSelectionLoad)
ON_COMMAND(ID_MODIFY_ALIGNOBJTOSURF, OnAlignToVoxel)
ON_COMMAND(ID_OBJECTMODIFY_ALIGNTOGRID, OnAlignToGrid)
ON_COMMAND(ID_LOCK_SELECTION, OnLockSelection)
ON_COMMAND(ID_EDIT_LEVELDATA, OnEditLevelData)
@@ -524,12 +516,10 @@ void CCryEditApp::RegisterActionHandlers()
ON_COMMAND(ID_OPEN_MATERIAL_EDITOR, OnOpenMaterialEditor)
ON_COMMAND(ID_GOTO_VIEWPORTSEARCH, OnGotoViewportSearch)
ON_COMMAND(ID_MATERIAL_PICKTOOL, OnMaterialPicktool)
ON_COMMAND(ID_DISPLAY_SHOWHELPERS, OnShowHelpers)
ON_COMMAND(ID_OPEN_TRACKVIEW, OnOpenTrackView)
ON_COMMAND(ID_OPEN_UICANVASEDITOR, OnOpenUICanvasEditor)
ON_COMMAND(ID_GOTO_VIEWPORTSEARCH, OnGotoViewportSearch)
ON_COMMAND(ID_MATERIAL_PICKTOOL, OnMaterialPicktool)
ON_COMMAND(ID_TERRAIN_TIMEOFDAY, OnTimeOfDay)
ON_COMMAND(ID_TERRAIN_TIMEOFDAYBUTTON, OnTimeOfDay)
@@ -2739,15 +2729,6 @@ void CCryEditApp::OnEditDelete()
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::DeleteSelectedEntities([[maybe_unused]] bool includeDescendants)
{
// If Edit tool active cannot delete object.
if (GetIEditor()->GetEditTool())
{
if (GetIEditor()->GetEditTool()->OnKeyDown(GetIEditor()->GetViewManager()->GetView(0), VK_DELETE, 0, 0))
{
return;
}
}
GetIEditor()->BeginUndo();
CUndo undo("Delete Selected Object");
GetIEditor()->GetObjectManager()->DeleteSelection();
@@ -2756,75 +2737,6 @@ void CCryEditApp::DeleteSelectedEntities([[maybe_unused]] bool includeDescendant
GetIEditor()->SetModifiedModule(eModifiedBrushes);
}
void CCryEditApp::OnEditClone()
{
if (!GetIEditor()->IsNewViewportInteractionModelEnabled())
{
if (GetIEditor()->GetObjectManager()->GetSelection()->IsEmpty())
{
QMessageBox::critical(AzToolsFramework::GetActiveWindow(), QString(),
QObject::tr("You have to select objects before you can clone them!"));
return;
}
// Clear Widget selection - Prevents issues caused by cloning entities while a property in the Reflected Property Editor is being edited.
if (QApplication::focusWidget())
{
QApplication::focusWidget()->clearFocus();
}
CEditTool* tool = GetIEditor()->GetEditTool();
if (tool && qobject_cast<CObjectCloneTool*>(tool))
{
((CObjectCloneTool*)tool)->Accept();
}
CObjectCloneTool* cloneTool = new CObjectCloneTool;
GetIEditor()->SetEditTool(cloneTool);
GetIEditor()->SetModifiedFlag();
GetIEditor()->SetModifiedModule(eModifiedBrushes);
// Accept the clone operation if users didn't choose to stick duplicated entities to the cursor
// This setting can be changed in the global preference of the editor
if (!gSettings.deepSelectionSettings.bStickDuplicate)
{
cloneTool->Accept();
GetIEditor()->GetSelection()->FinishChanges();
}
}
}
void CCryEditApp::OnEditEscape()
{
if (!GetIEditor()->IsNewViewportInteractionModelEnabled())
{
CEditTool* pEditTool = GetIEditor()->GetEditTool();
// Abort current operation.
if (pEditTool)
{
// If Edit tool active cannot delete object.
CViewport* vp = GetIEditor()->GetActiveView();
if (GetIEditor()->GetEditTool()->OnKeyDown(vp, VK_ESCAPE, 0, 0))
{
return;
}
if (GetIEditor()->GetEditMode() == eEditModeSelectArea)
{
GetIEditor()->SetEditMode(eEditModeSelect);
}
// Disable current tool.
GetIEditor()->SetEditTool(0);
}
else
{
// Clear selection on escape.
GetIEditor()->ClearSelection();
}
}
}
void CCryEditApp::OnMoveObject()
{
////////////////////////////////////////////////////////////////////////
@@ -2986,14 +2898,6 @@ void CCryEditApp::OnUpdateEditmodeScale(QAction* action)
}
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateEditmodeVertexSnapping(QAction* action)
{
Q_ASSERT(action->isCheckable());
CEditTool* pEditTool = GetIEditor()->GetEditTool();
action->setChecked(qobject_cast<CVertexSnappingModeTool*>(pEditTool) != nullptr);
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnObjectSetArea()
{
@@ -3143,19 +3047,6 @@ void CCryEditApp::OnObjectSetHeight()
}
}
void CCryEditApp::OnObjectVertexSnapping()
{
CEditTool* pEditTool = GetIEditor()->GetEditTool();
if (qobject_cast<CVertexSnappingModeTool*>(pEditTool))
{
GetIEditor()->SetEditTool(NULL);
}
else
{
GetIEditor()->SetEditTool("EditTool.VertexSnappingMode");
}
}
void CCryEditApp::OnObjectmodifyFreeze()
{
// Freeze selection.
@@ -3480,37 +3371,8 @@ void CCryEditApp::OnAlignToGrid()
}
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAlignToVoxel()
{
CEditTool* pEditTool = GetIEditor()->GetEditTool();
if (qobject_cast<CVoxelAligningTool*>(pEditTool) != nullptr)
{
GetIEditor()->SetEditTool(nullptr);
}
else
{
GetIEditor()->SetEditTool(new CVoxelAligningTool());
}
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateAlignToVoxel(QAction* action)
{
Q_ASSERT(action->isCheckable());
CEditTool* pEditTool = GetIEditor()->GetEditTool();
action->setChecked(qobject_cast<CVoxelAligningTool*>(pEditTool) != nullptr);
action->setEnabled(!GetIEditor()->GetSelection()->IsEmpty());
}
void CCryEditApp::OnShowHelpers()
{
CEditTool* pEditTool(GetIEditor()->GetEditTool());
if (pEditTool && pEditTool->IsNeedSpecificBehaviorForSpaceAcce())
{
return;
}
GetIEditor()->GetDisplaySettings()->DisplayHelpers(!GetIEditor()->GetDisplaySettings()->IsDisplayHelpers());
GetIEditor()->Notify(eNotify_OnDisplayRenderUpdate);
}
@@ -5136,12 +4998,6 @@ void CCryEditApp::OnOpenUICanvasEditor()
QtViewPaneManager::instance()->OpenPane(LyViewPane::UiEditor);
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnMaterialPicktool()
{
GetIEditor()->SetEditTool("EditTool.PickMaterial");
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnTimeOfDay()
{
@@ -5296,12 +5152,6 @@ void CCryEditApp::OnOpenQuickAccessBar()
return;
}
CEditTool* pEditTool(GetIEditor()->GetEditTool());
if (pEditTool && pEditTool->IsNeedSpecificBehaviorForSpaceAcce())
{
return;
}
QRect geo = m_pQuickAccessBar->geometry();
geo.moveCenter(MainWindow::instance()->geometry().center());
m_pQuickAccessBar->setGeometry(geo);
-7
View File
@@ -225,11 +225,8 @@ public:
void OnEditmodeRotate();
void OnEditmodeScale();
void OnEditmodeSelect();
void OnEditEscape();
void OnObjectSetArea();
void OnObjectSetHeight();
void OnObjectVertexSnapping();
void OnUpdateEditmodeVertexSnapping(QAction* action);
void OnUpdateEditmodeSelect(QAction* action);
void OnUpdateEditmodeMove(QAction* action);
void OnUpdateEditmodeRotate(QAction* action);
@@ -247,14 +244,11 @@ public:
void OnUpdateSelectAxisY(QAction* action);
void OnUpdateSelectAxisZ(QAction* action);
void OnUndo();
void OnEditClone();
void OnSelectionSave();
void OnOpenAssetImporter();
void OnSelectionLoad();
void OnUpdateSelected(QAction* action);
void OnAlignToVoxel();
void OnAlignToGrid();
void OnUpdateAlignToVoxel(QAction* action);
void OnLockSelection();
void OnEditLevelData();
void OnFileEditLogFile();
@@ -491,7 +485,6 @@ private:
void OnOpenAudioControlsEditor();
void OnOpenUICanvasEditor();
void OnGotoViewportSearch();
void OnMaterialPicktool();
void OnTimeOfDay();
void OnChangeGameSpec(UINT nID);
void SetGameSpecCheck(ESystemConfigSpec spec, ESystemConfigPlatform platform, int &nCheck, bool &enable);
-1
View File
@@ -279,7 +279,6 @@ void CCryEditDoc::DeleteContents()
// [LY-90904] move this to the EditorVegetationManager component
InstanceStatObjEventBus::Broadcast(&InstanceStatObjEventBus::Events::ReleaseData);
GetIEditor()->SetEditTool(0); // Turn off any active edit tools.
GetIEditor()->SetEditMode(eEditModeSelect);
//////////////////////////////////////////////////////////////////////////
@@ -1,123 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "EditorDefs.h"
#include "ButtonsPanel.h"
// Qt
#include <QGridLayout>
// Editor
#include "Controls/ToolButton.h"
/////////////////////////////////////////////////////////////////////////////
// CButtonsPanel dialog
CButtonsPanel::CButtonsPanel(QWidget* parent)
: QWidget(parent)
{
}
CButtonsPanel::~CButtonsPanel()
{
}
//////////////////////////////////////////////////////////////////////////
void CButtonsPanel::AddButton(const SButtonInfo& button)
{
SButton b;
b.info = button;
m_buttons.push_back(b);
}
//////////////////////////////////////////////////////////////////////////
void CButtonsPanel::AddButton(const QString& name, const QString& toolClass)
{
SButtonInfo bi;
bi.name = name;
bi.toolClassName = toolClass;
AddButton(bi);
}
//////////////////////////////////////////////////////////////////////////
void CButtonsPanel::AddButton(const QString& name, const QMetaObject* pToolClass)
{
SButtonInfo bi;
bi.name = name;
bi.pToolClass = pToolClass;
AddButton(bi);
}
//////////////////////////////////////////////////////////////////////////
void CButtonsPanel::ClearButtons()
{
auto buttons = layout()->findChildren<QEditorToolButton*>();
foreach(auto button, buttons)
{
layout()->removeWidget(button);
delete button;
}
m_buttons.clear();
}
void CButtonsPanel::UncheckAll()
{
for (auto& button : m_buttons)
{
button.pButton->SetSelected(false);
}
}
void CButtonsPanel::OnInitDialog()
{
auto layout = new QGridLayout(this);
setLayout(layout);
layout->setMargin(4);
layout->setHorizontalSpacing(4);
layout->setVerticalSpacing(1);
// Create Buttons.
int index = 0;
for (auto& button : m_buttons)
{
button.pButton = new QEditorToolButton(this);
button.pButton->setObjectName(button.info.name);
button.pButton->setText(button.info.name);
button.pButton->SetNeedDocument(button.info.bNeedDocument);
button.pButton->setToolTip(button.info.toolTip);
if (button.info.pToolClass)
{
button.pButton->SetToolClass(button.info.pToolClass, button.info.toolUserDataKey, (void*)button.info.toolUserData.c_str());
}
else if (!button.info.toolClassName.isEmpty())
{
button.pButton->SetToolName(button.info.toolClassName, button.info.toolUserDataKey, (void*)button.info.toolUserData.c_str());
}
layout->addWidget(button.pButton, index / 2, index % 2);
connect(button.pButton, &QEditorToolButton::clicked, this, [&]() { OnButtonPressed(button.info); });
++index;
}
}
void CButtonsPanel::EnableButton(const QString& buttonName, bool enable)
{
for (auto& button : m_buttons)
{
if (button.pButton->objectName() == buttonName)
{
button.pButton->setEnabled(enable);
}
}
}
#include <Dialogs/moc_ButtonsPanel.cpp>
@@ -1,76 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_EDITOR_DIALOGS_BUTTONSPANEL_H
#define CRYINCLUDE_EDITOR_DIALOGS_BUTTONSPANEL_H
#pragma once
#if !defined(Q_MOC_RUN)
#include <QWidget>
#endif
class QEditorToolButton;
/////////////////////////////////////////////////////////////////////////////
// Panel with custom auto arranged buttons
class CButtonsPanel
: public QWidget
{
Q_OBJECT
public:
struct SButtonInfo
{
QString name;
QString toolClassName;
QString toolUserDataKey;
std::string toolUserData;
QString toolTip;
bool bNeedDocument;
const QMetaObject* pToolClass;
SButtonInfo()
: pToolClass(nullptr)
, bNeedDocument(true) {};
};
CButtonsPanel(QWidget* parent);
virtual ~CButtonsPanel();
virtual void AddButton(const SButtonInfo& button);
virtual void AddButton(const QString& name, const QString& toolClass);
virtual void AddButton(const QString& name, const QMetaObject* pToolClass);
virtual void EnableButton(const QString& buttonName, bool disable);
virtual void ClearButtons();
virtual void OnButtonPressed([[maybe_unused]] const SButtonInfo& button) {};
virtual void UncheckAll();
protected:
void ReleaseGuiButtons();
virtual void OnInitDialog();
//////////////////////////////////////////////////////////////////////////
struct SButton
{
SButtonInfo info;
QEditorToolButton* pButton;
SButton()
: pButton(nullptr) {};
};
std::vector<SButton> m_buttons;
};
#endif // CRYINCLUDE_EDITOR_DIALOGS_BUTTONSPANEL_H
File diff suppressed because it is too large Load Diff
-134
View File
@@ -1,134 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Object edit mode describe viewport input behavior when operating on objects.
#ifndef CRYINCLUDE_EDITOR_EDITMODE_OBJECTMODE_H
#define CRYINCLUDE_EDITOR_EDITMODE_OBJECTMODE_H
#pragma once
// {87109FED-BDB5-4874-936D-338400079F58}
DEFINE_GUID(OBJECT_MODE_GUID, 0x87109fed, 0xbdb5, 0x4874, 0x93, 0x6d, 0x33, 0x84, 0x0, 0x7, 0x9f, 0x58);
#include "EditTool.h"
class CBaseObject;
class CDeepSelection;
/*!
* CObjectMode is an abstract base class for All Editing Tools supported by Editor.
* Edit tools handle specific editing modes in viewports.
*/
class SANDBOX_API CObjectMode
: public CEditTool
{
Q_OBJECT
public:
Q_INVOKABLE CObjectMode(QObject* parent = nullptr);
virtual ~CObjectMode();
static const GUID& GetClassID() { return OBJECT_MODE_GUID; }
// Registration function.
static void RegisterTool(CRegistrationContext& rc);
//////////////////////////////////////////////////////////////////////////
// CEditTool implementation.
//////////////////////////////////////////////////////////////////////////
virtual void BeginEditParams([[maybe_unused]] IEditor* ie, [[maybe_unused]] int flags) {};
virtual void EndEditParams();
virtual void Display(struct DisplayContext& dc);
virtual void DisplaySelectionPreview(struct DisplayContext& dc);
virtual void DrawSelectionPreview(struct DisplayContext& dc, CBaseObject* drawObject);
void DisplayExtraLightInfo(struct DisplayContext& dc);
virtual bool MouseCallback(CViewport* view, EMouseEvent event, QPoint& point, int flags);
virtual bool OnKeyDown(CViewport* view, uint32 nChar, uint32 nRepCnt, uint32 nFlags);
virtual bool OnKeyUp(CViewport* view, uint32 nChar, uint32 nRepCnt, uint32 nFlags);
virtual bool OnSetCursor([[maybe_unused]] CViewport* vp) { return false; };
virtual void OnManipulatorDrag(CViewport* view, ITransformManipulator* pManipulator, QPoint& p0, QPoint& p1, const Vec3& value) override;
bool IsUpdateUIPanel() override { return true; }
protected:
enum ECommandMode
{
NothingMode = 0,
ScrollZoomMode,
SelectMode,
MoveMode,
RotateMode,
ScaleMode,
ScrollMode,
ZoomMode,
};
virtual bool OnLButtonDown(CViewport* view, int nFlags, const QPoint& point);
virtual bool OnLButtonDblClk(CViewport* view, int nFlags, const QPoint& point);
virtual bool OnLButtonUp(CViewport* view, int nFlags, const QPoint& point);
virtual bool OnRButtonDown(CViewport* view, int nFlags, const QPoint& point);
virtual bool OnRButtonUp(CViewport* view, int nFlags, const QPoint& point);
virtual bool OnMButtonDown(CViewport* view, int nFlags, const QPoint& point);
virtual bool OnMouseMove(CViewport* view, int nFlags, const QPoint& point);
virtual bool OnMouseLeave(CViewport* view);
void SetCommandMode(ECommandMode mode) { m_commandMode = mode; }
ECommandMode GetCommandMode() const { return m_commandMode; }
//! Ctrl-Click in move mode to move selected objects to given pos.
void MoveSelectionToPos(CViewport* view, Vec3& pos, bool align, const QPoint& point);
void SetObjectCursor(CViewport* view, CBaseObject* hitObj, bool bChangeNow = false);
virtual void DeleteThis() { delete this; };
void UpdateStatusText();
void AwakeObjectAtPoint(CViewport* view, const QPoint& point);
void HideMoveByFaceNormGizmo();
void HandleMoveByFaceNormal(HitContext& hitInfo);
void UpdateMoveByFaceNormGizmo(CBaseObject* pHitObject);
protected:
bool m_openContext;
private:
void CheckDeepSelection(HitContext& hitContext, CViewport* view);
Vec3& GetScale(const CViewport* view, const QPoint& point, Vec3& OutScale);
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
QPoint m_cMouseDownPos;
bool m_bDragThresholdExceeded;
ECommandMode m_commandMode;
GUID m_MouseOverObject;
typedef std::vector<GUID> TGuidContainer;
TGuidContainer m_PreviewGUIDs;
_smart_ptr<CDeepSelection> m_pDeepSelection;
bool m_bMoveByFaceNormManipShown;
CBaseObject* m_pHitObject;
bool m_bTransformChanged;
QPoint m_prevMousePos = QPoint(0, 0);
Vec3 m_lastValidMoveVector = Vec3(0, 0, 0);
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
};
#endif // CRYINCLUDE_EDITOR_EDITMODE_OBJECTMODE_H
@@ -1,430 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "EditorDefs.h"
#if defined(AZ_PLATFORM_WINDOWS)
#include <InitGuid.h>
#endif
#include "VertexSnappingModeTool.h"
// Editor
#include "Settings.h"
#include "Viewport.h"
#include "SurfaceInfoPicker.h"
#include "Material/Material.h"
#include "Util/KDTree.h"
// {3e008046-9269-41d7-82e2-07ffd7254c10}
DEFINE_GUID(VERTEXSNAPPING_MODE_GUID, 0x3e008046, 0x9269, 0x41d7, 0x82, 0xe2, 0x07, 0xff, 0xd7, 0x25, 0x4c, 0x10);
bool FindNearestVertex(CBaseObject* pObject, CKDTree* pTree, const Vec3& vWorldRaySrc, const Vec3& vWorldRayDir, Vec3& outPos, Vec3& vOutHitPosOnCube)
{
Matrix34 worldInvTM = pObject->GetWorldTM().GetInverted();
Vec3 vRaySrc = worldInvTM.TransformPoint(vWorldRaySrc);
Vec3 vRayDir = worldInvTM.TransformVector(vWorldRayDir);
Vec3 vLocalCameraPos = worldInvTM.TransformPoint(gEnv->pRenderer->GetCamera().GetPosition());
Vec3 vPos;
Vec3 vHitPosOnCube;
if (pTree)
{
if (pTree->FindNearestVertex(vRaySrc, vRayDir, gSettings.vertexSnappingSettings.vertexCubeSize, vLocalCameraPos, vPos, vHitPosOnCube))
{
outPos = pObject->GetWorldTM().TransformPoint(vPos);
vOutHitPosOnCube = pObject->GetWorldTM().TransformPoint(vHitPosOnCube);
return true;
}
}
else
{
// for objects without verts, the pivot is the nearest vertex
// return true if the ray hits the bounding box
outPos = pObject->GetWorldPos();
AABB bbox;
pObject->GetBoundBox(bbox);
if (bbox.IsContainPoint(vWorldRaySrc))
{
// if ray starts inside bounding box, reject cases where pivot is behind the ray
float hitDistAlongRay = vWorldRayDir.Dot(outPos - vWorldRaySrc);
if (hitDistAlongRay >= 0.f)
{
vHitPosOnCube = vWorldRaySrc + (vWorldRayDir * hitDistAlongRay);
return true;
}
}
else if (Intersect::Ray_AABB(vWorldRaySrc, vWorldRayDir, bbox, vOutHitPosOnCube))
{
return true;
}
}
return false;
}
CVertexSnappingModeTool::CVertexSnappingModeTool()
{
m_modeStatus = eVSS_SelectFirstVertex;
m_bHit = false;
}
CVertexSnappingModeTool::~CVertexSnappingModeTool()
{
std::map<CBaseObjectPtr, CKDTree*>::iterator ii = m_ObjectKdTreeMap.begin();
for (; ii != m_ObjectKdTreeMap.end(); ++ii)
{
delete ii->second;
}
}
const GUID& CVertexSnappingModeTool::GetClassID()
{
return VERTEXSNAPPING_MODE_GUID;
}
void CVertexSnappingModeTool::RegisterTool(CRegistrationContext& rc)
{
rc.pClassFactory->RegisterClass(new CQtViewClass<CVertexSnappingModeTool>("EditTool.VertexSnappingMode", "Select", ESYSTEM_CLASS_EDITTOOL));
}
bool CVertexSnappingModeTool::MouseCallback(CViewport* view, EMouseEvent event, QPoint& point, int flags)
{
CBaseObjectPtr pExcludedObject = NULL;
if (m_modeStatus == eVSS_MoveSelectVertexToAnotherVertex)
{
pExcludedObject = m_SelectionInfo.m_pObject;
}
m_bHit = HitTest(view, point, pExcludedObject, m_vHitVertex, m_pHitObject, m_Objects);
if (event == eMouseLDown && m_bHit && m_pHitObject && m_modeStatus == eVSS_SelectFirstVertex)
{
m_modeStatus = eVSS_MoveSelectVertexToAnotherVertex;
m_SelectionInfo.m_pObject = m_pHitObject;
m_SelectionInfo.m_vPos = m_vHitVertex;
GetIEditor()->BeginUndo();
m_pHitObject->StoreUndo("Vertex Snapping", true);
view->SetCapture();
}
if (m_modeStatus == eVSS_MoveSelectVertexToAnotherVertex)
{
if (event == eMouseLUp)
{
m_modeStatus = eVSS_SelectFirstVertex;
GetIEditor()->AcceptUndo("Vertex Snapping");
view->ReleaseMouse();
}
else if ((flags & MK_LBUTTON) && event == eMouseMove)
{
Vec3 vOffset = m_SelectionInfo.m_pObject->GetWorldPos() - m_SelectionInfo.m_vPos;
m_SelectionInfo.m_pObject->SetWorldPos(m_vHitVertex + vOffset);
m_SelectionInfo.m_vPos = m_SelectionInfo.m_pObject->GetWorldPos() - vOffset;
}
}
return true;
}
bool CVertexSnappingModeTool::HitTest(CViewport* view, const QPoint& point, CBaseObject* pExcludedObj, Vec3& outHitPos, CBaseObjectPtr& pOutHitObject, std::vector<CBaseObjectPtr>& outObjects)
{
if (gSettings.vertexSnappingSettings.bRenderPenetratedBoundBox)
{
m_DebugBoxes.clear();
}
pOutHitObject = NULL;
outObjects.clear();
//
// Collect valid objects that mouse is over
//
CSurfaceInfoPicker picker;
CSurfaceInfoPicker::CExcludedObjects excludedObjects;
if (pExcludedObj)
{
excludedObjects.Add(pExcludedObj);
}
int nPickFlag = CSurfaceInfoPicker::ePOG_Entity;
std::vector<CBaseObjectPtr> penetratedObjects;
if (!picker.PickByAABB(point, nPickFlag, view, &excludedObjects, &penetratedObjects))
{
return false;
}
for (int i = 0, iCount(penetratedObjects.size()); i < iCount; ++i)
{
CMaterial* pMaterial = penetratedObjects[i]->GetMaterial();
if (pMaterial)
{
QString matName = pMaterial->GetName();
if (!QString::compare(matName, "Objects/sky/forest_sky_dome", Qt::CaseInsensitive))
{
continue;
}
}
outObjects.push_back(penetratedObjects[i]);
}
//
// Find the best vertex.
//
Vec3 vWorldRaySrc, vWorldRayDir;
view->ViewToWorldRay(point, vWorldRaySrc, vWorldRayDir);
std::vector<CBaseObjectPtr>::iterator ii = outObjects.begin();
float fNearestDist = 3e10f;
Vec3 vNearestPos;
CBaseObjectPtr pNearestObject = NULL;
for (ii = outObjects.begin(); ii != outObjects.end(); ++ii)
{
if (gSettings.vertexSnappingSettings.bRenderPenetratedBoundBox)
{
// add to debug boxes: the penetrated nodes of each object's kd-tree
if (auto pTree = GetKDTree(*ii))
{
Matrix34 invWorldTM = (*ii)->GetWorldTM().GetInverted();
int nIndex = m_DebugBoxes.size();
Vec3 vLocalRaySrc = invWorldTM.TransformPoint(vWorldRaySrc);
Vec3 vLocalRayDir = invWorldTM.TransformVector(vWorldRayDir);
pTree->GetPenetratedBoxes(vLocalRaySrc, vLocalRayDir, m_DebugBoxes);
for (int i = nIndex; i < m_DebugBoxes.size(); ++i)
{
m_DebugBoxes[i].SetTransformedAABB((*ii)->GetWorldTM(), m_DebugBoxes[i]);
}
}
}
// find the nearest vertex on this object
Vec3 vPos, vHitPosOnCube;
if (FindNearestVertex(*ii, GetKDTree(*ii), vWorldRaySrc, vWorldRayDir, vPos, vHitPosOnCube))
{
// is this the best so far?
float fDistance = vHitPosOnCube.GetDistance(vWorldRaySrc);
if (fDistance < fNearestDist)
{
fNearestDist = fDistance;
vNearestPos = vPos;
pNearestObject = *ii;
}
}
}
if (fNearestDist < 3e10f)
{
outHitPos = vNearestPos;
pOutHitObject = pNearestObject;
}
// if the mouse is over the object's pivot, use that instead of a vertex
if (pOutHitObject)
{
Vec3 vPivotPos = pOutHitObject->GetWorldPos();
Vec3 vPivotBox = GetCubeSize(view, pOutHitObject->GetWorldPos());
AABB pivotAABB(vPivotPos - vPivotBox, vPivotPos + vPivotBox);
Vec3 vPosOnPivotCube;
if (Intersect::Ray_AABB(vWorldRaySrc, vWorldRayDir, pivotAABB, vPosOnPivotCube))
{
outHitPos = vPivotPos;
return true;
}
}
return pOutHitObject && pOutHitObject == pNearestObject;
}
Vec3 CVertexSnappingModeTool::GetCubeSize(IDisplayViewport* pView, const Vec3& pos) const
{
if (!pView)
{
return Vec3(0, 0, 0);
}
float fScreenFactor = pView->GetScreenScaleFactor(pos);
return gSettings.vertexSnappingSettings.vertexCubeSize * Vec3(fScreenFactor, fScreenFactor, fScreenFactor);
}
void CVertexSnappingModeTool::Display(struct DisplayContext& dc)
{
const ColorB SnappedColor(0xFF00FF00);
const ColorB PivotColor(0xFF2020FF);
const ColorB VertexColor(0xFFFFAAAA);
// draw all objects under mouse
dc.SetColor(VertexColor);
for (int i = 0, iCount(m_Objects.size()); i < iCount; ++i)
{
AABB worldAABB;
m_Objects[i]->GetBoundBox(worldAABB);
if (!dc.view->IsBoundsVisible(worldAABB))
{
continue;
}
if (auto pStatObj = m_Objects[i]->GetIStatObj())
{
DrawVertexCubes(dc, m_Objects[i]->GetWorldTM(), pStatObj);
}
else
{
dc.DrawWireBox(worldAABB.min, worldAABB.max);
}
}
// draw object being moved
if (m_modeStatus == eVSS_MoveSelectVertexToAnotherVertex && m_SelectionInfo.m_pObject)
{
dc.SetColor(QColor(0xaa, 0xaa, 0xaa));
if (auto pStatObj = m_SelectionInfo.m_pObject->GetIStatObj())
{
DrawVertexCubes(dc, m_SelectionInfo.m_pObject->GetWorldTM(), pStatObj);
}
else
{
AABB bounds;
m_SelectionInfo.m_pObject->GetBoundBox(bounds);
dc.DrawWireBox(bounds.min, bounds.max);
}
}
// draw pivot of hit object
if (m_pHitObject && (!m_bHit || m_bHit && !m_pHitObject->GetWorldPos().IsEquivalent(m_vHitVertex, 0.001f)))
{
dc.SetColor(PivotColor);
dc.DepthTestOff();
Vec3 vBoxSize = GetCubeSize(dc.view, m_pHitObject->GetWorldPos()) * 1.2f;
AABB vertexBox(m_pHitObject->GetWorldPos() - vBoxSize, m_pHitObject->GetWorldPos() + vBoxSize);
dc.DrawBall((vertexBox.min + vertexBox.max) * 0.5f, (vertexBox.max.x - vertexBox.min.x) * 0.5f);
dc.DepthTestOn();
}
// draw the vertex (or pivot) that's being hit
if (m_bHit)
{
dc.DepthTestOff();
dc.SetColor(SnappedColor);
Vec3 vBoxSize = GetCubeSize(dc.view, m_vHitVertex);
if (m_vHitVertex.IsEquivalent(m_pHitObject->GetWorldPos(), 0.001f))
{
dc.DrawBall(m_vHitVertex, vBoxSize.x * 1.2f);
}
else
{
dc.DrawSolidBox(m_vHitVertex - vBoxSize, m_vHitVertex + vBoxSize);
}
dc.DepthTestOn();
}
// draw wireframe of hit object
if (m_pHitObject && m_pHitObject->GetIStatObj())
{
SGeometryDebugDrawInfo dd;
dd.tm = m_pHitObject->GetWorldTM();
dd.color = ColorB(250, 0, 250, 30);
dd.lineColor = ColorB(255, 255, 0, 160);
dd.bExtrude = true;
m_pHitObject->GetIStatObj()->DebugDraw(dd);
}
// draw debug boxes
if (gSettings.vertexSnappingSettings.bRenderPenetratedBoundBox)
{
ColorB boxColor(40, 40, 40);
for (int i = 0, iCount(m_DebugBoxes.size()); i < iCount; ++i)
{
dc.SetColor(boxColor);
boxColor += ColorB(25, 25, 25);
dc.DrawWireBox(m_DebugBoxes[i].min, m_DebugBoxes[i].max);
}
}
}
void CVertexSnappingModeTool::DrawVertexCubes(DisplayContext& dc, const Matrix34& tm, IStatObj* pStatObj)
{
if (!pStatObj)
{
return;
}
IIndexedMesh* pIndexedMesh = pStatObj->GetIndexedMesh();
if (pIndexedMesh)
{
IIndexedMesh::SMeshDescription md;
pIndexedMesh->GetMeshDescription(md);
for (int k = 0; k < md.m_nVertCount; ++k)
{
Vec3 vPos(0, 0, 0);
if (md.m_pVerts)
{
vPos = md.m_pVerts[k];
}
else if (md.m_pVertsF16)
{
vPos = md.m_pVertsF16[k].ToVec3();
}
else
{
continue;
}
vPos = tm.TransformPoint(vPos);
Vec3 vBoxSize = GetCubeSize(dc.view, vPos);
if (!m_bHit || !m_vHitVertex.IsEquivalent(vPos, 0.001f))
{
dc.DrawSolidBox(vPos - vBoxSize, vPos + vBoxSize);
}
}
}
for (int i = 0, iSubStatObjNum(pStatObj->GetSubObjectCount()); i < iSubStatObjNum; ++i)
{
IStatObj::SSubObject* pSubObj = pStatObj->GetSubObject(i);
if (pSubObj)
{
DrawVertexCubes(dc, tm * pSubObj->localTM, pSubObj->pStatObj);
}
}
}
CKDTree* CVertexSnappingModeTool::GetKDTree(CBaseObject* pObject)
{
auto existingTree = m_ObjectKdTreeMap.find(pObject);
if (existingTree != m_ObjectKdTreeMap.end())
{
return existingTree->second;
}
// Don't build a kd-tree for objects without verts
CKDTree* pTree = nullptr;
if (auto pStatObj = pObject->GetIStatObj())
{
pTree = new CKDTree();
pTree->Build(pObject->GetIStatObj());
}
m_ObjectKdTreeMap[pObject] = pTree;
return pTree;
}
#include <EditMode/moc_VertexSnappingModeTool.cpp>
@@ -1,91 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_EDITOR_EDITMODE_VERTEXSNAPPINGMODETOOL_H
#define CRYINCLUDE_EDITOR_EDITMODE_VERTEXSNAPPINGMODETOOL_H
#pragma once
#include "EditTool.h"
#include "Objects/BaseObject.h"
class CKDTree;
struct IDisplayViewport;
class CVertexSnappingModeTool
: public CEditTool
{
Q_OBJECT
public:
Q_INVOKABLE CVertexSnappingModeTool();
~CVertexSnappingModeTool();
static const GUID& GetClassID();
static void RegisterTool(CRegistrationContext& rc);
void Display(DisplayContext& dc);
bool MouseCallback(CViewport* view, EMouseEvent event, QPoint& point, int flags);
protected:
void DrawVertexCubes(DisplayContext& dc, const Matrix34& tm, IStatObj* pStatObj);
void DeleteThis(){ delete this; }
Vec3 GetCubeSize(IDisplayViewport* pView, const Vec3& pos) const;
private:
using CEditTool::HitTest;
bool HitTest(CViewport* view, const QPoint& point, CBaseObject* pExcludedObj, Vec3& outHitPos, CBaseObjectPtr& pOutHitObject, std::vector<CBaseObjectPtr>& outObjects);
CKDTree* GetKDTree(CBaseObject* pObject);
enum EVertexSnappingStatus
{
eVSS_SelectFirstVertex,
eVSS_MoveSelectVertexToAnotherVertex
};
EVertexSnappingStatus m_modeStatus;
struct SSelectionInfo
{
SSelectionInfo()
{
m_pObject = NULL;
m_vPos = Vec3(0, 0, 0);
}
CBaseObjectPtr m_pObject;
Vec3 m_vPos;
};
/// Info on object being moved (when in eVSS_MoveSelectVertexToAnotherVertex mode).
SSelectionInfo m_SelectionInfo;
/// Objects that mouse is over
std::vector<CBaseObjectPtr> m_Objects;
/// Position of vertex that mouse is hitting.
/// Invalid when m_bHit is false.
Vec3 m_vHitVertex;
/// Whether the mouse hit test succeeded
bool m_bHit;
/// Object that mouse is hitting
CBaseObjectPtr m_pHitObject;
/// Boxes to render for debug drawing
std::vector<AABB> m_DebugBoxes;
/// For each object, a tree containing its vertices.
std::map<CBaseObjectPtr, CKDTree*> m_ObjectKdTreeMap;
};
#endif // CRYINCLUDE_EDITOR_EDITMODE_VERTEXSNAPPINGMODETOOL_H
-89
View File
@@ -1,89 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "EditorDefs.h"
#include "EditTool.h"
// Editor
#include "Include/IObjectManager.h"
#include "Objects/SelectionGroup.h"
//////////////////////////////////////////////////////////////////////////
// Class description.
//////////////////////////////////////////////////////////////////////////
class CEditTool_ClassDesc
: public CRefCountClassDesc
{
virtual ESystemClassID SystemClassID() { return ESYSTEM_CLASS_EDITTOOL; }
virtual REFGUID ClassID()
{
// {0A43AB8E-B1AE-44aa-93B1-229F73D58CA4}
static const GUID guid = {
0xa43ab8e, 0xb1ae, 0x44aa, { 0x93, 0xb1, 0x22, 0x9f, 0x73, 0xd5, 0x8c, 0xa4 }
};
return guid;
}
virtual QString ClassName() { return "EditTool.Default"; };
virtual QString Category() { return "EditTool"; };
};
CEditTool_ClassDesc g_stdClassDesc;
//////////////////////////////////////////////////////////////////////////
CEditTool::CEditTool(QObject* parent)
: QObject(parent)
{
m_pClassDesc = &g_stdClassDesc;
m_nRefCount = 0;
};
//////////////////////////////////////////////////////////////////////////
void CEditTool::SetParentTool(CEditTool* pTool)
{
m_pParentTool = pTool;
}
//////////////////////////////////////////////////////////////////////////
CEditTool* CEditTool::GetParentTool()
{
return m_pParentTool;
}
//////////////////////////////////////////////////////////////////////////
void CEditTool::Abort()
{
if (m_pParentTool)
{
GetIEditor()->SetEditTool(m_pParentTool);
}
else
{
GetIEditor()->SetEditTool(0);
}
}
//////////////////////////////////////////////////////////////////////////
void CEditTool::GetAffectedObjects(DynArray<CBaseObject*>& outAffectedObjects)
{
CSelectionGroup* pSelection = GetIEditor()->GetObjectManager()->GetSelection();
if (pSelection == NULL)
{
return;
}
for (int i = 0, iCount(pSelection->GetCount()); i < iCount; ++i)
{
outAffectedObjects.push_back(pSelection->GetObject(i));
}
}
#include <moc_EditTool.cpp>
-175
View File
@@ -1,175 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_EDITOR_EDITTOOL_H
#define CRYINCLUDE_EDITOR_EDITTOOL_H
#pragma once
#if !defined(Q_MOC_RUN)
#include "QtViewPaneManager.h"
#endif
class CViewport;
struct IClassDesc;
struct ITransformManipulator;
struct HitContext;
enum EEditToolType
{
EDIT_TOOL_TYPE_PRIMARY,
EDIT_TOOL_TYPE_SECONDARY,
};
/*!
* CEditTool is an abstract base class for All Editing Tools supported by Editor.
* Edit tools handle specific editing modes in viewports.
*/
class SANDBOX_API CEditTool
: public QObject
{
Q_OBJECT
public:
explicit CEditTool(QObject* parent = nullptr);
//////////////////////////////////////////////////////////////////////////
// For reference counting.
//////////////////////////////////////////////////////////////////////////
void AddRef() { m_nRefCount++; };
void Release()
{
AZ_Assert(m_nRefCount > 0, "Negative ref count");
if (--m_nRefCount == 0)
{
DeleteThis();
}
};
//! Returns class description for this tool.
IClassDesc* GetClassDesc() const { return m_pClassDesc; }
virtual void SetParentTool(CEditTool* pTool);
virtual CEditTool* GetParentTool();
virtual EEditToolType GetType() { return EDIT_TOOL_TYPE_PRIMARY; }
virtual EOperationMode GetMode() { return eOperationModeNone; }
// Abort tool.
virtual void Abort();
// Accept tool.
virtual void Accept([[maybe_unused]] bool resetPosition = false) {}
//! Status text displayed when this tool is active.
void SetStatusText(const QString& text) { m_statusText = text; };
QString GetStatusText() { return m_statusText; };
// Description:
// Activates tool.
// Arguments:
// pPreviousTool - Previously active edit tool.
// Return:
// True if the tool can be activated,
virtual bool Activate([[maybe_unused]] CEditTool* pPreviousTool) { return true; };
//! Used to pass user defined data to edit tool from ToolButton.
virtual void SetUserData([[maybe_unused]] const char* key, [[maybe_unused]] void* userData) {};
//! Called when user starts using this tool.
//! Flags is comnination of ObjectEditFlags flags.
virtual void BeginEditParams([[maybe_unused]] IEditor* ie, [[maybe_unused]] int flags) {};
//! Called when user ends using this tool.
virtual void EndEditParams() {};
// Called each frame to display tool for given viewport.
virtual void Display(struct DisplayContext& dc) = 0;
//! Mouse callback sent from viewport.
//! Returns true if event processed by callback, and all other processing for this event should abort.
//! Return false if event was not processed by callback, and other processing for this event should occur.
//! @param view Viewport that sent this callback.
//! @param event Indicate what kind of event occured in viewport.
//! @param point 2D coordinate in viewport where event occured.
//! @param flags Additional flags (MK_LBUTTON,etc..) or from (MouseEventFlags) specified by viewport when calling callback.
virtual bool MouseCallback(CViewport* view, EMouseEvent event, QPoint& point, int flags) = 0;
//! Called when key in viewport is pressed while using this tool.
//! Returns true if event processed by callback, and all other processing for this event should abort.
//! Returns false if event was not processed by callback, and other processing for this event should occur.
//! @param view Viewport where key was pressed.
//! @param nChar Specifies the virtual key code of the given key. For a list of standard virtual key codes, see Winuser.h
//! @param nRepCnt Specifies the repeat count, that is, the number of times the keystroke is repeated as a result of the user holding down the key.
//! @param nFlags Specifies the scan code, key-transition code, previous key state, and context code, (see WM_KEYDOWN)
virtual bool OnKeyDown([[maybe_unused]] CViewport* view, [[maybe_unused]] uint32 nChar, [[maybe_unused]] uint32 nRepCnt, [[maybe_unused]] uint32 nFlags) { return false; };
//! Called when key in viewport is released while using this tool.
//! Returns true if event processed by callback, and all other processing for this event should abort.
//! Returns false if event was not processed by callback, and other processing for this event should occur.
//! @param view Viewport where key was pressed.
//! @param nChar Specifies the virtual key code of the given key. For a list of standard virtual key codes, see Winuser.h
//! @param nRepCnt Specifies the repeat count, that is, the number of times the keystroke is repeated as a result of the user holding down the key.
//! @param nFlags Specifies the scan code, key-transition code, previous key state, and context code, (see WM_KEYDOWN)
virtual bool OnKeyUp([[maybe_unused]] CViewport* view, [[maybe_unused]] uint32 nChar, [[maybe_unused]] uint32 nRepCnt, [[maybe_unused]] uint32 nFlags) { return false; };
//! Called when mouse is moved and give oportunity to tool to set it own cursor.
//! @return true if cursor changed. or false otherwise.
virtual bool OnSetCursor([[maybe_unused]] CViewport* vp) { return false; };
// Return objects affected by this edit tool. The returned objects usually will be the selected objects.
virtual void GetAffectedObjects(DynArray<CBaseObject*>& outAffectedObjects);
// Called in response to the dragging of the manipulator in the view.
// Allow edit tool to handle manipulator dragging the way it wants.
virtual void OnManipulatorDrag([[maybe_unused]] CViewport* view, [[maybe_unused]] ITransformManipulator* pManipulator, [[maybe_unused]] QPoint& p0, [[maybe_unused]] QPoint& p1, [[maybe_unused]] const Vec3& value) {}
virtual void OnManipulatorDrag(CViewport* view, ITransformManipulator* pManipulator, const Vec3& value)
{
// Overload with less boiler-plate
QPoint p0, p1;
OnManipulatorDrag(view, pManipulator, p0, p1, value);
}
// Called in response to mouse event of the manipulator in the view
virtual void OnManipulatorMouseEvent([[maybe_unused]] CViewport* view, [[maybe_unused]] ITransformManipulator* pManipulator, [[maybe_unused]] EMouseEvent event, [[maybe_unused]] QPoint& point, [[maybe_unused]] int flags, [[maybe_unused]] bool bHitGizmo = false) {}
virtual bool IsNeedMoveTool() { return false; }
virtual bool IsNeedSpecificBehaviorForSpaceAcce() { return false; }
virtual bool IsNeedToSkipPivotBoxForObjects() { return false; }
virtual bool IsDisplayGrid() { return true; }
virtual bool IsUpdateUIPanel() { return false; }
virtual bool IsMoveToObjectModeAfterEnd() { return true; }
virtual bool IsCircleTypeRotateGizmo() { return false; }
// Draws object specific helpers for this tool
virtual void DrawObjectHelpers([[maybe_unused]] CBaseObject* pObject, [[maybe_unused]] DisplayContext& dc) {}
// Hit test against edit tool
virtual bool HitTest([[maybe_unused]] CBaseObject* pObject, [[maybe_unused]] HitContext& hc) { return false; }
protected:
virtual ~CEditTool() {};
//////////////////////////////////////////////////////////////////////////
// Delete edit tool.
//////////////////////////////////////////////////////////////////////////
virtual void DeleteThis() = 0;
protected:
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
_smart_ptr<CEditTool> m_pParentTool; // Pointer to parent edit tool.
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
QString m_statusText;
IClassDesc* m_pClassDesc;
int m_nRefCount;
};
#endif // CRYINCLUDE_EDITOR_EDITTOOL_H
@@ -63,11 +63,6 @@ void CEditorPreferencesPage_General::Reflect(AZ::SerializeContext& serialize)
->Field("DeepSelectionRange", &DeepSelection::m_deepSelectionRange)
->Field("StickDuplicate", &DeepSelection::m_stickDuplicate);
serialize.Class<VertexSnapping>()
->Version(1)
->Field("VertexCubeSize", &VertexSnapping::m_vertexCubeSize)
->Field("RenderPenetratedBoundBox", &VertexSnapping::m_bRenderPenetratedBoundBox);
serialize.Class<SliceSettings>()
->Version(1)
->Field("DynamicByDefault", &SliceSettings::m_slicesDynamicByDefault);
@@ -78,7 +73,6 @@ void CEditorPreferencesPage_General::Reflect(AZ::SerializeContext& serialize)
->Field("Messaging", &CEditorPreferencesPage_General::m_messaging)
->Field("Undo", &CEditorPreferencesPage_General::m_undo)
->Field("Deep Selection", &CEditorPreferencesPage_General::m_deepSelection)
->Field("Vertex Snapping", &CEditorPreferencesPage_General::m_vertexSnapping)
->Field("Slice Settings", &CEditorPreferencesPage_General::m_sliceSettings);
@@ -119,12 +113,6 @@ void CEditorPreferencesPage_General::Reflect(AZ::SerializeContext& serialize)
->Attribute(AZ::Edit::Attributes::Min, 0.0f)
->Attribute(AZ::Edit::Attributes::Max, 1000.0f);
editContext->Class<VertexSnapping>("Vertex Snapping", "")
->DataElement(AZ::Edit::UIHandlers::SpinBox, &VertexSnapping::m_vertexCubeSize, "Vertex Cube Size", "Vertex Cube Size")
->Attribute(AZ::Edit::Attributes::Min, 0.0001f)
->Attribute(AZ::Edit::Attributes::Max, 1.0f)
->DataElement(AZ::Edit::UIHandlers::CheckBox, &VertexSnapping::m_bRenderPenetratedBoundBox, "Render Penetrated BoundBoxes", "Render Penetrated BoundBoxes");
editContext->Class<SliceSettings>("Slices", "")
->DataElement(AZ::Edit::UIHandlers::CheckBox, &SliceSettings::m_slicesDynamicByDefault, "New Slices Dynamic By Default", "When creating slices, they will be set to dynamic by default");
@@ -135,7 +123,6 @@ void CEditorPreferencesPage_General::Reflect(AZ::SerializeContext& serialize)
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_General::m_messaging, "Messaging", "Messaging")
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_General::m_undo, "Undo", "Undo Preferences")
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_General::m_deepSelection, "Selection", "Selection")
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_General::m_vertexSnapping, "Vertex Snapping", "Vertex Snapping")
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_General::m_sliceSettings, "Slices", "Slice Settings");
}
}
@@ -189,10 +176,6 @@ void CEditorPreferencesPage_General::OnApply()
gSettings.deepSelectionSettings.fRange = m_deepSelection.m_deepSelectionRange;
gSettings.deepSelectionSettings.bStickDuplicate = m_deepSelection.m_stickDuplicate;
//vertex snapping
gSettings.vertexSnappingSettings.vertexCubeSize = m_vertexSnapping.m_vertexCubeSize;
gSettings.vertexSnappingSettings.bRenderPenetratedBoundBox = m_vertexSnapping.m_bRenderPenetratedBoundBox;
//slices
gSettings.sliceSettings.dynamicByDefault = m_sliceSettings.m_slicesDynamicByDefault;
@@ -236,10 +219,6 @@ void CEditorPreferencesPage_General::InitializeSettings()
m_deepSelection.m_deepSelectionRange = gSettings.deepSelectionSettings.fRange;
m_deepSelection.m_stickDuplicate = gSettings.deepSelectionSettings.bStickDuplicate;
//vertex snapping
m_vertexSnapping.m_vertexCubeSize = gSettings.vertexSnappingSettings.vertexCubeSize;
m_vertexSnapping.m_bRenderPenetratedBoundBox = gSettings.vertexSnappingSettings.bRenderPenetratedBoundBox;
//slices
m_sliceSettings.m_slicesDynamicByDefault = gSettings.sliceSettings.dynamicByDefault;
}
@@ -88,14 +88,6 @@ private:
bool m_stickDuplicate;
};
struct VertexSnapping
{
AZ_TYPE_INFO(VertexSnapping, "{20F16350-990C-4096-86E3-40D56DDDD702}")
float m_vertexCubeSize;
bool m_bRenderPenetratedBoundBox;
};
struct SliceSettings
{
AZ_TYPE_INFO(SliceSettings, "{8505CCC1-874C-4389-B51A-B9E5FF70CFDA}")
@@ -107,7 +99,6 @@ private:
Messaging m_messaging;
Undo m_undo;
DeepSelection m_deepSelection;
VertexSnapping m_vertexSnapping;
SliceSettings m_sliceSettings;
QIcon m_icon;
};
+12 -1
View File
@@ -65,7 +65,6 @@
#include "Util/fastlib.h"
#include "CryEditDoc.h"
#include "GameEngine.h"
#include "EditTool.h"
#include "ViewManager.h"
#include "Objects/DisplayContext.h"
#include "DisplaySettings.h"
@@ -679,6 +678,11 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event)
}
SetCurrentCursor(STD_CURSOR_GAME);
}
if (m_renderViewport)
{
m_renderViewport->GetControllerList()->SetEnabled(false);
}
}
break;
@@ -697,6 +701,11 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event)
RestoreViewportAfterGameMode();
}
if (m_renderViewport)
{
m_renderViewport->GetControllerList()->SetEnabled(true);
}
break;
case eNotify_OnCloseScene:
@@ -727,6 +736,8 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event)
// meters above the terrain (default terrain height is 32)
viewTM.SetTranslation(Vec3(sx * 0.5f, sy * 0.5f, 34.0f));
SetViewTM(viewTM);
UpdateScene();
}
break;
-3
View File
@@ -125,9 +125,6 @@ bool CGameExporter::Export(unsigned int flags, [[maybe_unused]] EEndian eExportE
{
QDir::setCurrent(pEditor->GetPrimaryCDFolder());
// Close all Editor tools
pEditor->SetEditTool(0);
QString sLevelPath = Path::AddSlash(pGameEngine->GetLevelPath());
if (subdirectory && subdirectory[0] && strcmp(subdirectory, ".") != 0)
{
-9
View File
@@ -40,7 +40,6 @@ struct QMetaObject;
class CBaseObject;
class CCryEditDoc;
class CSelectionGroup;
class CEditTool;
class CAnimationContext;
class CTrackViewSequenceManager;
class CGameEngine;
@@ -623,14 +622,6 @@ struct IEditor
//! editMode - EEditMode
virtual void SetEditMode(int editMode) = 0;
virtual int GetEditMode() = 0;
//! Assign current edit tool, destroy previously used edit too.
virtual void SetEditTool(CEditTool* tool, bool bStopCurrentTool = true) = 0;
//! Assign current edit tool by class name.
virtual void SetEditTool(const QString& sEditToolName, bool bStopCurrentTool = true) = 0;
//! Reinitializes the current edit tool if one is selected.
virtual void ReinitializeEditTool() = 0;
//! Returns current edit tool.
virtual CEditTool* GetEditTool() = 0;
//! Shows/Hides transformation manipulator.
//! if bShow is true also returns a valid ITransformManipulator pointer.
virtual ITransformManipulator* ShowTransformManipulator(bool bShow) = 0;
-157
View File
@@ -54,7 +54,6 @@ AZ_POP_DISABLE_WARNING
#include "Export/ExportManager.h"
#include "LevelIndependentFileMan.h"
#include "Material/MaterialManager.h"
#include "Material/MaterialPickTool.h"
#include "TrackView/TrackViewSequenceManager.h"
#include "AnimationContext.h"
#include "GameEngine.h"
@@ -71,13 +70,9 @@ AZ_POP_DISABLE_WARNING
#include "Objects/SelectionGroup.h"
#include "Objects/ObjectManager.h"
#include "RotateTool.h"
#include "NullEditTool.h"
#include "BackgroundTaskManager.h"
#include "BackgroundScheduleManager.h"
#include "EditorFileMonitor.h"
#include "EditMode/VertexSnappingModeTool.h"
#include "Mission.h"
#include "MainStatusBar.h"
@@ -451,12 +446,6 @@ void CEditorImpl::RegisterTools()
rc.pCommandManager = m_pCommandManager;
rc.pClassFactory = m_pClassFactory;
CObjectMode::RegisterTool(rc);
CMaterialPickTool::RegisterTool(rc);
CVertexSnappingModeTool::RegisterTool(rc);
CRotateTool::RegisterTool(rc);
NullEditTool::RegisterTool(rc);
}
void CEditorImpl::ExecuteCommand(const char* sCommand, ...)
@@ -682,14 +671,6 @@ void CEditorImpl::SetEditMode(int editMode)
}
}
if ((EEditMode)editMode == eEditModeRotate)
{
if (GetEditTool() && GetEditTool()->IsCircleTypeRotateGizmo())
{
editMode = eEditModeRotateCircle;
}
}
EEditMode newEditMode = (EEditMode)editMode;
if (m_currEditMode == newEditMode)
{
@@ -700,11 +681,6 @@ void CEditorImpl::SetEditMode(int editMode)
AABB box(Vec3(0, 0, 0), Vec3(0, 0, 0));
SetSelectedRegion(box);
if (GetEditTool() && !GetEditTool()->IsNeedMoveTool())
{
SetEditTool(0, true);
}
Notify(eNotify_OnEditModeChange);
}
@@ -719,139 +695,6 @@ EOperationMode CEditorImpl::GetOperationMode()
return m_operationMode;
}
bool CEditorImpl::HasCorrectEditTool() const
{
if (!m_pEditTool)
{
return false;
}
switch (m_currEditMode)
{
case eEditModeRotate:
return qobject_cast<CRotateTool*>(m_pEditTool) != nullptr;
default:
return qobject_cast<CObjectMode*>(m_pEditTool) != nullptr && qobject_cast<CRotateTool*>(m_pEditTool) == nullptr;
}
}
CEditTool* CEditorImpl::CreateCorrectEditTool()
{
if (m_currEditMode == eEditModeRotate)
{
CBaseObject* selectedObj = nullptr;
CSelectionGroup* pSelection = GetIEditor()->GetObjectManager()->GetSelection();
if (pSelection && pSelection->GetCount() > 0)
{
selectedObj = pSelection->GetObject(0);
}
return (new CRotateTool(selectedObj));
}
return (new CObjectMode);
}
void CEditorImpl::SetEditTool(CEditTool* tool, bool bStopCurrentTool)
{
CViewport* pViewport = GetIEditor()->GetActiveView();
if (pViewport)
{
pViewport->SetCurrentCursor(STD_CURSOR_DEFAULT);
}
if (!tool)
{
if (HasCorrectEditTool())
{
return;
}
else
{
tool = CreateCorrectEditTool();
}
}
if (!tool->Activate(m_pEditTool))
{
return;
}
if (bStopCurrentTool)
{
if (m_pEditTool && m_pEditTool != tool)
{
m_pEditTool->EndEditParams();
SetStatusText("Ready");
}
}
m_pEditTool = tool;
if (m_pEditTool)
{
m_pEditTool->BeginEditParams(this, 0);
}
Notify(eNotify_OnEditToolChange);
}
void CEditorImpl::ReinitializeEditTool()
{
if (m_pEditTool)
{
m_pEditTool->EndEditParams();
m_pEditTool->BeginEditParams(this, 0);
}
}
void CEditorImpl::SetEditTool(const QString& sEditToolName, [[maybe_unused]] bool bStopCurrentTool)
{
CEditTool* pTool = GetEditTool();
if (pTool && pTool->GetClassDesc())
{
// Check if already selected.
if (QString::compare(pTool->GetClassDesc()->ClassName(), sEditToolName, Qt::CaseInsensitive) == 0)
{
return;
}
}
IClassDesc* pClass = GetIEditor()->GetClassFactory()->FindClass(sEditToolName.toUtf8().data());
if (!pClass)
{
Warning("Editor Tool %s not registered.", sEditToolName.toUtf8().data());
return;
}
if (pClass->SystemClassID() != ESYSTEM_CLASS_EDITTOOL)
{
Warning("Class name %s is not a valid Edit Tool class.", sEditToolName.toUtf8().data());
return;
}
QScopedPointer<QObject> o(pClass->CreateQObject());
if (CEditTool* pEditTool = qobject_cast<CEditTool*>(o.data()))
{
GetIEditor()->SetEditTool(pEditTool);
o.take();
return;
}
else
{
Warning("Class name %s is not a valid Edit Tool class.", sEditToolName.toUtf8().data());
return;
}
}
CEditTool* CEditorImpl::GetEditTool()
{
if (m_isNewViewportInteractionModelEnabled)
{
return nullptr;
}
return m_pEditTool;
}
ITransformManipulator* CEditorImpl::ShowTransformManipulator(bool bShow)
{
if (bShow)
-13
View File
@@ -229,18 +229,6 @@ public:
void SetEditMode(int editMode);
int GetEditMode();
//! A correct tool is one that corresponds to the previously set edit mode.
bool HasCorrectEditTool() const;
//! Returns the edit tool required for the edit mode specified.
CEditTool* CreateCorrectEditTool();
void SetEditTool(CEditTool* tool, bool bStopCurrentTool = true) override;
void SetEditTool(const QString& sEditToolName, bool bStopCurrentTool = true) override;
void ReinitializeEditTool() override;
//! Returns current edit tool.
CEditTool* GetEditTool() override;
ITransformManipulator* ShowTransformManipulator(bool bShow);
ITransformManipulator* GetTransformManipulator();
void SetAxisConstraints(AxisConstrains axis);
@@ -400,7 +388,6 @@ protected:
CXmlTemplateRegistry m_templateRegistry;
CDisplaySettings* m_pDisplaySettings;
CShaderEnum* m_pShaderEnum;
_smart_ptr<CEditTool> m_pEditTool;
CIconManager* m_pIconManager;
std::unique_ptr<SGizmoParameters> m_pGizmoParameters;
QString m_primaryCDFolder;
@@ -188,8 +188,6 @@ public:
virtual void SetSelection(const QString& name) = 0;
//! Removes one of named selections.
virtual void RemoveSelection(const QString& name) = 0;
//! Checks for changes to the current selection and makes adjustments accordingly
virtual void CheckAndFixSelection() = 0;
//! Delete all objects in current selection group.
virtual void DeleteSelection() = 0;
+11 -52
View File
@@ -25,7 +25,6 @@
#include "Objects/SelectionGroup.h"
#include "Include/IObjectManager.h"
#include "MathConversion.h"
#include "EditTool.h"
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
#include <ui_InfoBar.h>
@@ -58,7 +57,6 @@ CInfoBar::CInfoBar(QWidget* parent)
m_prevEditMode = 0;
m_bSelectionLocked = false;
m_bSelectionChanged = false;
m_editTool = 0;
m_bDragMode = false;
m_prevMoveSpeed = 0;
m_currValue = Vec3(-111, +222, -333); //this wasn't initialized. I don't know what a good value is
@@ -251,28 +249,6 @@ void CInfoBar::OnVectorUpdate(bool followTerrain)
ITransformManipulator* pManipulator = GetIEditor()->GetTransformManipulator();
if (pManipulator)
{
CEditTool* pEditTool = GetIEditor()->GetEditTool();
if (pEditTool)
{
Vec3 diff = v - m_lastValue;
if (emode == eEditModeMove)
{
//GetIEditor()->RestoreUndo();
pEditTool->OnManipulatorDrag(GetIEditor()->GetActiveView(), pManipulator, diff);
}
if (emode == eEditModeRotate)
{
diff = DEG2RAD(diff);
//GetIEditor()->RestoreUndo();
pEditTool->OnManipulatorDrag(GetIEditor()->GetActiveView(), pManipulator, diff);
}
if (emode == eEditModeScale)
{
//GetIEditor()->RestoreUndo();
pEditTool->OnManipulatorDrag(GetIEditor()->GetActiveView(), pManipulator, diff);
}
}
return;
}
@@ -421,39 +397,22 @@ void CInfoBar::IdleUpdate()
updateUI = true;
}
if (GetIEditor()->GetEditTool() != m_editTool)
{
updateUI = true;
m_editTool = GetIEditor()->GetEditTool();
}
QString str;
if (m_editTool)
{
str = m_editTool->GetStatusText();
if (str != m_sLastText)
{
updateUI = true;
}
}
if (updateUI)
{
if (!m_editTool)
if (m_numSelected == 0)
{
if (m_numSelected == 0)
{
str = tr("None Selected");
}
else if (m_numSelected == 1)
{
str = tr("1 Object Selected");
}
else
{
str = tr("%1 Objects Selected").arg(m_numSelected);
}
str = tr("None Selected");
}
else if (m_numSelected == 1)
{
str = tr("1 Object Selected");
}
else
{
str = tr("%1 Objects Selected").arg(m_numSelected);
}
ui->m_statusText->setText(str);
m_sLastText = str;
}
-1
View File
@@ -124,7 +124,6 @@ protected:
bool m_bDragMode;
QString m_sLastText;
CEditTool* m_editTool;
Vec3 m_lastValue;
Vec3 m_currValue;
float m_oldMainVolume;
@@ -408,6 +408,13 @@ bool LegacyViewportCameraControllerInstance::HandleInputChannelEvent(const AzFra
}
}
UpdateCursorCapture(shouldCaptureCursor);
return shouldConsumeEvent;
}
void LegacyViewportCameraControllerInstance::UpdateCursorCapture(bool shouldCaptureCursor)
{
if (m_capturingCursor != shouldCaptureCursor)
{
if (shouldCaptureCursor)
@@ -427,8 +434,14 @@ bool LegacyViewportCameraControllerInstance::HandleInputChannelEvent(const AzFra
m_capturingCursor = shouldCaptureCursor;
}
}
return shouldConsumeEvent;
void LegacyViewportCameraControllerInstance::ResetInputChannels()
{
m_modifiers = 0;
m_pressedKeys.clear();
UpdateCursorCapture(false);
m_inRotateMode = m_inMoveMode = m_inOrbitMode = m_inZoomMode = false;
}
void LegacyViewportCameraControllerInstance::UpdateViewport(const AzFramework::ViewportControllerUpdateEvent& event)
@@ -35,6 +35,7 @@ namespace SandboxEditor
explicit LegacyViewportCameraControllerInstance(AzFramework::ViewportId viewport);
bool HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event) override;
void ResetInputChannels() override;
void UpdateViewport(const AzFramework::ViewportControllerUpdateEvent& event) override;
private:
@@ -53,6 +54,7 @@ namespace SandboxEditor
bool HandleMouseMove(const AzFramework::ScreenPoint& currentMousePos, const AzFramework::ScreenPoint& previousMousePos);
bool HandleMouseWheel(float zDelta);
bool IsKeyDown(Qt::Key key) const;
void UpdateCursorCapture(bool shouldCaptureCursor);
bool m_inRotateMode = false;
bool m_inMoveMode = false;
@@ -125,10 +125,6 @@ public:
MOCK_METHOD0(GetOperationMode, EOperationMode());
MOCK_METHOD1(SetEditMode, void(int ));
MOCK_METHOD0(GetEditMode, int());
MOCK_METHOD2(SetEditTool, void(CEditTool*, bool));
MOCK_METHOD2(SetEditTool, void(const QString&, bool));
MOCK_METHOD0(ReinitializeEditTool, void());
MOCK_METHOD0(GetEditTool, CEditTool* ());
MOCK_METHOD1(ShowTransformManipulator, ITransformManipulator* (bool));
MOCK_METHOD0(GetTransformManipulator, ITransformManipulator* ());
MOCK_METHOD1(SetAxisConstraints, void(AxisConstrains ));
-23
View File
@@ -60,7 +60,6 @@ AZ_POP_DISABLE_WARNING
// Editor
#include "Resource.h"
#include "EditTool.h"
#include "Core/LevelEditorMenuHandler.h"
#include "ShortcutDispatcher.h"
#include "LayoutWnd.h"
@@ -270,15 +269,6 @@ namespace
return QtViewPaneManager::instance()->IsVisible(viewClassName);
}
AZStd::string PyGetStatusText()
{
if (GetIEditor()->GetEditTool())
{
return AZStd::string(GetIEditor()->GetEditTool()->GetStatusText().toUtf8().data());
}
return AZStd::string("");
}
AZStd::vector<AZStd::string> PyGetViewPaneNames()
{
const QtViewPanes panes = QtViewPaneManager::instance()->GetRegisteredPanes();
@@ -693,7 +683,6 @@ void MainWindow::closeEvent(QCloseEvent* event)
}
// Close all edit panels.
GetIEditor()->ClearSelection();
GetIEditor()->SetEditTool(0);
GetIEditor()->GetObjectManager()->EndEditParams();
// force clean up of all deferred deletes, so that we don't have any issues with windows from plugins not being deleted yet
@@ -1104,11 +1093,6 @@ void MainWindow::InitActions()
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateSelected)
.SetIcon(Style::icon("Align_to_grid"))
.SetApplyHoverEffect();
am->AddAction(ID_MODIFY_ALIGNOBJTOSURF, tr("Align object to surface (Hold CTRL)")).SetCheckable(true)
.SetToolTip(tr("Align object to surface (Hold CTRL)"))
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateAlignToVoxel)
.SetIcon(Style::icon("Align_object_to_surface"))
.SetApplyHoverEffect();
}
am->AddAction(ID_SNAP_TO_GRID, tr("Snap to grid"))
@@ -1459,10 +1443,6 @@ void MainWindow::InitActions()
.SetIcon(QIcon(":/MainWindow/toolbars/object_toolbar-03.svg"))
.SetApplyHoverEffect()
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateSelected);
// vertex snapping not yet supported when the new Viewport Interaction Model is enabled
am->AddAction(ID_OBJECTMODIFY_VERTEXSNAPPING, tr("Vertex snapping"))
.SetIcon(Style::icon("Vertex_snapping"))
.SetApplyHoverEffect();
}
// Misc Toolbar Actions
@@ -1510,8 +1490,6 @@ void MainWindow::OnEscapeAction()
{
AzToolsFramework::EditorEvents::Bus::Broadcast(
&AzToolsFramework::EditorEvents::OnEscape);
CCryEditApp::instance()->OnEditEscape();
}
}
}
@@ -2640,7 +2618,6 @@ namespace AzToolsFramework
addLegacyGeneral(behaviorContext->Method("exit", PyExit, nullptr, "Exits the editor."));
addLegacyGeneral(behaviorContext->Method("exit_no_prompt", PyExitNoPrompt, nullptr, "Exits the editor without prompting to save first."));
addLegacyGeneral(behaviorContext->Method("report_test_result", PyReportTest, nullptr, "Report test information."));
addLegacyGeneral(behaviorContext->Method("get_status_text", PyGetStatusText, nullptr, "Gets the status text from the Editor's current edit tool"));
}
}
}
@@ -1,170 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "EditorDefs.h"
#include "MaterialPickTool.h"
// Editor
#include "MaterialManager.h"
#include "SurfaceInfoPicker.h"
#include "Viewport.h"
#define RENDER_MESH_TEST_DISTANCE 0.2f
static IClassDesc * s_ToolClass = NULL;
//////////////////////////////////////////////////////////////////////////
CMaterialPickTool::CMaterialPickTool()
{
m_pClassDesc = s_ToolClass;
m_statusText = tr("Left Click To Pick Material");
}
//////////////////////////////////////////////////////////////////////////
CMaterialPickTool::~CMaterialPickTool()
{
SetMaterial(0);
}
//////////////////////////////////////////////////////////////////////////
bool CMaterialPickTool::MouseCallback(CViewport* view, EMouseEvent event, QPoint& point, int flags)
{
if (event == eMouseLDown)
{
if (m_pMaterial)
{
CMaterial* pMtl = GetIEditor()->GetMaterialManager()->FromIMaterial(m_pMaterial);
if (pMtl)
{
GetIEditor()->GetMaterialManager()->SetHighlightedMaterial(0);
GetIEditor()->OpenMaterialLibrary(pMtl);
Abort();
return true;
}
}
}
else if (event == eMouseMove)
{
return OnMouseMove(view, flags, point);
}
return true;
}
//////////////////////////////////////////////////////////////////////////
void CMaterialPickTool::Display(DisplayContext& dc)
{
QPoint mousePoint = QCursor::pos();
dc.view->ScreenToClient(mousePoint);
Vec3 wp = dc.view->ViewToWorld(mousePoint);
if (m_pMaterial)
{
float color[4] = {1, 1, 1, 1};
dc.renderer->Draw2dLabel(mousePoint.x() + 12, mousePoint.y ()+ 8, 1.2f, color, false, "%s", m_displayString.toUtf8().data());
}
float fScreenScale = dc.view->GetScreenScaleFactor(m_HitInfo.vHitPos) * 0.06f;
dc.DepthTestOff();
dc.SetColor(ColorB(0, 0, 255, 255));
if (!m_HitInfo.vHitNormal.IsZero())
{
dc.DrawLine(m_HitInfo.vHitPos, m_HitInfo.vHitPos + m_HitInfo.vHitNormal * fScreenScale);
Vec3 raySrc, rayDir;
dc.view->ViewToWorldRay(mousePoint, raySrc, rayDir);
Matrix34 tm;
Vec3 zAxis = m_HitInfo.vHitNormal;
Vec3 xAxis = rayDir.Cross(zAxis);
if (!xAxis.IsZero())
{
xAxis.Normalize();
Vec3 yAxis = xAxis.Cross(zAxis).GetNormalized();
tm.SetFromVectors(xAxis, yAxis, zAxis, m_HitInfo.vHitPos);
dc.PushMatrix(tm);
dc.DrawCircle(Vec3(0, 0, 0), 0.5f * fScreenScale);
dc.PopMatrix();
}
}
dc.DepthTestOn();
}
//////////////////////////////////////////////////////////////////////////
bool CMaterialPickTool::OnMouseMove(CViewport* view, [[maybe_unused]] UINT nFlags, const QPoint& point)
{
view->SetCurrentCursor(STD_CURSOR_HIT, "");
_smart_ptr<IMaterial> pNearestMaterial(NULL);
m_Mouse2DPosition = point;
CSurfaceInfoPicker surfacePicker;
int nPickObjectGroupFlag = CSurfaceInfoPicker::ePOG_All;
if (surfacePicker.Pick(point, pNearestMaterial, m_HitInfo, NULL, nPickObjectGroupFlag))
{
SetMaterial(pNearestMaterial);
return true;
}
SetMaterial(0);
return false;
}
const GUID& CMaterialPickTool::GetClassID()
{
// {FD20F6F2-7B87-4349-A5D4-7533538E357F}
static const GUID guid = {
0xfd20f6f2, 0x7b87, 0x4349, { 0xa5, 0xd4, 0x75, 0x33, 0x53, 0x8e, 0x35, 0x7f }
};
return guid;
}
//////////////////////////////////////////////////////////////////////////
void CMaterialPickTool::RegisterTool(CRegistrationContext& rc)
{
rc.pClassFactory->RegisterClass(s_ToolClass = new CQtViewClass<CMaterialPickTool>("EditTool.PickMaterial", "Material", ESYSTEM_CLASS_EDITTOOL));
}
//////////////////////////////////////////////////////////////////////////
void CMaterialPickTool::SetMaterial(_smart_ptr<IMaterial> pMaterial)
{
if (pMaterial == m_pMaterial)
{
return;
}
m_pMaterial = pMaterial;
CMaterial* pCMaterial = GetIEditor()->GetMaterialManager()->FromIMaterial(m_pMaterial);
GetIEditor()->GetMaterialManager()->SetHighlightedMaterial(pCMaterial);
m_displayString = "";
if (pMaterial)
{
QString sfType;
sfType = QStringLiteral("%1 : %2").arg(pMaterial->GetSurfaceType()->GetId()).arg(pMaterial->GetSurfaceType()->GetName());
m_displayString = "\n";
m_displayString += pMaterial->GetName();
m_displayString += "\n";
m_displayString += sfType;
}
}
#include <Material/moc_MaterialPickTool.cpp>
@@ -1,57 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Definition of PickObjectTool, tool used to pick objects.
#ifndef CRYINCLUDE_EDITOR_MATERIAL_MATERIALPICKTOOL_H
#define CRYINCLUDE_EDITOR_MATERIAL_MATERIALPICKTOOL_H
#pragma once
#include "EditTool.h"
//////////////////////////////////////////////////////////////////////////
class CMaterialPickTool
: public CEditTool
{
Q_OBJECT
public:
Q_INVOKABLE CMaterialPickTool();
static const GUID& GetClassID();
static void RegisterTool(CRegistrationContext& rc);
//////////////////////////////////////////////////////////////////////////
// CEditTool implementation
//////////////////////////////////////////////////////////////////////////
virtual bool MouseCallback(CViewport* view, EMouseEvent event, QPoint& point, int flags);
virtual void Display(DisplayContext& dc);
//////////////////////////////////////////////////////////////////////////
protected:
bool OnMouseMove(CViewport* view, UINT nFlags, const QPoint& point);
void SetMaterial(_smart_ptr<IMaterial> pMaterial);
virtual ~CMaterialPickTool();
// Delete itself.
void DeleteThis() { delete this; };
_smart_ptr<IMaterial> m_pMaterial;
QString m_displayString;
QPoint m_Mouse2DPosition;
SRayHitInfo m_HitInfo;
};
#endif // CRYINCLUDE_EDITOR_MATERIAL_MATERIALPICKTOOL_H
-37
View File
@@ -1,37 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "EditorDefs.h"
#include "NullEditTool.h"
NullEditTool::NullEditTool() {}
const GUID& NullEditTool::GetClassID()
{
// {65AFF87A-34E0-479B-B062-94B1B867B13D}
static const GUID guid =
{
0x65AFF87A, 0x34E0, 0x479B,{ 0xB0, 0x62, 0x94, 0xB1, 0xB8, 0x67, 0xB1, 0x3D }
};
return guid;
}
void NullEditTool::RegisterTool(CRegistrationContext& rc)
{
rc.pClassFactory->RegisterClass(
new CQtViewClass<NullEditTool>("EditTool.NullEditTool", "Select", ESYSTEM_CLASS_EDITTOOL));
}
#include <moc_NullEditTool.cpp>
-39
View File
@@ -1,39 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#if !defined(Q_MOC_RUN)
#include "EditTool.h"
#endif
/// An EditTool that does nothing - it provides the Null-Object pattern.
class SANDBOX_API NullEditTool
: public CEditTool
{
Q_OBJECT
public:
Q_INVOKABLE NullEditTool();
virtual ~NullEditTool() = default;
static const GUID& GetClassID();
static void RegisterTool(CRegistrationContext& rc);
// CEditTool
void BeginEditParams([[maybe_unused]] IEditor* ie, [[maybe_unused]] int flags) override {}
void EndEditParams() override {}
void Display([[maybe_unused]] DisplayContext& dc) override {}
bool MouseCallback([[maybe_unused]] CViewport* view, [[maybe_unused]] EMouseEvent event, [[maybe_unused]] QPoint& point, [[maybe_unused]] int flags) override { return false; }
bool OnKeyDown([[maybe_unused]] CViewport* view, [[maybe_unused]] uint32 nChar, [[maybe_unused]] uint32 nRepCnt, [[maybe_unused]] uint32 nFlags) override { return false; }
bool OnKeyUp([[maybe_unused]] CViewport* view, [[maybe_unused]] uint32 nChar, [[maybe_unused]] uint32 nRepCnt, [[maybe_unused]] uint32 nFlags) override { return true; }
void DeleteThis() override { delete this; }
};
-336
View File
@@ -1,336 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "EditorDefs.h"
#include "ObjectCloneTool.h"
// Editor
#include "MainWindow.h"
#include "Viewport.h"
#include "ViewManager.h"
#include "Include/IObjectManager.h"
#include "Objects/SelectionGroup.h"
#include "Settings.h"
//////////////////////////////////////////////////////////////////////////
// Class description.
//////////////////////////////////////////////////////////////////////////
class CObjectCloneTool_ClassDesc
: public CRefCountClassDesc
{
virtual ESystemClassID SystemClassID() { return ESYSTEM_CLASS_EDITTOOL; }
virtual REFGUID ClassID()
{
// {6A73E865-71DF-4ED0-ABA2-457E66119B35}
static const GUID guid = {
0x6a73e865, 0x71df, 0x4ed0,{ 0xab, 0xa2, 0x45, 0x7e, 0x66, 0x11, 0x9b, 0x35 }
};
return guid;
}
virtual QString ClassName() { return "EditTool.Clone"; };
virtual QString Category() { return "EditTool"; };
};
CObjectCloneTool_ClassDesc g_cloneClassDesc;
//////////////////////////////////////////////////////////////////////////
CObjectCloneTool::CObjectCloneTool()
: m_currentUndoBatch(nullptr)
{
m_pClassDesc = &g_cloneClassDesc;
m_bSetConstrPlane = true;
GetIEditor()->SuperBeginUndo();
GetIEditor()->BeginUndo();
m_selection = nullptr;
if (!GetIEditor()->GetSelection()->IsEmpty())
{
QWaitCursor wait;
CloneSelection();
m_selection = GetIEditor()->GetSelection();
m_origin = m_selection->GetCenter();
}
GetIEditor()->AcceptUndo("Clone");
GetIEditor()->BeginUndo();
if (!gSettings.deepSelectionSettings.bStickDuplicate)
{
SetStatusText("Clone object at the same location");
}
else
{
SetStatusText("Left click to clone object");
}
}
//////////////////////////////////////////////////////////////////////////
CObjectCloneTool::~CObjectCloneTool()
{
EndUndoBatch();
if (GetIEditor()->IsUndoRecording())
{
GetIEditor()->SuperCancelUndo();
}
}
//////////////////////////////////////////////////////////////////////////
void CObjectCloneTool::CloneSelection()
{
// Allow component application to intercept cloning behavior.
// This is to allow support for "smart" cloning of prefabs, and other contextual features.
AZ_Assert(!m_currentUndoBatch, "CloneSelection undo batch already created.");
EBUS_EVENT_RESULT(m_currentUndoBatch, AzToolsFramework::ToolsApplicationRequests::Bus, BeginUndoBatch, "Clone Selection");
bool handled = false;
EBUS_EVENT(AzToolsFramework::EditorRequests::Bus, CloneSelection, handled);
if (handled)
{
GetIEditor()->GetObjectManager()->CheckAndFixSelection();
return;
}
// This is the legacy case. We're not cloning AZ entities, so abandon the AZ undo batch.
EndUndoBatch();
CSelectionGroup selObjects;
CSelectionGroup sel;
CSelectionGroup* currSelection = GetIEditor()->GetSelection();
currSelection->Clone(selObjects);
GetIEditor()->ClearSelection();
for (int i = 0; i < selObjects.GetCount(); i++)
{
if (selObjects.GetObject(i))
{
GetIEditor()->SelectObject(selObjects.GetObject(i));
}
}
MainWindow::instance()->setFocus();
}
//////////////////////////////////////////////////////////////////////////
void CObjectCloneTool::SetConstrPlane(CViewport* view, [[maybe_unused]] const QPoint& point)
{
Matrix34 originTM;
originTM.SetIdentity();
CSelectionGroup* selection = GetIEditor()->GetSelection();
if (selection->GetCount() == 1)
{
originTM = selection->GetObject(0)->GetWorldTM();
}
else if (selection->GetCount() > 1)
{
originTM = selection->GetObject(0)->GetWorldTM();
Vec3 center = view->SnapToGrid(originTM.GetTranslation());
originTM.SetTranslation(center);
}
view->SetConstructionMatrix(COORDS_LOCAL, originTM);
}
//static Vec3 gP1,gP2;
//////////////////////////////////////////////////////////////////////////
void CObjectCloneTool::Display([[maybe_unused]] DisplayContext& dc)
{
//dc.SetColor( 1,1,0,1 );
//dc.DrawBall( gP1,1.1f );
//dc.DrawBall( gP2,1.1f );
}
//////////////////////////////////////////////////////////////////////////
bool CObjectCloneTool::MouseCallback(CViewport* view, EMouseEvent event, QPoint& point, int flags)
{
if (m_selection)
{
// Set construction plane origin to selection origin.
if (m_bSetConstrPlane)
{
SetConstrPlane(view, point);
m_bSetConstrPlane = false;
}
if (event == eMouseLDown)
{
// Accept group.
Accept();
GetIEditor()->GetSelection()->FinishChanges();
return true;
}
if (event == eMouseMove)
{
// Move selection.
CSelectionGroup* selection = GetIEditor()->GetSelection();
if (selection != m_selection)
{
Abort();
}
else if (!selection->IsEmpty())
{
GetIEditor()->RestoreUndo();
Vec3 v;
bool followTerrain = false;
CSelectionGroup* pSelection = GetIEditor()->GetSelection();
Vec3 selectionCenter = view->SnapToGrid(pSelection->GetCenter());
int axis = GetIEditor()->GetAxisConstrains();
if (axis == AXIS_TERRAIN)
{
bool hitTerrain;
v = view->ViewToWorld(point, &hitTerrain) - selectionCenter;
if (axis == AXIS_TERRAIN)
{
v = view->SnapToGrid(v);
if (hitTerrain)
{
followTerrain = true;
v.z = 0;
}
}
}
else
{
Vec3 p1 = selectionCenter;
Vec3 p2 = view->MapViewToCP(point);
if (p2.IsZero())
{
return true;
}
v = view->GetCPVector(p1, p2);
// Snap v offset to grid if its enabled.
view->SnapToGrid(v);
}
CSelectionGroup::EMoveSelectionFlag selectionFlag = CSelectionGroup::eMS_None;
if (followTerrain)
{
selectionFlag = CSelectionGroup::eMS_FollowTerrain;
}
// Disable undo recording for these move commands as the only operation we need
// to undo is the creation of the new object. Undo commands are queued so it's
// possible that the object creation could be undone before attempting to undo
// these move operations causing undesired behavior.
bool wasRecording = CUndo::IsRecording();
if (wasRecording)
{
GetIEditor()->SuspendUndo();
}
GetIEditor()->GetSelection()->Move(v, selectionFlag, GetIEditor()->GetReferenceCoordSys(), point);
if (wasRecording)
{
GetIEditor()->ResumeUndo();
}
}
}
if (event == eMouseWheel)
{
CSelectionGroup* selection = GetIEditor()->GetSelection();
if (selection != m_selection)
{
Abort();
}
else if (!selection->IsEmpty())
{
double angle = 1;
if (view->GetViewManager()->GetGrid()->IsAngleSnapEnabled())
{
angle = view->GetViewManager()->GetGrid()->GetAngleSnap();
}
for (int i = 0; i < selection->GetCount(); ++i)
{
CBaseObject* pObj = selection->GetFilteredObject(i);
Quat rot = pObj->GetRotation();
rot.SetRotationXYZ(Ang3(0, 0, rot.GetRotZ() + DEG2RAD(flags > 0 ? angle * (-1) : angle)));
pObj->SetRotation(rot);
}
GetIEditor()->AcceptUndo("Rotate Selection");
}
}
}
return true;
}
//////////////////////////////////////////////////////////////////////////
void CObjectCloneTool::Abort()
{
EndUndoBatch();
// Abort
GetIEditor()->SetEditTool(0);
}
//////////////////////////////////////////////////////////////////////////
void CObjectCloneTool::Accept(bool resetPosition)
{
// Close the az undo batch so it can add the appropriate objects to the cry undo stack
EndUndoBatch();
if (resetPosition)
{
GetIEditor()->GetSelection()->MoveTo(m_origin, CSelectionGroup::eMS_None, GetIEditor()->GetReferenceCoordSys());
}
if (GetIEditor()->IsUndoRecording())
{
GetIEditor()->SuperAcceptUndo("Clone");
}
GetIEditor()->SetEditTool(0);
}
//////////////////////////////////////////////////////////////////////////
void CObjectCloneTool::EndUndoBatch()
{
if (m_currentUndoBatch)
{
AzToolsFramework::UndoSystem::URSequencePoint* undoBatch = nullptr;
EBUS_EVENT_RESULT(undoBatch, AzToolsFramework::ToolsApplicationRequests::Bus, GetCurrentUndoBatch);
AZ_Error("ObjectCloneTool", undoBatch == m_currentUndoBatch, "Undo batch is not in sync.");
if (undoBatch == m_currentUndoBatch)
{
EBUS_EVENT(AzToolsFramework::ToolsApplicationRequests::Bus, EndUndoBatch);
}
m_currentUndoBatch = nullptr;
}
}
//////////////////////////////////////////////////////////////////////////
void CObjectCloneTool::BeginEditParams([[maybe_unused]] IEditor* ie, [[maybe_unused]] int flags)
{
}
//////////////////////////////////////////////////////////////////////////
void CObjectCloneTool::EndEditParams()
{
}
//////////////////////////////////////////////////////////////////////////
bool CObjectCloneTool::OnKeyDown([[maybe_unused]] CViewport* view, uint32 nChar, [[maybe_unused]] uint32 nRepCnt, [[maybe_unused]] uint32 nFlags)
{
if (nChar == VK_ESCAPE)
{
Abort();
}
return false;
}
#include <moc_ObjectCloneTool.cpp>
-81
View File
@@ -1,81 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Definition of ObjectCloneTool, edit tool for cloning of objects..
#ifndef CRYINCLUDE_EDITOR_OBJECTCLONETOOL_H
#define CRYINCLUDE_EDITOR_OBJECTCLONETOOL_H
#pragma once
#include "EditTool.h"
class CBaseObject;
namespace AzToolsFramework
{
namespace UndoSystem
{
class URSequencePoint;
}
}
/*!
* CObjectCloneTool, When created duplicate current selection, and manages cloned selection.
*
*/
class CObjectCloneTool
: public CEditTool
{
Q_OBJECT
public:
Q_INVOKABLE CObjectCloneTool();
//////////////////////////////////////////////////////////////////////////
// Ovverides from CEditTool
bool MouseCallback(CViewport* view, EMouseEvent event, QPoint& point, int flags);
virtual void BeginEditParams(IEditor* ie, int flags);
virtual void EndEditParams();
virtual void Display(DisplayContext& dc);
virtual bool OnKeyDown(CViewport* view, uint32 nChar, uint32 nRepCnt, uint32 nFlags);
virtual bool OnKeyUp([[maybe_unused]] CViewport* view, [[maybe_unused]] uint32 nChar, [[maybe_unused]] uint32 nRepCnt, [[maybe_unused]] uint32 nFlags) { return false; };
//////////////////////////////////////////////////////////////////////////
void Accept(bool resetPosition = false);
void Abort();
protected:
virtual ~CObjectCloneTool();
// Delete itself.
void DeleteThis() { delete this; };
private:
void CloneSelection();
void SetConstrPlane(CViewport* view, const QPoint& point);
CSelectionGroup* m_selection;
Vec3 m_origin;
bool m_bSetConstrPlane;
//bool m_bSetCapture;
void EndUndoBatch();
AzToolsFramework::UndoSystem::URSequencePoint* m_currentUndoBatch;
};
#endif // CRYINCLUDE_EDITOR_OBJECTCLONETOOL_H
-25
View File
@@ -24,7 +24,6 @@
#include "RenderHelpers/AxisHelper.h"
#include "RenderHelpers/AxisHelperExtended.h"
#include "IObjectManager.h"
#include "EditTool.h"
//////////////////////////////////////////////////////////////////////////
// CAxisGizmo implementation.
@@ -381,12 +380,6 @@ bool CAxisGizmo::MouseCallback(CViewport* view, EMouseEvent event, QPoint& point
break;
}
CEditTool* pEditTool = view->GetEditTool();
if (pEditTool)
{
pEditTool->OnManipulatorMouseEvent(view, this, event, point, nFlags);
}
return true;
}
}
@@ -540,12 +533,6 @@ bool CAxisGizmo::MouseCallback(CViewport* view, EMouseEvent event, QPoint& point
break;
}
CEditTool* pEditTool = view->GetEditTool();
if (pEditTool && bCallBack)
{
pEditTool->OnManipulatorDrag(view, this, m_cMouseDownPos, point, vDragValue);
}
return true;
}
else
@@ -573,12 +560,6 @@ bool CAxisGizmo::MouseCallback(CViewport* view, EMouseEvent event, QPoint& point
}
bHit = true;
}
CEditTool* pEditTool = view->GetEditTool();
if (pEditTool)
{
pEditTool->OnManipulatorMouseEvent(view, this, event, point, nFlags, bHit);
}
}
}
else if (event == eMouseLUp)
@@ -593,12 +574,6 @@ bool CAxisGizmo::MouseCallback(CViewport* view, EMouseEvent event, QPoint& point
{
GetIEditor()->SetReferenceCoordSys(m_coordSysBackUp);
}
CEditTool* pEditTool = view->GetEditTool();
if (pEditTool)
{
pEditTool->OnManipulatorMouseEvent(view, this, event, point, nFlags);
}
}
}
@@ -39,7 +39,6 @@
#include "ViewManager.h"
#include "IEditorImpl.h"
#include "GameEngine.h"
#include "EditTool.h"
// To use the Andrew's algorithm in order to make convex hull from the points, this header is needed.
#include "Util/GeometryUtil.h"
@@ -3264,11 +3263,6 @@ ERotationWarningLevel CBaseObject::GetRotationWarningLevel() const
bool CBaseObject::IsSkipSelectionHelper() const
{
CEditTool* pEditTool(GetIEditor()->GetEditTool());
if (pEditTool && pEditTool->IsNeedToSkipPivotBoxForObjects())
{
return true;
}
return false;
}
@@ -22,12 +22,10 @@
#include "Settings.h"
#include "DisplaySettings.h"
#include "EntityObject.h"
#include "NullEditTool.h"
#include "Viewport.h"
#include "GizmoManager.h"
#include "AxisGizmo.h"
#include "ObjectPhysicsManager.h"
#include "EditMode/ObjectMode.h"
#include "GameEngine.h"
#include "WaitProgress.h"
#include "Util/Image.h"
@@ -838,8 +836,6 @@ void CObjectManager::Update()
QWidget* prevActiveWindow = QApplication::activeWindow();
CheckAndFixSelection();
// Restore focus if it changed.
if (prevActiveWindow && QApplication::activeWindow() != prevActiveWindow)
{
@@ -1230,60 +1226,6 @@ void CObjectManager::RemoveSelection(const QString& name)
}
}
//! Checks the state of the current selection and fixes it if necessary - Used when AZ Code modifies the selection
void CObjectManager::CheckAndFixSelection()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
bool bObjectMode = qobject_cast<CObjectMode*>(GetIEditor()->GetEditTool()) != nullptr;
if (m_currSelection->GetCount() == 0)
{
// Nothing selected.
EndEditParams();
if (bObjectMode)
{
GetIEditor()->ShowTransformManipulator(false);
}
}
else if (m_currSelection->GetCount() == 1)
{
if (!m_bSingleSelection)
{
EndEditParams();
}
CBaseObject* newSelObject = m_currSelection->GetObject(0);
// Single object selected.
if (m_currEditObject != m_currSelection->GetObject(0))
{
m_bSelectionChanged = false;
if (!m_currEditObject || (m_currEditObject->metaObject() != newSelObject->metaObject()))
{
// If old object and new objects are of different classes.
EndEditParams();
}
if (GetIEditor()->GetEditTool() && GetIEditor()->GetEditTool()->IsUpdateUIPanel())
{
BeginEditParams(newSelObject, OBJECT_EDIT);
}
//AfxGetMainWnd()->SetFocus();
}
}
else if (m_currSelection->GetCount() > 1)
{
// Multiple objects are selected.
if (m_bSelectionChanged && bObjectMode)
{
m_bSelectionChanged = false;
m_nLastSelCount = m_currSelection->GetCount();
EndEditParams();
m_currEditObject = m_currSelection->GetObject(0);
}
}
}
void CObjectManager::SelectCurrent()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
@@ -1404,8 +1346,6 @@ void CObjectManager::FindDisplayableObjects(DisplayContext& dc, bool bDisplay)
pDispayedViewObjects->ClearObjects();
pDispayedViewObjects->Reserve(m_visibleObjects.size());
CEditTool* pEditTool = GetIEditor()->GetEditTool();
const bool newViewportInteractionModelEnabled = GetIEditor()->IsNewViewportInteractionModelEnabled();
if (dc.flags & DISPLAY_2D)
@@ -1426,11 +1366,6 @@ void CObjectManager::FindDisplayableObjects(DisplayContext& dc, bool bDisplay)
{
obj->Display(dc);
}
if (pEditTool)
{
pEditTool->DrawObjectHelpers(obj, dc);
}
}
}
}
@@ -1476,11 +1411,6 @@ void CObjectManager::FindDisplayableObjects(DisplayContext& dc, bool bDisplay)
{
obj->Display(dc);
}
if (pEditTool)
{
pEditTool->DrawObjectHelpers(obj, dc);
}
}
}
}
@@ -1737,12 +1667,6 @@ bool CObjectManager::HitTestObject(CBaseObject* obj, HitContext& hc)
{
return false;
}
CEditTool* pEditTool = GetIEditor()->GetEditTool();
if (pEditTool && pEditTool->HitTest(obj, hc))
{
return true;
}
}
return (bSelectionHelperHit || obj->HitTest(hc));
@@ -2742,10 +2666,6 @@ void CObjectManager::SelectObjectInRect(CBaseObject* pObj, CViewport* view, HitC
void CObjectManager::EnteredComponentMode(const AZStd::vector<AZ::Uuid>& /*componentModeTypes*/)
{
// provide an EditTool that does nothing.
// note: will hide rotation gizmo when active (CRotateTool)
GetIEditor()->SetEditTool(new NullEditTool());
// hide current gizmo for entity (translate/rotate/scale)
IGizmoManager* gizmoManager = GetGizmoManager();
const size_t gizmoCount = static_cast<size_t>(gizmoManager->GetGizmoCount());
@@ -2757,9 +2677,6 @@ void CObjectManager::EnteredComponentMode(const AZStd::vector<AZ::Uuid>& /*compo
void CObjectManager::LeftComponentMode(const AZStd::vector<AZ::Uuid>& /*componentModeTypes*/)
{
// return to default EditTool (in whatever transform mode is set)
GetIEditor()->SetEditTool(nullptr);
// show translate/rotate/scale gizmo again
if (IGizmoManager* gizmoManager = GetGizmoManager())
{
@@ -226,8 +226,6 @@ public:
//! Set one of name selections as current selection.
void SetSelection(const QString& name);
void RemoveSelection(const QString& name);
//! Checks for changes to the current selection and makes adjustments accordingly
void CheckAndFixSelection() override;
bool IsObjectDeletionAllowed(CBaseObject* pObject);
+18 -2
View File
@@ -36,6 +36,8 @@
#include <algorithm>
#include <QScopedValueRollback>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzAssetBrowser/AzAssetBrowserWindow.h>
#include <AzToolsFramework/UI/UICore/WidgetHelpers.h>
#include <AzQtComponents/Utilities/AutoSettingsGroup.h>
@@ -983,6 +985,11 @@ bool QtViewPaneManager::ClosePanesWithRollback(const QVector<QString>& panesToKe
*/
void QtViewPaneManager::RestoreDefaultLayout(bool resetSettings)
{
// Get whether the prefab system is enabled
bool isPrefabSystemEnabled = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
isPrefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
if (resetSettings)
{
// We're going to do something destructive (removing all of the viewpane settings). Better confirm with the user
@@ -1022,7 +1029,11 @@ void QtViewPaneManager::RestoreDefaultLayout(bool resetSettings)
state.viewPanes.push_back(LyViewPane::EntityInspector);
state.viewPanes.push_back(LyViewPane::AssetBrowser);
state.viewPanes.push_back(LyViewPane::Console);
state.viewPanes.push_back(LyViewPane::LevelInspector);
if (!isPrefabSystemEnabled)
{
state.viewPanes.push_back(LyViewPane::LevelInspector);
}
state.mainWindowState = m_defaultMainWindowState;
@@ -1047,7 +1058,12 @@ void QtViewPaneManager::RestoreDefaultLayout(bool resetSettings)
const QtViewPane* assetBrowserViewPane = OpenPane(LyViewPane::AssetBrowser, QtViewPane::OpenMode::UseDefaultState);
const QtViewPane* entityInspectorViewPane = OpenPane(LyViewPane::EntityInspector, QtViewPane::OpenMode::UseDefaultState);
const QtViewPane* consoleViewPane = OpenPane(LyViewPane::Console, QtViewPane::OpenMode::UseDefaultState);
const QtViewPane* levelInspectorPane = OpenPane(LyViewPane::LevelInspector, QtViewPane::OpenMode::UseDefaultState);
const QtViewPane* levelInspectorPane = nullptr;
if (!isPrefabSystemEnabled)
{
levelInspectorPane = OpenPane(LyViewPane::LevelInspector, QtViewPane::OpenMode::UseDefaultState);
}
// This class does all kinds of behind the scenes magic to make docking / restore work, especially with groups
// so instead of doing our special default layout attach / docking right now, we want to make it happen
@@ -17,7 +17,6 @@
#include "Include/IDisplayViewport.h"
#include "Include/HitContext.h"
#include "Util/Math.h"
#include "EditTool.h"
#include "IObjectManager.h"
#include <Cry_Geo.h>
-40
View File
@@ -66,7 +66,6 @@
#include "Util/fastlib.h"
#include "CryEditDoc.h"
#include "GameEngine.h"
#include "EditTool.h"
#include "ViewManager.h"
#include "Objects/DisplayContext.h"
#include "DisplaySettings.h"
@@ -1948,12 +1947,6 @@ void CRenderViewport::RenderAll()
m_entityVisibilityQuery.DisplayVisibility(*debugDisplay);
if (GetEditTool())
{
// display editing tool
GetEditTool()->Display(displayContext);
}
if (m_manipulatorManager != nullptr)
{
using namespace AzToolsFramework::ViewportInteraction;
@@ -2776,35 +2769,6 @@ void CRenderViewport::OnMouseWheel(Qt::KeyboardModifiers modifiers, short zDelta
handled = result != MouseInteractionResult::None;
}
else
{
if (m_manipulatorManager == nullptr || m_manipulatorManager->ConsumeViewportMouseWheel(mouseInteraction))
{
return;
}
if (AzToolsFramework::ComponentModeFramework::InComponentMode())
{
AzToolsFramework::EditorInteractionSystemViewportSelectionRequestBus::EventResult(
handled, AzToolsFramework::GetEntityContextId(),
&EditorInteractionSystemViewportSelectionRequestBus::Events::InternalHandleMouseViewportInteraction,
MouseInteractionEvent(mouseInteraction, zDelta));
}
else
{
//////////////////////////////////////////////////////////////////////////
// Asks current edit tool to handle mouse callback.
CEditTool* pEditTool = GetEditTool();
if (pEditTool && (modifiers & Qt::ControlModifier))
{
QPoint tempPoint(scaledPoint.x(), scaledPoint.y());
if (pEditTool->MouseCallback(this, eMouseWheel, tempPoint, zDelta))
{
handled = true;
}
}
}
}
if (!handled)
{
@@ -4347,10 +4311,6 @@ void CRenderViewport::RenderSnappingGrid()
{
return;
}
if (GetIEditor()->GetEditTool() && !GetIEditor()->GetEditTool()->IsDisplayGrid())
{
return;
}
DisplayContext& dc = m_displayContext;
-2
View File
@@ -123,7 +123,6 @@
#define ID_TOOL_SHELVE_LAST 33375
#define ID_EDIT_SELECTALL 33376
#define ID_EDIT_SELECTNONE 33377
#define ID_OBJECTMODIFY_VERTEXSNAPPING 33384
#define ID_WIREFRAME 33410
#define ID_FILE_GENERATETERRAINTEXTURE 33445
#define ID_GENERATORS_LIGHTING 33446
@@ -275,7 +274,6 @@
#define ID_GAME_PC_ENABLEMEDIUMSPEC 33961
#define ID_GAME_PC_ENABLEHIGHSPEC 33962
#define ID_GAME_PC_ENABLEVERYHIGHSPEC 33963
#define ID_MODIFY_ALIGNOBJTOSURF 33968
#define ID_PANEL_VEG_CREATE_SEL 33990
#define ID_TOOLS_UPDATEPROCEDURALVEGETATION 33999
#define ID_DISPLAY_GOTOPOSITION 34004
File diff suppressed because it is too large Load Diff
-283
View File
@@ -1,283 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#ifndef CRYINCLUDE_EDITOR_ROTATETOOL_H
#define CRYINCLUDE_EDITOR_ROTATETOOL_H
#pragma once
#if !defined(Q_MOC_RUN)
#include "EditTool.h"
#include "IObjectManager.h"
#include "EditMode/ObjectMode.h"
#include "Objects/BaseObject.h" // for CBaseObject::EventListener
#include "Objects/DisplayContext.h"
#include "Include/HitContext.h"
#endif
//! Provides rendering utilities to support CRotateTool
namespace RotationDrawHelper
{
//! Circle drawing and hit testing functionality over arbitrary axes
class Axis
{
public:
//! \param defaultColor Color used to draw the camera aligned portion of the axis.
//! \param highlightColor Color used to draw the circle when it is in focus.
Axis(const ColorF& defaultColor = Col_White, const ColorF& highlightColor = Col_Yellow);
//! Draws an axis aligned circle.
//! \param dc DisplayContext to use for rendering.
//! \param position World space position used as the center of the circle.
//! \param axis The axis by which to align the circle.
//! \param angleRadians The angle towards which the circle will be highlighted.
//! \param radius The radius of the circle.
//! \param highlighted If true it will draw the circle in the specified highlightColor.
void Draw(DisplayContext& dc, const Vec3& position, const Vec3& axis, float angleRadians, float angleStepRadians, float radius, bool highlighted, CBaseObject* object, float screenScale);
//! Calculates a hit testing mesh (invisible) used for intersection testing.
//! \param object The object selected if hit testing return true.
//! \param hc The HitContext in which the hit object is set if an intersection is true.
//! \param radius The radius for the axis' circle.
//! \param angleStepRadians The angle for the step used to calculate the circle, a smaller angle results in a higher quality circle.
//! \param axis The axis by which to align the intersection geometry.
//! \param screenScale This is an internal parameter used to deduce the view distance ratio in order to scale the tool.
bool HitTest(CBaseObject* object, HitContext& hc, float radius, float angleStepRadians, const Vec3& axis, float screenScale);
//! Draws the generated hit testing geometry, good for diagnostics and debugging.
//! \param dc DisplayContext to use for rendering.
//! \param hc The HitContext that contains the view direction raycast.
//! \param position World space position used as the center of the circle.
//! \param radius The radius for the axis' circle.
//! \param angleStepRadians The angle for the step used to calculate the circle, a smaller angle results in a higher quality circle.
//! \param axis The axis by which to align the intersection geometry.
//! \param screenScale This is an internal parameter used to deduce the view distance ratio in order to scale the tool.
void DebugDrawHitTestSurface(DisplayContext& dc, HitContext& hc, const Vec3& position, float radius, float angleStepRadians, const Vec3& axis, float screenScale);
protected:
enum States
{
StateDefault,
StateHighlight,
StateCount
};
ColorF m_colors[StateCount];
//! Defines the width of the generated hit testing geometry.
float m_hitTestWidth = 0.4f;
//! Contains the vertices that make up the ring for the intersection testing geometry.
//! \remark Only contains the center positions, quads are generated by calculating the four vertices offset by m_hitTestWidth.
std::vector<Vec3> m_vertices;
//! Generates the world space geometry necessary to perform hit testing.
//! \param hc The HitContext data.
//! \param position The world space position around which the geometry will be centered.
//! \param radius The radius of the ring.
//! \param angleStepRadians The angle for the step used to calculate the circle, a smaller angle results in a higher quality circle.
//! \param axis The axis to which the geometry will be aligned to.
//! \param screenScale This is an internal parameter used to deduce the view distance ratio in order to scale the tool.
void GenerateHitTestGeometry(HitContext& hc, const Vec3& position, float radius, float angleStepRadians, const Vec3& axis, float screenScale);
//! Performs intersection testing between a ray and both sides of a quad
//! \param ray The ray to test (in world space)
//! \param quad An array of four Vec3 points in world space.
//! \param[out] contact The intersection position in world space at which the intersection occurred.
bool IntersectRayWithQuad(const Ray&ray, Vec3 quad[4], Vec3 & contact);
};
//! Provides the means to set and restore DisplayContext settings within a given scope.
class DisplayContextScope
{
public:
DisplayContextScope(DisplayContext& dc)
: m_dc(dc)
{
m_dc.DepthTestOff();
m_dc.CullOff();
}
~DisplayContextScope()
{
m_dc.DepthTestOn();
m_dc.CullOn();
}
DisplayContext& m_dc;
};
//! Helper function that draws the representation of the inner angle of a rotation.
namespace AngleDecorator
{
//! \param dc
//! \param position World space position of the center of the decorator.
//! \param axisToAlign Axis to which the decorator will be aligned to.
//! \param startAngleRadians The starting angle from which the rotation will be performed.
//! \param sweepAngleRadians An angle that represents the sweep of the rotation arc.
//! \param angleStepRadians The angle for the step used to calculate the circle, a smaller angle results in a higher quality circle.
//! \param radius The radius of the decorator.
//! \param screenScale This is an internal parameter used to deduce the view distance ratio in order to scale the tool.
void Draw(DisplayContext& dc, const Vec3& position, const Vec3& axisToAlign, float startAngleRadians, float sweepAngleRadians, float stepAngleRadians, float radius, float screenScale);
}
}
//! Provides rotation manipulation controls.
class SANDBOX_API CRotateTool
: public CObjectMode
, public IObjectSelectCallback
, public CBaseObject::EventListener
{
Q_OBJECT
public:
Q_INVOKABLE CRotateTool(CBaseObject* pObject = nullptr, QWidget* parent = nullptr);
virtual ~CRotateTool();
static const GUID& GetClassID();
// Registration function.
static void RegisterTool(CRegistrationContext& rc);
void Display(DisplayContext& dc) override;
void DrawObjectHelpers([[maybe_unused]] CBaseObject* pObject, [[maybe_unused]] DisplayContext& dc) override {}
bool HitTest(CBaseObject* pObject, HitContext& hc) override;
void DeleteThis() override;
bool OnLButtonDown(CViewport* view, int nFlags, const QPoint& point) override;
bool OnLButtonUp(CViewport* view, int nFlags, const QPoint& point) override;
bool OnMouseMove(CViewport* view, int nFlags, const QPoint& point) override;
protected:
//! Utility to calculate the view distance ratio used to scale the tool.
float GetScreenScale(IDisplayViewport* view, CCamera* camera = nullptr);
enum Axis
{
AxisNone,
AxisX, //! X axis visualization and hit testing
AxisY, //! Y axis visualization and hit testing
AxisZ, //! Z axis visualization and hit testing
AxisView, //! View direction axis, used to rotate along the vector from the camera to the object.
AxisCount
};
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
//! Axis visualization and hit testing
RotationDrawHelper::Axis m_axes[Axis::AxisCount];
//! We record the starting angle when we begin to drag an object
float m_initialViewAxisAngleRadians;
//! The angle from the object's (or selection's) center to the mouse cursor.
float m_angleToCursor;
//! Specified which axis is currently selected.
Axis m_highlightAxis;
//! True when we are using the view direction rotation axis.
bool m_viewAxisRotation;
//! True when the mouse has been pressed, becomes false on release.
bool m_draggingMouse;
//! The last mouse position on screen when rotating.
QPoint m_lastPosition;
//! Cumulative rotation angle in degrees.
Ang3 m_rotationAngles;
//! The selected object.
CBaseObject* m_object;
//! True if there has been a change in rotation that affects the object.
bool m_bTransformChanged;
//! Sum of the total rotation angles.
float m_totalRotationAngle;
//! Radius used to draw the XYZ axes
float m_basisAxisRadius;
//! Radius used to draw the view direction axis
float m_viewAxisRadius;
//! Rotation step controls the quality of the axes, a smaller angle represents a higher number of vertices.
float m_arcRotationStepRadians;
//! Thickness of for the axis line rendering.
float m_lineThickness = 4.f;
//! Draws angle decorator for the current rotation axis.
void DrawAngleDecorator(DisplayContext& dc);
//! Useful for debugging and visualizing hit testing
void DrawHitTestGeometry(DisplayContext& dc, HitContext& hc);
//! Diagnostic tool to examine view direction angle (follows mouse cursor)
void DrawViewDirectionAngleTracking(DisplayContext& dc, HitContext& hc);
//! Callback registered to receive Selection callbacks to set m_object
bool OnSelectObject(CBaseObject* object) override;
//! Callback to check that an object can be selected
bool CanSelectObject(CBaseObject* object) override;
//! Callback installed on the object, used to determine destruction or deselection.
void OnObjectEvent(CBaseObject* object, int event) override;
//! Handle key down events.
bool OnKeyDown(CViewport* view, uint32 nChar, uint32 nRepCnt, uint32 nFlags) override;
//! Retrieves the object's transformation according to the specified reference coordinate system.
Matrix34 GetTransform(RefCoordSys referenceCoordinateSystem, IDisplayViewport* view);
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
//! Calculate orientation of 3 points on screen, return 1.0f if clockwise, -1.0f if counter-clockwise
float CalculateOrientation(const QPoint& p1, const QPoint& p2, const QPoint& p3);
private:
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
HitContext m_hc; //!< HACK: Cache the hitcontext given that it's values may differ depending on the viewport they are coming from.
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
};
//! Singleton that holds all the configuration cvars for the different features and debug options
//! used by the CRotationControl
class RotationControlConfiguration
{
public:
static RotationControlConfiguration& Get()
{
static RotationControlConfiguration instance;
return instance;
}
//! If enabled it will draw the inner rotation decorator.
DeclareConstIntCVar(RotationControl_DrawDecorators, 0);
//! If enabled the hit testing geometry is rendered.
DeclareConstIntCVar(RotationControl_DebugHitTesting, 0);
//! If enabled a sphere will be drawn to represent the view axis angle to the mouse cursor.
DeclareConstIntCVar(RotationControl_AngleTracking, 0);
private:
RotationControlConfiguration();
RotationControlConfiguration(const RotationControlConfiguration&) = delete;
RotationControlConfiguration& operator = (const RotationControlConfiguration&) = delete;
~RotationControlConfiguration() {}
};
#endif // CRYINCLUDE_EDITOR_ROTATETOOL_H
-12
View File
@@ -653,12 +653,6 @@ void SEditorSettings::Save()
SaveValue("Settings", "ForceSkyUpdate", gSettings.bForceSkyUpdate);
//////////////////////////////////////////////////////////////////////////
// Vertex snapping settings
//////////////////////////////////////////////////////////////////////////
SaveValue("Settings\\VertexSnapping", "VertexCubeSize", vertexSnappingSettings.vertexCubeSize);
SaveValue("Settings\\VertexSnapping", "RenderPenetratedBoundBox", vertexSnappingSettings.bRenderPenetratedBoundBox);
//////////////////////////////////////////////////////////////////////////
// Smart file open settings
//////////////////////////////////////////////////////////////////////////
@@ -886,12 +880,6 @@ void SEditorSettings::Load()
LoadValue("Settings", "ForceSkyUpdate", gSettings.bForceSkyUpdate);
//////////////////////////////////////////////////////////////////////////
// Vertex snapping settings
//////////////////////////////////////////////////////////////////////////
LoadValue("Settings\\VertexSnapping", "VertexCubeSize", vertexSnappingSettings.vertexCubeSize);
LoadValue("Settings\\VertexSnapping", "RenderPenetratedBoundBox", vertexSnappingSettings.bRenderPenetratedBoundBox);
//////////////////////////////////////////////////////////////////////////
// Smart file open settings
//////////////////////////////////////////////////////////////////////////
-15
View File
@@ -119,18 +119,6 @@ struct SDeepSelectionSettings
bool bStickDuplicate;
};
//////////////////////////////////////////////////////////////////////////
// Settings for vertex snapping.
//////////////////////////////////////////////////////////////////////////
struct SVertexSnappingSettings
{
SVertexSnappingSettings()
: vertexCubeSize(0.01f)
, bRenderPenetratedBoundBox(false) {}
float vertexCubeSize;
bool bRenderPenetratedBoundBox;
};
//////////////////////////////////////////////////////////////////////////
struct SObjectColors
{
@@ -474,9 +462,6 @@ AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
// Object Highlight Settings
SObjectColors objectColorSettings;
// Vertex Snapping Settings
SVertexSnappingSettings vertexSnappingSettings;
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
SSmartOpenDialogSettings smartOpenSettings;
-3
View File
@@ -625,7 +625,6 @@ AmazonToolbar ToolbarManager::GetObjectToolbar() const
t.AddAction(ID_GOTO_SELECTED, ORIGINAL_TOOLBAR_VERSION);
t.AddAction(ID_OBJECTMODIFY_ALIGNTOGRID, ORIGINAL_TOOLBAR_VERSION);
t.AddAction(ID_OBJECTMODIFY_SETHEIGHT, ORIGINAL_TOOLBAR_VERSION);
t.AddAction(ID_MODIFY_ALIGNOBJTOSURF, ORIGINAL_TOOLBAR_VERSION);
if (!GetIEditor()->IsNewViewportInteractionModelEnabled())
{
@@ -634,8 +633,6 @@ AmazonToolbar ToolbarManager::GetObjectToolbar() const
t.AddAction(ID_EDIT_UNFREEZEALL, ORIGINAL_TOOLBAR_VERSION);
}
t.AddAction(ID_OBJECTMODIFY_VERTEXSNAPPING, ORIGINAL_TOOLBAR_VERSION);
return t;
}
+2 -91
View File
@@ -30,7 +30,6 @@
#include "Util/Ruler.h"
#include "PluginManager.h"
#include "Include/IRenderListener.h"
#include "EditTool.h"
#include "GameEngine.h"
#include "Settings.h"
@@ -207,8 +206,6 @@ QtViewport::QtViewport(QWidget* parent)
GetIEditor()->GetViewManager()->RegisterViewport(this);
m_pLocalEditTool = 0;
m_nCurViewportID = MAX_NUM_VIEWPORTS - 1;
m_dropCallback = nullptr; // Leroy@Conffx
@@ -232,8 +229,6 @@ QtViewport::QtViewport(QWidget* parent)
//////////////////////////////////////////////////////////////////////////
QtViewport::~QtViewport()
{
if (m_pLocalEditTool)
m_pLocalEditTool->deleteLater();
delete m_pVisibleObjectsCache;
GetIEditor()->GetViewManager()->UnregisterViewport(this);
@@ -258,42 +253,6 @@ void QtViewport::GetDimensions(int* pWidth, int* pHeight) const
}
}
//////////////////////////////////////////////////////////////////////////
CEditTool* QtViewport::GetEditTool()
{
if (m_pLocalEditTool)
{
return m_pLocalEditTool;
}
return GetIEditor()->GetEditTool();
}
//////////////////////////////////////////////////////////////////////////
void QtViewport::SetEditTool(CEditTool* pEditTool, bool bLocalToViewport /*=false */)
{
if (m_pLocalEditTool == pEditTool)
{
return;
}
if (m_pLocalEditTool)
{
m_pLocalEditTool->EndEditParams();
}
m_pLocalEditTool = 0;
if (bLocalToViewport)
{
m_pLocalEditTool = pEditTool;
m_pLocalEditTool->BeginEditParams(GetIEditor(), 0);
}
else
{
m_pLocalEditTool = 0;
GetIEditor()->SetEditTool(pEditTool);
}
}
//////////////////////////////////////////////////////////////////////////
void QtViewport::RegisterRenderListener(IRenderListener* piListener)
{
@@ -466,12 +425,6 @@ void QtViewport::Update()
m_bAdvancedSelectMode = false;
bool bSpaceClick = false;
CEditTool* pEditTool = GetIEditor()->GetEditTool();
if (pEditTool && pEditTool->IsNeedSpecificBehaviorForSpaceAcce())
{
bSpaceClick = CheckVirtualKey(Qt::Key_Space);
}
else
{
bSpaceClick = CheckVirtualKey(Qt::Key_Space) & !CheckVirtualKey(Qt::Key_Shift) /*& !CheckVirtualKey(Qt::Key_Control)*/;
}
@@ -726,10 +679,6 @@ void QtViewport::OnMouseMove(Qt::KeyboardModifiers modifiers, Qt::MouseButtons b
//////////////////////////////////////////////////////////////////////////
void QtViewport::OnSetCursor()
{
if (GetEditTool())
{
GetEditTool()->OnSetCursor(this);
}
}
//////////////////////////////////////////////////////////////////////////
@@ -803,39 +752,23 @@ void QtViewport::OnRButtonDblClk(Qt::KeyboardModifiers modifiers, const QPoint&
}
//////////////////////////////////////////////////////////////////////////
void QtViewport::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
void QtViewport::OnKeyDown([[maybe_unused]] UINT nChar, [[maybe_unused]] UINT nRepCnt, [[maybe_unused]] UINT nFlags)
{
if (GetIEditor()->IsInGameMode())
{
// Ignore key downs while in game.
return;
}
if (GetEditTool())
{
if (GetEditTool()->OnKeyDown(this, nChar, nRepCnt, nFlags))
{
return;
}
}
}
//////////////////////////////////////////////////////////////////////////
void QtViewport::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
void QtViewport::OnKeyUp([[maybe_unused]] UINT nChar, [[maybe_unused]] UINT nRepCnt, [[maybe_unused]] UINT nFlags)
{
if (GetIEditor()->IsInGameMode())
{
// Ignore key downs while in game.
return;
}
if (GetEditTool())
{
if (GetEditTool()->OnKeyUp(this, nChar, nRepCnt, nFlags))
{
return;
}
}
}
//////////////////////////////////////////////////////////////////////////
@@ -1454,28 +1387,6 @@ bool QtViewport::MouseCallback(EMouseEvent event, const QPoint& point, Qt::Keybo
}
}
//////////////////////////////////////////////////////////////////////////
// Asks current edit tool to handle mouse callback.
CEditTool* pEditTool = GetEditTool();
if (pEditTool)
{
if (pEditTool->MouseCallback(this, event, tempPoint, flags))
{
return true;
}
// Ask all chain of parent tools if they are handling mouse event.
CEditTool* pParentTool = pEditTool->GetParentTool();
while (pParentTool)
{
if (pParentTool->MouseCallback(this, event, tempPoint, flags))
{
return true;
}
pParentTool = pParentTool->GetParentTool();
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////
-9
View File
@@ -45,7 +45,6 @@ struct DisplayContext;
class CCryEditDoc;
class CLayoutViewPane;
class CViewManager;
class CEditTool;
class CBaseObjectsCache;
struct HitContext;
struct IRenderListener;
@@ -255,8 +254,6 @@ public:
virtual void SetSupplementaryCursorStr(const QString& str) = 0;
virtual void SetCursorString(const QString& str) = 0;
virtual CEditTool* GetEditTool() = 0;
virtual void SetFocus() = 0;
virtual void Invalidate(BOOL bErase = 1) = 0;
@@ -488,10 +485,6 @@ public:
void ResetCursor();
void SetSupplementaryCursorStr(const QString& str);
virtual CEditTool* GetEditTool();
// Assign an edit tool to viewport
virtual void SetEditTool(CEditTool* pEditTool, bool bLocalToViewport = false);
//////////////////////////////////////////////////////////////////////////
// Return visble objects cache.
CBaseObjectsCache* GetVisibleObjectsCache() { return m_pVisibleObjectsCache; };
@@ -627,8 +620,6 @@ protected:
// Same construction matrix is shared by all viewports.
Matrix34 m_constructionMatrix[LAST_COORD_SYSTEM];
QPointer<CEditTool> m_pLocalEditTool;
std::vector<IRenderListener*> m_cRenderListeners;
typedef std::vector<_smart_ptr<IPostRenderer> > PostRenderers;
@@ -202,6 +202,12 @@ bool ViewportManipulatorControllerInstance::HandleInputChannelEvent(const AzFram
return interactionHandled;
}
void ViewportManipulatorControllerInstance::ResetInputChannels()
{
m_pendingDoubleClicks.clear();
m_state = AzToolsFramework::ViewportInteraction::MouseInteraction();
}
void ViewportManipulatorControllerInstance::UpdateViewport(const AzFramework::ViewportControllerUpdateEvent& event)
{
m_curTime = event.m_time;
@@ -26,6 +26,7 @@ namespace SandboxEditor
explicit ViewportManipulatorControllerInstance(AzFramework::ViewportId viewport);
bool HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event) override;
void ResetInputChannels() override;
void UpdateViewport(const AzFramework::ViewportControllerUpdateEvent& event) override;
private:
-151
View File
@@ -1,151 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "EditorDefs.h"
#include "VoxelAligningTool.h"
// Editor
#include "SurfaceInfoPicker.h"
#include "Objects/SelectionGroup.h"
//////////////////////////////////////////////////////////////////////////
CVoxelAligningTool::CVoxelAligningTool()
{
m_curObj = 0;
m_PreviewMode = ePM_Idle;
CSelectionGroup* sel = GetIEditor()->GetSelection();
if (!sel->IsEmpty())
{
m_curObj = sel->GetObject(0);
m_CurObjTMBeforePreviewMode = m_curObj->GetWorldTM();
m_q = m_curObj->GetRotation();
}
}
//////////////////////////////////////////////////////////////////////////
CVoxelAligningTool::~CVoxelAligningTool()
{
}
//////////////////////////////////////////////////////////////////////////
void CVoxelAligningTool::Display([[maybe_unused]] DisplayContext& dc)
{
}
//////////////////////////////////////////////////////////////////////////
bool CVoxelAligningTool::MouseCallback([[maybe_unused]] CViewport* view, EMouseEvent event, QPoint& point, int flags)
{
// Get contrl key status.
bool bCtrlClick = (flags & MK_CONTROL);
bool bShiftClick = (flags & MK_SHIFT);
bool bOnlyCtrlClick = bCtrlClick && !bShiftClick;
CSelectionGroup* sel = GetIEditor()->GetSelection();
if (sel->IsEmpty() || m_curObj != sel->GetObject(0))
{
GetIEditor()->SetEditTool(0);
return true;
}
if (event == eMouseMove)
{
if (m_PreviewMode == ePM_Idle)
{
if (bOnlyCtrlClick)
{
if (m_curObj)
{
m_CurObjTMBeforePreviewMode = m_curObj->GetWorldTM();
}
m_PreviewMode = ePM_Previewing;
GetIEditor()->BeginUndo();
}
}
else if (!bOnlyCtrlClick)
{
if (m_curObj)
{
m_curObj->SetWorldTM(m_CurObjTMBeforePreviewMode);
//m_curObj->SetRotation(m_extraRot);
}
m_PreviewMode = ePM_Idle;
GetIEditor()->CancelUndo();
}
if (m_PreviewMode == ePM_Previewing && bOnlyCtrlClick)
{ // Preview align to normal
ApplyPickedTM2CurObj(point);
}
}
if (event == eMouseLDown && m_PreviewMode == ePM_Previewing)
{
m_CurObjTMBeforePreviewMode = m_curObj->GetWorldTM();
GetIEditor()->AcceptUndo("Surface Normal Aligning");
GetIEditor()->SetEditTool(NULL);
}
return true;
}
//////////////////////////////////////////////////////////////////////////
void CVoxelAligningTool::ApplyPickedTM2CurObj(const QPoint& point, [[maybe_unused]] bool bPickOnlyTerrain)
{
int nPickFlag = CSurfaceInfoPicker::ePOG_All;
SRayHitInfo hitInfo;
CSurfaceInfoPicker::CExcludedObjects excludeObjects;
if (m_curObj)
{
excludeObjects.Add(m_curObj);
}
CSurfaceInfoPicker surfacePicker;
if (surfacePicker.Pick(point, hitInfo, &excludeObjects, nPickFlag))
{
m_curObj->SetPos(hitInfo.vHitPos, eObjectUpdateFlags_UserInput);
ApplyRotation(hitInfo.vHitNormal);
}
}
//////////////////////////////////////////////////////////////////////////
void CVoxelAligningTool::ApplyRotation(Vec3& normal)
{
Vec3 zaxis = m_q * Vec3(0, 0, 1);
zaxis.Normalize();
Quat nq;
nq.SetRotationV0V1(zaxis, normal);
m_curObj->SetRotation(nq * m_q, eObjectUpdateFlags_UserInput);
}
//////////////////////////////////////////////////////////////////////////
void CVoxelAligningTool::BeginEditParams([[maybe_unused]] IEditor* ie, [[maybe_unused]] int flags)
{
}
//////////////////////////////////////////////////////////////////////////
void CVoxelAligningTool::EndEditParams()
{
}
//////////////////////////////////////////////////////////////////////////
bool CVoxelAligningTool::OnKeyDown([[maybe_unused]] CViewport* view, uint32 nChar, [[maybe_unused]] uint32 nRepCnt, [[maybe_unused]] uint32 nFlags)
{
if (nChar == VK_ESCAPE)
{
GetIEditor()->SetEditTool(0);
}
return false;
}
#include <moc_VoxelAligningTool.cpp>
-75
View File
@@ -1,75 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Definition of VoxelAligningTool, edit tool for cloning of objects..
#ifndef CRYINCLUDE_EDITOR_VOXELALIGNINGTOOL_H
#define CRYINCLUDE_EDITOR_VOXELALIGNINGTOOL_H
#pragma once
#if !defined(Q_MOC_RUN)
#include "EditTool.h"
#endif
class CBaseObject;
/*!
* CVoxelAligningTool, When created duplicate current selection, and manages cloned selection.
*
*/
class CVoxelAligningTool
: public CEditTool
{
Q_OBJECT
public:
Q_INVOKABLE CVoxelAligningTool();
//////////////////////////////////////////////////////////////////////////
// Ovverides from CEditTool
bool MouseCallback(CViewport* view, EMouseEvent event, QPoint& point, int flags);
virtual void BeginEditParams(IEditor* ie, int flags);
virtual void EndEditParams();
virtual void Display(DisplayContext& dc);
virtual bool OnKeyDown(CViewport* view, uint32 nChar, uint32 nRepCnt, uint32 nFlags);
virtual bool OnKeyUp([[maybe_unused]] CViewport* view, [[maybe_unused]] uint32 nChar, [[maybe_unused]] uint32 nRepCnt, [[maybe_unused]] uint32 nFlags) { return false; };
//////////////////////////////////////////////////////////////////////////
protected:
virtual ~CVoxelAligningTool();
// Delete itself.
void DeleteThis() { delete this; };
void ApplyPickedTM2CurObj(const QPoint& point, bool bPickOnlyTerrain = false);
void ApplyRotation(Vec3& normal);
private:
CBaseObject* m_curObj;
Quat m_q;
enum EPreviewMode
{
ePM_Idle,
ePM_Previewing,
};
EPreviewMode m_PreviewMode;
Matrix34 m_CurObjTMBeforePreviewMode;
};
#endif // CRYINCLUDE_EDITOR_VOXELALIGNINGTOOL_H
@@ -10,8 +10,6 @@
#
set(FILES
NullEditTool.h
NullEditTool.cpp
Translations/editor_en-us.ts
Translations/assetbrowser_en-us.ts
DPIAware.xml
@@ -389,8 +387,6 @@ set(FILES
Controls/NumberCtrl.h
Controls/PreviewModelCtrl.cpp
Controls/PreviewModelCtrl.h
Controls/QRollupCtrl.cpp
Controls/QRollupCtrl.h
Controls/SplineCtrl.cpp
Controls/SplineCtrl.h
Controls/SplineCtrlEx.cpp
@@ -401,8 +397,6 @@ set(FILES
Controls/TimelineCtrl.h
Controls/TimeOfDaySlider.cpp
Controls/TimeOfDaySlider.h
Controls/ToolButton.cpp
Controls/ToolButton.h
Controls/WndGridHelper.h
Controls/ReflectedPropertyControl/PropertyAnimationCtrl.cpp
Controls/ReflectedPropertyControl/PropertyAnimationCtrl.h
@@ -451,8 +445,6 @@ set(FILES
CustomResolutionDlg.cpp
CustomResolutionDlg.ui
CustomResolutionDlg.h
Dialogs/ButtonsPanel.cpp
Dialogs/ButtonsPanel.h
ErrorReportDialog.ui
ErrorReportDialog.cpp
ErrorReportDialog.h
@@ -533,18 +525,8 @@ set(FILES
Dialogs/PythonScriptsDialog.ui
Dialogs/Generic/UserOptions.cpp
Dialogs/Generic/UserOptions.h
ObjectCloneTool.cpp
ObjectCloneTool.h
EditMode/SubObjectSelectionReferenceFrameCalculator.cpp
EditMode/SubObjectSelectionReferenceFrameCalculator.h
EditMode/ObjectMode.cpp
EditMode/ObjectMode.h
RotateTool.cpp
RotateTool.h
EditTool.cpp
EditTool.h
VoxelAligningTool.cpp
VoxelAligningTool.h
Export/ExportManager.cpp
Export/ExportManager.h
Export/OBJExporter.cpp
@@ -575,7 +557,6 @@ set(FILES
Dialogs/DuplicatedObjectsHandlerDlg.h
DocMultiArchive.h
EditMode/DeepSelection.h
EditMode/VertexSnappingModeTool.h
FBXExporterDialog.h
FileTypeUtils.h
GridUtils.h
@@ -639,8 +620,6 @@ set(FILES
Material/MaterialLibrary.h
Material/MaterialManager.cpp
Material/MaterialManager.h
Material/MaterialPickTool.cpp
Material/MaterialPickTool.h
MaterialSender.h
MaterialSender.cpp
Material/MaterialPythonFuncs.h
@@ -742,7 +721,6 @@ set(FILES
ErrorReportTableModel.h
ErrorReportTableModel.cpp
EditMode/DeepSelection.cpp
EditMode/VertexSnappingModeTool.cpp
FBXExporterDialog.cpp
FBXExporterDialog.ui
FileTypeUtils.cpp
@@ -143,15 +143,6 @@ ComponentEntityEditorPlugin::ComponentEntityEditorPlugin([[maybe_unused]] IEdito
LyViewPane::CategoryTools,
pinnedInspectorOptions);
ViewPaneOptions levelInspectorOptions;
levelInspectorOptions.canHaveMultipleInstances = false;
levelInspectorOptions.preferedDockingArea = Qt::RightDockWidgetArea;
levelInspectorOptions.paneRect = QRect(50, 50, 400, 700);
RegisterViewPane<QComponentLevelEntityEditorInspectorWindow>(
LyViewPane::LevelInspector,
LyViewPane::CategoryTools,
levelInspectorOptions);
bool prefabSystemEnabled = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(prefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
@@ -170,8 +161,14 @@ ComponentEntityEditorPlugin::ComponentEntityEditorPlugin([[maybe_unused]] IEdito
}
else
{
// Add the Legacy Outliner to the Tools Menu
ViewPaneOptions levelInspectorOptions;
levelInspectorOptions.canHaveMultipleInstances = false;
levelInspectorOptions.preferedDockingArea = Qt::RightDockWidgetArea;
levelInspectorOptions.paneRect = QRect(50, 50, 400, 700);
RegisterViewPane<QComponentLevelEntityEditorInspectorWindow>(
LyViewPane::LevelInspector, LyViewPane::CategoryTools, levelInspectorOptions);
// Add the Legacy Outliner to the Tools Menu
ViewPaneOptions outlinerOptions;
outlinerOptions.canHaveMultipleInstances = true;
outlinerOptions.preferedDockingArea = Qt::LeftDockWidgetArea;
@@ -21,7 +21,6 @@
#include <ISerialize.h>
#include <CryName.h>
#include <EditorDefs.h>
#include <EditTool.h>
#include <Resource.h>
/////////////////////////////////////////////////////////////////////////////
@@ -320,14 +320,6 @@ void CComponentEntityObject::OnSelected()
// Invoked when selected via tools application, so we notify sandbox.
const bool wasSelected = IsSelected();
GetIEditor()->GetObjectManager()->SelectObject(this);
// If we get here and we're not already selected in sandbox land it means
// the selection started in AZ land and we need to clear any edit tool
// the user may have selected from the rollup bar
if (GetIEditor()->GetEditTool() && !wasSelected)
{
GetIEditor()->SetEditTool(nullptr);
}
}
}
@@ -24,6 +24,8 @@
#include <AzToolsFramework/ToolsComponents/EditorEntityIconComponentBus.h>
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
#include <QtViewPane.h>
#include "../Editor/Objects/EntityObject.h"
#include <LmbrCentral/Rendering/MeshComponentBus.h>
#include <LmbrCentral/Rendering/RenderBoundsBus.h>
@@ -1383,11 +1383,6 @@ void SandboxIntegrationManager::SetShowCircularDependencyError(const bool& showC
}
//////////////////////////////////////////////////////////////////////////
void SandboxIntegrationManager::SetEditTool(const char* tool)
{
GetIEditor()->SetEditTool(tool);
}
void SandboxIntegrationManager::LaunchLuaEditor(const char* files)
{
CCryEditApp::instance()->OpenLUAEditor(files);
@@ -162,7 +162,6 @@ private:
bool GetUndoSliceOverrideSaveValue() override;
bool GetShowCircularDependencyError() override;
void SetShowCircularDependencyError(const bool& showCircularDependencyError) override;
void SetEditTool(const char* tool) override;
void LaunchLuaEditor(const char* files) override;
bool IsLevelDocumentOpen() override;
AZStd::string GetLevelName() override;
@@ -28,6 +28,7 @@
#include <AzToolsFramework/ToolsComponents/ComponentMimeData.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzToolsFramework/API/ViewPaneOptions.h>
#include <QLabel>
@@ -312,19 +312,6 @@ void OutlinerWidget::OnSelectionChanged(const QItemSelection& selected, const QI
AzToolsFramework::EntityIdList newlyDeselected;
ExtractEntityIdsFromSelection(deselected, newlyDeselected);
CEditTool* tool = GetIEditor()->GetEditTool();
IClassDesc* classDescription = tool ? tool->GetClassDesc() : nullptr;
if (classDescription && QString::compare(classDescription->ClassName(), "EditTool.Clone") == 0)
{
// if the user clicks an empty space or selects a different entity in the entity outliner, the clone operation will be accepted.
if ((newlySelected.empty() && !newlyDeselected.empty()) || !newlySelected.empty())
{
tool->Accept(true);
GetIEditor()->GetSelection()->FinishChanges();
}
}
AzToolsFramework::ScopedUndoBatch undo("Select Entity");
// initialize the selection command here to store the current selection before
-1
View File
@@ -14,7 +14,6 @@ add_subdirectory(AssetProcessor)
add_subdirectory(AWSNativeSDKInit)
add_subdirectory(AzTestRunner)
add_subdirectory(CryCommonTools)
add_subdirectory(CrySCompileServer)
add_subdirectory(CryXML)
add_subdirectory(HLSLCrossCompiler)
add_subdirectory(HLSLCrossCompilerMETAL)

Some files were not shown because too many files have changed in this diff Show More