Merge branch 'development' into issues/exception_handling

Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>

# Conflicts:
#	Code/Framework/AzFramework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp
This commit is contained in:
Esteban Papp
2021-10-15 08:55:35 -07:00
159 changed files with 3504 additions and 3481 deletions
@@ -74,6 +74,7 @@ def update_manifest(scene):
source_filename_only = os.path.basename(clean_filename)
created_entities = []
previous_entity_id = azlmbr.entity.InvalidEntityId
# Loop every mesh node in the scene
for activeMeshIndex in range(len(mesh_name_list)):
@@ -102,14 +103,33 @@ def update_manifest(scene):
# The MeshGroup we created will be output as a product in the asset's path named mesh_group_name.azmodel
# The assetHint will be converted to an AssetId later during prefab loading
json_update = json.dumps({
"Controller": { "Configuration": { "ModelAsset": {
"assetHint": os.path.join(source_relative_path, mesh_group_name) + ".azmodel" }}}
});
"Controller": { "Configuration": { "ModelAsset": {
"assetHint": os.path.join(source_relative_path, mesh_group_name) + ".azmodel" }}}
});
# Apply the JSON above to the component we created
result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id, editor_mesh_component, json_update)
if not result:
raise RuntimeError("UpdateComponentForEntity failed")
raise RuntimeError("UpdateComponentForEntity failed for Mesh component")
# Get the transform component
transform_component = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "GetOrAddComponentByTypeName", entity_id, "27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0")
# Set this entity to be a child of the last entity we created
# This is just an example of how to do parenting and isn't necessarily useful to parent everything like this
if previous_entity_id is not None:
transform_json = json.dumps({
"Parent Entity" : previous_entity_id.to_json()
});
# Apply the JSON update
result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id, transform_component, transform_json)
if not result:
raise RuntimeError("UpdateComponentForEntity failed for Transform component")
# Update the last entity id for next time
previous_entity_id = entity_id
# Keep track of the entity we set up, we'll add them all to the prefab we're creating later
created_entities.append(entity_id)
@@ -147,6 +167,8 @@ def on_update_manifest(args):
except RuntimeError as err:
print (f'ERROR - {err}')
log_exception_traceback()
except:
log_exception_traceback()
global sceneJobHandler
sceneJobHandler = None
+3
View File
@@ -264,6 +264,9 @@ void EditorPreferencesDialog::SetFilter(const QString& filter)
else if (m_currentPageItem)
{
m_currentPageItem->UpdateEditorFilter(ui->propertyEditor, m_filter);
// Refresh the Stylesheet - when using search functionality.
AzQtComponents::StyleManager::repolishStyleSheet(this);
}
}
+12 -10
View File
@@ -14,6 +14,7 @@
// Editor
#include "Settings.h"
#include "EditorViewportSettings.h"
@@ -43,17 +44,16 @@ void CEditorPreferencesPage_Files::Reflect(AZ::SerializeContext& serialize)
->Field("MaxCount", &AutoBackup::m_maxCount)
->Field("RemindTime", &AutoBackup::m_remindTime);
serialize.Class<AssetBrowserSearch>()
serialize.Class<AssetBrowserSettings>()
->Version(1)
->Field("Max number of items displayed", &AssetBrowserSearch::m_maxNumberOfItemsShownInSearch);
->Field("MaxEntriesShownCount", &AssetBrowserSettings::m_maxNumberOfItemsShownInSearch);
serialize.Class<CEditorPreferencesPage_Files>()
->Version(1)
->Field("Files", &CEditorPreferencesPage_Files::m_files)
->Field("Editors", &CEditorPreferencesPage_Files::m_editors)
->Field("AutoBackup", &CEditorPreferencesPage_Files::m_autoBackup)
->Field("AssetBrowserSearch", &CEditorPreferencesPage_Files::m_assetBrowserSearch);
->Field("AssetBrowserSettings", &CEditorPreferencesPage_Files::m_assetBrowserSettings);
AZ::EditContext* editContext = serialize.GetEditContext();
if (editContext)
@@ -85,9 +85,10 @@ void CEditorPreferencesPage_Files::Reflect(AZ::SerializeContext& serialize)
->Attribute(AZ::Edit::Attributes::Max, 100)
->DataElement(AZ::Edit::UIHandlers::SpinBox, &AutoBackup::m_remindTime, "Remind Time", "Auto Remind Every (Minutes)");
editContext->Class<AssetBrowserSearch>("Asset Browser Search View", "Asset Browser Search View")
->DataElement(AZ::Edit::UIHandlers::SpinBox, &AssetBrowserSearch::m_maxNumberOfItemsShownInSearch, "Maximum number of displayed items",
"Maximum number of displayed items displayed in the Search View")
editContext->Class<AssetBrowserSettings>("Asset Browser Settings", "Asset Browser Settings")
->DataElement(
AZ::Edit::UIHandlers::SpinBox, &AssetBrowserSettings::m_maxNumberOfItemsShownInSearch, "Maximum number of displayed items",
"Maximum number of items to display in the Search View.")
->Attribute(AZ::Edit::Attributes::Min, 50)
->Attribute(AZ::Edit::Attributes::Max, 5000);
@@ -97,7 +98,7 @@ void CEditorPreferencesPage_Files::Reflect(AZ::SerializeContext& serialize)
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_Files::m_files, "Files", "File Preferences")
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_Files::m_editors, "External Editors", "External Editors")
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_Files::m_autoBackup, "Auto Backup", "Auto Backup")
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_Files::m_assetBrowserSearch, "Asset Browser Search", "Asset Browser Search");
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_Files::m_assetBrowserSettings, "Asset Browser Settings","Asset Browser Settings");
}
}
@@ -117,6 +118,7 @@ QIcon& CEditorPreferencesPage_Files::GetIcon()
void CEditorPreferencesPage_Files::OnApply()
{
using namespace AzToolsFramework::SliceUtilities;
auto sliceSettings = AZ::UserSettings::CreateFind<SliceUserSettings>(AZ_CRC("SliceUserSettings", 0x055b32eb), AZ::UserSettings::CT_LOCAL);
sliceSettings->m_autoNumber = m_files.m_autoNumberSlices;
sliceSettings->m_saveLocation = m_files.m_saveLocation;
@@ -137,7 +139,7 @@ void CEditorPreferencesPage_Files::OnApply()
gSettings.autoBackupMaxCount = m_autoBackup.m_maxCount;
gSettings.autoRemindTime = m_autoBackup.m_remindTime;
gSettings.maxNumberOfItemsShownInSearch = m_assetBrowserSearch.m_maxNumberOfItemsShownInSearch;
SandboxEditor::SetMaxItemsShownInAssetBrowserSearch(m_assetBrowserSettings.m_maxNumberOfItemsShownInSearch);
}
void CEditorPreferencesPage_Files::InitializeSettings()
@@ -163,5 +165,5 @@ void CEditorPreferencesPage_Files::InitializeSettings()
m_autoBackup.m_maxCount = gSettings.autoBackupMaxCount;
m_autoBackup.m_remindTime = gSettings.autoRemindTime;
m_assetBrowserSearch.m_maxNumberOfItemsShownInSearch = gSettings.maxNumberOfItemsShownInSearch;
m_assetBrowserSettings.m_maxNumberOfItemsShownInSearch = SandboxEditor::MaxItemsShownInAssetBrowserSearch();
}
+4 -7
View File
@@ -69,18 +69,15 @@ private:
int m_remindTime;
};
struct AssetBrowserSearch
struct AssetBrowserSettings
{
AZ_TYPE_INFO(AssetBrowserSearch, "{9FBFCD24-9452-49DF-99F4-2711443CEAAE}")
int m_maxNumberOfItemsShownInSearch;
AZ_TYPE_INFO(AssetBrowserSettings, "{5F407EC4-BBD1-4A87-92DB-D938D7127BB0}")
AZ::u64 m_maxNumberOfItemsShownInSearch;
};
Files m_files;
ExternalEditors m_editors;
AutoBackup m_autoBackup;
AssetBrowserSearch m_assetBrowserSearch;
AssetBrowserSettings m_assetBrowserSettings;
QIcon m_icon;
};
+11
View File
@@ -15,6 +15,7 @@
namespace SandboxEditor
{
constexpr AZStd::string_view AssetBrowserMaxItemsShownInSearchSetting = "/Amazon/Preferences/Editor/AssetBrowser/MaxItemsShowInSearch";
constexpr AZStd::string_view GridSnappingSetting = "/Amazon/Preferences/Editor/GridSnapping";
constexpr AZStd::string_view GridSizeSetting = "/Amazon/Preferences/Editor/GridSize";
constexpr AZStd::string_view AngleSnappingSetting = "/Amazon/Preferences/Editor/AngleSnapping";
@@ -110,6 +111,16 @@ namespace SandboxEditor
return AZStd::make_unique<EditorViewportSettingsCallbacksImpl>();
}
AZ::u64 MaxItemsShownInAssetBrowserSearch()
{
return GetRegistry(AssetBrowserMaxItemsShownInSearchSetting, aznumeric_cast<AZ::u64>(50));
}
void SetMaxItemsShownInAssetBrowserSearch(const AZ::u64 numberOfItemsShown)
{
SetRegistry(AssetBrowserMaxItemsShownInSearchSetting, numberOfItemsShown);
}
bool GridSnappingEnabled()
{
return GetRegistry(GridSnappingSetting, false);
+3
View File
@@ -32,6 +32,9 @@ namespace SandboxEditor
//! event will fire when a value in the settings registry (editorpreferences.setreg) is modified.
SANDBOX_API AZStd::unique_ptr<EditorViewportSettingsCallbacks> CreateEditorViewportSettingsCallbacks();
SANDBOX_API AZ::u64 MaxItemsShownInAssetBrowserSearch();
SANDBOX_API void SetMaxItemsShownInAssetBrowserSearch(AZ::u64 numberOfItemsShown);
SANDBOX_API bool GridSnappingEnabled();
SANDBOX_API void SetGridSnapping(bool enabled);
-35
View File
@@ -108,15 +108,11 @@ CObjectManager::CObjectManager()
m_objectsByName.reserve(1024);
LoadRegistry();
AzToolsFramework::ViewportEditorModeNotificationsBus::Handler::BusConnect(AzToolsFramework::GetEntityContextId());
}
//////////////////////////////////////////////////////////////////////////
CObjectManager::~CObjectManager()
{
AzToolsFramework::ViewportEditorModeNotificationsBus::Handler::BusDisconnect();
m_bExiting = true;
SaveRegistry();
DeleteAllObjects();
@@ -2307,37 +2303,6 @@ void CObjectManager::SelectObjectInRect(CBaseObject* pObj, CViewport* view, HitC
}
}
void CObjectManager::OnEditorModeActivated(
[[maybe_unused]] const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode)
{
if (mode == AzToolsFramework::ViewportEditorMode::Component)
{
// hide current gizmo for entity (translate/rotate/scale)
IGizmoManager* gizmoManager = GetGizmoManager();
const size_t gizmoCount = static_cast<size_t>(gizmoManager->GetGizmoCount());
for (size_t i = 0; i < gizmoCount; ++i)
{
gizmoManager->RemoveGizmo(gizmoManager->GetGizmoByIndex(static_cast<int>(i)));
}
}
}
void CObjectManager::OnEditorModeDeactivated(
[[maybe_unused]] const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode)
{
if (mode == AzToolsFramework::ViewportEditorMode::Component)
{
// show translate/rotate/scale gizmo again
if (IGizmoManager* gizmoManager = GetGizmoManager())
{
if (CBaseObject* selectedObject = GetIEditor()->GetSelectedObject())
{
gizmoManager->AddGizmo(new CAxisGizmo(selectedObject));
}
}
}
}
//////////////////////////////////////////////////////////////////////////
namespace
{
-8
View File
@@ -20,7 +20,6 @@
#include "ObjectManagerEventBus.h"
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <AzToolsFramework/API/ViewportEditorModeTrackerNotificationBus.h>
#include <AzCore/EBus/EBus.h>
#include <AzCore/Component/Component.h>
#include <Include/SandboxAPI.h>
@@ -59,7 +58,6 @@ public:
*/
class CObjectManager
: public IObjectManager
, private AzToolsFramework::ViewportEditorModeNotificationsBus::Handler
{
public:
//! Selection functor callback.
@@ -330,12 +328,6 @@ private:
void FindDisplayableObjects(DisplayContext& dc, bool bDisplay);
// ViewportEditorModeNotificationsBus overrides ...
void OnEditorModeActivated(
const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode) override;
void OnEditorModeDeactivated(
const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode) override;
private:
typedef std::map<GUID, CBaseObjectPtr, guid_less_predicate> Objects;
Objects m_objects;
+3 -4
View File
@@ -10,6 +10,7 @@
#include "EditorDefs.h"
#include "Settings.h"
#include "EditorViewportSettings.h"
// Qt
#include <QGuiApplication>
@@ -487,7 +488,6 @@ void SEditorSettings::Save()
SaveValue("Settings", "AutoBackupTime", autoBackupTime);
SaveValue("Settings", "AutoBackupMaxCount", autoBackupMaxCount);
SaveValue("Settings", "AutoRemindTime", autoRemindTime);
SaveValue("Settings", "MaxDisplayedItemsNumInSearch", maxNumberOfItemsShownInSearch);
SaveValue("Settings", "CameraMoveSpeed", cameraMoveSpeed);
SaveValue("Settings", "CameraRotateSpeed", cameraRotateSpeed);
SaveValue("Settings", "StylusMode", stylusMode);
@@ -682,7 +682,6 @@ void SEditorSettings::Load()
LoadValue("Settings", "AutoBackupTime", autoBackupTime);
LoadValue("Settings", "AutoBackupMaxCount", autoBackupMaxCount);
LoadValue("Settings", "AutoRemindTime", autoRemindTime);
LoadValue("Settings", "MaxDisplayedItemsNumInSearch", maxNumberOfItemsShownInSearch);
LoadValue("Settings", "CameraMoveSpeed", cameraMoveSpeed);
LoadValue("Settings", "CameraRotateSpeed", cameraRotateSpeed);
LoadValue("Settings", "StylusMode", stylusMode);
@@ -1174,7 +1173,7 @@ AzToolsFramework::ConsoleColorTheme SEditorSettings::GetConsoleColorTheme() cons
return consoleBackgroundColorTheme;
}
int SEditorSettings::GetMaxNumberOfItemsShownInSearchView() const
AZ::u64 SEditorSettings::GetMaxNumberOfItemsShownInSearchView() const
{
return SEditorSettings::maxNumberOfItemsShownInSearch;
return SandboxEditor::MaxItemsShownInAssetBrowserSearch();
}
+1 -9
View File
@@ -279,7 +279,7 @@ AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
SettingOutcome GetValue(const AZStd::string_view path) override;
SettingOutcome SetValue(const AZStd::string_view path, const AZStd::any& value) override;
AzToolsFramework::ConsoleColorTheme GetConsoleColorTheme() const override;
int GetMaxNumberOfItemsShownInSearchView() const override;
AZ::u64 GetMaxNumberOfItemsShownInSearchView() const override;
void ConvertPath(const AZStd::string_view sourcePath, AZStd::string& category, AZStd::string& attribute);
@@ -353,14 +353,6 @@ AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
int autoRemindTime;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// Asset Browser Search View.
//////////////////////////////////////////////////////////////////////////
//! Current maximum number of items that can be displayed in the AssetBrowser Search View.
int maxNumberOfItemsShownInSearch;
//////////////////////////////////////////////////////////////////////////
//! If true preview windows is displayed when browsing geometries.
bool bPreviewGeometryWindow;
+2 -2
View File
@@ -1195,7 +1195,7 @@ bool CFileUtil::IsFileExclusivelyAccessable(const QString& strFilePath)
//////////////////////////////////////////////////////////////////////////
bool CFileUtil::CreatePath(const QString& strPath)
{
#if defined(AZ_PLATFORM_MAC)
#if !AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS
bool pathCreated = true;
QString cleanPath = QDir::cleanPath(strPath);
@@ -1252,7 +1252,7 @@ bool CFileUtil::CreatePath(const QString& strPath)
}
return true;
#endif
#endif // !AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS
}
//////////////////////////////////////////////////////////////////////////
@@ -225,8 +225,16 @@ namespace AZ
ConsoleCommandContainer commandSubset;
for (ConsoleFunctorBase* curr = m_head; curr != nullptr; curr = curr->m_next)
for (const auto& functor : m_commands)
{
if (functor.second.empty())
{
continue;
}
// Filter functors registered with the same name
const ConsoleFunctorBase* curr = functor.second.front();
if ((curr->GetFlags() & ConsoleFunctorFlags::IsInvisible) == ConsoleFunctorFlags::IsInvisible)
{
// Filter functors marked as invisible
@@ -236,7 +244,12 @@ namespace AZ
if (StringFunc::StartsWith(curr->m_name, command, false))
{
AZLOG_INFO("- %s : %s\n", curr->m_name, curr->m_desc);
commandSubset.push_back(curr->m_name);
if (commandSubset.size() < MaxConsoleCommandPlusArgsLength)
{
commandSubset.push_back(curr->m_name);
}
if (matches)
{
matches->push_back(curr->m_name);
@@ -271,7 +284,10 @@ namespace AZ
{
for (auto& curr : m_commands)
{
visitor(curr.second.front());
if (!curr.second.empty())
{
visitor(curr.second.front());
}
}
}
@@ -336,6 +352,11 @@ namespace AZ
{
iter->second.erase(iter2);
}
if (iter->second.empty())
{
m_commands.erase(iter);
}
}
functor->Unlink(m_head);
functor->m_console = nullptr;
@@ -288,6 +288,21 @@ namespace AZ
AZStd::string completeCommand = console->AutoCompleteCommand("testVec3");
AZ_TEST_ASSERT(completeCommand == "testVec3");
}
// Duplicate names
{
// Register two cvars with the same name
auto id = AZ::TypeId();
auto flag = AZ::ConsoleFunctorFlags::Null;
auto signature = AZ::ConsoleFunctor<void, false>::FunctorSignature();
AZ::ConsoleFunctor<void, false> cvarOne(*console, "testAutoCompleteDuplication", "", flag, id, signature);
AZ::ConsoleFunctor<void, false> cvarTwo(*console, "testAutoCompleteDuplication", "", flag, id, signature);
// Autocomplete given name expecting one match (not two)
AZStd::vector<AZStd::string> matches;
AZStd::string completeCommand = console->AutoCompleteCommand("testAutoCompleteD", &matches);
AZ_TEST_ASSERT(matches.size() == 1 && completeCommand == "testAutoCompleteDuplication");
}
}
TEST_F(ConsoleTests, ConsoleFunctor_FreeFunctorExecutionTest)
@@ -1,234 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Math/Matrix3x3.h>
#include <AzCore/Math/Vector3.h>
#include <AzCore/Math/Aabb.h>
#include <AzFramework/Physics/WorldBody.h>
#include <AzFramework/Physics/ShapeConfiguration.h>
namespace
{
class ReflectContext;
}
namespace Physics
{
class ShapeConfiguration;
class World;
class Shape;
/// Default values used for initializing RigidBodySettings.
/// These can be modified by Physics Implementation gems. // O3DE_DEPRECATED(LY-114472) - DefaultRigidBodyConfiguration values are not shared across modules.
// Use RigidBodyConfiguration default values.
struct DefaultRigidBodyConfiguration
{
static float m_mass;
static bool m_computeInertiaTensor;
static float m_linearDamping;
static float m_angularDamping;
static float m_sleepMinEnergy;
static float m_maxAngularVelocity;
};
enum class MassComputeFlags : AZ::u8
{
NONE = 0,
//! Flags indicating whether a certain mass property should be auto-computed or not.
COMPUTE_MASS = 1,
COMPUTE_INERTIA = 1 << 1,
COMPUTE_COM = 1 << 2,
//! If set, non-simulated shapes will also be included in the mass properties calculation.
INCLUDE_ALL_SHAPES = 1 << 3,
DEFAULT = COMPUTE_COM | COMPUTE_INERTIA | COMPUTE_MASS
};
class RigidBodyConfiguration
: public WorldBodyConfiguration
{
public:
AZ_CLASS_ALLOCATOR(RigidBodyConfiguration, AZ::SystemAllocator, 0);
AZ_RTTI(RigidBodyConfiguration, "{ACFA8900-8530-4744-AF00-AA533C868A8E}", WorldBodyConfiguration);
static void Reflect(AZ::ReflectContext* context);
enum PropertyVisibility : AZ::u16
{
InitialVelocities = 1 << 0, ///< Whether the initial linear and angular velocities are visible.
InertiaProperties = 1 << 1, ///< Whether the whole category of inertia properties (mass, compute inertia,
///< inertia tensor etc) is visible.
Damping = 1 << 2, ///< Whether linear and angular damping are visible.
SleepOptions = 1 << 3, ///< Whether the sleep threshold and start asleep options are visible.
Interpolation = 1 << 4, ///< Whether the interpolation option is visible.
Gravity = 1 << 5, ///< Whether the effected by gravity option is visible.
Kinematic = 1 << 6, ///< Whether the option to make the body kinematic is visible.
ContinuousCollisionDetection = 1 << 7, ///< Whether the option to enable continuous collision detection is visible.
MaxVelocities = 1 << 8 ///< Whether upper limits on velocities are visible.
};
RigidBodyConfiguration() = default;
RigidBodyConfiguration(const RigidBodyConfiguration& settings) = default;
// Visibility functions.
AZ::Crc32 GetPropertyVisibility(PropertyVisibility property) const;
void SetPropertyVisibility(PropertyVisibility property, bool isVisible);
AZ::Crc32 GetInitialVelocitiesVisibility() const;
/// Returns whether the whole category of inertia settings (mass, inertia, center of mass offset etc) is visible.
AZ::Crc32 GetInertiaSettingsVisibility() const;
/// Returns whether the individual inertia tensor field is visible or is hidden because the compute inertia option is selected.
AZ::Crc32 GetInertiaVisibility() const;
/// Returns whether the mass field is visible or is hidden because compute mass option is selected.
AZ::Crc32 GetMassVisibility() const;
/// Returns whether the individual centre of mass offset field is visible or is hidden because compute CoM option is selected.
AZ::Crc32 GetCoMVisibility() const;
AZ::Crc32 GetDampingVisibility() const;
AZ::Crc32 GetSleepOptionsVisibility() const;
AZ::Crc32 GetInterpolationVisibility() const;
AZ::Crc32 GetGravityVisibility() const;
AZ::Crc32 GetKinematicVisibility() const;
AZ::Crc32 GetCCDVisibility() const;
AZ::Crc32 GetMaxVelocitiesVisibility() const;
MassComputeFlags GetMassComputeFlags() const;
void SetMassComputeFlags(MassComputeFlags flags);
bool IsCCDEnabled() const;
// Basic initial settings.
AZ::Vector3 m_initialLinearVelocity = AZ::Vector3::CreateZero();
AZ::Vector3 m_initialAngularVelocity = AZ::Vector3::CreateZero();
AZ::Vector3 m_centerOfMassOffset = AZ::Vector3::CreateZero();
// Simulation parameters.
float m_mass = DefaultRigidBodyConfiguration::m_mass;
AZ::Matrix3x3 m_inertiaTensor = AZ::Matrix3x3::CreateIdentity();
float m_linearDamping = DefaultRigidBodyConfiguration::m_linearDamping;
float m_angularDamping = DefaultRigidBodyConfiguration::m_angularDamping;
float m_sleepMinEnergy = DefaultRigidBodyConfiguration::m_sleepMinEnergy;
float m_maxAngularVelocity = DefaultRigidBodyConfiguration::m_maxAngularVelocity;
// Visibility settings.
AZ::u16 m_propertyVisibilityFlags = (std::numeric_limits<AZ::u16>::max)();
bool m_startAsleep = false;
bool m_interpolateMotion = false;
bool m_gravityEnabled = true;
bool m_simulated = true;
bool m_kinematic = false;
bool m_ccdEnabled = false; ///< Whether continuous collision detection is enabled.
float m_ccdMinAdvanceCoefficient = 0.15f; ///< Coefficient affecting how granularly time is subdivided in CCD.
bool m_ccdFrictionEnabled = false; ///< Whether friction is applied when resolving CCD collisions.
bool m_computeCenterOfMass = true;
bool m_computeInertiaTensor = true;
bool m_computeMass = true;
//! If set, non-simulated shapes will also be included in the mass properties calculation.
bool m_includeAllShapesInMassCalculation = false;
};
/// Dynamic rigid body.
class RigidBody
: public WorldBody
{
public:
AZ_CLASS_ALLOCATOR(RigidBody, AZ::SystemAllocator, 0);
AZ_RTTI(RigidBody, "{156E459F-7BB7-4B4E-ADA0-2130D96B7E80}", WorldBody);
public:
RigidBody() = default;
explicit RigidBody(const RigidBodyConfiguration& settings);
virtual void AddShape(AZStd::shared_ptr<Shape> shape) = 0;
virtual void RemoveShape(AZStd::shared_ptr<Shape> shape) = 0;
virtual AZ::u32 GetShapeCount() { return 0; }
virtual AZStd::shared_ptr<Shape> GetShape(AZ::u32 /*index*/) { return nullptr; }
virtual AZ::Vector3 GetCenterOfMassWorld() const = 0;
virtual AZ::Vector3 GetCenterOfMassLocal() const = 0;
virtual AZ::Matrix3x3 GetInverseInertiaWorld() const = 0;
virtual AZ::Matrix3x3 GetInverseInertiaLocal() const = 0;
virtual float GetMass() const = 0;
virtual float GetInverseMass() const = 0;
virtual void SetMass(float mass) = 0;
virtual void SetCenterOfMassOffset(const AZ::Vector3& comOffset) = 0;
/// Retrieves the velocity at center of mass; only linear velocity, no rotational velocity contribution.
virtual AZ::Vector3 GetLinearVelocity() const = 0;
virtual void SetLinearVelocity(const AZ::Vector3& velocity) = 0;
virtual AZ::Vector3 GetAngularVelocity() const = 0;
virtual void SetAngularVelocity(const AZ::Vector3& angularVelocity) = 0;
virtual AZ::Vector3 GetLinearVelocityAtWorldPoint(const AZ::Vector3& worldPoint) = 0;
virtual void ApplyLinearImpulse(const AZ::Vector3& impulse) = 0;
virtual void ApplyLinearImpulseAtWorldPoint(const AZ::Vector3& impulse, const AZ::Vector3& worldPoint) = 0;
virtual void ApplyAngularImpulse(const AZ::Vector3& angularImpulse) = 0;
virtual float GetLinearDamping() const = 0;
virtual void SetLinearDamping(float damping) = 0;
virtual float GetAngularDamping() const = 0;
virtual void SetAngularDamping(float damping) = 0;
virtual bool IsAwake() const = 0;
virtual void ForceAsleep() = 0;
virtual void ForceAwake() = 0;
virtual float GetSleepThreshold() const = 0;
virtual void SetSleepThreshold(float threshold) = 0;
virtual bool IsKinematic() const = 0;
virtual void SetKinematic(bool kinematic) = 0;
virtual void SetKinematicTarget(const AZ::Transform& targetPosition) = 0;
virtual bool IsGravityEnabled() const = 0;
virtual void SetGravityEnabled(bool enabled) = 0;
virtual void SetSimulationEnabled(bool enabled) = 0;
virtual void SetCCDEnabled(bool enabled) = 0;
//! Recalculates mass, inertia and center of mass based on the flags passed.
//! @param flags MassComputeFlags specifying which properties should be recomputed.
//! @param centerOfMassOffsetOverride Optional override of the center of mass. Note: This parameter will be ignored if COMPUTE_COM is passed in flags.
//! @param inertiaTensorOverride Optional override of the inertia. Note: This parameter will be ignored if COMPUTE_INERTIA is passed in flags.
//! @param massOverride Optional override of the mass. Note: This parameter will be ignored if COMPUTE_MASS is passed in flags.
virtual void UpdateMassProperties(MassComputeFlags flags = MassComputeFlags::DEFAULT,
const AZ::Vector3* centerOfMassOffsetOverride = nullptr,
const AZ::Matrix3x3* inertiaTensorOverride = nullptr,
const float* massOverride = nullptr) = 0;
};
/// Bitwise operators for MassComputeFlags
inline MassComputeFlags operator|(MassComputeFlags lhs, MassComputeFlags rhs)
{
return aznumeric_cast<MassComputeFlags>(aznumeric_cast<AZ::u8>(lhs) | aznumeric_cast<AZ::u8>(rhs));
}
inline MassComputeFlags operator&(MassComputeFlags lhs, MassComputeFlags rhs)
{
return aznumeric_cast<MassComputeFlags>(aznumeric_cast<AZ::u8>(lhs) & aznumeric_cast<AZ::u8>(rhs));
}
/// Static rigid body.
class RigidBodyStatic
: public WorldBody
{
public:
AZ_CLASS_ALLOCATOR(RigidBodyStatic, AZ::SystemAllocator, 0);
AZ_RTTI(RigidBodyStatic, "{13A677BB-7085-4EDB-BCC8-306548238692}", WorldBody);
virtual void AddShape(const AZStd::shared_ptr<Shape>& shape) = 0;
virtual AZ::u32 GetShapeCount() { return 0; }
virtual AZStd::shared_ptr<Shape> GetShape(AZ::u32 /*index*/) { return nullptr; }
};
} // namespace Physics
@@ -89,9 +89,9 @@ namespace AzPhysics
//! @param inertiaTensorOverride Optional override of the inertia. Note: This parameter will be ignored if COMPUTE_INERTIA is passed in flags.
//! @param massOverride Optional override of the mass. Note: This parameter will be ignored if COMPUTE_MASS is passed in flags.
virtual void UpdateMassProperties(MassComputeFlags flags = MassComputeFlags::DEFAULT,
const AZ::Vector3* centerOfMassOffsetOverride = nullptr,
const AZ::Matrix3x3* inertiaTensorOverride = nullptr,
const float* massOverride = nullptr) = 0;
const AZ::Vector3& centerOfMassOffsetOverride = AZ::Vector3::CreateZero(),
const AZ::Matrix3x3& inertiaTensorOverride = AZ::Matrix3x3::CreateIdentity(),
const float massOverride = 1.0f) = 0;
};
} // namespace AzPhysics
@@ -569,14 +569,12 @@ namespace UnitTest
FillSpawnable(NumEntities);
CreateEntityReferences(refScheme);
AZ_PUSH_DISABLE_WARNING(5233, "-Wunknown-warning-option") // Older versions of MSVC toolchain require to pass constexpr in the
// capture. Newer versions issue unused warning
AZ_PUSH_DISABLE_WARNING(5233, "-Wunused-lambda-capture") // Older versions of MSVC toolchain require to pass constexpr in the
// capture. Newer versions issue unused warning
auto callback =
[this, refScheme, NumEntities](AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
AZ_POP_DISABLE_WARNING
{
AZ_UNUSED(refScheme);
AZ_UNUSED(NumEntities);
ValidateEntityReferences(refScheme, NumEntities, entities);
};
@@ -594,14 +592,12 @@ namespace UnitTest
FillSpawnable(NumEntities);
CreateEntityReferences(refScheme);
AZ_PUSH_DISABLE_WARNING(5233, "-Wunknown-warning-option") // Older versions of MSVC toolchain require to pass constexpr in the
// capture. Newer versions issue unused warning
AZ_PUSH_DISABLE_WARNING(5233, "-Wunused-lambda-capture") // Older versions of MSVC toolchain require to pass constexpr in the
// capture. Newer versions issue unused warning
auto callback =
[this, refScheme, NumEntities](AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
AZ_POP_DISABLE_WARNING
{
AZ_UNUSED(refScheme);
AZ_UNUSED(NumEntities);
ValidateEntityReferences(refScheme, NumEntities, entities);
};
@@ -726,14 +722,12 @@ namespace UnitTest
FillSpawnable(NumEntities);
CreateEntityReferences(refScheme);
AZ_PUSH_DISABLE_WARNING(5233, "-Wunknown-warning-option") // Older versions of MSVC toolchain require to pass constexpr in the
// capture. Newer versions issue unused warning
AZ_PUSH_DISABLE_WARNING(5233, "-Wunused-lambda-capture") // Older versions of MSVC toolchain require to pass constexpr in the
// capture. Newer versions issue unused warning
auto callback =
[this, refScheme, NumEntities](AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
AZ_POP_DISABLE_WARNING
{
AZ_UNUSED(refScheme);
AZ_UNUSED(NumEntities);
ValidateEntityReferences(refScheme, NumEntities, entities);
};
-9
View File
@@ -90,13 +90,6 @@ namespace AZ
}
}
//! Filter out integration tests from the test run
void excludeIntegTests()
{
AddExcludeFilter("INTEG_*");
AddExcludeFilter("Integ_*");
}
void ApplyGlobalParameters(int* argc, char** argv)
{
// this is a hook that can be used to apply any other global parameters that we use.
@@ -164,7 +157,6 @@ namespace AZ
}
::testing::InitGoogleMock(&argc, argv);
AZ::Test::excludeIntegTests();
AZ::Test::ApplyGlobalParameters(&argc, argv);
AZ::Test::printUnusedParametersWarning(argc, argv);
AZ::Test::addTestEnvironments(m_envs);
@@ -285,7 +277,6 @@ namespace AZ
}
}
AZ::Test::excludeIntegTests();
AZ::Test::printUnusedParametersWarning(argc, argv);
return RUN_ALL_TESTS();
-2
View File
@@ -104,7 +104,6 @@ namespace AZ
void addTestEnvironment(ITestEnvironment* env);
void addTestEnvironments(std::vector<ITestEnvironment*> envs);
void excludeIntegTests();
//! A hook that can be used to read any other misc parameters and remove them before google sees them.
//! Note that this modifies argc and argv to delete the parameters it consumes.
@@ -266,7 +265,6 @@ namespace AZ
::testing::TestEventListeners& listeners = testing::UnitTest::GetInstance()->listeners(); \
listeners.Append(new AZ::Test::OutputEventListener); \
} \
AZ::Test::excludeIntegTests(); \
AZ::Test::ApplyGlobalParameters(&argc, argv); \
AZ::Test::printUnusedParametersWarning(argc, argv); \
AZ::Test::addTestEnvironments({TEST_ENV}); \
@@ -43,8 +43,7 @@ namespace AzToolsFramework
};
//! Provides a bus to notify when the different editor modes are entered/exit.
class ViewportEditorModeNotifications
: public AZ::EBusTraits
class ViewportEditorModeNotifications : public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
@@ -58,14 +57,17 @@ namespace AzToolsFramework
static void Reflect(AZ::ReflectContext* context);
//! Notifies subscribers of the a given viewport to the activation of the specified editor mode.
virtual void OnEditorModeActivated([[maybe_unused]] const ViewportEditorModesInterface& editorModeState, [[maybe_unused]] ViewportEditorMode mode)
virtual void OnEditorModeActivated(
[[maybe_unused]] const ViewportEditorModesInterface& editorModeState, [[maybe_unused]] ViewportEditorMode mode)
{
}
//! Notifies subscribers of the a given viewport to the deactivation of the specified editor mode.
virtual void OnEditorModeDeactivated([[maybe_unused]] const ViewportEditorModesInterface& editorModeState, [[maybe_unused]] ViewportEditorMode mode)
virtual void OnEditorModeDeactivated(
[[maybe_unused]] const ViewportEditorModesInterface& editorModeState, [[maybe_unused]] ViewportEditorMode mode)
{
}
};
using ViewportEditorModeNotificationsBus = AZ::EBus<ViewportEditorModeNotifications>;
} // namespace AzToolsFramework
@@ -53,7 +53,7 @@ namespace AzToolsFramework
private slots:
void SourceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
private:
int m_numberOfItemsDisplayed = 50;
AZ::u64 m_numberOfItemsDisplayed = 0;
int m_displayedItemsCounter = 0;
QPointer<AssetBrowserFilterModel> m_filterModel;
QMap<int, QModelIndex> m_indexMap;
@@ -137,6 +137,7 @@ namespace AzToolsFramework
if (componentTypeIt == m_activeComponentTypes.end())
{
m_activeComponentTypes.push_back(componentType);
m_viewportUiHandlers.emplace_back(componentType);
}
// see if we already have a ComponentModeBuilder for the specific component on this entity
@@ -225,6 +226,7 @@ namespace AzToolsFramework
if (!m_entitiesAndComponentModes.empty())
{
RefreshActions();
PopulateViewportUi();
}
// if entering ComponentMode not as an undo/redo step (an action was
@@ -285,6 +287,10 @@ namespace AzToolsFramework
componentModeCommand.release();
}
// remove the component mode viewport border
ViewportUi::ViewportUiRequestBus::Event(
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::RemoveViewportBorder);
// notify listeners the editor has left ComponentMode - listeners may
// wish to modify state to indicate this (e.g. appearance, functionality etc.)
m_viewportEditorModeTracker->DeactivateMode({ GetEntityContextId() }, ViewportEditorMode::Component);
@@ -301,6 +307,7 @@ namespace AzToolsFramework
}
m_entitiesAndComponentModeBuilders.clear();
m_activeComponentTypes.clear();
m_viewportUiHandlers.clear();
m_componentMode = false;
m_selectedComponentModeIndex = 0;
@@ -385,6 +392,24 @@ namespace AzToolsFramework
return m_activeComponentTypes.size() > 1;
}
static ComponentModeViewportUi* FindViewportUiHandlerForType(
AZStd::vector<ComponentModeViewportUi>& viewportUiHandlers, const AZ::Uuid& componentType)
{
auto handler = AZStd::find_if(
viewportUiHandlers.begin(), viewportUiHandlers.end(),
[componentType](const ComponentModeViewportUi& handler)
{
return handler.GetComponentType() == componentType;
});
if (handler == viewportUiHandlers.end())
{
return nullptr;
}
return handler;
}
bool ComponentModeCollection::ActiveComponentModeChanged(const AZ::Uuid& previousComponentType)
{
if (m_activeComponentTypes[m_selectedComponentModeIndex] != previousComponentType)
@@ -410,6 +435,20 @@ namespace AzToolsFramework
// replace the current component mode by invoking the builder
// for the new 'active' component mode
componentMode.m_componentMode = componentModeBuilder->m_componentModeBuilder();
// populate the viewport UI with the new component mode
PopulateViewportUi();
// set the appropriate viewportUiHandler to active
if (auto viewportUiHandler =
FindViewportUiHandlerForType(m_viewportUiHandlers, m_activeComponentTypes[m_selectedComponentModeIndex]))
{
viewportUiHandler->SetComponentModeViewportUiActive(true);
}
ViewportUi::ViewportUiRequestBus::Event(
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder,
componentMode.m_componentMode->GetComponentModeName().c_str());
}
RefreshActions();
@@ -519,5 +558,18 @@ namespace AzToolsFramework
}
}
void ComponentModeCollection::PopulateViewportUi()
{
// update viewport UI for new component type
if (m_selectedComponentModeIndex < m_activeComponentTypes.size())
{
// iterate over all entities and their active Component Mode, populate viewport UI for the new mode
for (auto& entityAndComponentMode : m_entitiesAndComponentModes)
{
// build viewport UI based on current state
entityAndComponentMode.m_componentMode->PopulateViewportUi();
}
}
}
} // namespace ComponentModeFramework
} // namespace AzToolsFramework
@@ -55,7 +55,7 @@ namespace AzToolsFramework
GetEntityComponentIdPair(), elementIdsToDisplay);
// create the component mode border with the specific name for this component mode
ViewportUi::ViewportUiRequestBus::Event(
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateComponentModeBorder,
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder,
GetComponentModeName());
// set the EntityComponentId for this ComponentMode to active in the ComponentModeViewportUi system
ComponentModeViewportUiRequestBus::Event(
@@ -38,7 +38,7 @@ namespace AzToolsFramework
virtual SettingOutcome GetValue(const AZStd::string_view path) = 0;
virtual SettingOutcome SetValue(const AZStd::string_view path, const AZStd::any& value) = 0;
virtual ConsoleColorTheme GetConsoleColorTheme() const = 0;
virtual int GetMaxNumberOfItemsShownInSearchView() const = 0;
virtual AZ::u64 GetMaxNumberOfItemsShownInSearchView() const = 0;
};
using EditorSettingsAPIBus = AZ::EBus<EditorSettingsAPIRequests>;
@@ -71,12 +71,7 @@ namespace AzToolsFramework
return;
}
AZ::EntityId previousFocusEntityId = m_focusRoot;
m_focusRoot = entityId;
FocusModeNotificationBus::Broadcast(&FocusModeNotifications::OnEditorFocusChanged, previousFocusEntityId, m_focusRoot);
if (auto tracker = AZ::Interface<ViewportEditorModeTrackerInterface>::Get();
tracker != nullptr)
if (auto tracker = AZ::Interface<ViewportEditorModeTrackerInterface>::Get())
{
if (!m_focusRoot.IsValid() && entityId.IsValid())
{
@@ -87,6 +82,10 @@ namespace AzToolsFramework
tracker->DeactivateMode({ GetEntityContextId() }, ViewportEditorMode::Focus);
}
}
AZ::EntityId previousFocusEntityId = m_focusRoot;
m_focusRoot = entityId;
FocusModeNotificationBus::Broadcast(&FocusModeNotifications::OnEditorFocusChanged, previousFocusEntityId, m_focusRoot);
}
void FocusModeSystemComponent::ClearFocusRoot([[maybe_unused]] AzFramework::EntityContextId entityContextId)
@@ -43,6 +43,12 @@ namespace AzToolsFramework
m_instanceToTemplateInterface = AZ::Interface<InstanceToTemplateInterface>::Get();
AZ_Assert(m_instanceToTemplateInterface, "PrefabPublicHandler - Could not retrieve instance of InstanceToTemplateInterface");
m_prefabFocusInterface = AZ::Interface<PrefabFocusInterface>::Get();
AZ_Assert(m_prefabFocusInterface, "Could not get PrefabFocusInterface on PrefabPublicHandler construction.");
m_prefabFocusPublicInterface = AZ::Interface<PrefabFocusPublicInterface>::Get();
AZ_Assert(m_prefabFocusPublicInterface, "Could not get PrefabFocusPublicInterface on PrefabPublicHandler construction.");
m_prefabLoaderInterface = AZ::Interface<PrefabLoaderInterface>::Get();
AZ_Assert(m_prefabLoaderInterface, "Could not get PrefabLoaderInterface on PrefabPublicHandler construction.");
@@ -552,6 +558,13 @@ namespace AzToolsFramework
PrefabEntityResult PrefabPublicHandler::CreateEntity(AZ::EntityId parentId, const AZ::Vector3& position)
{
// If the parent is invalid, parent to the container of the currently focused prefab.
if (!parentId.IsValid())
{
AzFramework::EntityContextId editorEntityContextId = AzToolsFramework::GetEntityContextId();
parentId = m_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId);
}
InstanceOptionalReference owningInstanceOfParentEntity = GetOwnerInstanceByEntityId(parentId);
if (!owningInstanceOfParentEntity)
{
@@ -968,13 +981,13 @@ namespace AzToolsFramework
return AZ::Failure(AZStd::string("No entities to duplicate."));
}
const EntityIdList entityIdsNoLevelInstance = GenerateEntityIdListWithoutLevelInstance(entityIds);
if (entityIdsNoLevelInstance.empty())
const EntityIdList entityIdsNoFocusContainer = GenerateEntityIdListWithoutFocusedInstanceContainer(entityIds);
if (entityIdsNoFocusContainer.empty())
{
return AZ::Failure(AZStd::string("No entities to duplicate because only instance selected is the level instance."));
return AZ::Failure(AZStd::string("No entities to duplicate because only instance selected is the container entity of the focused instance."));
}
if (!EntitiesBelongToSameInstance(entityIdsNoLevelInstance))
if (!EntitiesBelongToSameInstance(entityIdsNoFocusContainer))
{
return AZ::Failure(AZStd::string("Cannot duplicate multiple entities belonging to different instances with one operation."
"Change your selection to contain entities in the same instance."));
@@ -982,7 +995,7 @@ namespace AzToolsFramework
// We've already verified the entities are all owned by the same instance,
// so we can just retrieve our instance from the first entity in the list.
AZ::EntityId firstEntityIdToDuplicate = entityIdsNoLevelInstance[0];
AZ::EntityId firstEntityIdToDuplicate = entityIdsNoFocusContainer[0];
InstanceOptionalReference commonOwningInstance = GetOwnerInstanceByEntityId(firstEntityIdToDuplicate);
if (!commonOwningInstance.has_value())
{
@@ -1002,7 +1015,7 @@ namespace AzToolsFramework
// This will cull out any entities that have ancestors in the list, since we will end up duplicating
// the full nested hierarchy with what is returned from RetrieveAndSortPrefabEntitiesAndInstances
AzToolsFramework::EntityIdSet duplicationSet = AzToolsFramework::GetCulledEntityHierarchy(entityIdsNoLevelInstance);
AzToolsFramework::EntityIdSet duplicationSet = AzToolsFramework::GetCulledEntityHierarchy(entityIdsNoFocusContainer);
AZ_PROFILE_FUNCTION(AzToolsFramework);
@@ -1039,10 +1052,10 @@ namespace AzToolsFramework
DuplicateNestedEntitiesInInstance(commonOwningInstance->get(),
entities, instanceDomAfter, duplicatedEntityAndInstanceIds, duplicateEntityAliasMap);
PrefabUndoInstance* command = aznew PrefabUndoInstance("Entity/Instance duplication");
PrefabUndoInstance* command = aznew PrefabUndoInstance("Entity/Instance duplication", false);
command->SetParent(undoBatch.GetUndoBatch());
command->Capture(instanceDomBefore, instanceDomAfter, commonOwningInstance->get().GetTemplateId());
command->RedoBatched();
command->Redo();
DuplicateNestedInstancesInInstance(commonOwningInstance->get(),
instances, instanceDomAfter, duplicatedEntityAndInstanceIds, newInstanceAliasToOldInstanceMap);
@@ -1106,19 +1119,21 @@ namespace AzToolsFramework
PrefabOperationResult PrefabPublicHandler::DeleteFromInstance(const EntityIdList& entityIds, bool deleteDescendants)
{
const EntityIdList entityIdsNoLevelInstance = GenerateEntityIdListWithoutLevelInstance(entityIds);
// Remove the container entity of the focused prefab from the list, if it is included.
const EntityIdList entityIdsNoFocusContainer = GenerateEntityIdListWithoutFocusedInstanceContainer(entityIds);
if (entityIdsNoLevelInstance.empty())
if (entityIdsNoFocusContainer.empty())
{
return AZ::Success();
}
if (!EntitiesBelongToSameInstance(entityIdsNoLevelInstance))
// All entities in this list need to belong to the same prefab instance for the operation to be valid.
if (!EntitiesBelongToSameInstance(entityIdsNoFocusContainer))
{
return AZ::Failure(AZStd::string("Cannot delete multiple entities belonging to different instances with one operation."));
}
AZ::EntityId firstEntityIdToDelete = entityIdsNoLevelInstance[0];
AZ::EntityId firstEntityIdToDelete = entityIdsNoFocusContainer[0];
InstanceOptionalReference commonOwningInstance = GetOwnerInstanceByEntityId(firstEntityIdToDelete);
// If the first entity id is a container entity id, then we need to mark its parent as the common owning instance because you
@@ -1128,8 +1143,15 @@ namespace AzToolsFramework
commonOwningInstance = commonOwningInstance->get().GetParentInstance();
}
// We only allow explicit deletions for entities inside the currently focused prefab.
AzFramework::EntityContextId editorEntityContextId = AzToolsFramework::GetEntityContextId();
if (&m_prefabFocusInterface->GetFocusedPrefabInstance(editorEntityContextId)->get() != &commonOwningInstance->get())
{
return AZ::Failure(AZStd::string("Cannot delete entities belonging to an instance that is not being edited."));
}
// Retrieve entityList from entityIds
EntityList inputEntityList = EntityIdListToEntityList(entityIdsNoLevelInstance);
EntityList inputEntityList = EntityIdListToEntityList(entityIdsNoFocusContainer);
AZ_PROFILE_FUNCTION(AzToolsFramework);
@@ -1186,7 +1208,7 @@ namespace AzToolsFramework
}
else
{
for (AZ::EntityId entityId : entityIdsNoLevelInstance)
for (AZ::EntityId entityId : entityIdsNoFocusContainer)
{
InstanceOptionalReference owningInstance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
// If this is the container entity, it actually represents the instance so get its owner
@@ -1227,9 +1249,12 @@ namespace AzToolsFramework
return AZ::Failure(AZStd::string("Cannot detach Prefab Instance with invalid container entity."));
}
if (IsLevelInstanceContainerEntity(containerEntityId))
auto editorEntityContextId = AzFramework::EntityContextId::CreateNull();
EditorEntityContextRequestBus::BroadcastResult(editorEntityContextId, &EditorEntityContextRequests::GetEditorEntityContextId);
if (containerEntityId == m_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId))
{
return AZ::Failure(AZStd::string("Cannot detach level Prefab Instance."));
return AZ::Failure(AZStd::string("Cannot detach focused Prefab Instance."));
}
InstanceOptionalReference owningInstance = GetOwnerInstanceByEntityId(containerEntityId);
@@ -1298,7 +1323,7 @@ namespace AzToolsFramework
Prefab::PrefabDom instanceDomAfter;
m_instanceToTemplateInterface->GenerateDomForInstance(instanceDomAfter, parentInstance);
PrefabUndoInstance* command = aznew PrefabUndoInstance("Instance detachment");
PrefabUndoInstance* command = aznew PrefabUndoInstance("Instance detachment", false);
command->Capture(instanceDomBefore, instanceDomAfter, parentTemplateId);
command->SetParent(undoBatch.GetUndoBatch());
{
@@ -1452,9 +1477,14 @@ namespace AzToolsFramework
AZStd::queue<AZ::Entity*> entityQueue;
auto editorEntityContextId = AzFramework::EntityContextId::CreateNull();
EditorEntityContextRequestBus::BroadcastResult(editorEntityContextId, &EditorEntityContextRequests::GetEditorEntityContextId);
AZ::EntityId focusedPrefabContainerEntityId =
m_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId);
for (auto inputEntity : inputEntities)
{
if (inputEntity && !IsLevelInstanceContainerEntity(inputEntity->GetId()))
if (inputEntity && inputEntity->GetId() != focusedPrefabContainerEntityId)
{
entityQueue.push(inputEntity);
}
@@ -1548,19 +1578,19 @@ namespace AzToolsFramework
return AZ::Success();
}
EntityIdList PrefabPublicHandler::GenerateEntityIdListWithoutLevelInstance(
EntityIdList PrefabPublicHandler::GenerateEntityIdListWithoutFocusedInstanceContainer(
const EntityIdList& entityIds) const
{
EntityIdList outEntityIds;
outEntityIds.reserve(entityIds.size()); // Actual size could be smaller.
EntityIdList outEntityIds(entityIds);
for (const AZ::EntityId& entityId : entityIds)
AzFramework::EntityContextId editorEntityContextId = AzToolsFramework::GetEntityContextId();
AZ::EntityId focusedInstanceContainerEntityId = m_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId);
if (auto iter = AZStd::find(outEntityIds.begin(), outEntityIds.end(), focusedInstanceContainerEntityId); iter != outEntityIds.end())
{
if (!IsLevelInstanceContainerEntity(entityId))
{
outEntityIds.emplace_back(entityId);
}
outEntityIds.erase(iter);
}
return outEntityIds;
}
@@ -74,7 +74,7 @@ namespace AzToolsFramework
Instance& commonRootEntityOwningInstance,
EntityList& outEntities,
AZStd::vector<Instance*>& outInstances) const;
EntityIdList GenerateEntityIdListWithoutLevelInstance(const EntityIdList& entityIds) const;
EntityIdList GenerateEntityIdListWithoutFocusedInstanceContainer(const EntityIdList& entityIds) const;
InstanceOptionalReference GetOwnerInstanceByEntityId(AZ::EntityId entityId) const;
bool EntitiesBelongToSameInstance(const EntityIdList& entityIds) const;
@@ -187,6 +187,8 @@ namespace AzToolsFramework
InstanceEntityMapperInterface* m_instanceEntityMapperInterface = nullptr;
InstanceToTemplateInterface* m_instanceToTemplateInterface = nullptr;
PrefabFocusInterface* m_prefabFocusInterface = nullptr;
PrefabFocusPublicInterface* m_prefabFocusPublicInterface = nullptr;
PrefabLoaderInterface* m_prefabLoaderInterface = nullptr;
PrefabSystemComponentInterface* m_prefabSystemComponentInterface = nullptr;
@@ -6,11 +6,14 @@
*
*/
#include <API/ToolsApplicationAPI.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <Prefab/PrefabSystemComponentInterface.h>
#include <Prefab/PrefabSystemScriptingHandler.h>
#include <AzCore/Component/Entity.h>
#include <AzCore/Component/TransformBus.h>
#include <ToolsComponents/TransformComponent.h>
namespace AzToolsFramework::Prefab
{
@@ -61,9 +64,29 @@ namespace AzToolsFramework::Prefab
entities.push_back(entity);
}
}
auto prefab = m_prefabSystemComponentInterface->CreatePrefab(entities, {}, AZ::IO::PathView(AZStd::string_view(filePath)));
bool result = false;
[[maybe_unused]] AZ::EntityId commonRoot;
EntityList topLevelEntities;
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(result, &AzToolsFramework::ToolsApplicationRequestBus::Events::FindCommonRootInactive,
entities, commonRoot, &topLevelEntities);
auto containerEntity = AZStd::make_unique<AZ::Entity>();
for (AZ::Entity* entity : topLevelEntities)
{
AzToolsFramework::Components::TransformComponent* transformComponent =
entity->FindComponent<AzToolsFramework::Components::TransformComponent>();
if (transformComponent)
{
transformComponent->SetParent(containerEntity->GetId());
}
}
auto prefab = m_prefabSystemComponentInterface->CreatePrefab(
entities, {}, AZ::IO::PathView(AZStd::string_view(filePath)), AZStd::move(containerEntity));
if (!prefab)
{
AZ_Error("PrefabSystemComponenent", false, "Failed to create prefab %s", filePath.c_str());
@@ -17,17 +17,16 @@ namespace AzToolsFramework
{
PrefabUndoBase::PrefabUndoBase(const AZStd::string& undoOperationName)
: UndoSystem::URSequencePoint(undoOperationName)
, m_changed(true)
, m_templateId(InvalidTemplateId)
{
m_instanceToTemplateInterface = AZ::Interface<InstanceToTemplateInterface>::Get();
AZ_Assert(m_instanceToTemplateInterface, "Failed to grab instance to template interface");
}
//PrefabInstanceUndo
PrefabUndoInstance::PrefabUndoInstance(const AZStd::string& undoOperationName)
PrefabUndoInstance::PrefabUndoInstance(const AZStd::string& undoOperationName, const bool useImmediatePropagation)
: PrefabUndoBase(undoOperationName)
{
m_useImmediatePropagation = useImmediatePropagation;
}
void PrefabUndoInstance::Capture(
@@ -43,17 +42,12 @@ namespace AzToolsFramework
void PrefabUndoInstance::Undo()
{
m_instanceToTemplateInterface->PatchTemplate(m_undoPatch, m_templateId, true);
m_instanceToTemplateInterface->PatchTemplate(m_undoPatch, m_templateId, m_useImmediatePropagation);
}
void PrefabUndoInstance::Redo()
{
m_instanceToTemplateInterface->PatchTemplate(m_redoPatch, m_templateId, true);
}
void PrefabUndoInstance::RedoBatched()
{
m_instanceToTemplateInterface->PatchTemplate(m_redoPatch, m_templateId);
m_instanceToTemplateInterface->PatchTemplate(m_redoPatch, m_templateId, m_useImmediatePropagation);
}
@@ -29,14 +29,15 @@ namespace AzToolsFramework
bool Changed() const override { return m_changed; }
protected:
TemplateId m_templateId;
TemplateId m_templateId = InvalidTemplateId;
PrefabDom m_redoPatch;
PrefabDom m_undoPatch;
InstanceToTemplateInterface* m_instanceToTemplateInterface = nullptr;
bool m_changed;
bool m_changed = true;
bool m_useImmediatePropagation = true;
};
//! handles the addition and removal of entities from instances
@@ -44,7 +45,7 @@ namespace AzToolsFramework
: public PrefabUndoBase
{
public:
explicit PrefabUndoInstance(const AZStd::string& undoOperationName);
explicit PrefabUndoInstance(const AZStd::string& undoOperationName, const bool useImmediatePropagation = true);
void Capture(
const PrefabDom& initialState,
@@ -53,7 +54,6 @@ namespace AzToolsFramework
void Undo() override;
void Redo() override;
void RedoBatched();
};
//! handles entity updates, such as when the values on an entity change
@@ -23,10 +23,10 @@ namespace AzToolsFramework
PrefabDom instanceDomAfterUpdate;
PrefabDomUtils::StoreInstanceInPrefabDom(instance, instanceDomAfterUpdate);
PrefabUndoInstance* state = aznew Prefab::PrefabUndoInstance(undoMessage);
PrefabUndoInstance* state = aznew Prefab::PrefabUndoInstance(undoMessage, false);
state->Capture(instanceDomBeforeUpdate, instanceDomAfterUpdate, instance.GetTemplateId());
state->SetParent(undoBatch);
state->RedoBatched();
state->Redo();
}
LinkId CreateLink(
@@ -24,6 +24,7 @@
#include <AzToolsFramework/AssetBrowser/AssetSelectionModel.h>
#include <AzToolsFramework/AssetBrowser/Entries/SourceAssetBrowserEntry.h>
#include <AzToolsFramework/ContainerEntity/ContainerEntityInterface.h>
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <AzToolsFramework/Prefab/EditorPrefabComponent.h>
#include <AzToolsFramework/Prefab/Instance/InstanceEntityMapperInterface.h>
#include <AzToolsFramework/Prefab/PrefabFocusPublicInterface.h>
@@ -175,12 +176,16 @@ namespace AzToolsFramework
AzFramework::ApplicationRequests::Bus::BroadcastResult(
prefabWipFeaturesEnabled, &AzFramework::ApplicationRequests::ArePrefabWipFeaturesEnabled);
auto editorEntityContextId = AzFramework::EntityContextId::CreateNull();
EditorEntityContextRequestBus::BroadcastResult(editorEntityContextId, &EditorEntityContextRequests::GetEditorEntityContextId);
// Create Prefab
{
if (!selectedEntities.empty())
{
// Hide if the only selected entity is the Level Container
if (selectedEntities.size() > 1 || !s_prefabPublicInterface->IsLevelInstanceContainerEntity(selectedEntities[0]))
// Hide if the only selected entity is the Focused Instance Container
if (selectedEntities.size() > 1 ||
selectedEntities[0] != s_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId))
{
bool layerInSelection = false;
@@ -247,14 +252,14 @@ namespace AzToolsFramework
// Edit Prefab
if (prefabWipFeaturesEnabled && !s_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(selectedEntity))
{
QAction* editAction = menu->addAction(QObject::tr("Edit Prefab"));
editAction->setToolTip(QObject::tr("Edit the prefab in focus mode."));
QAction* editAction = menu->addAction(QObject::tr("Edit Prefab"));
editAction->setToolTip(QObject::tr("Edit the prefab in focus mode."));
QObject::connect(editAction, &QAction::triggered, editAction, [selectedEntity] {
ContextMenu_EditPrefab(selectedEntity);
});
QObject::connect(editAction, &QAction::triggered, editAction, [selectedEntity] {
ContextMenu_EditPrefab(selectedEntity);
});
itemWasShown = true;
itemWasShown = true;
}
// Save Prefab
@@ -283,8 +288,9 @@ namespace AzToolsFramework
QAction* deleteAction = menu->addAction(QObject::tr("Delete"));
QObject::connect(deleteAction, &QAction::triggered, deleteAction, [] { ContextMenu_DeleteSelected(); });
if (selectedEntities.size() == 0 ||
(selectedEntities.size() == 1 && s_prefabPublicInterface->IsLevelInstanceContainerEntity(selectedEntities[0])))
if (selectedEntities.empty() ||
(selectedEntities.size() == 1 && selectedEntities[0] == s_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId)))
{
deleteAction->setDisabled(true);
}
@@ -292,17 +298,17 @@ namespace AzToolsFramework
// Detach Prefab
if (selectedEntities.size() == 1)
{
AZ::EntityId selectedEntity = selectedEntities[0];
AZ::EntityId selectedEntityId = selectedEntities[0];
if (s_prefabPublicInterface->IsInstanceContainerEntity(selectedEntity) &&
!s_prefabPublicInterface->IsLevelInstanceContainerEntity(selectedEntity))
if (s_prefabPublicInterface->IsInstanceContainerEntity(selectedEntityId) &&
selectedEntityId != s_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId))
{
QAction* detachPrefabAction = menu->addAction(QObject::tr("Detach Prefab..."));
QObject::connect(
detachPrefabAction, &QAction::triggered, detachPrefabAction,
[selectedEntity]
[selectedEntityId]
{
ContextMenu_DetachPrefab(selectedEntity);
ContextMenu_DetachPrefab(selectedEntityId);
});
}
}
@@ -331,13 +337,21 @@ namespace AzToolsFramework
QWidget* activeWindow = QApplication::activeWindow();
const AZStd::string prefabFilesPath = "@projectroot@/Prefabs";
// Remove Level entity if it's part of the list
auto levelContainerIter =
AZStd::find(selectedEntities.begin(), selectedEntities.end(), s_prefabPublicInterface->GetLevelInstanceContainerEntityId());
if (levelContainerIter != selectedEntities.end())
// Remove focused instance container entity if it's part of the list
auto editorEntityContextId = AzFramework::EntityContextId::CreateNull();
EditorEntityContextRequestBus::BroadcastResult(editorEntityContextId, &EditorEntityContextRequests::GetEditorEntityContextId);
auto focusedContainerIter = AZStd::find(
selectedEntities.begin(), selectedEntities.end(),
s_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId));
if (focusedContainerIter != selectedEntities.end())
{
selectedEntities.erase(levelContainerIter);
selectedEntities.erase(focusedContainerIter);
}
if (selectedEntities.empty())
{
return;
}
// Set default folder for prefabs
@@ -178,12 +178,6 @@ namespace AzToolsFramework
AZ::EntityId entityId(index.data(EntityOutlinerListModel::EntityIdRole).value<AZ::u64>());
// We hide the root instance container entity from the Outliner, so avoid drawing its full container on children
if (m_prefabPublicInterface->IsLevelInstanceContainerEntity(entityId))
{
return;
}
const QTreeView* outlinerTreeView(qobject_cast<const QTreeView*>(option.widget));
const int ancestorLeft = outlinerTreeView->visualRect(index).left() + (m_prefabBorderThickness / 2) - 1;
const int curveRectSize = m_prefabCapsuleRadius * 2;
@@ -9,6 +9,7 @@
#include "EditorHelpers.h"
#include <AzCore/Console/Console.h>
#include <AzCore/Math/VectorConversions.h>
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
#include <AzFramework/Viewport/CameraState.h>
#include <AzFramework/Viewport/ViewportScreen.h>
@@ -123,6 +124,11 @@ namespace AzToolsFramework
"EditorHelpers - "
"Focus Mode Interface could not be found. "
"Check that it is being correctly initialized.");
AZStd::vector<AZStd::unique_ptr<InvalidClick>> invalidClicks;
invalidClicks.push_back(AZStd::make_unique<FadingText>("Not in focus"));
invalidClicks.push_back(AZStd::make_unique<ExpandingFadingCircles>());
m_invalidClicks = AZStd::make_unique<InvalidClicks>(AZStd::move(invalidClicks));
}
AZ::EntityId EditorHelpers::HandleMouseInteraction(
@@ -186,13 +192,20 @@ namespace AzToolsFramework
}
}
// Verify if the entity Id corresponds to an entity that is focused; if not, halt selection.
if (!IsSelectableAccordingToFocusMode(entityIdUnderCursor))
// verify if the entity Id corresponds to an entity that is focused; if not, halt selection.
if (entityIdUnderCursor.IsValid() && !IsSelectableAccordingToFocusMode(entityIdUnderCursor))
{
if (mouseInteraction.m_mouseInteraction.m_mouseButtons.Left() &&
mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::Down ||
mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::DoubleClick)
{
m_invalidClicks->AddInvalidClick(mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates);
}
return AZ::EntityId();
}
// Container Entity support - if the entity that is being selected is part of a closed container,
// container entity support - if the entity that is being selected is part of a closed container,
// change the selection to the container instead.
if (ContainerEntityInterface* containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get())
{
@@ -202,6 +215,12 @@ namespace AzToolsFramework
return entityIdUnderCursor;
}
void EditorHelpers::Display2d(
[[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay)
{
m_invalidClicks->Display2d(viewportInfo, debugDisplay);
}
void EditorHelpers::DisplayHelpers(
const AzFramework::ViewportInfo& viewportInfo,
const AzFramework::CameraState& cameraState,
@@ -263,19 +282,19 @@ namespace AzToolsFramework
}
}
bool EditorHelpers::IsSelectableInViewport(AZ::EntityId entityId)
bool EditorHelpers::IsSelectableInViewport(const AZ::EntityId entityId) const
{
return IsSelectableAccordingToFocusMode(entityId) && IsSelectableAccordingToContainerEntities(entityId);
}
bool EditorHelpers::IsSelectableAccordingToFocusMode(AZ::EntityId entityId)
bool EditorHelpers::IsSelectableAccordingToFocusMode(const AZ::EntityId entityId) const
{
return m_focusModeInterface->IsInFocusSubTree(entityId);
}
bool EditorHelpers::IsSelectableAccordingToContainerEntities(AZ::EntityId entityId)
bool EditorHelpers::IsSelectableAccordingToContainerEntities(const AZ::EntityId entityId) const
{
if (ContainerEntityInterface* containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get())
if (const auto* containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get())
{
return !containerEntityInterface->IsUnderClosedContainerEntity(entityId);
}
@@ -11,6 +11,9 @@
#include <AzCore/Component/EntityId.h>
#include <AzCore/Memory/Memory.h>
#include <AzCore/std/functional.h>
#include <AzCore/std/containers/vector.h>
#include <AzFramework/Viewport/ScreenGeometry.h>
#include <AzToolsFramework/ViewportSelection/InvalidClicks.h>
namespace AzFramework
{
@@ -58,20 +61,27 @@ namespace AzToolsFramework
AzFramework::DebugDisplayRequests& debugDisplay,
const AZStd::function<bool(AZ::EntityId)>& showIconCheck);
//! Handle 2d drawing for EditorHelper functionality.
void Display2d(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay);
//! Returns whether the entityId can be selected in the viewport according
//! to the current Editor Focus Mode and Container Entity setup.
bool IsSelectableInViewport(AZ::EntityId entityId);
bool IsSelectableInViewport(AZ::EntityId entityId) const;
private:
//! Returns whether the entityId can be selected in the viewport according
//! to the current Editor Focus Mode setup.
bool IsSelectableAccordingToFocusMode(AZ::EntityId entityId);
bool IsSelectableAccordingToFocusMode(AZ::EntityId entityId) const;
//! Returns whether the entityId can be selected in the viewport according
//! to the current Container Entityu setup.
bool IsSelectableAccordingToContainerEntities(AZ::EntityId entityId);
//! to the current Container Entity setup.
bool IsSelectableAccordingToContainerEntities(AZ::EntityId entityId) const;
AZStd::unique_ptr<InvalidClicks> m_invalidClicks; //!< Display for invalid click behavior.
const EditorVisibleEntityDataCache* m_entityDataCache = nullptr; //!< Entity Data queried by the EditorHelpers.
const FocusModeInterface* m_focusModeInterface = nullptr;
const FocusModeInterface* m_focusModeInterface = nullptr; //!< API to interact with focus mode functionality.
};
} // namespace AzToolsFramework
@@ -3560,6 +3560,8 @@ namespace AzToolsFramework
DrawAxisGizmo(viewportInfo, debugDisplay);
m_boxSelect.Display2d(viewportInfo, debugDisplay);
m_editorHelpers->Display2d(viewportInfo, debugDisplay);
}
void EditorTransformComponentSelection::RefreshSelectedEntityIds()
@@ -3663,26 +3665,63 @@ namespace AzToolsFramework
void EditorTransformComponentSelection::OnEditorModeActivated(
[[maybe_unused]] const ViewportEditorModesInterface& editorModeState, ViewportEditorMode mode)
{
if (mode == ViewportEditorMode::Component)
switch (mode)
{
SetAllViewportUiVisible(false);
case ViewportEditorMode::Component:
{
SetAllViewportUiVisible(false);
EditorEntityLockComponentNotificationBus::Router::BusRouterDisconnect();
EditorEntityVisibilityNotificationBus::Router::BusRouterDisconnect();
ToolsApplicationNotificationBus::Handler::BusDisconnect();
EditorEntityLockComponentNotificationBus::Router::BusRouterDisconnect();
EditorEntityVisibilityNotificationBus::Router::BusRouterDisconnect();
ToolsApplicationNotificationBus::Handler::BusDisconnect();
}
break;
case ViewportEditorMode::Focus:
{
ViewportUi::ViewportUiRequestBus::Event(
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder, "Focus Mode");
}
break;
case ViewportEditorMode::Default:
case ViewportEditorMode::Pick:
// noop
break;
}
}
void EditorTransformComponentSelection::OnEditorModeDeactivated(
[[maybe_unused]] const ViewportEditorModesInterface& editorModeState, ViewportEditorMode mode)
const ViewportEditorModesInterface& editorModeState, const ViewportEditorMode mode)
{
if (mode == ViewportEditorMode::Component)
switch (mode)
{
SetAllViewportUiVisible(true);
case ViewportEditorMode::Component:
{
SetAllViewportUiVisible(true);
ToolsApplicationNotificationBus::Handler::BusConnect();
EditorEntityVisibilityNotificationBus::Router::BusRouterConnect();
EditorEntityLockComponentNotificationBus::Router::BusRouterConnect();
ToolsApplicationNotificationBus::Handler::BusConnect();
EditorEntityVisibilityNotificationBus::Router::BusRouterConnect();
EditorEntityLockComponentNotificationBus::Router::BusRouterConnect();
// note: when leaving component mode, we check if we're still in focus mode (i.e. component mode was
// started from within focus mode), if we are, ensure we create/update the viewport border (as leaving
// component mode will attempt to remove it)
if (editorModeState.IsModeActive(ViewportEditorMode::Focus))
{
ViewportUi::ViewportUiRequestBus::Event(
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder, "Focus Mode");
}
}
break;
case ViewportEditorMode::Focus:
{
ViewportUi::ViewportUiRequestBus::Event(
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::RemoveViewportBorder);
}
break;
case ViewportEditorMode::Default:
case ViewportEditorMode::Pick:
// noop
break;
}
}
@@ -0,0 +1,142 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/Console/Console.h>
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
#include <AzToolsFramework/Viewport/ViewportTypes.h>
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
#include <AzToolsFramework/ViewportSelection/InvalidClicks.h>
AZ_CVAR(float, ed_invalidClickRadius, 10.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "Maximum invalid click radius to expand to");
AZ_CVAR(float, ed_invalidClickDuration, 1.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "Duration to display the invalid click feedback");
AZ_CVAR(float, ed_invalidClickMessageSize, 0.8f, nullptr, AZ::ConsoleFunctorFlags::Null, "Size of text for invalid message");
AZ_CVAR(
float,
ed_invalidClickMessageVerticalOffset,
30.0f,
nullptr,
AZ::ConsoleFunctorFlags::Null,
"Vertical offset from cursor of invalid click message");
namespace AzToolsFramework
{
void ExpandingFadingCircles::Begin(const AzFramework::ScreenPoint& screenPoint)
{
FadingCircle fadingCircle;
fadingCircle.m_position = screenPoint;
fadingCircle.m_opacity = 1.0f;
fadingCircle.m_radius = 0.0f;
m_fadingCircles.push_back(fadingCircle);
}
void ExpandingFadingCircles::Update(const float deltaTime)
{
for (auto& fadingCircle : m_fadingCircles)
{
fadingCircle.m_opacity = AZStd::max(fadingCircle.m_opacity - (deltaTime / ed_invalidClickDuration), 0.0f);
fadingCircle.m_radius += deltaTime * ed_invalidClickRadius;
}
m_fadingCircles.erase(
AZStd::remove_if(
m_fadingCircles.begin(), m_fadingCircles.end(),
[](const FadingCircle& fadingCircle)
{
return fadingCircle.m_opacity <= 0.0f;
}),
m_fadingCircles.end());
}
bool ExpandingFadingCircles::Updating()
{
return !m_fadingCircles.empty();
}
void ExpandingFadingCircles::Display(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay)
{
const AZ::Vector2 viewportSize = AzToolsFramework::GetCameraState(viewportInfo.m_viewportId).m_viewportSize;
for (const auto& fadingCircle : m_fadingCircles)
{
const auto position = AzFramework::Vector2FromScreenPoint(fadingCircle.m_position) / viewportSize;
debugDisplay.SetColor(AZ::Color(1.0f, 1.0f, 1.0f, fadingCircle.m_opacity));
debugDisplay.DrawWireCircle2d(position, fadingCircle.m_radius * 0.005f, 0.0f);
}
}
void FadingText::Begin(const AzFramework::ScreenPoint& screenPoint)
{
m_opacity = 1.0f;
m_invalidClickPosition = screenPoint;
}
void FadingText::Update(const float deltaTime)
{
m_opacity -= deltaTime / ed_invalidClickDuration;
}
bool FadingText::Updating()
{
return m_opacity >= 0.0f;
}
void FadingText::Display(
[[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay)
{
if (constexpr float MinOpacity = 0.05f; m_opacity >= MinOpacity)
{
debugDisplay.SetColor(AZ::Color(1.0f, 1.0f, 1.0f, m_opacity));
debugDisplay.Draw2dTextLabel(
aznumeric_cast<float>(m_invalidClickPosition.m_x),
aznumeric_cast<float>(m_invalidClickPosition.m_y) - ed_invalidClickMessageVerticalOffset, ed_invalidClickMessageSize,
m_message.c_str(), true);
}
}
void InvalidClicks::AddInvalidClick(const AzFramework::ScreenPoint& screenPoint)
{
AZ::TickBus::Handler::BusConnect();
for (auto& invalidClickBehavior : m_invalidClickBehaviors)
{
invalidClickBehavior->Begin(screenPoint);
}
}
void InvalidClicks::OnTick(const float deltaTime, [[maybe_unused]] const AZ::ScriptTimePoint time)
{
for (auto& invalidClickBehavior : m_invalidClickBehaviors)
{
invalidClickBehavior->Update(deltaTime);
}
const auto updating = AZStd::any_of(
m_invalidClickBehaviors.begin(), m_invalidClickBehaviors.end(),
[](const auto& invalidClickBehavior)
{
return invalidClickBehavior->Updating();
});
if (!updating && AZ::TickBus::Handler::BusIsConnected())
{
AZ::TickBus::Handler::BusDisconnect();
}
}
void InvalidClicks::Display2d(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay)
{
debugDisplay.DepthTestOff();
for (const auto& invalidClickBehavior : m_invalidClickBehaviors)
{
invalidClickBehavior->Display(viewportInfo, debugDisplay);
}
debugDisplay.DepthTestOn();
}
} // namespace AzToolsFramework
@@ -0,0 +1,108 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Component/TickBus.h>
#include <AzFramework/Viewport/ScreenGeometry.h>
namespace AzFramework
{
class DebugDisplayRequests;
struct ViewportInfo;
} // namespace AzFramework
namespace AzToolsFramework
{
namespace ViewportInteraction
{
struct MouseInteractionEvent;
}
//! An interface to provide invalid click feedback in the editor viewport.
class InvalidClick
{
public:
virtual ~InvalidClick() = default;
//! Begin the feedback.
//! @param screenPoint The position of the click in screen coordinates.
virtual void Begin(const AzFramework::ScreenPoint& screenPoint) = 0;
//! Update the invalid click feedback
virtual void Update(float deltaTime) = 0;
//! Report if the click feedback is running or not (returning false will signal the TickBus can be disconnected from).
virtual bool Updating() = 0;
//! Display the click feedback in the viewport.
virtual void Display(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) = 0;
};
//! Display expanding fading circles for every click of the mouse that is invalid.
class ExpandingFadingCircles : public InvalidClick
{
public:
void Begin(const AzFramework::ScreenPoint& screenPoint) override;
void Update(float deltaTime) override;
bool Updating() override;
void Display(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override;
private:
//! Stores a circle representation with a lifetime to grow and fade out over time.
struct FadingCircle
{
AzFramework::ScreenPoint m_position;
float m_radius;
float m_opacity;
};
using FadingCircles = AZStd::vector<FadingCircle>;
FadingCircles m_fadingCircles; //!< Collection of fading circles to draw for clicks that have no effect.
};
//! Display fading text where an invalid click happened.
//! @note There is only one fading text, each click will update its position.
class FadingText : public InvalidClick
{
public:
explicit FadingText(AZStd::string message)
: m_message(AZStd::move(message))
{
}
void Begin(const AzFramework::ScreenPoint& screenPoint) override;
void Update(float deltaTime) override;
bool Updating() override;
void Display(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override;
private:
AZStd::string m_message; //!< Message to display for fading text.
float m_opacity = 1.0f; //!< The opacity of the invalid click message.
AzFramework::ScreenPoint m_invalidClickPosition; //!< The position to display the invalid click message.
};
//! Interface to begin invalid click feedback (will run all added InvalidClick behaviors).
class InvalidClicks : private AZ::TickBus::Handler
{
public:
explicit InvalidClicks(AZStd::vector<AZStd::unique_ptr<InvalidClick>> invalidClickBehaviors)
: m_invalidClickBehaviors(AZStd::move(invalidClickBehaviors))
{
}
//! Add an invalid click and activate one or more of the added invalid click behaviors.
void AddInvalidClick(const AzFramework::ScreenPoint& screenPoint);
//! Handle 2d drawing for EditorHelper functionality.
void Display2d(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay);
private:
//! AZ::TickBus overrides ...
void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
AZStd::vector<AZStd::unique_ptr<InvalidClick>> m_invalidClickBehaviors; //!< Invalid click behaviors to run.
};
} // namespace AzToolsFramework
@@ -290,9 +290,9 @@ namespace AzToolsFramework::ViewportUi::Internal
return false;
}
void ViewportUiDisplay::CreateComponentModeBorder(const AZStd::string& borderTitle)
void ViewportUiDisplay::CreateViewportBorder(const AZStd::string& borderTitle)
{
AZStd::string styleSheet = AZStd::string::format(
const AZStd::string styleSheet = AZStd::string::format(
"border: %dpx solid %s; border-top: %dpx solid %s;", HighlightBorderSize, HighlightBorderColor, TopHighlightBorderSize,
HighlightBorderColor);
m_uiOverlay.setStyleSheet(styleSheet.c_str());
@@ -303,7 +303,7 @@ namespace AzToolsFramework::ViewportUi::Internal
m_componentModeBorderText.setText(borderTitle.c_str());
}
void ViewportUiDisplay::RemoveComponentModeBorder()
void ViewportUiDisplay::RemoveViewportBorder()
{
m_componentModeBorderText.setVisible(false);
m_uiOverlay.setStyleSheet("border: none;");
@@ -420,6 +420,7 @@ namespace AzToolsFramework::ViewportUi::Internal
m_uiMainWindow.setVisible(true);
m_uiOverlay.setVisible(true);
}
m_uiMainWindow.setMask(region);
}
@@ -437,6 +438,7 @@ namespace AzToolsFramework::ViewportUi::Internal
{
return element->second;
}
return ViewportUiElementInfo{ nullptr, InvalidViewportUiElementId, false };
}
@@ -89,8 +89,8 @@ namespace AzToolsFramework::ViewportUi::Internal
AZStd::shared_ptr<QWidget> GetViewportUiElement(ViewportUiElementId elementId);
bool IsViewportUiElementVisible(ViewportUiElementId elementId);
void CreateComponentModeBorder(const AZStd::string& borderTitle);
void RemoveComponentModeBorder();
void CreateViewportBorder(const AZStd::string& borderTitle);
void RemoveViewportBorder();
private:
void PrepareWidgetForViewportUi(QPointer<QWidget> widget);
@@ -240,14 +240,14 @@ namespace AzToolsFramework::ViewportUi
}
}
void ViewportUiManager::CreateComponentModeBorder(const AZStd::string& borderTitle)
void ViewportUiManager::CreateViewportBorder(const AZStd::string& borderTitle)
{
m_viewportUi->CreateComponentModeBorder(borderTitle);
m_viewportUi->CreateViewportBorder(borderTitle);
}
void ViewportUiManager::RemoveComponentModeBorder()
void ViewportUiManager::RemoveViewportBorder()
{
m_viewportUi->RemoveComponentModeBorder();
m_viewportUi->RemoveViewportBorder();
}
void ViewportUiManager::PressButton(ClusterId clusterId, ButtonId buttonId)
@@ -50,8 +50,8 @@ namespace AzToolsFramework::ViewportUi
void RegisterTextFieldCallback(TextFieldId textFieldId, AZ::Event<AZStd::string>::Handler& handler) override;
void RemoveTextField(TextFieldId textFieldId) override;
void SetTextFieldVisible(TextFieldId textFieldId, bool visible) override;
void CreateComponentModeBorder(const AZStd::string& borderTitle) override;
void RemoveComponentModeBorder() override;
void CreateViewportBorder(const AZStd::string& borderTitle) override;
void RemoveViewportBorder() override;
void PressButton(ClusterId clusterId, ButtonId buttonId) override;
void PressButton(SwitcherId switcherId, ButtonId buttonId) override;
@@ -78,7 +78,7 @@ namespace AzToolsFramework::ViewportUi
virtual void RegisterSwitcherEventHandler(SwitcherId switcherId, AZ::Event<ButtonId>::Handler& handler) = 0;
//! Removes a cluster from the Viewport UI system.
virtual void RemoveCluster(ClusterId clusterId) = 0;
//!
//! Removes a switcher from the Viewport UI system.
virtual void RemoveSwitcher(SwitcherId switcherId) = 0;
//! Sets the visibility of the cluster.
virtual void SetClusterVisible(ClusterId clusterId, bool visible) = 0;
@@ -96,12 +96,12 @@ namespace AzToolsFramework::ViewportUi
//! Sets the visibility of the text field.
virtual void SetTextFieldVisible(TextFieldId textFieldId, bool visible) = 0;
//! Create the highlight border for Component Mode.
virtual void CreateComponentModeBorder(const AZStd::string& borderTitle) = 0;
virtual void CreateViewportBorder(const AZStd::string& borderTitle) = 0;
//! Remove the highlight border for Component Mode.
virtual void RemoveComponentModeBorder() = 0;
//! Invoke a button press in a cluster.
virtual void RemoveViewportBorder() = 0;
//! Invoke a button press on a cluster.
virtual void PressButton(ClusterId clusterId, ButtonId buttonId) = 0;
//!
//! Invoke a button press on a switcher.
virtual void PressButton(SwitcherId switcherId, ButtonId buttonId) = 0;
};
@@ -553,6 +553,8 @@ set(FILES
ViewportSelection/EditorTransformComponentSelectionRequestBus.cpp
ViewportSelection/EditorVisibleEntityDataCache.h
ViewportSelection/EditorVisibleEntityDataCache.cpp
ViewportSelection/InvalidClicks.h
ViewportSelection/InvalidClicks.cpp
ViewportSelection/ViewportEditorModeTracker.cpp
ViewportSelection/ViewportEditorModeTracker.h
ToolsFileUtils/ToolsFileUtils.h
+40 -40
View File
@@ -333,7 +333,7 @@ namespace UnitTest
};
template<class SocketProvider = SocketDriverProvider>
class Integ_CarrierAsyncHandshakeTestTemplate
class CarrierAsyncHandshakeTestTemplate
: public GridMateMPTestFixture
, protected SocketProvider
{
@@ -761,7 +761,7 @@ namespace UnitTest
};
template<class SocketProvider = SocketDriverProvider>
class Integ_CarrierDisconnectDetectionTestTemplate
class CarrierDisconnectDetectionTestTemplate
: public GridMateMPTestFixture
, protected SocketProvider
{
@@ -846,7 +846,7 @@ namespace UnitTest
* Sends reliable messages across different channels to each other
*/
template<class SocketProvider = SocketDriverProvider>
class Integ_CarrierMultiChannelTestTemplate
class CarrierMultiChannelTestTemplate
: public GridMateMPTestFixture
, protected SocketProvider
{
@@ -950,7 +950,7 @@ namespace UnitTest
* Stress tests multiple simultaneous Carriers
*/
template<class SocketProvider = SocketDriverProvider>
class Integ_CarrierMultiStressTestTemplate
class CarrierMultiStressTestTemplate
: public GridMateMPTestFixture
, protected SocketProvider
{
@@ -977,7 +977,7 @@ namespace UnitTest
public:
void run()
{
AZ_TracePrintf("GridMate", "Integ_CarrierMultiStressTest\n\n");
AZ_TracePrintf("GridMate", "CarrierMultiStressTest\n\n");
// initialize transport
const int k_numChannels = 1;
@@ -1108,7 +1108,7 @@ namespace UnitTest
/*** Congestion control back pressure test */
template<class SocketProvider = SocketDriverProvider>
class Integ_CarrierBackpressureTestTemplate
class CarrierBackpressureTestTemplate
: public GridMateMPTestFixture
, protected SocketProvider
, public CarrierEventBus::Handler
@@ -1380,7 +1380,7 @@ namespace UnitTest
};
template<class SocketProvider = SocketDriverProvider>
class Integ_CarrierACKTestTemplate
class CarrierACKTestTemplate
: public GridMateMPTestFixture
, protected SocketProvider
{
@@ -1544,13 +1544,13 @@ namespace UnitTest
//Create specific tests
using CarrierBasicTest = CarrierBasicTestTemplate<>;
using CarrierTest = CarrierTestTemplate<>;
using Integ_CarrierDisconnectDetectionTest = Integ_CarrierDisconnectDetectionTestTemplate<>;
using Integ_CarrierAsyncHandshakeTest = Integ_CarrierAsyncHandshakeTestTemplate<>;
using Integ_CarrierStressTest = CarrierStressTestTemplate<>;
using Integ_CarrierMultiChannelTest = Integ_CarrierMultiChannelTestTemplate<>;
using Integ_CarrierMultiStressTest = Integ_CarrierMultiStressTestTemplate<>;
using Integ_CarrierBackpressureTest = Integ_CarrierBackpressureTestTemplate<>;
using Integ_CarrierACKTest = Integ_CarrierACKTestTemplate<>;
using DISABLED_CarrierDisconnectDetectionTest = CarrierDisconnectDetectionTestTemplate<>;
using DISABLED_CarrierAsyncHandshakeTest = CarrierAsyncHandshakeTestTemplate<>;
using DISABLED_CarrierStressTest = CarrierStressTestTemplate<>;
using DISABLED_CarrierMultiChannelTest = CarrierMultiChannelTestTemplate<>;
using DISABLED_CarrierMultiStressTest = CarrierMultiStressTestTemplate<>;
using DISABLED_CarrierBackpressureTest = CarrierBackpressureTestTemplate<>;
using DISABLED_CarrierACKTest = CarrierACKTestTemplate<>;
#if AZ_TRAIT_GRIDMATE_TEST_WITH_SECURE_SOCKET_DRIVER
@@ -1658,20 +1658,20 @@ namespace UnitTest
using SecureProviderBadHost = SecureDriverProvider<SecureSocketDriver, SecureSocketHandshakeDrop<false>>;
using SecureProviderBadBoth = SecureDriverProvider<SecureSocketHandshakeDrop<true>, SecureSocketHandshakeDrop<false>>;
using Integ_CarrierSecureSocketHandshakeTestClient = CarrierBasicTestTemplate<SecureProviderBadClient, 200>;
using Integ_CarrierSecureSocketHandshakeTestHost = CarrierBasicTestTemplate<SecureProviderBadHost, 200>;
using Integ_CarrierSecureSocketHandshakeTestBoth = CarrierBasicTestTemplate<SecureProviderBadBoth, 200>;
using DISABLED_CarrierSecureSocketHandshakeTestClient = CarrierBasicTestTemplate<SecureProviderBadClient, 200>;
using DISABLED_CarrierSecureSocketHandshakeTestHost = CarrierBasicTestTemplate<SecureProviderBadHost, 200>;
using DISABLED_CarrierSecureSocketHandshakeTestBoth = CarrierBasicTestTemplate<SecureProviderBadBoth, 200>;
//Create secure socket variants of tests
using CarrierBasicTestSecure = CarrierBasicTestTemplate<SecureDriverProvider<>>;
using CarrierTestSecure = CarrierTestTemplate<SecureDriverProvider<>>;
using Integ_CarrierDisconnectDetectionTestSecure = Integ_CarrierDisconnectDetectionTestTemplate<SecureDriverProvider<>>;
using Integ_CarrierAsyncHandshakeTestSecure = Integ_CarrierAsyncHandshakeTestTemplate<SecureDriverProvider<>>;
using Integ_CarrierStressTestSecure = CarrierStressTestTemplate<SecureDriverProvider<>>;
using Integ_CarrierMultiChannelTestSecure = Integ_CarrierMultiChannelTestTemplate<SecureDriverProvider<>>;
using Integ_CarrierMultiStressTestSecure = Integ_CarrierMultiStressTestTemplate<SecureDriverProvider<>>;
using Integ_CarrierBackpressureTestSecure = Integ_CarrierBackpressureTestTemplate<SecureDriverProvider<>>;
using Integ_CarrierACKTestSecure = Integ_CarrierACKTestTemplate<SecureDriverProvider<>>;
using DISABLED_CarrierDisconnectDetectionTestSecure = CarrierDisconnectDetectionTestTemplate<SecureDriverProvider<>>;
using DISABLED_CarrierAsyncHandshakeTestSecure = CarrierAsyncHandshakeTestTemplate<SecureDriverProvider<>>;
using DISABLED_CarrierStressTestSecure = CarrierStressTestTemplate<SecureDriverProvider<>>;
using DISABLED_CarrierMultiChannelTestSecure = CarrierMultiChannelTestTemplate<SecureDriverProvider<>>;
using DISABLED_CarrierMultiStressTestSecure = CarrierMultiStressTestTemplate<SecureDriverProvider<>>;
using DISABLED_CarrierBackpressureTestSecure = CarrierBackpressureTestTemplate<SecureDriverProvider<>>;
using DISABLED_CarrierACKTestSecure = CarrierACKTestTemplate<SecureDriverProvider<>>;
#endif
}
@@ -1720,30 +1720,30 @@ GM_TEST_SUITE(CarrierSuite)
GM_TEST(CarrierBasicTest)
GM_TEST(CarrierTest)
#endif //AZ_TRAIT_GRIDMATE_UNIT_TEST_DISABLE_CARRIER_SESSION_TESTS
GM_TEST(Integ_CarrierAsyncHandshakeTest)
GM_TEST(DISABLED_CarrierAsyncHandshakeTest)
#if !defined(AZ_DEBUG_BUILD) // this test is a little slow for debug
GM_TEST(Integ_CarrierStressTest)
GM_TEST(Integ_CarrierMultiStressTest)
GM_TEST(DISABLED_CarrierStressTest)
GM_TEST(DISABLED_CarrierMultiStressTest)
#endif
GM_TEST(Integ_CarrierMultiChannelTest)
GM_TEST(Integ_CarrierBackpressureTest)
GM_TEST(Integ_CarrierACKTest)
GM_TEST(DISABLED_CarrierMultiChannelTest)
GM_TEST(DISABLED_CarrierBackpressureTest)
GM_TEST(DISABLED_CarrierACKTest)
#if AZ_TRAIT_GRIDMATE_TEST_WITH_SECURE_SOCKET_DRIVER
GM_TEST(CarrierBasicTestSecure)
GM_TEST(Integ_CarrierSecureSocketHandshakeTestClient)
GM_TEST(Integ_CarrierSecureSocketHandshakeTestHost)
GM_TEST(Integ_CarrierSecureSocketHandshakeTestBoth)
GM_TEST(DISABLED_CarrierBasicTestSecure)
GM_TEST(DISABLED_CarrierSecureSocketHandshakeTestClient)
GM_TEST(DISABLED_CarrierSecureSocketHandshakeTestHost)
GM_TEST(DISABLED_CarrierSecureSocketHandshakeTestBoth)
GM_TEST(CarrierTestSecure)
GM_TEST(Integ_CarrierAsyncHandshakeTestSecure)
GM_TEST(DISABLED_CarrierAsyncHandshakeTestSecure)
#if !defined(AZ_DEBUG_BUILD) // this test is a little slow for debug
GM_TEST(Integ_CarrierStressTestSecure)
GM_TEST(Integ_CarrierMultiStressTestSecure)
GM_TEST(DISABLED_CarrierStressTestSecure)
GM_TEST(DISABLED_CarrierMultiStressTestSecure)
#endif
GM_TEST(Integ_CarrierMultiChannelTestSecure)
GM_TEST(Integ_CarrierBackpressureTestSecure)
GM_TEST(Integ_CarrierACKTestSecure)
GM_TEST(DISABLED_CarrierMultiChannelTestSecure)
GM_TEST(DISABLED_CarrierBackpressureTestSecure)
GM_TEST(DISABLED_CarrierACKTestSecure)
#endif
@@ -172,7 +172,7 @@ public:
namespace UnitTest
{
class Integ_CarrierStreamBasicTest
class DISABLED_CarrierStreamBasicTest
: public GridMateMPTestFixture
, protected SocketDriverSupplier
{
@@ -330,7 +330,7 @@ namespace UnitTest
}
};
class Integ_CarrierStreamAsyncHandshakeTest
class DISABLED_CarrierStreamAsyncHandshakeTest
: public GridMateMPTestFixture
, protected SocketDriverSupplier
{
@@ -462,7 +462,7 @@ namespace UnitTest
}
};
class Integ_CarrierStreamStressTest
class CarrierStreamStressTest
: public GridMateMPTestFixture
, protected SocketDriverSupplier
, public ::testing::Test
@@ -470,7 +470,7 @@ namespace UnitTest
public:
};
TEST_F(Integ_CarrierStreamStressTest, Stress_Test)
TEST_F(CarrierStreamStressTest, DISABLED_Stress_Test)
{
CarrierStreamCallbacksHandler clientCB, serverCB;
UnitTest::TestCarrierDesc serverCarrierDesc, clientCarrierDesc;
@@ -581,7 +581,7 @@ namespace UnitTest
//////////////////////////////////////////////////////////////////////////
}
class Integ_CarrierStreamTest
class DISABLED_CarrierStreamTest
: public GridMateMPTestFixture
, protected SocketDriverSupplier
{
@@ -783,7 +783,7 @@ namespace UnitTest
}
};
class Integ_CarrierStreamDisconnectDetectionTest
class DISABLED_CarrierStreamDisconnectDetectionTest
: public GridMateMPTestFixture
, protected SocketDriverSupplier
{
@@ -873,7 +873,7 @@ namespace UnitTest
}
};
class Integ_CarrierStreamMultiChannelTest
class DISABLED_CarrierStreamMultiChannelTest
: public GridMateMPTestFixture
, protected SocketDriverSupplier
{
@@ -999,8 +999,8 @@ namespace UnitTest
}
GM_TEST_SUITE(CarrierStreamSuite)
GM_TEST(Integ_CarrierStreamBasicTest)
GM_TEST(Integ_CarrierStreamTest)
GM_TEST(Integ_CarrierStreamAsyncHandshakeTest)
GM_TEST(Integ_CarrierStreamMultiChannelTest)
GM_TEST(DISABLED_CarrierStreamBasicTest)
GM_TEST(DISABLED_CarrierStreamTest)
GM_TEST(DISABLED_CarrierStreamAsyncHandshakeTest)
GM_TEST(DISABLED_CarrierStreamMultiChannelTest)
GM_TEST_SUITE_END()
+47 -48
View File
@@ -6,7 +6,6 @@
*
*/
#include "Tests.h"
#include "TestProfiler.h"
#include <GridMate/Replica/ReplicaFunctions.h>
@@ -1888,12 +1887,12 @@ protected:
};
//-----------------------------------------------------------------------------
class Integ_ReplicaGMTest
class ReplicaGMTest
: public UnitTest::GridMateMPTestFixture
, public ::testing::Test
{};
TEST_F(Integ_ReplicaGMTest, ReplicaTest)
TEST_F(ReplicaGMTest, DISABLED_ReplicaTest)
{
ReplicaChunkDescriptorTable::Get().RegisterChunkType<MigratableReplica, MigratableReplica::Descriptor>();
ReplicaChunkDescriptorTable::Get().RegisterChunkType<NonMigratableReplica>();
@@ -2157,7 +2156,7 @@ TEST_F(Integ_ReplicaGMTest, ReplicaTest)
}
}
class Integ_ForcedReplicaMigrationTest
class ForcedReplicaMigrationTest
: public UnitTest::GridMateMPTestFixture
, public ReplicaMgrCallbackBus::Handler
, public MigratableReplica::MigratableReplicaDebugMsgs::EBus::Handler
@@ -2186,8 +2185,8 @@ class Integ_ForcedReplicaMigrationTest
}
public:
Integ_ForcedReplicaMigrationTest() { ReplicaMgrCallbackBus::Handler::BusConnect(m_gridMate); }
~Integ_ForcedReplicaMigrationTest() { ReplicaMgrCallbackBus::Handler::BusDisconnect(); }
ForcedReplicaMigrationTest() { ReplicaMgrCallbackBus::Handler::BusConnect(m_gridMate); }
~ForcedReplicaMigrationTest() { ReplicaMgrCallbackBus::Handler::BusDisconnect(); }
enum
@@ -2205,11 +2204,11 @@ public:
AZStd::unordered_map<ReplicaId, ReplicaManager*> m_replicaOwnership;
};
const int Integ_ForcedReplicaMigrationTest::k_frameTimePerNodeMs;
const int Integ_ForcedReplicaMigrationTest::k_numFramesToRun;
const int Integ_ForcedReplicaMigrationTest::k_hostSendRateMs;
const int ForcedReplicaMigrationTest::k_frameTimePerNodeMs;
const int ForcedReplicaMigrationTest::k_numFramesToRun;
const int ForcedReplicaMigrationTest::k_hostSendRateMs;
TEST_F(Integ_ForcedReplicaMigrationTest, ForcedReplicaMigrationTest)
TEST_F(ForcedReplicaMigrationTest, DISABLED_ForcedReplicaMigrationTest)
{
ReplicaChunkDescriptorTable::Get().RegisterChunkType<MigratableReplica, MigratableReplica::Descriptor>();
ReplicaChunkDescriptorTable::Get().RegisterChunkType<NonMigratableReplica>();
@@ -2360,7 +2359,7 @@ TEST_F(Integ_ForcedReplicaMigrationTest, ForcedReplicaMigrationTest)
MigratableReplica::MigratableReplicaDebugMsgs::EBus::Handler::BusDisconnect();
}
class Integ_ReplicaMigrationRequestTest
class ReplicaMigrationRequestTest
: public UnitTest::GridMateMPTestFixture
, public ::testing::Test
{
@@ -2516,7 +2515,7 @@ public:
static const int k_hostSendTimeMs = k_frameTimePerNodeMs * TotalNodes * 4; // limiting host send rate to be x4 times slower than tick
};
TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest)
TEST_F(ReplicaMigrationRequestTest, DISABLED_ReplicaMigrationRequestTest)
{
/*
Topology:
@@ -2837,11 +2836,11 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest)
}
}
const int Integ_ReplicaMigrationRequestTest::k_frameTimePerNodeMs;
const int Integ_ReplicaMigrationRequestTest::k_hostSendTimeMs;
const int ReplicaMigrationRequestTest::k_frameTimePerNodeMs;
const int ReplicaMigrationRequestTest::k_hostSendTimeMs;
class Integ_PeerRejoinTest
class PeerRejoinTest
: public UnitTest::GridMateMPTestFixture
, public ReplicaMgrCallbackBus::Handler
, public ::testing::Test
@@ -2860,11 +2859,11 @@ class Integ_PeerRejoinTest
}
public:
Integ_PeerRejoinTest() { ReplicaMgrCallbackBus::Handler::BusConnect(m_gridMate); }
~Integ_PeerRejoinTest() { ReplicaMgrCallbackBus::Handler::BusDisconnect(); }
PeerRejoinTest() { ReplicaMgrCallbackBus::Handler::BusConnect(m_gridMate); }
~PeerRejoinTest() { ReplicaMgrCallbackBus::Handler::BusDisconnect(); }
};
TEST_F(Integ_PeerRejoinTest, PeerRejoinTest)
TEST_F(PeerRejoinTest, DISABLED_PeerRejoinTest)
{
ReplicaChunkDescriptorTable::Get().RegisterChunkType<MigratableReplica, MigratableReplica::Descriptor>();
ReplicaChunkDescriptorTable::Get().RegisterChunkType<NonMigratableReplica>();
@@ -3011,7 +3010,7 @@ TEST_F(Integ_PeerRejoinTest, PeerRejoinTest)
}
}
class Integ_ReplicationSecurityOptionsTest
class ReplicationSecurityOptionsTest
: public UnitTest::GridMateMPTestFixture
, public ::testing::Test
{
@@ -3156,7 +3155,7 @@ public:
using TestChunkPtr = AZStd::intrusive_ptr<TestChunk> ;
};
TEST_F(Integ_ReplicationSecurityOptionsTest, ReplicationSecurityOptionsTest)
TEST_F(ReplicationSecurityOptionsTest, DISABLED_ReplicationSecurityOptionsTest)
{
AZ_TracePrintf("GridMate", "\n");
@@ -3356,7 +3355,7 @@ TEST_F(Integ_ReplicationSecurityOptionsTest, ReplicationSecurityOptionsTest)
Replica update time (msec): avg=4.94, min=1, max=9 (peers=40, replicas=16000, freq=10%, samples=4000)
Replica update time (msec): avg=8.05, min=6, max=15 (peers=40, replicas=16000, freq=100%, samples=4000)
*/
class Integ_ReplicaStressTest
class DISABLED_ReplicaStressTest
: public UnitTest::GridMateMPTestFixture
{
public:
@@ -3388,7 +3387,7 @@ public:
static const int BASE_PORT = 44270;
// TODO: Reduce the size or disable the test for platforms which can't allocate 2 GiB
Integ_ReplicaStressTest()
DISABLED_ReplicaStressTest()
: UnitTest::GridMateMPTestFixture(2000u * 1024u * 1024u)
{}
@@ -3516,33 +3515,33 @@ public:
virtual void RunStressTests(MPSession* sessions, vector<AZStd::pair<ReplicaPtr, StressTestReplica::Ptr> >& replicas)
{
// testing 3 cases & waiting for system to settle in between
TestProfiler::StartProfiling();
//TestProfiler::StartProfiling();
Wait(sessions, replicas, 50, FRAME_TIME);
TestProfiler::PrintProfilingTotal("GridMate");
//TestProfiler::PrintProfilingTotal("GridMate");
Wait(sessions, replicas, 20, FRAME_TIME);
TestProfiler::StartProfiling();
//TestProfiler::StartProfiling();
TestReplicas(sessions, replicas, 100, FRAME_TIME, 0.0); // no replicas are dirty
TestProfiler::PrintProfilingTotal("GridMate");
//TestProfiler::PrintProfilingTotal("GridMate");
Wait(sessions, replicas, 20, FRAME_TIME);
TestProfiler::StartProfiling();
//TestProfiler::StartProfiling();
TestReplicas(sessions, replicas, 1, FRAME_TIME, 1.0); // single burst dirty replicas
Wait(sessions, replicas, 2, FRAME_TIME);
TestProfiler::PrintProfilingTotal("GridMate");
//TestProfiler::PrintProfilingTotal("GridMate");
Wait(sessions, replicas, 20, FRAME_TIME);
TestProfiler::StartProfiling();
//TestProfiler::StartProfiling();
TestReplicas(sessions, replicas, 100, FRAME_TIME, 0.1); // 10% of replicas are marked dirty every frame
TestProfiler::PrintProfilingTotal("GridMate");
//TestProfiler::PrintProfilingTotal("GridMate");
Wait(sessions, replicas, 20, FRAME_TIME);
TestProfiler::StartProfiling();
//TestProfiler::StartProfiling();
TestReplicas(sessions, replicas, 100, FRAME_TIME, 1.0); // every replica is marked dirty every frame
TestProfiler::PrintProfilingTotal("GridMate");
TestProfiler::PrintProfilingSelf("GridMate");
//TestProfiler::PrintProfilingTotal("GridMate");
//TestProfiler::PrintProfilingSelf("GridMate");
TestProfiler::StopProfiling();
//TestProfiler::StopProfiling();
}
virtual void MarkChanging(vector<AZStd::pair<ReplicaPtr, StressTestReplica::Ptr> >& replicas, double freq)
@@ -3623,8 +3622,8 @@ public:
Replica update time (msec): avg=2.01, min=1, max=5 (peers=40, replicas=16000, freq=10%, samples=4000)
Replica update time (msec): avg=4.61, min=3, max=10 (peers=40, replicas=16000, freq=50%, samples=4000)
*/
class Integ_ReplicaStableStressTest
: public Integ_ReplicaStressTest
class DISABLED_ReplicaStableStressTest
: public DISABLED_ReplicaStressTest
{
public:
@@ -3636,21 +3635,21 @@ public:
void RunStressTests(MPSession* sessions, vector<AZStd::pair<ReplicaPtr, StressTestReplica::Ptr> >& replicas) override
{
Integ_ReplicaStressTest::MarkChanging(replicas, 0.1); // picks 10% of replicas
DISABLED_ReplicaStressTest::MarkChanging(replicas, 0.1); // picks 10% of replicas
Wait(sessions, replicas, 20, FRAME_TIME);
TestProfiler::StartProfiling();
//TestProfiler::StartProfiling();
TestReplicas(sessions, replicas, 100, FRAME_TIME, 0.1);
TestProfiler::PrintProfilingTotal("GridMate");
TestProfiler::PrintProfilingSelf("GridMate");
/*TestProfiler::PrintProfilingTotal("GridMate");
TestProfiler::PrintProfilingSelf("GridMate");*/
Integ_ReplicaStressTest::MarkChanging(replicas, 0.5); // picks 50% of replicas
DISABLED_ReplicaStressTest::MarkChanging(replicas, 0.5); // picks 50% of replicas
Wait(sessions, replicas, 20, FRAME_TIME);
TestProfiler::StartProfiling();
//TestProfiler::StartProfiling();
TestReplicas(sessions, replicas, 100, FRAME_TIME, 0.5);
TestProfiler::PrintProfilingTotal("GridMate");
/*TestProfiler::PrintProfilingTotal("GridMate");
TestProfiler::PrintProfilingSelf("GridMate");
TestProfiler::StopProfiling();
TestProfiler::StopProfiling();*/
}
};
@@ -3666,7 +3665,7 @@ public:
* expected |none |brst | capped |under cap |brst | capped |
*
*/
class Integ_ReplicaBandiwdthTest
class DISABLED_ReplicaBandiwdthTest
: public UnitTest::GridMateMPTestFixture
{
public:
@@ -3944,9 +3943,9 @@ GM_TEST_SUITE(ReplicaSuite)
GM_TEST(InterpolatorTest)
#if !defined(AZ_DEBUG_BUILD) // these tests are a little slow for debug
GM_TEST(Integ_ReplicaBandiwdthTest)
GM_TEST(Integ_ReplicaStressTest)
GM_TEST(Integ_ReplicaStableStressTest)
GM_TEST(DISABLED_ReplicaBandiwdthTest)
GM_TEST(DISABLED_ReplicaStressTest)
GM_TEST(DISABLED_ReplicaStableStressTest)
#endif
GM_TEST_SUITE_END()
@@ -457,13 +457,13 @@ namespace ReplicaBehavior {
Completed,
};
class Integ_SimpleBehaviorTest
class SimpleBehaviorTest
: public UnitTest::GridMateMPTestFixture
{
public:
//GM_CLASS_ALLOCATOR(SimpleBehaviorTest);
Integ_SimpleBehaviorTest()
SimpleBehaviorTest()
: m_sessionCount(0) { }
virtual int GetNumSessions() { return 0; }
@@ -654,11 +654,11 @@ namespace ReplicaBehavior {
*
* This is a simple sanity check to ensure the logic sends the update when it's necessary.
*/
class Integ_Replica_DontSendDataSets_WithNoDiffFromCtorData
: public Integ_SimpleBehaviorTest
class Replica_DontSendDataSets_WithNoDiffFromCtorData
: public SimpleBehaviorTest
{
public:
Integ_Replica_DontSendDataSets_WithNoDiffFromCtorData()
Replica_DontSendDataSets_WithNoDiffFromCtorData()
: m_replicaIdDefault(InvalidReplicaId), m_replicaIdModified(InvalidReplicaId)
{
}
@@ -774,9 +774,9 @@ namespace ReplicaBehavior {
FilteredHook<LargeChunkWithDefaults> m_driller;
};
TEST(Integ_Replica_DontSendDataSets_WithNoDiffFromCtorData, Integ_Replica_DontSendDataSets_WithNoDiffFromCtorData)
TEST(Replica_DontSendDataSets_WithNoDiffFromCtorData, DISABLED_Replica_DontSendDataSets_WithNoDiffFromCtorData)
{
Integ_Replica_DontSendDataSets_WithNoDiffFromCtorData tester;
Replica_DontSendDataSets_WithNoDiffFromCtorData tester;
tester.run();
}
@@ -784,11 +784,11 @@ namespace ReplicaBehavior {
* This test checks the actual size of the replica as marshalled in the binary payload.
* The assessment of the payload size is done using driller EBus.
*/
class Integ_ReplicaDefaultDataSetDriller
: public Integ_SimpleBehaviorTest
class ReplicaDefaultDataSetDriller
: public SimpleBehaviorTest
{
public:
Integ_ReplicaDefaultDataSetDriller()
ReplicaDefaultDataSetDriller()
: m_replicaId(InvalidReplicaId)
{
}
@@ -815,7 +815,7 @@ namespace ReplicaBehavior {
m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica);
}
~Integ_ReplicaDefaultDataSetDriller() override
~ReplicaDefaultDataSetDriller() override
{
m_driller.BusDisconnect();
}
@@ -880,11 +880,11 @@ namespace ReplicaBehavior {
ReplicaId m_replicaId;
};
const int Integ_ReplicaDefaultDataSetDriller::NonDefaultValue;
const int ReplicaDefaultDataSetDriller::NonDefaultValue;
TEST(Integ_ReplicaDefaultDataSetDriller, Integ_ReplicaDefaultDataSetDriller)
TEST(ReplicaDefaultDataSetDriller, DISABLED_ReplicaDefaultDataSetDriller)
{
Integ_ReplicaDefaultDataSetDriller tester;
ReplicaDefaultDataSetDriller tester;
tester.run();
}
@@ -892,11 +892,11 @@ namespace ReplicaBehavior {
* This test checks the actual size of the replica as marshalled in the binary payload.
* The assessment of the payload size is done using driller EBus.
*/
class Integ_Replica_ComparePackingBoolsVsU8
: public Integ_SimpleBehaviorTest
class Replica_ComparePackingBoolsVsU8
: public SimpleBehaviorTest
{
public:
Integ_Replica_ComparePackingBoolsVsU8()
Replica_ComparePackingBoolsVsU8()
: m_replicaBoolsId(InvalidReplicaId)
, m_replicaU8Id(InvalidReplicaId)
{
@@ -928,7 +928,7 @@ namespace ReplicaBehavior {
m_replicaU8Id = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica2);
}
~Integ_Replica_ComparePackingBoolsVsU8() override
~Replica_ComparePackingBoolsVsU8() override
{
m_driller.BusDisconnect();
}
@@ -1020,17 +1020,17 @@ namespace ReplicaBehavior {
ReplicaId m_replicaU8Id;
};
TEST(Integ_Replica_ComparePackingBoolsVsU8, Integ_Replica_ComparePackingBoolsVsU8)
TEST(Replica_ComparePackingBoolsVsU8, DISABLED_Replica_ComparePackingBoolsVsU8)
{
Integ_Replica_ComparePackingBoolsVsU8 tester;
Replica_ComparePackingBoolsVsU8 tester;
tester.run();
}
class Integ_CheckDataSetStreamIsntWrittenMoreThanNecessary
: public Integ_SimpleBehaviorTest
class CheckDataSetStreamIsntWrittenMoreThanNecessary
: public SimpleBehaviorTest
{
public:
Integ_CheckDataSetStreamIsntWrittenMoreThanNecessary()
CheckDataSetStreamIsntWrittenMoreThanNecessary()
: m_replicaId(InvalidReplicaId)
{
}
@@ -1057,7 +1057,7 @@ namespace ReplicaBehavior {
m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica);
}
~Integ_CheckDataSetStreamIsntWrittenMoreThanNecessary() override
~CheckDataSetStreamIsntWrittenMoreThanNecessary() override
{
m_driller.BusDisconnect();
}
@@ -1117,17 +1117,17 @@ namespace ReplicaBehavior {
ReplicaId m_replicaId;
};
TEST(Integ_CheckDataSetStreamIsntWrittenMoreThanNecessary, Integ_CheckDataSetStreamIsntWrittenMoreThanNecessary)
TEST(CheckDataSetStreamIsntWrittenMoreThanNecessary, DISABLED_CheckDataSetStreamIsntWrittenMoreThanNecessary)
{
Integ_CheckDataSetStreamIsntWrittenMoreThanNecessary tester;
CheckDataSetStreamIsntWrittenMoreThanNecessary tester;
tester.run();
}
class Integ_CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty
: public Integ_SimpleBehaviorTest
class CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty
: public SimpleBehaviorTest
{
public:
Integ_CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty()
CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty()
: m_replicaId(InvalidReplicaId)
{
}
@@ -1154,7 +1154,7 @@ namespace ReplicaBehavior {
m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica);
}
~Integ_CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty() override
~CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty() override
{
m_driller.BusDisconnect();
}
@@ -1213,17 +1213,17 @@ namespace ReplicaBehavior {
ReplicaId m_replicaId;
};
TEST(Integ_CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty, Integ_CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty)
TEST(CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty, DISABLED_CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty)
{
Integ_CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty tester;
CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty tester;
tester.run();
}
class Integ_CheckReplicaIsntSentWithNoChanges
: public Integ_SimpleBehaviorTest
class CheckReplicaIsntSentWithNoChanges
: public SimpleBehaviorTest
{
public:
Integ_CheckReplicaIsntSentWithNoChanges()
CheckReplicaIsntSentWithNoChanges()
: m_replicaId(InvalidReplicaId)
{
}
@@ -1248,7 +1248,7 @@ namespace ReplicaBehavior {
m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica);
}
~Integ_CheckReplicaIsntSentWithNoChanges() override
~CheckReplicaIsntSentWithNoChanges() override
{
m_driller.BusDisconnect();
}
@@ -1323,17 +1323,17 @@ namespace ReplicaBehavior {
ReplicaId m_replicaId;
};
TEST(Integ_CheckReplicaIsntSentWithNoChanges, Integ_CheckReplicaIsntSentWithNoChanges)
TEST(CheckReplicaIsntSentWithNoChanges, DISABLED_CheckReplicaIsntSentWithNoChanges)
{
Integ_CheckReplicaIsntSentWithNoChanges tester;
CheckReplicaIsntSentWithNoChanges tester;
tester.run();
}
class Integ_CheckEntityScriptReplicaIsntSentWithNoChanges
: public Integ_SimpleBehaviorTest
class CheckEntityScriptReplicaIsntSentWithNoChanges
: public SimpleBehaviorTest
{
public:
Integ_CheckEntityScriptReplicaIsntSentWithNoChanges()
CheckEntityScriptReplicaIsntSentWithNoChanges()
: m_replicaId(InvalidReplicaId)
{
}
@@ -1359,7 +1359,7 @@ namespace ReplicaBehavior {
m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica);
}
~Integ_CheckEntityScriptReplicaIsntSentWithNoChanges() override
~CheckEntityScriptReplicaIsntSentWithNoChanges() override
{
m_driller.BusDisconnect();
}
@@ -1410,9 +1410,9 @@ namespace ReplicaBehavior {
ReplicaId m_replicaId;
};
TEST(Integ_CheckEntityScriptReplicaIsntSentWithNoChanges, Integ_CheckEntityScriptReplicaIsntSentWithNoChanges)
TEST(CheckEntityScriptReplicaIsntSentWithNoChanges, DISABLED_CheckEntityScriptReplicaIsntSentWithNoChanges)
{
Integ_CheckEntityScriptReplicaIsntSentWithNoChanges tester;
CheckEntityScriptReplicaIsntSentWithNoChanges tester;
tester.run();
}
+80 -80
View File
@@ -596,12 +596,12 @@ public:
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
class MPSession
class MPSessionMedium
: public CarrierEventBus::Handler
{
public:
~MPSession() override
~MPSessionMedium() override
{
CarrierEventBus::Handler::BusDisconnect();
}
@@ -708,14 +708,14 @@ enum class TestStatus
Completed,
};
class Integ_SimpleTest
class SimpleTest
: public UnitTest::GridMateMPTestFixture
, public ::testing::Test
{
public:
//GM_CLASS_ALLOCATOR(Integ_SimpleTest);
//GM_CLASS_ALLOCATOR(SimpleTest);
Integ_SimpleTest()
SimpleTest()
: m_sessionCount(0) { }
virtual int GetNumSessions() { return 0; }
@@ -858,15 +858,15 @@ public:
}
int m_sessionCount;
AZStd::array<MPSession, 10> m_sessions;
AZStd::array<MPSessionMedium, 10> m_sessions;
AZStd::unique_ptr<DefaultSimulator> m_defaultSimulator;
};
class Integ_ReplicaChunkRPCExec
: public Integ_SimpleTest
class ReplicaChunkRPCExec
: public SimpleTest
{
public:
Integ_ReplicaChunkRPCExec()
ReplicaChunkRPCExec()
: m_chunk(nullptr)
, m_replicaId(0)
{ }
@@ -893,7 +893,7 @@ public:
ReplicaId m_replicaId;
};
TEST_F(Integ_ReplicaChunkRPCExec, ReplicaChunkRPCExec)
TEST_F(ReplicaChunkRPCExec, DISABLED_ReplicaChunkRPCExec)
{
RunTickLoop([this](int tick) -> TestStatus
{
@@ -1050,8 +1050,8 @@ int DestroyRPCChunk::s_afterDestroyFromPrimaryCalls = 0;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
class Integ_ReplicaDestroyedInRPC
: public Integ_SimpleTest
class ReplicaDestroyedInRPC
: public SimpleTest
{
public:
enum
@@ -1080,7 +1080,7 @@ public:
ReplicaId m_repId[2];
};
TEST_F(Integ_ReplicaDestroyedInRPC, ReplicaDestroyedInRPC)
TEST_F(ReplicaDestroyedInRPC, DISABLED_ReplicaDestroyedInRPC)
{
RunTickLoop([this](int tick)->TestStatus
{
@@ -1129,11 +1129,11 @@ TEST_F(Integ_ReplicaDestroyedInRPC, ReplicaDestroyedInRPC)
});
}
class Integ_ReplicaChunkAddWhileReplicated
: public Integ_SimpleTest
class ReplicaChunkAddWhileReplicated
: public SimpleTest
{
public:
Integ_ReplicaChunkAddWhileReplicated()
ReplicaChunkAddWhileReplicated()
: m_replica(nullptr)
, m_chunk(nullptr)
, m_replicaId(0)
@@ -1161,7 +1161,7 @@ public:
ReplicaId m_replicaId;
};
TEST_F(Integ_ReplicaChunkAddWhileReplicated, ReplicaChunkAddWhileReplicated)
TEST_F(ReplicaChunkAddWhileReplicated, DISABLED_ReplicaChunkAddWhileReplicated)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -1203,11 +1203,11 @@ TEST_F(Integ_ReplicaChunkAddWhileReplicated, ReplicaChunkAddWhileReplicated)
}
class Integ_ReplicaRPCValues
: public Integ_SimpleTest
class ReplicaRPCValues
: public SimpleTest
{
public:
Integ_ReplicaRPCValues()
ReplicaRPCValues()
: m_replica(nullptr)
, m_chunk(nullptr)
, m_replicaId(0)
@@ -1236,7 +1236,7 @@ public:
ReplicaId m_replicaId;
};
TEST_F(Integ_ReplicaRPCValues, ReplicaRPCValues)
TEST_F(ReplicaRPCValues, DISABLED_ReplicaRPCValues)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -1257,11 +1257,11 @@ TEST_F(Integ_ReplicaRPCValues, ReplicaRPCValues)
});
}
class Integ_FullRPCValues
: public Integ_SimpleTest
class FullRPCValues
: public SimpleTest
{
public:
Integ_FullRPCValues()
FullRPCValues()
: m_replica(nullptr)
, m_chunk(nullptr)
, m_replicaId(0)
@@ -1290,7 +1290,7 @@ public:
ReplicaId m_replicaId;
};
TEST_F(Integ_FullRPCValues, FullRPCValues)
TEST_F(FullRPCValues, DISABLED_FullRPCValues)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -1364,11 +1364,11 @@ TEST_F(Integ_FullRPCValues, FullRPCValues)
}
class Integ_ReplicaRemoveProxy
: public Integ_SimpleTest
class ReplicaRemoveProxy
: public SimpleTest
{
public:
Integ_ReplicaRemoveProxy()
ReplicaRemoveProxy()
: m_replica(nullptr)
, m_replicaId(0)
{
@@ -1395,7 +1395,7 @@ public:
ReplicaId m_replicaId;
};
TEST_F(Integ_ReplicaRemoveProxy, ReplicaRemoveProxy)
TEST_F(ReplicaRemoveProxy, DISABLED_ReplicaRemoveProxy)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -1424,11 +1424,11 @@ TEST_F(Integ_ReplicaRemoveProxy, ReplicaRemoveProxy)
}
class Integ_ReplicaChunkEvents
: public Integ_SimpleTest
class ReplicaChunkEvents
: public SimpleTest
{
public:
Integ_ReplicaChunkEvents()
ReplicaChunkEvents()
: m_replicaId(InvalidReplicaId)
, m_chunk(nullptr)
, m_proxyChunk(nullptr)
@@ -1463,7 +1463,7 @@ public:
AllEventChunk::Ptr m_proxyChunk;
};
TEST_F(Integ_ReplicaChunkEvents, ReplicaChunkEvents)
TEST_F(ReplicaChunkEvents, DISABLED_ReplicaChunkEvents)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -1501,11 +1501,11 @@ TEST_F(Integ_ReplicaChunkEvents, ReplicaChunkEvents)
}
class Integ_ReplicaChunksBeyond32
: public Integ_SimpleTest
class ReplicaChunksBeyond32
: public SimpleTest
{
public:
Integ_ReplicaChunksBeyond32()
ReplicaChunksBeyond32()
: m_replicaId(InvalidReplicaId)
{
}
@@ -1537,7 +1537,7 @@ public:
ReplicaId m_replicaId;
};
TEST_F(Integ_ReplicaChunksBeyond32, ReplicaChunksBeyond32)
TEST_F(ReplicaChunksBeyond32, DISABLED_ReplicaChunksBeyond32)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -1565,11 +1565,11 @@ TEST_F(Integ_ReplicaChunksBeyond32, ReplicaChunksBeyond32)
}
class Integ_ReplicaChunkEventsDeactivate
: public Integ_SimpleTest
class ReplicaChunkEventsDeactivate
: public SimpleTest
{
public:
Integ_ReplicaChunkEventsDeactivate()
ReplicaChunkEventsDeactivate()
: m_replica(nullptr)
, m_replicaId(0)
, m_chunk(nullptr)
@@ -1604,7 +1604,7 @@ public:
AllEventChunk::Ptr m_proxyChunk;
};
TEST_F(Integ_ReplicaChunkEventsDeactivate, ReplicaChunkEventsDeactivate)
TEST_F(ReplicaChunkEventsDeactivate, DISABLED_ReplicaChunkEventsDeactivate)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -1649,11 +1649,11 @@ TEST_F(Integ_ReplicaChunkEventsDeactivate, ReplicaChunkEventsDeactivate)
}
class Integ_ReplicaDriller
: public Integ_SimpleTest
class ReplicaDriller
: public SimpleTest
{
public:
Integ_ReplicaDriller()
ReplicaDriller()
: m_replicaId(InvalidReplicaId)
{
}
@@ -2007,7 +2007,7 @@ public:
m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica);
}
~Integ_ReplicaDriller() override
~ReplicaDriller() override
{
m_driller.BusDisconnect();
}
@@ -2016,7 +2016,7 @@ public:
ReplicaId m_replicaId;
};
TEST_F(Integ_ReplicaDriller, ReplicaDriller)
TEST_F(ReplicaDriller, DISABLED_ReplicaDriller)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -2082,11 +2082,11 @@ TEST_F(Integ_ReplicaDriller, ReplicaDriller)
}
class Integ_DataSetChangedTest
: public Integ_SimpleTest
class DataSetChangedTest
: public SimpleTest
{
public:
Integ_DataSetChangedTest()
DataSetChangedTest()
: m_replica(nullptr)
, m_replicaId(0)
, m_chunk(nullptr)
@@ -2115,7 +2115,7 @@ public:
DataSetChunk::Ptr m_chunk;
};
TEST_F(Integ_DataSetChangedTest, DataSetChangedTest)
TEST_F(DataSetChangedTest, DISABLED_DataSetChangedTest)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -2144,11 +2144,11 @@ TEST_F(Integ_DataSetChangedTest, DataSetChangedTest)
}
class Integ_CustomHandlerTest
: public Integ_SimpleTest
class CustomHandlerTest
: public SimpleTest
{
public:
Integ_CustomHandlerTest()
CustomHandlerTest()
: m_replica(nullptr)
, m_replicaId(0)
, m_chunk(nullptr)
@@ -2181,7 +2181,7 @@ public:
AZStd::scoped_ptr<CustomHandler> m_proxyHandler;
};
TEST_F(Integ_CustomHandlerTest, CustomHandlerTest)
TEST_F(CustomHandlerTest, DISABLED_CustomHandlerTest)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -2234,11 +2234,11 @@ TEST_F(Integ_CustomHandlerTest, CustomHandlerTest)
}
class Integ_NonConstMarshalerTest
: public Integ_SimpleTest
class NonConstMarshalerTest
: public SimpleTest
{
public:
Integ_NonConstMarshalerTest()
NonConstMarshalerTest()
: m_replica(nullptr)
, m_replicaId(0)
, m_chunk(nullptr)
@@ -2266,7 +2266,7 @@ public:
NonConstMarshalerChunk::Ptr m_chunk;
};
TEST_F(Integ_NonConstMarshalerTest, NonConstMarshalerTest)
TEST_F(NonConstMarshalerTest, DISABLED_NonConstMarshalerTest)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -2309,11 +2309,11 @@ TEST_F(Integ_NonConstMarshalerTest, NonConstMarshalerTest)
}
class Integ_SourcePeerTest
: public Integ_SimpleTest
class SourcePeerTest
: public SimpleTest
{
public:
Integ_SourcePeerTest()
SourcePeerTest()
: m_replica(nullptr)
, m_replicaId(0)
, m_chunk(nullptr)
@@ -2343,7 +2343,7 @@ public:
SourcePeerChunk::Ptr m_chunk2;
};
TEST_F(Integ_SourcePeerTest, SourcePeerTest)
TEST_F(SourcePeerTest, DISABLED_SourcePeerTest)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -2404,8 +2404,8 @@ TEST_F(Integ_SourcePeerTest, SourcePeerTest)
}
class Integ_SendWithPriority
: public Integ_SimpleTest
class SendWithPriority
: public SimpleTest
{
public:
enum
@@ -2438,8 +2438,8 @@ public:
{
public:
ReplicaDrillerHook()
: m_expectedSendValue(Integ_SendWithPriority::kNumReplicas)
, m_expectedRecvValue(Integ_SendWithPriority::kNumReplicas)
: m_expectedSendValue(SendWithPriority::kNumReplicas)
, m_expectedRecvValue(SendWithPriority::kNumReplicas)
{
}
@@ -2495,7 +2495,7 @@ public:
PriorityChunk::Ptr m_chunks[kNumReplicas];
};
TEST_F(Integ_SendWithPriority, SendWithPriority)
TEST_F(SendWithPriority, DISABLED_SendWithPriority)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -2511,8 +2511,8 @@ TEST_F(Integ_SendWithPriority, SendWithPriority)
}
class Integ_SuspendUpdatesTest
: public Integ_SimpleTest
class SuspendUpdatesTest
: public SimpleTest
{
public:
enum
@@ -2597,7 +2597,7 @@ public:
unsigned int m_numRpcCalled = 0;
};
TEST_F(Integ_SuspendUpdatesTest, SuspendUpdatesTest)
TEST_F(SuspendUpdatesTest, DISABLED_SuspendUpdatesTest)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -2657,7 +2657,7 @@ TEST_F(Integ_SuspendUpdatesTest, SuspendUpdatesTest)
}
class Integ_BasicHostChunkDescriptorTest
class BasicHostChunkDescriptorTest
: public UnitTest::GridMateMPTestFixture
, public ::testing::Test
{
@@ -2694,17 +2694,17 @@ public:
static int nProxyActivations;
};
};
int Integ_BasicHostChunkDescriptorTest::HostChunk::nPrimaryActivations = 0;
int Integ_BasicHostChunkDescriptorTest::HostChunk::nProxyActivations = 0;
int BasicHostChunkDescriptorTest::HostChunk::nPrimaryActivations = 0;
int BasicHostChunkDescriptorTest::HostChunk::nProxyActivations = 0;
TEST_F(Integ_BasicHostChunkDescriptorTest, BasicHostChunkDescriptorTest)
TEST_F(BasicHostChunkDescriptorTest, DISABLED_BasicHostChunkDescriptorTest)
{
AZ_TracePrintf("GridMate", "\n");
// Register test chunks
ReplicaChunkDescriptorTable::Get().RegisterChunkType<HostChunk, GridMate::BasicHostChunkDescriptor<HostChunk>>();
MPSession nodes[nNodes];
MPSessionMedium nodes[nNodes];
// initialize transport
int basePort = 4427;
@@ -2791,8 +2791,8 @@ TEST_F(Integ_BasicHostChunkDescriptorTest, BasicHostChunkDescriptorTest)
* Create and immedietly destroy primary replica
* Test that it does not result in any network sync
*/
class Integ_CreateDestroyPrimary
: public Integ_SimpleTest
class CreateDestroyPrimary
: public SimpleTest
, public Debug::ReplicaDrillerBus::Handler
{
public:
@@ -2827,7 +2827,7 @@ public:
}
};
TEST_F(Integ_CreateDestroyPrimary, CreateDestroyPrimary)
TEST_F(CreateDestroyPrimary, DISABLED_CreateDestroyPrimary)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -2861,7 +2861,7 @@ TEST_F(Integ_CreateDestroyPrimary, CreateDestroyPrimary)
* The ReplicaTarget will prevent sending more updates.
*/
class ReplicaACKfeedbackTestFixture
: public Integ_SimpleTest
: public SimpleTest
{
public:
ReplicaACKfeedbackTestFixture()
@@ -2900,7 +2900,7 @@ public:
size_t m_replicaBytesSentPrev = 0;
ReplicaId m_replicaId;
Integ_ReplicaDriller::ReplicaDrillerHook m_driller;
ReplicaDriller::ReplicaDrillerHook m_driller;
};
TEST_F(ReplicaACKfeedbackTestFixture, ReplicaACKfeedbackTest)
+30 -30
View File
@@ -40,7 +40,7 @@ namespace UnitTest
}
}
class Integ_LANSessionMatchmakingParamsTest
class DISABLED_LANSessionMatchmakingParamsTest
: public GridMateMPTestFixture
, public SessionEventBus::MultiHandler
{
@@ -52,7 +52,7 @@ namespace UnitTest
}
public:
Integ_LANSessionMatchmakingParamsTest(bool useIPv6 = false)
DISABLED_LANSessionMatchmakingParamsTest(bool useIPv6 = false)
: m_hostSession(nullptr)
, m_clientGridMate(nullptr)
{
@@ -71,7 +71,7 @@ namespace UnitTest
AZ_TEST_ASSERT(GridMate::LANSessionServiceBus::FindFirstHandler(m_clientGridMate) != nullptr);
//////////////////////////////////////////////////////////////////////////
}
~Integ_LANSessionMatchmakingParamsTest() override
~DISABLED_LANSessionMatchmakingParamsTest() override
{
SessionEventBus::MultiHandler::BusDisconnect(m_gridMate);
SessionEventBus::MultiHandler::BusDisconnect(m_clientGridMate);
@@ -192,7 +192,7 @@ namespace UnitTest
IGridMate* m_clientGridMate;
};
class Integ_LANSessionTest
class DISABLED_LANSessionTest
: public GridMateMPTestFixture
{
class TestPeerInfo
@@ -264,7 +264,7 @@ namespace UnitTest
};
public:
Integ_LANSessionTest(bool useIPv6 = false)
DISABLED_LANSessionTest(bool useIPv6 = false)
{
m_driverType = useIPv6 ? Driver::BSD_AF_INET6 : Driver::BSD_AF_INET;
m_doSessionParamsTest = k_numMachines > 1;
@@ -290,7 +290,7 @@ namespace UnitTest
AZ_TEST_ASSERT(LANSessionServiceBus::FindFirstHandler(m_peers[i].m_gridMate) != nullptr);
}
}
~Integ_LANSessionTest() override
~DISABLED_LANSessionTest() override
{
StopGridMateService<LANSessionService>(m_peers[0].m_gridMate);
@@ -555,15 +555,15 @@ namespace UnitTest
bool m_doSessionParamsTest;
};
class Integ_LANSessionTestIPv6
: public Integ_LANSessionTest
class DISABLED_LANSessionTestIPv6
: public DISABLED_LANSessionTest
{
public:
Integ_LANSessionTestIPv6()
: Integ_LANSessionTest(true) {}
DISABLED_LANSessionTestIPv6()
: DISABLED_LANSessionTest(true) {}
};
class Integ_LANMultipleSessionTest
class DISABLED_LANMultipleSessionTest
: public GridMateMPTestFixture
, public SessionEventBus::Handler
{
@@ -620,7 +620,7 @@ namespace UnitTest
m_sessions[i] = nullptr;
}
Integ_LANMultipleSessionTest()
DISABLED_LANMultipleSessionTest()
: GridMateMPTestFixture(200 * 1024 * 1024)
{
//////////////////////////////////////////////////////////////////////////
@@ -645,7 +645,7 @@ namespace UnitTest
}
}
~Integ_LANMultipleSessionTest() override
~DISABLED_LANMultipleSessionTest() override
{
GridMate::StopGridMateService<GridMate::LANSessionService>(m_gridMates[0]);
@@ -799,7 +799,7 @@ namespace UnitTest
* Testing session with low latency. This is special mode usually used by tools and communication channels
* where we try to response instantly on messages.
*/
class Integ_LANLatencySessionTest
class DISABLED_LANLatencySessionTest
: public GridMateMPTestFixture
, public SessionEventBus::Handler
{
@@ -857,7 +857,7 @@ namespace UnitTest
m_sessions[i] = nullptr;
}
Integ_LANLatencySessionTest()
DISABLED_LANLatencySessionTest()
#ifdef AZ_TEST_LANLATENCY_ENABLE_MONSTER_BUFFER
: GridMateMPTestFixture(50 * 1024 * 1024)
#endif
@@ -884,7 +884,7 @@ namespace UnitTest
}
}
~Integ_LANLatencySessionTest() override
~DISABLED_LANLatencySessionTest() override
{
StopGridMateService<LANSessionService>(m_gridMates[0]);
@@ -1162,7 +1162,7 @@ namespace UnitTest
* 5. After host migration we drop the new host again. (after migration we have 3 members).
* Session should be fully operational at the end with 3 members left.
*/
class Integ_LANSessionMigarationTestTest
class LANSessionMigarationTestTest
: public SessionEventBus::Handler
, public GridMateMPTestFixture
{
@@ -1257,7 +1257,7 @@ namespace UnitTest
}
}
Integ_LANSessionMigarationTestTest()
LANSessionMigarationTestTest()
{
//////////////////////////////////////////////////////////////////////////
// Create all grid mates
@@ -1283,7 +1283,7 @@ namespace UnitTest
//StartDrilling("lanmigration");
}
~Integ_LANSessionMigarationTestTest() override
~LANSessionMigarationTestTest() override
{
StopGridMateService<LANSessionService>(m_gridMates[0]);
@@ -1476,7 +1476,7 @@ namespace UnitTest
* 5. We join a 2 new members to the session.
* Session should be fully operational at the end with 4 members in it.
*/
class Integ_LANSessionMigarationTestTest2
class LANSessionMigarationTestTest2
: public SessionEventBus::Handler
, public GridMateMPTestFixture
{
@@ -1571,7 +1571,7 @@ namespace UnitTest
}
}
}
Integ_LANSessionMigarationTestTest2()
LANSessionMigarationTestTest2()
{
//////////////////////////////////////////////////////////////////////////
// Create all grid mates
@@ -1597,7 +1597,7 @@ namespace UnitTest
//StartDrilling("lanmigration2");
}
~Integ_LANSessionMigarationTestTest2() override
~LANSessionMigarationTestTest2() override
{
StopGridMateService<LANSessionService>(m_gridMates[0]);
@@ -1816,7 +1816,7 @@ namespace UnitTest
* 3. Add 2 new joins to the original session.
* Original session should remain fully operational with 4 members in it.
*/
class Integ_LANSessionMigarationTestTest3
class LANSessionMigarationTestTest3
: public SessionEventBus::Handler
, public GridMateMPTestFixture
{
@@ -1910,7 +1910,7 @@ namespace UnitTest
}
}
}
Integ_LANSessionMigarationTestTest3()
LANSessionMigarationTestTest3()
{
//////////////////////////////////////////////////////////////////////////
// Create all grid mates
@@ -1936,7 +1936,7 @@ namespace UnitTest
//StartDrilling("lanmigration2");
}
~Integ_LANSessionMigarationTestTest3() override
~LANSessionMigarationTestTest3() override
{
StopGridMateService<LANSessionService>(m_gridMates[0]);
@@ -2122,13 +2122,13 @@ namespace UnitTest
}
GM_TEST_SUITE(SessionSuite)
GM_TEST(Integ_LANSessionMatchmakingParamsTest)
GM_TEST(Integ_LANSessionTest)
GM_TEST(DISABLED_LANSessionMatchmakingParamsTest)
GM_TEST(DISABLED_LANSessionTest)
#if (AZ_TRAIT_GRIDMATE_TEST_SOCKET_IPV6_SUPPORT_ENABLED)
GM_TEST(Integ_LANSessionTestIPv6)
GM_TEST(DISABLED_LANSessionTestIPv6)
#endif
GM_TEST(Integ_LANMultipleSessionTest)
GM_TEST(Integ_LANLatencySessionTest)
GM_TEST(DISABLED_LANMultipleSessionTest)
GM_TEST(DISABLED_LANLatencySessionTest)
// Manually enabled tests (require 2+ machines and online services)
//GM_TEST(LANSessionMigarationTestTest)
@@ -110,7 +110,7 @@ namespace UnitTest
std::array<char, SIZE> m_buffer;
};
class Integ_StreamSecureSocketDriverTestsBindSocketEmpty
class DISABLED_StreamSecureSocketDriverTestsBindSocketEmpty
: public GridMateMPTestFixture
{
public:
@@ -134,7 +134,7 @@ namespace UnitTest
}
};
class Integ_StreamSecureSocketDriverTestsConnection
class DISABLED_StreamSecureSocketDriverTestsConnection
: public GridMateMPTestFixture
{
public:
@@ -146,7 +146,7 @@ namespace UnitTest
}
};
class Integ_StreamSecureSocketDriverTestsConnectionAndHelloWorld
class DISABLED_StreamSecureSocketDriverTestsConnectionAndHelloWorld
: public GridMateMPTestFixture
{
public:
@@ -190,7 +190,7 @@ namespace UnitTest
}
};
class Integ_StreamSecureSocketDriverTestsPingPong
class DISABLED_StreamSecureSocketDriverTestsPingPong
: public GridMateMPTestFixture
{
public:
@@ -425,13 +425,13 @@ namespace UnitTest
void BuildStateMachine()
{
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_TOP), AZ::HSM::StateHandler(this, &Integ_StreamSecureSocketDriverTestsPingPong::OnStateTop), AZ::HSM::InvalidStateId, TS_START);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_START), AZ::HSM::StateHandler(this, &Integ_StreamSecureSocketDriverTestsPingPong::OnStateStart), TS_TOP);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_SERVER_GET_PING), AZ::HSM::StateHandler(this, &Integ_StreamSecureSocketDriverTestsPingPong::OnStateServerGetPing), TS_TOP);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_PING_GET_SERVER), AZ::HSM::StateHandler(this, &Integ_StreamSecureSocketDriverTestsPingPong::OnStatePingGetServer), TS_TOP);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_SERVER_GET_PONG), AZ::HSM::StateHandler(this, &Integ_StreamSecureSocketDriverTestsPingPong::OnStateServerGetPong), TS_TOP);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_PONG_GET_SERVER), AZ::HSM::StateHandler(this, &Integ_StreamSecureSocketDriverTestsPingPong::OnStatePongGetServer), TS_TOP);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_IN_ERROR), AZ::HSM::StateHandler(this, &Integ_StreamSecureSocketDriverTestsPingPong::OnStateInError), TS_TOP);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_TOP), AZ::HSM::StateHandler(this, &DISABLED_StreamSecureSocketDriverTestsPingPong::OnStateTop), AZ::HSM::InvalidStateId, TS_START);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_START), AZ::HSM::StateHandler(this, &DISABLED_StreamSecureSocketDriverTestsPingPong::OnStateStart), TS_TOP);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_SERVER_GET_PING), AZ::HSM::StateHandler(this, &DISABLED_StreamSecureSocketDriverTestsPingPong::OnStateServerGetPing), TS_TOP);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_PING_GET_SERVER), AZ::HSM::StateHandler(this, &DISABLED_StreamSecureSocketDriverTestsPingPong::OnStatePingGetServer), TS_TOP);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_SERVER_GET_PONG), AZ::HSM::StateHandler(this, &DISABLED_StreamSecureSocketDriverTestsPingPong::OnStateServerGetPong), TS_TOP);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_PONG_GET_SERVER), AZ::HSM::StateHandler(this, &DISABLED_StreamSecureSocketDriverTestsPingPong::OnStatePongGetServer), TS_TOP);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_IN_ERROR), AZ::HSM::StateHandler(this, &DISABLED_StreamSecureSocketDriverTestsPingPong::OnStateInError), TS_TOP);
m_stateMachine.Start();
}
@@ -486,10 +486,10 @@ namespace UnitTest
}
GM_TEST_SUITE(StreamSecureSocketDriverTests)
GM_TEST(Integ_StreamSecureSocketDriverTestsBindSocketEmpty);
GM_TEST(Integ_StreamSecureSocketDriverTestsConnection);
GM_TEST(Integ_StreamSecureSocketDriverTestsConnectionAndHelloWorld);
GM_TEST(Integ_StreamSecureSocketDriverTestsPingPong);
GM_TEST(DISABLED_StreamSecureSocketDriverTestsBindSocketEmpty);
GM_TEST(DISABLED_StreamSecureSocketDriverTestsConnection);
GM_TEST(DISABLED_StreamSecureSocketDriverTestsConnectionAndHelloWorld);
GM_TEST(DISABLED_StreamSecureSocketDriverTestsPingPong);
GM_TEST_SUITE_END()
#endif // AZ_TRAIT_GRIDMATE_ENABLE_OPENSSL
@@ -308,7 +308,7 @@ namespace UnitTest
}
};
class Integ_StreamSocketDriverTestsTooManyConnections
class DISABLED_StreamSocketDriverTestsTooManyConnections
: public GridMateMPTestFixture
{
public:
@@ -529,7 +529,7 @@ GM_TEST_SUITE(StreamSocketDriverTests)
GM_TEST(StreamSocketDriverTestsSimpleLockStepConnection);
GM_TEST(StreamSocketDriverTestsEstablishConnectAndSend);
GM_TEST(StreamSocketDriverTestsManyRandomPackets);
GM_TEST(Integ_StreamSocketDriverTestsTooManyConnections);
GM_TEST(DISABLED_StreamSocketDriverTestsTooManyConnections);
GM_TEST(StreamSocketDriverTestsClientToInvalidServer);
GM_TEST(StreamSocketDriverTestsManySends);
@@ -1,244 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "Tests.h"
#include "TestProfiler.h"
#include <AzCore/Debug/Profiler.h>
#include <AzCore/Math/Crc.h>
#include <GridMate/Containers/set.h>
#include <GridMate/Containers/unordered_set.h>
using namespace GridMate;
typedef set<const AZ::Debug::ProfilerRegister*> ProfilerSet;
static bool CollectPerformanceCounters(const AZ::Debug::ProfilerRegister& reg, const AZStd::thread_id&, ProfilerSet& profilers, const char* systemId)
{
if (reg.m_type != AZ::Debug::ProfilerRegister::PRT_TIME)
{
return true;
}
if (reg.m_systemId != AZ::Crc32(systemId))
{
return true;
}
const AZ::Debug::ProfilerRegister* profReg = &reg;
profilers.insert(profReg);
return true;
}
static AZStd::string FormatString(const AZStd::string& pre, const AZStd::string& name, const AZStd::string& post, AZ::u64 time, AZ::u64 calls)
{
AZStd::string units = "us";
if (AZ::u64 divtime = time / 1000)
{
time = divtime;
units = "ms";
}
return AZStd::string::format("%s%s %s %10llu%s (%llu calls)\n", pre.c_str(), name.c_str(), post.c_str(), time, units.c_str(), calls);
}
struct TotalSortContainer
{
TotalSortContainer(const AZ::Debug::ProfilerRegister* self = nullptr)
{
m_self = self;
}
void Print(AZ::s32 level, const char* systemId)
{
if (m_self && level >= 0)
{
AZStd::string levelIndent;
for (AZ::s32 i = 0; i < level; i++)
{
levelIndent += (i == level - 1) ? "+---" : "| ";
}
AZStd::string name = m_self->m_name ? m_self->m_name : m_self->m_function;
AZStd::string outputTotal = FormatString(levelIndent, name, " Total:", m_self->m_timeData.m_time, m_self->m_timeData.m_calls);
AZ_Printf(systemId, outputTotal.c_str());
if (m_self->m_timeData.m_childrenTime || m_self->m_timeData.m_childrenCalls)
{
AZStd::string childIndent = levelIndent;
for (auto i = name.begin(); i != name.end(); ++i)
{
childIndent += " ";
}
childIndent[level * 4] = '|';
AZStd::string outputChild = FormatString(childIndent, "", "Child:", m_self->m_timeData.m_childrenTime, m_self->m_timeData.m_childrenCalls);
AZ_Printf(systemId, outputChild.c_str());
AZStd::string outputSelf = FormatString(childIndent, "", "Self :", m_self->m_timeData.m_time - m_self->m_timeData.m_childrenTime, m_self->m_timeData.m_calls);
AZ_Printf(systemId, outputSelf.c_str());
}
}
for (auto i = m_children.begin(); i != m_children.end(); ++i)
{
i->Print(level + 1, systemId);
}
}
TotalSortContainer* Find(const AZ::Debug::ProfilerRegister* obj)
{
if (m_self == obj)
{
return this;
}
for (TotalSortContainer& child : m_children)
{
TotalSortContainer* found = child.Find(obj);
if (found)
{
return found;
}
}
return nullptr;
}
struct TotalSorter
{
bool operator()(const TotalSortContainer& a, const TotalSortContainer& b) const
{
if (a.m_self->m_timeData.m_time == b.m_self->m_timeData.m_time)
{
return a.m_self > b.m_self;
}
return a.m_self->m_timeData.m_time > b.m_self->m_timeData.m_time;
}
};
set<TotalSortContainer, TotalSorter> m_children;
const AZ::Debug::ProfilerRegister* m_self;
};
void TestProfiler::StartProfiling()
{
StopProfiling();
AZ::Debug::Profiler::Create();
}
void TestProfiler::StopProfiling()
{
if (AZ::Debug::Profiler::IsReady())
{
AZ::Debug::Profiler::Destroy();
}
}
void TestProfiler::PrintProfilingTotal(const char* systemId)
{
if (!AZ::Debug::Profiler::IsReady())
{
return;
}
ProfilerSet profilers;
AZ::Debug::Profiler::Instance().ReadRegisterValues(AZStd::bind(&CollectPerformanceCounters, AZStd::placeholders::_1, AZStd::placeholders::_2, AZStd::ref(profilers), systemId));
// Validate we wont get stuck in an infinite loop
TotalSortContainer root;
for (auto i = profilers.begin(); i != profilers.end(); )
{
const AZ::Debug::ProfilerRegister* profile = *i;
if (profile->m_timeData.m_lastParent)
{
auto parent = profilers.find(profile->m_timeData.m_lastParent);
if (parent == profilers.end())
{
// Error, just ignore this entry
i = profilers.erase(i);
continue;
}
}
++i;
}
// Put all root nodes into the final list
for (auto i = profilers.begin(); i != profilers.end(); )
{
const AZ::Debug::ProfilerRegister* profile = *i;
if (!profile->m_timeData.m_lastParent)
{
root.m_children.insert(profile);
i = profilers.erase(i);
}
else
{
++i;
}
}
// Put all non-root nodes into the final list
while (!profilers.empty())
{
for (auto i = profilers.begin(); i != profilers.end(); )
{
const AZ::Debug::ProfilerRegister* profile = *i;
TotalSortContainer* found = root.Find(profile->m_timeData.m_lastParent);
if (found)
{
found->m_children.insert(profile);
i = profilers.erase(i);
}
else
{
++i;
}
}
}
AZ_Printf(systemId, "Profiling timers by total execution time:\n");
root.Print(-1, systemId);
}
void TestProfiler::PrintProfilingSelf(const char* systemId)
{
if (!AZ::Debug::Profiler::IsReady())
{
return;
}
ProfilerSet profilers;
AZ::Debug::Profiler::Instance().ReadRegisterValues(AZStd::bind(&CollectPerformanceCounters, AZStd::placeholders::_1, AZStd::placeholders::_2, AZStd::ref(profilers), systemId));
struct SelfSorter
{
bool operator()(const AZ::Debug::ProfilerRegister* a, const AZ::Debug::ProfilerRegister* b) const
{
auto aTime = a->m_timeData.m_time - a->m_timeData.m_childrenTime;
auto bTime = b->m_timeData.m_time - b->m_timeData.m_childrenTime;
if (aTime == bTime)
{
return a > b;
}
return aTime > bTime;
}
};
set<const AZ::Debug::ProfilerRegister*, SelfSorter> selfSorted;
for (auto& profiler : profilers)
{
selfSorted.insert(profiler);
}
AZ_Printf(systemId, "Profiling timers by exclusive execution time:\n");
for (auto profiler : selfSorted)
{
AZStd::string str = FormatString("", profiler->m_name ? profiler->m_name : profiler->m_function, "Self Time:",
profiler->m_timeData.m_time - profiler->m_timeData.m_childrenTime, profiler->m_timeData.m_calls);
AZ_Printf(systemId, str.c_str());
}
}
@@ -1,24 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef GM_TEST_PROFILER_H
#define GM_TEST_PROFILER_H
namespace GridMate
{
class TestProfiler
{
public:
static void StartProfiling();
static void StopProfiling();
static void PrintProfilingTotal(const char* systemId);
static void PrintProfilingSelf(const char* systemId);
};
}
#endif
@@ -12,6 +12,7 @@ set(FILES
Session.cpp
Serialize.cpp
Certificates.cpp
Replica.cpp
ReplicaSmall.cpp
ReplicaMedium.cpp
ReplicaBehavior.cpp
+5 -74
View File
@@ -18,45 +18,35 @@ namespace AzTestRunner
const int LIB_NOT_FOUND = 102;
const int SYMBOL_NOT_FOUND = 103;
// note that MODULE_SKIPPED is not an error condition, but not 0 to indicate its not the
// same as successfully running tests and finding them.
const int MODULE_SKIPPED = 104;
const char* INTEG_BOOTSTRAP = "AzTestIntegBootstrap";
//! display proper usage of the application
void usage([[maybe_unused]] AZ::Test::Platform& platform)
{
std::stringstream ss;
ss <<
"AzTestRunner\n"
"Runs AZ unit and integration tests. Exit code is the result from GoogleTest.\n"
"Runs AZ tests. Exit code is the result from GoogleTest.\n"
"\n"
"Usage:\n"
" AzTestRunner.exe <lib> (AzRunUnitTests|AzRunIntegTests) [--integ] [--wait-for-debugger] [--pause-on-completion] [google-test-args]\n"
" AzTestRunner.exe <lib> (AzRunUnitTests|AzRunBenchmarks) [--wait-for-debugger] [--pause-on-completion] [google-test-args]\n"
"\n"
"Options:\n"
" <lib>: the module to test\n"
" <hook>: the name of the aztest hook function to run in the <lib>\n"
" 'AzRunUnitTests' will hook into unit tests\n"
" 'AzRunIntegTests' will hook into integration tests\n"
" --integ: tells runner to bootstrap the engine, needed for integration tests\n"
" Note: you can run unit tests with a bootstrapped engine (AzRunUnitTests --integ),\n"
" but running integration tests without a bootstrapped engine (AzRunIntegTests w/ no --integ) might not work.\n"
" 'AzRunBenchmarks' will hook into benchmark tests\n"
" --wait-for-debugger: tells runner to wait for debugger to attach to process (on supported platforms)\n"
" --pause-on-completion: tells the runner to pause after running the tests\n"
" --quiet: disables stdout for minimal output while running tests\n"
"\n"
"Example:\n"
" AzTestRunner.exe CrySystem.dll AzRunUnitTests --pause-on-completion\n"
" AzTestRunner.exe CrySystem.dll AzRunIntegTests --integ\n"
" AzTestRunner.exe AzCore.Tests.dll AzRunUnitTests --pause-on-completion\n"
"\n"
"Exit Codes:\n"
" 0 - all tests pass\n"
" 1 - test failure\n"
<< " " << INCORRECT_USAGE << " - incorrect usage (see above)\n"
<< " " << LIB_NOT_FOUND << " - library/dll could not be loaded\n"
<< " " << SYMBOL_NOT_FOUND << " - export symbol not found\n"
<< " " << MODULE_SKIPPED << " - non-integ module was skipped (not an error)\n";
<< " " << SYMBOL_NOT_FOUND << " - export symbol not found\n";
std::cerr << ss.str() << std::endl;
}
@@ -82,7 +72,6 @@ namespace AzTestRunner
// capture optional arguments
bool waitForDebugger = false;
bool isInteg = false;
bool pauseOnCompletion = false;
bool quiet = false;
for (int i = 0; i < argc; i++)
@@ -93,12 +82,6 @@ namespace AzTestRunner
AZ::Test::RemoveParameters(argc, argv, i, i);
i--;
}
else if (strcmp(argv[i], "--integ") == 0)
{
isInteg = true;
AZ::Test::RemoveParameters(argc, argv, i, i);
i--;
}
else if (strcmp(argv[i], "--pause-on-completion") == 0)
{
pauseOnCompletion = true;
@@ -172,47 +155,11 @@ namespace AzTestRunner
if (result != 0)
{
module.reset();
if ((isInteg) && (result == SYMBOL_NOT_FOUND))
{
// special case: It is not required to put an INTEG test inside every DLL - so if
// we failed to find the INTEG entry point in this DLL, its not an error.
// its only an error if we find it and there are no tests, or we find it and tests actually
// fail.
std::cerr << "INTEG module has no entry point and will be skipped: " << lib << std::endl;
return MODULE_SKIPPED;
}
return result;
}
platform.SuppressPopupWindows();
// Grab a bootstrapper library if requested
std::shared_ptr<AZ::Test::IModuleHandle> bootstrap;
if (isInteg)
{
bootstrap = platform.GetModule(INTEG_BOOTSTRAP);
if (!bootstrap->IsValid())
{
std::cerr << "FAILED to load bootstrapper" << std::endl;
return LIB_NOT_FOUND;
}
// Initialize the bootstrapper
auto init = bootstrap->GetFunction("Initialize");
if (init->IsValid())
{
int initResult = (*init)();
if (initResult != 0)
{
std::cerr << "Bootstrapper Initialize failed with code " << initResult << ", exiting" << std::endl;
return initResult;
}
}
}
// run the test main function.
if (testMainFunction->IsValid())
{
@@ -231,22 +178,6 @@ namespace AzTestRunner
// system allocator / etc.
module.reset();
// Shutdown the bootstrapper
if (bootstrap)
{
auto shutdown = bootstrap->GetFunction("Shutdown");
if (shutdown->IsValid())
{
int shutdownResult = (*shutdown)();
if (shutdownResult != 0)
{
std::cerr << "Bootstrapper shutdown failed with code " << shutdownResult << ", exiting" << std::endl;
return shutdownResult;
}
}
bootstrap.reset();
}
if (pauseOnCompletion)
{
AzTestRunner::pause_on_completion();
-3
View File
@@ -10,8 +10,5 @@ ly_add_external_target(
NAME renderdoc
3RDPARTY_ROOT_DIRECTORY "${LY_RENDERDOC_PATH}"
VERSION
INCLUDE_DIRECTORIES
.
include
COMPILE_DEFINITIONS USE_RENDERDOC
)
@@ -7,3 +7,4 @@
#
set(RENDERDOC_RUNTIME_DEPENDENCIES "${BASE_PATH}/lib/librenderdoc.so")
set(RENDERDOC_INCLUDE_DIRECTORIES "include")
@@ -7,3 +7,4 @@
#
set(RENDERDOC_RUNTIME_DEPENDENCIES "${BASE_PATH}/renderdoc.dll")
set(RENDERDOC_INCLUDE_DIRECTORIES ".")
@@ -36,6 +36,7 @@ ly_add_target(
Gem::Atom_RPI.Edit
Gem::Atom_RPI.Public
Gem::Atom_RHI.Reflect
Gem::Atom_Feature_Common.Static
Gem::Atom_Bootstrap.Headers
)
@@ -0,0 +1,39 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Memory/Memory.h>
namespace AtomToolsFramework
{
//! Interface for describing scene content that will be rendered using the PreviewRenderer
class PreviewContent
{
public:
AZ_CLASS_ALLOCATOR(PreviewContent, AZ::SystemAllocator, 0);
PreviewContent() = default;
virtual ~PreviewContent() = default;
//! Initiate loading of scene content, models, materials, etc
virtual void Load() = 0;
//! Return true if content is loaded and ready to render
virtual bool IsReady() const = 0;
//! Return true if content failed to load
virtual bool IsError() const = 0;
//! Report any issues encountered while loading
virtual void ReportErrors() = 0;
//! Prepare or pose content before rendering
virtual void Update() = 0;
};
} // namespace AtomToolsFramework
@@ -0,0 +1,85 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <Atom/RPI.Public/Base.h>
#include <Atom/RPI.Public/Pass/AttachmentReadback.h>
#include <AtomToolsFramework/PreviewRenderer/PreviewContent.h>
#include <AtomToolsFramework/PreviewRenderer/PreviewRendererState.h>
#include <AtomToolsFramework/PreviewRenderer/PreviewerFeatureProcessorProviderBus.h>
#include <AzFramework/Entity/GameEntityContextComponent.h>
namespace AzFramework
{
class Scene;
}
class QPixmap;
namespace AtomToolsFramework
{
//! Processes requests for setting up content that gets rendered to a texture and captured to an image
class PreviewRenderer final : public PreviewerFeatureProcessorProviderBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(PreviewRenderer, AZ::SystemAllocator, 0);
PreviewRenderer(const AZStd::string& sceneName, const AZStd::string& pipelineName);
~PreviewRenderer();
struct CaptureRequest final
{
int m_size = 512;
AZStd::shared_ptr<PreviewContent> m_content;
AZStd::function<void()> m_captureFailedCallback;
AZStd::function<void(const QPixmap&)> m_captureCompleteCallback;
};
void AddCaptureRequest(const CaptureRequest& captureRequest);
AZ::RPI::ScenePtr GetScene() const;
AZ::RPI::ViewPtr GetView() const;
AZ::Uuid GetEntityContextId() const;
void ProcessCaptureRequests();
void CancelCaptureRequest();
void CompleteCaptureRequest();
void LoadContent();
void UpdateLoadContent();
void CancelLoadContent();
void PoseContent();
bool StartCapture();
void EndCapture();
private:
//! AZ::Render::PreviewerFeatureProcessorProviderBus::Handler interface overrides...
void GetRequiredFeatureProcessors(AZStd::unordered_set<AZStd::string>& featureProcessors) const override;
static constexpr float AspectRatio = 1.0f;
static constexpr float NearDist = 0.001f;
static constexpr float FarDist = 100.0f;
static constexpr float FieldOfView = AZ::Constants::HalfPi;
AZ::RPI::ScenePtr m_scene;
AZStd::shared_ptr<AzFramework::Scene> m_frameworkScene;
AZ::RPI::RenderPipelinePtr m_renderPipeline;
AZ::RPI::ViewPtr m_view;
AZStd::vector<AZStd::string> m_passHierarchy;
AZStd::unique_ptr<AzFramework::EntityContext> m_entityContext;
//! Incoming requests are appended to this queue and processed one at a time in OnTick function.
AZStd::queue<CaptureRequest> m_captureRequestQueue;
CaptureRequest m_currentCaptureRequest;
AZStd::unique_ptr<PreviewRendererState> m_state;
};
} // namespace AtomToolsFramework
@@ -0,0 +1,29 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
namespace AtomToolsFramework
{
class PreviewRenderer;
//! PreviewRendererState decouples PreviewRenderer logic into easy-to-understand and debug pieces
class PreviewRendererState
{
public:
explicit PreviewRendererState(PreviewRenderer* renderer)
: m_renderer(renderer)
{
}
virtual ~PreviewRendererState() = default;
protected:
PreviewRenderer* m_renderer = {};
};
} // namespace AtomToolsFramework
@@ -0,0 +1,25 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/std/containers/unordered_set.h>
#include <AzCore/std/string/string.h>
namespace AtomToolsFramework
{
//! PreviewerFeatureProcessorProviderRequests allows registering custom Feature Processors for preview image generation
class PreviewerFeatureProcessorProviderRequests : public AZ::EBusTraits
{
public:
//! Get a list of custom feature processors to register with preview image renderer
virtual void GetRequiredFeatureProcessors(AZStd::unordered_set<AZStd::string>& featureProcessors) const = 0;
};
using PreviewerFeatureProcessorProviderBus = AZ::EBus<PreviewerFeatureProcessorProviderRequests>;
} // namespace AtomToolsFramework
@@ -25,7 +25,7 @@
namespace AtomToolsFramework
{
//! The RenderViewportWidget class is a Qt wrapper around an Atom viewport.
//! RenderViewportWidget renders to an internal window using RPI::ViewportContext
//! RenderViewportWidget renders to an internal window using AZ::RPI::ViewportContext
//! and delegates input via its internal ViewportControllerList.
//! @see AZ::RPI::ViewportContext for Atom's API for setting up
class RenderViewportWidget
@@ -39,7 +39,7 @@ namespace AtomToolsFramework
public:
//! Creates a RenderViewportWidget.
//! Requires the Atom RPI to be initialized in order
//! to internally construct an RPI::ViewportContext.
//! to internally construct an AZ::RPI::ViewportContext.
//! If initializeViewportContext is set to false, nothing will be displayed on-screen until InitiliazeViewportContext is called.
explicit RenderViewportWidget(QWidget* parent = nullptr, bool shouldInitializeViewportContext = true);
~RenderViewportWidget();
@@ -0,0 +1,247 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <Atom/Feature/Utils/FrameCaptureBus.h>
#include <Atom/RPI.Public/Pass/Specific/RenderToTexturePass.h>
#include <Atom/RPI.Public/RPISystemInterface.h>
#include <Atom/RPI.Public/RenderPipeline.h>
#include <Atom/RPI.Public/Scene.h>
#include <Atom/RPI.Public/Shader/ShaderResourceGroup.h>
#include <Atom/RPI.Public/View.h>
#include <Atom/RPI.Reflect/System/RenderPipelineDescriptor.h>
#include <Atom/RPI.Reflect/System/SceneDescriptor.h>
#include <AtomToolsFramework/PreviewRenderer/PreviewRenderer.h>
#include <AzCore/Math/MatrixUtils.h>
#include <AzCore/Math/Transform.h>
#include <AzFramework/Scene/Scene.h>
#include <AzFramework/Scene/SceneSystemInterface.h>
#include <PreviewRenderer/PreviewRendererCaptureState.h>
#include <PreviewRenderer/PreviewRendererIdleState.h>
#include <PreviewRenderer/PreviewRendererLoadState.h>
#include <QImage>
#include <QPixmap>
namespace AtomToolsFramework
{
PreviewRenderer::PreviewRenderer(const AZStd::string& sceneName, const AZStd::string& pipelineName)
{
PreviewerFeatureProcessorProviderBus::Handler::BusConnect();
m_entityContext = AZStd::make_unique<AzFramework::EntityContext>();
m_entityContext->InitContext();
// Create and register a scene with all required feature processors
AZStd::unordered_set<AZStd::string> featureProcessors;
PreviewerFeatureProcessorProviderBus::Broadcast(
&PreviewerFeatureProcessorProviderBus::Handler::GetRequiredFeatureProcessors, featureProcessors);
AZ::RPI::SceneDescriptor sceneDesc;
sceneDesc.m_featureProcessorNames.assign(featureProcessors.begin(), featureProcessors.end());
m_scene = AZ::RPI::Scene::CreateScene(sceneDesc);
// Bind m_frameworkScene to the entity context's AzFramework::Scene
auto sceneSystem = AzFramework::SceneSystemInterface::Get();
AZ_Assert(sceneSystem, "Failed to get scene system implementation.");
AZ::Outcome<AZStd::shared_ptr<AzFramework::Scene>, AZStd::string> createSceneOutcome = sceneSystem->CreateScene(sceneName);
AZ_Assert(createSceneOutcome, createSceneOutcome.GetError().c_str());
m_frameworkScene = createSceneOutcome.TakeValue();
m_frameworkScene->SetSubsystem(m_scene);
m_frameworkScene->SetSubsystem(m_entityContext.get());
// Create a render pipeline from the specified asset for the window context and add the pipeline to the scene
AZ::RPI::RenderPipelineDescriptor pipelineDesc;
pipelineDesc.m_mainViewTagName = "MainCamera";
pipelineDesc.m_name = pipelineName;
pipelineDesc.m_rootPassTemplate = "MainPipelineRenderToTexture";
// We have to set the samples to 4 to match the pipeline passes' setting, otherwise it may lead to device lost issue
// [GFX TODO] [ATOM-13551] Default value sand validation required to prevent pipeline crash and device lost
pipelineDesc.m_renderSettings.m_multisampleState.m_samples = 4;
m_renderPipeline = AZ::RPI::RenderPipeline::CreateRenderPipeline(pipelineDesc);
m_scene->AddRenderPipeline(m_renderPipeline);
m_scene->Activate();
AZ::RPI::RPISystemInterface::Get()->RegisterScene(m_scene);
m_passHierarchy.push_back(pipelineName);
m_passHierarchy.push_back("CopyToSwapChain");
// Connect camera to pipeline's default view after camera entity activated
AZ::Matrix4x4 viewToClipMatrix;
AZ::MakePerspectiveFovMatrixRH(viewToClipMatrix, FieldOfView, AspectRatio, NearDist, FarDist, true);
m_view = AZ::RPI::View::CreateView(AZ::Name("MainCamera"), AZ::RPI::View::UsageCamera);
m_view->SetViewToClipMatrix(viewToClipMatrix);
m_renderPipeline->SetDefaultView(m_view);
m_state.reset(new PreviewRendererIdleState(this));
}
PreviewRenderer::~PreviewRenderer()
{
PreviewerFeatureProcessorProviderBus::Handler::BusDisconnect();
m_state.reset();
m_currentCaptureRequest = {};
m_captureRequestQueue = {};
m_scene->Deactivate();
m_scene->RemoveRenderPipeline(m_renderPipeline->GetId());
AZ::RPI::RPISystemInterface::Get()->UnregisterScene(m_scene);
m_frameworkScene->UnsetSubsystem(m_scene);
m_frameworkScene->UnsetSubsystem(m_entityContext.get());
}
void PreviewRenderer::AddCaptureRequest(const CaptureRequest& captureRequest)
{
m_captureRequestQueue.push(captureRequest);
}
AZ::RPI::ScenePtr PreviewRenderer::GetScene() const
{
return m_scene;
}
AZ::RPI::ViewPtr PreviewRenderer::GetView() const
{
return m_view;
}
AZ::Uuid PreviewRenderer::GetEntityContextId() const
{
return m_entityContext->GetContextId();
}
void PreviewRenderer::ProcessCaptureRequests()
{
if (!m_captureRequestQueue.empty())
{
// pop the next request to be rendered from the queue
m_currentCaptureRequest = m_captureRequestQueue.front();
m_captureRequestQueue.pop();
m_state.reset();
m_state.reset(new PreviewRendererLoadState(this));
}
}
void PreviewRenderer::CancelCaptureRequest()
{
if (m_currentCaptureRequest.m_captureFailedCallback)
{
m_currentCaptureRequest.m_captureFailedCallback();
}
m_state.reset();
m_state.reset(new PreviewRendererIdleState(this));
}
void PreviewRenderer::CompleteCaptureRequest()
{
m_state.reset();
m_state.reset(new PreviewRendererIdleState(this));
}
void PreviewRenderer::LoadContent()
{
m_currentCaptureRequest.m_content->Load();
}
void PreviewRenderer::UpdateLoadContent()
{
if (m_currentCaptureRequest.m_content->IsReady())
{
m_state.reset();
m_state.reset(new PreviewRendererCaptureState(this));
return;
}
if (m_currentCaptureRequest.m_content->IsError())
{
CancelLoadContent();
return;
}
}
void PreviewRenderer::CancelLoadContent()
{
m_currentCaptureRequest.m_content->ReportErrors();
CancelCaptureRequest();
}
void PreviewRenderer::PoseContent()
{
m_currentCaptureRequest.m_content->Update();
}
bool PreviewRenderer::StartCapture()
{
auto captureCompleteCallback = m_currentCaptureRequest.m_captureCompleteCallback;
auto captureFailedCallback = m_currentCaptureRequest.m_captureFailedCallback;
auto captureCallback = [captureCompleteCallback, captureFailedCallback](const AZ::RPI::AttachmentReadback::ReadbackResult& result)
{
if (result.m_dataBuffer)
{
if (captureCompleteCallback)
{
captureCompleteCallback(QPixmap::fromImage(QImage(
result.m_dataBuffer.get()->data(), result.m_imageDescriptor.m_size.m_width,
result.m_imageDescriptor.m_size.m_height, QImage::Format_RGBA8888)));
}
}
else
{
if (captureFailedCallback)
{
captureFailedCallback();
}
}
};
if (auto renderToTexturePass = azrtti_cast<AZ::RPI::RenderToTexturePass*>(m_renderPipeline->GetRootPass().get()))
{
renderToTexturePass->ResizeOutput(m_currentCaptureRequest.m_size, m_currentCaptureRequest.m_size);
}
m_renderPipeline->AddToRenderTickOnce();
bool startedCapture = false;
AZ::Render::FrameCaptureRequestBus::BroadcastResult(
startedCapture, &AZ::Render::FrameCaptureRequestBus::Events::CapturePassAttachmentWithCallback, m_passHierarchy,
AZStd::string("Output"), captureCallback, AZ::RPI::PassAttachmentReadbackOption::Output);
return startedCapture;
}
void PreviewRenderer::EndCapture()
{
m_currentCaptureRequest = {};
m_renderPipeline->RemoveFromRenderTick();
}
void PreviewRenderer::GetRequiredFeatureProcessors(AZStd::unordered_set<AZStd::string>& featureProcessors) const
{
featureProcessors.insert({
"AZ::Render::TransformServiceFeatureProcessor",
"AZ::Render::MeshFeatureProcessor",
"AZ::Render::SimplePointLightFeatureProcessor",
"AZ::Render::SimpleSpotLightFeatureProcessor",
"AZ::Render::PointLightFeatureProcessor",
// There is currently a bug where having multiple DirectionalLightFeatureProcessors active can result in shadow
// flickering [ATOM-13568]
// as well as continually rebuilding MeshDrawPackets [ATOM-13633]. Lets just disable the directional light FP for now.
// Possibly re-enable with [GFX TODO][ATOM-13639]
// "AZ::Render::DirectionalLightFeatureProcessor",
"AZ::Render::DiskLightFeatureProcessor",
"AZ::Render::CapsuleLightFeatureProcessor",
"AZ::Render::QuadLightFeatureProcessor",
"AZ::Render::DecalTextureArrayFeatureProcessor",
"AZ::Render::ImageBasedLightFeatureProcessor",
"AZ::Render::PostProcessFeatureProcessor",
"AZ::Render::SkyBoxFeatureProcessor" });
}
} // namespace AtomToolsFramework
@@ -0,0 +1,42 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AtomToolsFramework/PreviewRenderer/PreviewRenderer.h>
#include <PreviewRenderer/PreviewRendererCaptureState.h>
namespace AtomToolsFramework
{
PreviewRendererCaptureState::PreviewRendererCaptureState(PreviewRenderer* renderer)
: PreviewRendererState(renderer)
{
m_renderer->PoseContent();
AZ::TickBus::Handler::BusConnect();
}
PreviewRendererCaptureState::~PreviewRendererCaptureState()
{
AZ::Render::FrameCaptureNotificationBus::Handler::BusDisconnect();
AZ::TickBus::Handler::BusDisconnect();
m_renderer->EndCapture();
}
void PreviewRendererCaptureState::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time)
{
if ((m_ticksToCapture-- <= 0) && m_renderer->StartCapture())
{
AZ::Render::FrameCaptureNotificationBus::Handler::BusConnect();
AZ::TickBus::Handler::BusDisconnect();
}
}
void PreviewRendererCaptureState::OnCaptureFinished(
[[maybe_unused]] AZ::Render::FrameCaptureResult result, [[maybe_unused]] const AZStd::string& info)
{
m_renderer->CompleteCaptureRequest();
}
} // namespace AtomToolsFramework
@@ -0,0 +1,37 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <Atom/Feature/Utils/FrameCaptureBus.h>
#include <AtomToolsFramework/PreviewRenderer/PreviewRendererState.h>
#include <AzCore/Component/TickBus.h>
namespace AtomToolsFramework
{
//! PreviewRendererCaptureState renders a thumbnail to a pixmap and notifies MaterialOrModelThumbnail once finished
class PreviewRendererCaptureState final
: public PreviewRendererState
, public AZ::TickBus::Handler
, public AZ::Render::FrameCaptureNotificationBus::Handler
{
public:
PreviewRendererCaptureState(PreviewRenderer* renderer);
~PreviewRendererCaptureState();
private:
//! AZ::TickBus::Handler interface overrides...
void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
//! AZ::Render::FrameCaptureNotificationBus::Handler overrides...
void OnCaptureFinished(AZ::Render::FrameCaptureResult result, const AZStd::string& info) override;
//! This is necessary to suspend capture to allow a frame for Material and Mesh components to assign materials
int m_ticksToCapture = 1;
};
} // namespace AtomToolsFramework
@@ -0,0 +1,29 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AtomToolsFramework/PreviewRenderer/PreviewRenderer.h>
#include <PreviewRenderer/PreviewRendererIdleState.h>
namespace AtomToolsFramework
{
PreviewRendererIdleState::PreviewRendererIdleState(PreviewRenderer* renderer)
: PreviewRendererState(renderer)
{
AZ::TickBus::Handler::BusConnect();
}
PreviewRendererIdleState::~PreviewRendererIdleState()
{
AZ::TickBus::Handler::BusDisconnect();
}
void PreviewRendererIdleState::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time)
{
m_renderer->ProcessCaptureRequests();
}
} // namespace AtomToolsFramework
@@ -0,0 +1,29 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AtomToolsFramework/PreviewRenderer/PreviewRendererState.h>
#include <AzCore/Component/TickBus.h>
namespace AtomToolsFramework
{
//! PreviewRendererIdleState checks whether there are any new thumbnails that need to be rendered every tick
class PreviewRendererIdleState final
: public PreviewRendererState
, public AZ::TickBus::Handler
{
public:
PreviewRendererIdleState(PreviewRenderer* renderer);
~PreviewRendererIdleState();
private:
//! AZ::TickBus::Handler interface overrides...
void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
};
} // namespace AtomToolsFramework
@@ -0,0 +1,36 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AtomToolsFramework/PreviewRenderer/PreviewRenderer.h>
#include <PreviewRenderer/PreviewRendererLoadState.h>
namespace AtomToolsFramework
{
PreviewRendererLoadState::PreviewRendererLoadState(PreviewRenderer* renderer)
: PreviewRendererState(renderer)
{
m_renderer->LoadContent();
AZ::TickBus::Handler::BusConnect();
}
PreviewRendererLoadState::~PreviewRendererLoadState()
{
AZ::TickBus::Handler::BusDisconnect();
}
void PreviewRendererLoadState::OnTick(float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time)
{
if ((m_timeRemainingS += deltaTime) > TimeOutS)
{
m_renderer->CancelLoadContent();
return;
}
m_renderer->UpdateLoadContent();
}
} // namespace AtomToolsFramework
@@ -0,0 +1,32 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Component/TickBus.h>
#include <AtomToolsFramework/PreviewRenderer/PreviewRendererState.h>
namespace AtomToolsFramework
{
//! PreviewRendererLoadState pauses further rendering until all assets used for rendering a thumbnail have been loaded
class PreviewRendererLoadState final
: public PreviewRendererState
, public AZ::TickBus::Handler
{
public:
PreviewRendererLoadState(PreviewRenderer* renderer);
~PreviewRendererLoadState();
private:
//! AZ::TickBus::Handler interface overrides...
void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
static constexpr float TimeOutS = 5.0f;
float m_timeRemainingS = 0.0f;
};
} // namespace AtomToolsFramework
@@ -58,4 +58,15 @@ set(FILES
Source/Window/AtomToolsMainWindow.cpp
Source/Window/AtomToolsMainWindowSystemComponent.cpp
Source/Window/AtomToolsMainWindowSystemComponent.h
Include/AtomToolsFramework/PreviewRenderer/PreviewContent.h
Include/AtomToolsFramework/PreviewRenderer/PreviewRenderer.h
Include/AtomToolsFramework/PreviewRenderer/PreviewRendererState.h
Include/AtomToolsFramework/PreviewRenderer/PreviewerFeatureProcessorProviderBus.h
Source/PreviewRenderer/PreviewRenderer.cpp
Source/PreviewRenderer/PreviewRendererIdleState.cpp
Source/PreviewRenderer/PreviewRendererIdleState.h
Source/PreviewRenderer/PreviewRendererLoadState.cpp
Source/PreviewRenderer/PreviewRendererLoadState.h
Source/PreviewRenderer/PreviewRendererCaptureState.cpp
Source/PreviewRenderer/PreviewRendererCaptureState.h
)
@@ -1353,8 +1353,9 @@ namespace AZ::AtomBridge
// if 2d draw need to project pos to screen first
AzFramework::TextDrawParameters params;
AZ::RPI::ViewportContextPtr viewportContext = GetViewportContext();
const auto dpiScaleFactor = viewportContext->GetDpiScalingFactor();
params.m_drawViewportId = viewportContext->GetId(); // get the viewport ID so default viewport works
params.m_position = AZ::Vector3(x, y, 1.0f);
params.m_position = AZ::Vector3(x * dpiScaleFactor, y * dpiScaleFactor, 1.0f);
params.m_color = m_rendState.m_color;
params.m_scale = AZ::Vector2(size);
params.m_hAlign = center ? AzFramework::TextHorizontalAlignment::Center : AzFramework::TextHorizontalAlignment::Left; //! Horizontal text alignment
@@ -0,0 +1,34 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <Atom/Feature/Material/MaterialAssignmentId.h>
#include <AzCore/Component/EntityId.h>
#include <AzCore/EBus/EBus.h>
class QPixmap;
namespace AZ
{
namespace Render
{
//! EditorMaterialSystemComponentNotifications is an interface for handling notifications from EditorMaterialSystemComponent, like
//! being informed that material preview images are available
class EditorMaterialSystemComponentNotifications : public AZ::EBusTraits
{
public:
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
//! Notify that a material preview image is ready
virtual void OnRenderMaterialPreviewComplete(
const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId, const QPixmap& pixmap) = 0;
};
using EditorMaterialSystemComponentNotificationBus = AZ::EBus<EditorMaterialSystemComponentNotifications>;
} // namespace Render
} // namespace AZ
@@ -5,20 +5,22 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <Atom/Feature/Material/MaterialAssignmentId.h>
#include <AzCore/Component/EntityId.h>
#include <AzCore/EBus/EBus.h>
#include <AzCore/std/string/string.h>
#include <QPixmap>
namespace AZ
{
namespace Render
{
//! EditorMaterialSystemComponentRequests provides an interface to communicate with MaterialEditor
class EditorMaterialSystemComponentRequests
: public AZ::EBusTraits
//! EditorMaterialSystemComponentRequests provides an interface for interacting with EditorMaterialSystemComponent, performing
//! different operations like opening the material editor, the material instance inspector, and managing material preview images
class EditorMaterialSystemComponentRequests : public AZ::EBusTraits
{
public:
// Only a single handler is allowed
@@ -31,6 +33,14 @@ namespace AZ
//! Open material instance editor
virtual void OpenMaterialInspector(
const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId) = 0;
//! Generate a material preview image
virtual void RenderMaterialPreview(
const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId) = 0;
//! Get recently rendered material preview image
virtual QPixmap GetRenderedMaterialPreview(
const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId) const = 0;
};
using EditorMaterialSystemComponentRequestBus = AZ::EBus<EditorMaterialSystemComponentRequests>;
} // namespace Render
@@ -1,33 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/std/string/string.h>
namespace AZ
{
namespace LyIntegration
{
namespace Thumbnails
{
//! ThumbnailFeatureProcessorProviderRequests allows registering custom Feature Processors for thumbnail generation
//! Duplicates will be ignored
//! You can check minimal feature processors that are already registered in CommonThumbnailRenderer.cpp
class ThumbnailFeatureProcessorProviderRequests
: public AZ::EBusTraits
{
public:
//! Get a list of custom feature processors to register with thumbnail renderer
virtual const AZStd::vector<AZStd::string>& GetCustomFeatureProcessors() const = 0;
};
using ThumbnailFeatureProcessorProviderBus = AZ::EBus<ThumbnailFeatureProcessorProviderRequests>;
} // namespace Thumbnails
} // namespace LyIntegration
} // namespace AZ
@@ -6,15 +6,17 @@
*
*/
#include <EditorCommonFeaturesSystemComponent.h>
#include <SkinnedMesh/SkinnedMeshDebugDisplay.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/EditContextConstants.inl>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Utils/Utils.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzToolsFramework/API/EditorCameraBus.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
#include <EditorCommonFeaturesSystemComponent.h>
#include <SharedPreview/SharedThumbnail.h>
#include <SkinnedMesh/SkinnedMeshDebugDisplay.h>
#include <IEditor.h>
@@ -68,7 +70,7 @@ namespace AZ
void EditorCommonFeaturesSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
{
AZ_UNUSED(required);
required.push_back(AZ_CRC_CE("ThumbnailerService"));
}
void EditorCommonFeaturesSystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
@@ -82,24 +84,23 @@ namespace AZ
void EditorCommonFeaturesSystemComponent::Activate()
{
m_renderer = AZStd::make_unique<AZ::LyIntegration::Thumbnails::CommonThumbnailRenderer>();
m_previewerFactory = AZStd::make_unique <LyIntegration::CommonPreviewerFactory>();
m_skinnedMeshDebugDisplay = AZStd::make_unique<SkinnedMeshDebugDisplay>();
AzToolsFramework::EditorLevelNotificationBus::Handler::BusConnect();
AzToolsFramework::AssetBrowser::PreviewerRequestBus::Handler::BusConnect();
AzFramework::AssetCatalogEventBus::Handler::BusConnect();
AzFramework::ApplicationLifecycleEvents::Bus::Handler::BusConnect();
}
void EditorCommonFeaturesSystemComponent::Deactivate()
{
AzToolsFramework::EditorLevelNotificationBus::Handler::BusDisconnect();
AzFramework::ApplicationLifecycleEvents::Bus::Handler::BusDisconnect();
AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
AzToolsFramework::EditorLevelNotificationBus::Handler::BusDisconnect();
AzToolsFramework::AssetBrowser::PreviewerRequestBus::Handler::BusDisconnect();
m_skinnedMeshDebugDisplay.reset();
m_previewerFactory.reset();
m_renderer.reset();
TeardownThumbnails();
}
void EditorCommonFeaturesSystemComponent::OnNewLevelCreated()
@@ -191,6 +192,13 @@ namespace AZ
}
}
void EditorCommonFeaturesSystemComponent::OnCatalogLoaded([[maybe_unused]] const char* catalogFile)
{
AZ::TickBus::QueueFunction([this](){
SetupThumbnails();
});
}
const AzToolsFramework::AssetBrowser::PreviewerFactory* EditorCommonFeaturesSystemComponent::GetPreviewerFactory(
const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) const
{
@@ -199,7 +207,33 @@ namespace AZ
void EditorCommonFeaturesSystemComponent::OnApplicationAboutToStop()
{
TeardownThumbnails();
}
void EditorCommonFeaturesSystemComponent::SetupThumbnails()
{
using namespace AzToolsFramework::Thumbnailer;
using namespace LyIntegration;
ThumbnailerRequestsBus::Broadcast(
&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(SharedThumbnailCache),
ThumbnailContext::DefaultContext);
m_renderer = AZStd::make_unique<AZ::LyIntegration::SharedThumbnailRenderer>();
m_previewerFactory = AZStd::make_unique<LyIntegration::SharedPreviewerFactory>();
}
void EditorCommonFeaturesSystemComponent::TeardownThumbnails()
{
using namespace AzToolsFramework::Thumbnailer;
using namespace LyIntegration;
ThumbnailerRequestsBus::Broadcast(
&ThumbnailerRequests::UnregisterThumbnailProvider, SharedThumbnailCache::ProviderName,
ThumbnailContext::DefaultContext);
m_renderer.reset();
m_previewerFactory.reset();
}
} // namespace Render
} // namespace AZ
@@ -11,10 +11,10 @@
#include <AzCore/Component/Component.h>
#include <AzFramework/Application/Application.h>
#include <AzToolsFramework/API/EditorLevelNotificationBus.h>
#include <AzToolsFramework/Entity/SliceEditorEntityOwnershipServiceBus.h>
#include <AzToolsFramework/AssetBrowser/Previewer/PreviewerBus.h>
#include <Thumbnails/Rendering/CommonThumbnailRenderer.h>
#include <Source/Thumbnails/Preview/CommonPreviewerFactory.h>
#include <AzToolsFramework/Entity/SliceEditorEntityOwnershipServiceBus.h>
#include <SharedPreview/SharedPreviewerFactory.h>
#include <SharedPreview/SharedThumbnailRenderer.h>
namespace AZ
{
@@ -28,6 +28,7 @@ namespace AZ
, public AzToolsFramework::EditorLevelNotificationBus::Handler
, public AzToolsFramework::SliceEditorEntityOwnershipServiceNotificationBus::Handler
, public AzToolsFramework::AssetBrowser::PreviewerRequestBus::Handler
, public AzFramework::AssetCatalogEventBus::Handler
, public AzFramework::ApplicationLifecycleEvents::Bus::Handler
{
public:
@@ -53,15 +54,23 @@ namespace AZ
void OnNewLevelCreated() override;
// SliceEditorEntityOwnershipServiceBus overrides ...
void OnSliceInstantiated(const AZ::Data::AssetId&, AZ::SliceComponent::SliceInstanceAddress&, const AzFramework::SliceInstantiationTicket&) override;
void OnSliceInstantiated(
const AZ::Data::AssetId&, AZ::SliceComponent::SliceInstanceAddress&, const AzFramework::SliceInstantiationTicket&) override;
void OnSliceInstantiationFailed(const AZ::Data::AssetId&, const AzFramework::SliceInstantiationTicket&) override;
// AzFramework::AssetCatalogEventBus::Handler overrides ...
void OnCatalogLoaded(const char* catalogFile) override;
// AzToolsFramework::AssetBrowser::PreviewerRequestBus::Handler overrides...
const AzToolsFramework::AssetBrowser::PreviewerFactory* GetPreviewerFactory(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) const override;
const AzToolsFramework::AssetBrowser::PreviewerFactory* GetPreviewerFactory(
const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) const override;
// AzFramework::ApplicationLifecycleEvents overrides...
void OnApplicationAboutToStop() override;
void SetupThumbnails();
void TeardownThumbnails();
private:
AZStd::unique_ptr<SkinnedMeshDebugDisplay> m_skinnedMeshDebugDisplay;
@@ -69,8 +78,8 @@ namespace AZ
AZStd::string m_atomLevelDefaultAssetPath{ "LevelAssets/default.slice" };
float m_envProbeHeight{ 200.0f };
AZStd::unique_ptr<AZ::LyIntegration::Thumbnails::CommonThumbnailRenderer> m_renderer;
AZStd::unique_ptr<LyIntegration::CommonPreviewerFactory> m_previewerFactory;
AZStd::unique_ptr<AZ::LyIntegration::SharedThumbnailRenderer> m_renderer;
AZStd::unique_ptr<LyIntegration::SharedPreviewerFactory> m_previewerFactory;
};
} // namespace Render
} // namespace AZ
@@ -148,11 +148,13 @@ namespace AZ
BaseClass::Activate();
MaterialReceiverNotificationBus::Handler::BusConnect(GetEntityId());
MaterialComponentNotificationBus::Handler::BusConnect(GetEntityId());
EditorMaterialSystemComponentNotificationBus::Handler::BusConnect();
UpdateMaterialSlots();
}
void EditorMaterialComponent::Deactivate()
{
EditorMaterialSystemComponentNotificationBus::Handler::BusDisconnect();
MaterialReceiverNotificationBus::Handler::BusDisconnect();
MaterialComponentNotificationBus::Handler::BusDisconnect();
BaseClass::Deactivate();
@@ -260,6 +262,18 @@ namespace AZ
}
}
void EditorMaterialComponent::OnRenderMaterialPreviewComplete(
[[maybe_unused]] const AZ::EntityId& entityId,
[[maybe_unused]] const AZ::Render::MaterialAssignmentId& materialAssignmentId,
[[maybe_unused]] const QPixmap& pixmap)
{
if (entityId == GetEntityId())
{
AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast(
&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_AttributesAndValues);
}
}
AZ::u32 EditorMaterialComponent::OnConfigurationChanged()
{
return AZ::Edit::PropertyRefreshLevels::AttributesAndValues;
@@ -9,6 +9,7 @@
#pragma once
#include <Atom/Feature/Utils/EditorRenderComponentAdapter.h>
#include <AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentNotificationBus.h>
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentBus.h>
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentConstants.h>
#include <Material/EditorMaterialComponentSlot.h>
@@ -21,8 +22,9 @@ namespace AZ
//! In-editor material component for displaying and editing material assignments.
class EditorMaterialComponent final
: public EditorRenderComponentAdapter<MaterialComponentController, MaterialComponent, MaterialComponentConfig>
, private MaterialReceiverNotificationBus::Handler
, private MaterialComponentNotificationBus::Handler
, public MaterialReceiverNotificationBus::Handler
, public MaterialComponentNotificationBus::Handler
, public EditorMaterialSystemComponentNotificationBus::Handler
{
public:
using BaseClass = EditorRenderComponentAdapter<MaterialComponentController, MaterialComponent, MaterialComponentConfig>;
@@ -52,6 +54,10 @@ namespace AZ
//! MaterialComponentNotificationBus::Handler overrides...
void OnMaterialInstanceCreated(const MaterialAssignment& materialAssignment) override;
//! EditorMaterialSystemComponentNotificationBus::Handler overrides...
void OnRenderMaterialPreviewComplete(
const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId, const QPixmap& pixmap) override;
// Regenerates the editor component material slots based on the material and
// LOD mapping from the model or other consumer of materials.
// If any corresponding material assignments are found in the component
@@ -23,10 +23,6 @@
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <AzToolsFramework/API/EditorWindowRequestBus.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzToolsFramework/AssetBrowser/Thumbnails/ProductThumbnail.h>
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
#include <AzToolsFramework/Thumbnails/ThumbnailWidget.h>
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
#include <AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentRequestBus.h>
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentBus.h>
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentConfig.h>
@@ -49,29 +45,18 @@ namespace AZ
MaterialPropertyInspector::MaterialPropertyInspector(QWidget* parent)
: AtomToolsFramework::InspectorWidget(parent)
{
// Create the menu button
QToolButton* menuButton = new QToolButton(this);
menuButton->setAutoRaise(true);
menuButton->setIcon(QIcon(":/Cards/img/UI20/Cards/menu_ico.svg"));
menuButton->setVisible(true);
QObject::connect(menuButton, &QToolButton::clicked, this, [this]() { OpenMenu(); });
AddHeading(menuButton);
m_messageLabel = new QLabel(this);
m_messageLabel->setWordWrap(true);
m_messageLabel->setVisible(true);
m_messageLabel->setAlignment(Qt::AlignCenter);
m_messageLabel->setText(tr("Material not available"));
AddHeading(m_messageLabel);
CreateHeading();
AZ::TickBus::Handler::BusConnect();
AZ::EntitySystemBus::Handler::BusConnect();
EditorMaterialSystemComponentNotificationBus::Handler::BusConnect();
}
MaterialPropertyInspector::~MaterialPropertyInspector()
{
AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect();
AZ::EntitySystemBus::Handler::BusDisconnect();
AZ::TickBus::Handler::BusDisconnect();
AZ::EntitySystemBus::Handler::BusDisconnect();
EditorMaterialSystemComponentNotificationBus::Handler::BusDisconnect();
MaterialComponentNotificationBus::Handler::BusDisconnect();
}
@@ -140,7 +125,7 @@ namespace AZ
}
Populate();
m_messageLabel->setVisible(false);
LoadOverridesFromEntity();
return true;
}
@@ -152,8 +137,9 @@ namespace AZ
m_dirtyPropertyFlags.set();
m_editorFunctors = {};
m_internalEditNotification = {};
m_messageLabel->setVisible(true);
m_messageLabel->setText(tr("Material not available"));
m_updateUI = {};
m_updatePreview = {};
UpdateHeading();
}
bool MaterialPropertyInspector::IsLoaded() const
@@ -168,49 +154,63 @@ namespace AZ
m_dirtyPropertyFlags.set();
m_internalEditNotification = {};
AZ::TickBus::Handler::BusDisconnect();
AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect();
AtomToolsFramework::InspectorWidget::Reset();
}
void MaterialPropertyInspector::AddDetailsGroup()
void MaterialPropertyInspector::CreateHeading()
{
const AZStd::string& groupName = "Details";
const AZStd::string& groupDisplayName = "Details";
const AZStd::string& groupDescription = "";
// Create the menu button
QToolButton* menuButton = new QToolButton(this);
menuButton->setAutoRaise(true);
menuButton->setIcon(QIcon(":/Cards/img/UI20/Cards/menu_ico.svg"));
menuButton->setVisible(true);
QObject::connect(menuButton, &QToolButton::clicked, this, [this]() { OpenMenu(); });
AddHeading(menuButton);
auto propertyGroupContainer = new QWidget(this);
propertyGroupContainer->setLayout(new QHBoxLayout());
m_overviewImage = new QLabel(this);
m_overviewImage->setFixedSize(QSize(120, 120));
m_overviewImage->setScaledContents(true);
m_overviewImage->setVisible(false);
AzToolsFramework::Thumbnailer::SharedThumbnailKey thumbnailKey =
MAKE_TKEY(AzToolsFramework::AssetBrowser::ProductThumbnailKey, m_editData.m_materialAssetId);
auto thumbnailWidget = new AzToolsFramework::Thumbnailer::ThumbnailWidget(this);
thumbnailWidget->setFixedSize(QSize(120, 120));
thumbnailWidget->setVisible(true);
thumbnailWidget->SetThumbnailKey(thumbnailKey, AzToolsFramework::Thumbnailer::ThumbnailContext::DefaultContext);
propertyGroupContainer->layout()->addWidget(thumbnailWidget);
auto materialInfoWidget = new QLabel(this);
m_overviewText = new QLabel(this);
QSizePolicy sizePolicy1(QSizePolicy::Ignored, QSizePolicy::Preferred);
sizePolicy1.setHorizontalStretch(0);
sizePolicy1.setVerticalStretch(0);
sizePolicy1.setHeightForWidth(materialInfoWidget->sizePolicy().hasHeightForWidth());
materialInfoWidget->setSizePolicy(sizePolicy1);
materialInfoWidget->setMinimumSize(QSize(0, 0));
materialInfoWidget->setMaximumSize(QSize(16777215, 16777215));
materialInfoWidget->setTextFormat(Qt::AutoText);
materialInfoWidget->setScaledContents(false);
materialInfoWidget->setAlignment(Qt::AlignLeading | Qt::AlignLeft | Qt::AlignTop);
materialInfoWidget->setWordWrap(true);
sizePolicy1.setHeightForWidth(m_overviewText->sizePolicy().hasHeightForWidth());
m_overviewText->setSizePolicy(sizePolicy1);
m_overviewText->setMinimumSize(QSize(0, 0));
m_overviewText->setMaximumSize(QSize(16777215, 16777215));
m_overviewText->setTextFormat(Qt::AutoText);
m_overviewText->setScaledContents(false);
m_overviewText->setWordWrap(true);
m_overviewText->setVisible(true);
auto overviewContainer = new QWidget(this);
overviewContainer->setLayout(new QHBoxLayout());
overviewContainer->layout()->addWidget(m_overviewImage);
overviewContainer->layout()->addWidget(m_overviewText);
AddHeading(overviewContainer);
}
void MaterialPropertyInspector::UpdateHeading()
{
if (!IsLoaded())
{
m_overviewText->setText(tr("Material not available"));
m_overviewText->setAlignment(Qt::AlignCenter);
m_overviewImage->setVisible(false);
return;
}
QFileInfo materialFileInfo(AZ::RPI::AssetUtils::GetProductPathByAssetId(m_editData.m_materialAsset.GetId()).c_str());
QFileInfo materialSourceFileInfo(m_editData.m_materialSourcePath.c_str());
QFileInfo materialTypeSourceFileInfo(m_editData.m_materialTypeSourcePath.c_str());
QFileInfo materialParentSourceFileInfo(AZ::RPI::AssetUtils::GetSourcePathByAssetId(m_editData.m_materialParentAsset.GetId()).c_str());
QFileInfo materialParentSourceFileInfo(
AZ::RPI::AssetUtils::GetSourcePathByAssetId(m_editData.m_materialParentAsset.GetId()).c_str());
AZStd::string entityName;
AZ::ComponentApplicationBus::BroadcastResult(
entityName, &AZ::ComponentApplicationBus::Events::GetEntityName, m_entityId);
AZ::ComponentApplicationBus::BroadcastResult(entityName, &AZ::ComponentApplicationBus::Events::GetEntityName, m_entityId);
AZStd::string slotName;
MaterialComponentRequestBus::EventResult(
@@ -226,7 +226,8 @@ namespace AZ
}
if (!materialTypeSourceFileInfo.fileName().isEmpty())
{
materialInfo += tr("<tr><td><b>Material Type&emsp;</b></td><td>%1</td></tr>").arg(materialTypeSourceFileInfo.fileName());
materialInfo +=
tr("<tr><td><b>Material Type&emsp;</b></td><td>%1</td></tr>").arg(materialTypeSourceFileInfo.fileName());
}
if (!materialSourceFileInfo.fileName().isEmpty())
{
@@ -234,14 +235,21 @@ namespace AZ
}
if (!materialParentSourceFileInfo.fileName().isEmpty())
{
materialInfo += tr("<tr><td><b>Material Parent&emsp;</b></td><td>%1</td></tr>").arg(materialParentSourceFileInfo.fileName());
materialInfo +=
tr("<tr><td><b>Material Parent&emsp;</b></td><td>%1</td></tr>").arg(materialParentSourceFileInfo.fileName());
}
materialInfo += tr("</table>");
materialInfoWidget->setText(materialInfo);
propertyGroupContainer->layout()->addWidget(materialInfoWidget);
m_overviewText->setText(materialInfo);
m_overviewText->setAlignment(Qt::AlignLeading | Qt::AlignLeft | Qt::AlignTop);
AddGroup(groupName, groupDisplayName, groupDescription, propertyGroupContainer);
QPixmap pixmap;
EditorMaterialSystemComponentRequestBus::BroadcastResult(
pixmap, &EditorMaterialSystemComponentRequestBus::Events::GetRenderedMaterialPreview, m_entityId,
m_materialAssignmentId);
m_overviewImage->setPixmap(pixmap);
m_overviewImage->setVisible(true);
m_updatePreview |= pixmap.isNull();
}
void MaterialPropertyInspector::AddUvNamesGroup()
@@ -282,13 +290,8 @@ namespace AZ
AddGroup(groupName, groupDisplayName, groupDescription, propertyGroupWidget);
}
void MaterialPropertyInspector::Populate()
void MaterialPropertyInspector::AddPropertiesGroup()
{
AddGroupsBegin();
AddDetailsGroup();
AddUvNamesGroup();
// Copy all of the properties from the material asset to the source data that will be exported
for (const auto& groupDefinition : m_editData.m_materialTypeSourceData.GetGroupDefinitionsInDisplayOrder())
{
@@ -327,10 +330,14 @@ namespace AZ
[this](const auto node) { return GetInstanceNodePropertyIndicator(node); }, 0);
AddGroup(groupName, groupDisplayName, groupDescription, propertyGroupWidget);
}
}
void MaterialPropertyInspector::Populate()
{
AddGroupsBegin();
AddUvNamesGroup();
AddPropertiesGroup();
AddGroupsEnd();
LoadOverridesFromEntity();
}
void MaterialPropertyInspector::LoadOverridesFromEntity()
@@ -375,6 +382,7 @@ namespace AZ
m_dirtyPropertyFlags.set();
RunEditorMaterialFunctors();
RebuildAll();
UpdateHeading();
}
void MaterialPropertyInspector::SaveOverridesToEntity(bool commitChanges)
@@ -398,6 +406,9 @@ namespace AZ
MaterialComponentNotificationBus::Event(m_entityId, &MaterialComponentNotifications::OnMaterialsEdited);
m_internalEditNotification = false;
}
// m_updatePreview should be set to true here for continuous preview updates as slider/color properties change but needs
// throttling
}
void MaterialPropertyInspector::RunEditorMaterialFunctors()
@@ -607,7 +618,8 @@ namespace AZ
MaterialComponentRequestBus::Event(
m_entityId, &MaterialComponentRequestBus::Events::SetPropertyOverrides, m_materialAssignmentId,
MaterialPropertyOverrideMap());
QueueUpdateUI();
m_updateUI = true;
m_updatePreview = true;
});
action->setEnabled(IsLoaded());
@@ -702,10 +714,7 @@ namespace AZ
void MaterialPropertyInspector::OnEntityActivated(const AZ::EntityId& entityId)
{
if (m_entityId == entityId)
{
QueueUpdateUI();
}
m_updateUI |= (m_entityId == entityId);
}
void MaterialPropertyInspector::OnEntityDeactivated(const AZ::EntityId& entityId)
@@ -719,25 +728,39 @@ namespace AZ
void MaterialPropertyInspector::OnEntityNameChanged(const AZ::EntityId& entityId, const AZStd::string& name)
{
AZ_UNUSED(name);
if (m_entityId == entityId)
{
QueueUpdateUI();
}
m_updateUI |= (m_entityId == entityId);
}
void MaterialPropertyInspector::OnTick(float deltaTime, ScriptTimePoint time)
{
AZ_UNUSED(time);
AZ_UNUSED(deltaTime);
UpdateUI();
AZ::TickBus::Handler::BusDisconnect();
if (m_updateUI)
{
m_updateUI = false;
UpdateUI();
}
if (m_updatePreview)
{
m_updatePreview = false;
EditorMaterialSystemComponentRequestBus::Broadcast(
&EditorMaterialSystemComponentRequestBus::Events::RenderMaterialPreview, m_entityId, m_materialAssignmentId);
}
}
void MaterialPropertyInspector::OnMaterialsEdited()
{
if (!m_internalEditNotification)
m_updateUI |= !m_internalEditNotification;
m_updatePreview = true;
}
void MaterialPropertyInspector::OnRenderMaterialPreviewComplete(
const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId, const QPixmap& pixmap)
{
if (m_overviewImage && m_entityId == entityId && m_materialAssignmentId == materialAssignmentId)
{
QueueUpdateUI();
m_overviewImage->setPixmap(pixmap);
}
}
@@ -761,16 +784,6 @@ namespace AZ
LoadMaterial(m_entityId, m_materialAssignmentId);
}
}
void MaterialPropertyInspector::QueueUpdateUI()
{
if (!AZ::TickBus::Handler::BusIsConnected())
{
AZ::TickBus::Handler::BusConnect();
}
}
} // namespace EditorMaterialComponentInspector
} // namespace Render
} // namespace AZ
//#include <AtomLyIntegration/CommonFeatures/moc_EditorMaterialComponentInspector.cpp>
@@ -9,6 +9,7 @@
#pragma once
#if !defined(Q_MOC_RUN)
#include <AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentNotificationBus.h>
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentBus.h>
#include <AtomToolsFramework/DynamicProperty/DynamicPropertyGroup.h>
#include <AtomToolsFramework/Inspector/InspectorWidget.h>
@@ -31,14 +32,13 @@ namespace AZ
{
namespace EditorMaterialComponentInspector
{
using PropertyChangedCallback = AZStd::function<void(const MaterialPropertyOverrideMap&)>;
class MaterialPropertyInspector
: public AtomToolsFramework::InspectorWidget
, public AzToolsFramework::IPropertyEditorNotify
, public AZ::EntitySystemBus::Handler
, public AZ::TickBus::Handler
, public MaterialComponentNotificationBus::Handler
, public EditorMaterialSystemComponentNotificationBus::Handler
{
Q_OBJECT
public:
@@ -89,11 +89,19 @@ namespace AZ
//! MaterialComponentNotificationBus::Handler overrides...
void OnMaterialsEdited() override;
void UpdateUI();
void QueueUpdateUI();
//! EditorMaterialSystemComponentNotificationBus::Handler overrides...
void OnRenderMaterialPreviewComplete(
const AZ::EntityId& entityId,
const AZ::Render::MaterialAssignmentId& materialAssignmentId,
const QPixmap& pixmap) override;
void UpdateUI();
void CreateHeading();
void UpdateHeading();
void AddDetailsGroup();
void AddUvNamesGroup();
void AddPropertiesGroup();
void LoadOverridesFromEntity();
void SaveOverridesToEntity(bool commitChanges);
@@ -115,7 +123,10 @@ namespace AZ
AZ::RPI::MaterialPropertyFlags m_dirtyPropertyFlags = {};
AZStd::unordered_map<AZStd::string, AtomToolsFramework::DynamicPropertyGroup> m_groups = {};
bool m_internalEditNotification = {};
QLabel* m_messageLabel = {};
bool m_updateUI = {};
bool m_updatePreview = {};
QLabel* m_overviewText = {};
QLabel* m_overviewImage = {};
};
} // namespace EditorMaterialComponentInspector
} // namespace Render
@@ -6,23 +6,25 @@
*
*/
#include <Material/EditorMaterialComponentSlot.h>
#include <Material/EditorMaterialComponentExporter.h>
#include <Material/EditorMaterialComponentInspector.h>
#include <Material/EditorMaterialModelUvNameMapInspector.h>
#include <AzCore/Asset/AssetSerializer.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <Atom/RPI.Edit/Common/AssetUtils.h>
#include <Atom/RPI.Edit/Material/MaterialSourceData.h>
#include <AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentRequestBus.h>
#include <AzCore/Asset/AssetSerializer.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <Material/EditorMaterialComponentExporter.h>
#include <Material/EditorMaterialComponentInspector.h>
#include <Material/EditorMaterialComponentSlot.h>
#include <Material/EditorMaterialModelUvNameMapInspector.h>
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT
#include <QMenu>
#include <QAction>
#include <QAction>
#include <QByteArray>
#include <QCursor>
#include <QDataStream>
#include <QMenu>
AZ_POP_DISABLE_WARNING
namespace AZ
@@ -100,6 +102,7 @@ namespace AZ
->Attribute(AZ::Edit::Attributes::NameLabelOverride, &EditorMaterialComponentSlot::GetLabel)
->Attribute(AZ::Edit::Attributes::ShowProductAssetFileName, true)
->Attribute("ThumbnailCallback", &EditorMaterialComponentSlot::OpenPopupMenu)
->Attribute("ThumbnailIcon", &EditorMaterialComponentSlot::GetPreviewPixmapData)
;
}
}
@@ -118,6 +121,33 @@ namespace AZ
}
};
AZStd::vector<char> EditorMaterialComponentSlot::GetPreviewPixmapData() const
{
if (!GetActiveAssetId().IsValid())
{
return {};
}
QPixmap pixmap;
EditorMaterialSystemComponentRequestBus::BroadcastResult(
pixmap, &EditorMaterialSystemComponentRequestBus::Events::GetRenderedMaterialPreview, m_entityId, m_id);
if (pixmap.isNull())
{
if (m_updatePreview)
{
EditorMaterialSystemComponentRequestBus::Broadcast(
&EditorMaterialSystemComponentRequestBus::Events::RenderMaterialPreview, m_entityId, m_id);
m_updatePreview = false;
}
return {};
}
QByteArray pixmapBytes;
QDataStream stream(&pixmapBytes, QIODevice::WriteOnly);
stream << pixmap;
return AZStd::vector<char>(pixmapBytes.begin(), pixmapBytes.end());
}
AZ::Data::AssetId EditorMaterialComponentSlot::GetActiveAssetId() const
{
return m_materialAsset.GetId().IsValid() ? m_materialAsset.GetId() : GetDefaultAssetId();
@@ -169,14 +199,6 @@ namespace AZ
ClearOverrides();
}
void EditorMaterialComponentSlot::ClearToDefaultAsset()
{
m_materialAsset = AZ::Data::Asset<AZ::RPI::MaterialAsset>(GetDefaultAssetId(), AZ::AzTypeInfo<AZ::RPI::MaterialAsset>::Uuid());
MaterialComponentRequestBus::Event(
m_entityId, &MaterialComponentRequestBus::Events::SetMaterialOverride, m_id, m_materialAsset.GetId());
ClearOverrides();
}
void EditorMaterialComponentSlot::ClearOverrides()
{
MaterialComponentRequestBus::Event(
@@ -315,6 +337,10 @@ namespace AZ
AzToolsFramework::ToolsApplicationRequests::Bus::Broadcast(
&AzToolsFramework::ToolsApplicationRequests::Bus::Events::AddDirtyEntity, m_entityId);
EditorMaterialSystemComponentRequestBus::Broadcast(
&EditorMaterialSystemComponentRequestBus::Events::RenderMaterialPreview, m_entityId, m_id);
m_updatePreview = false;
MaterialComponentNotificationBus::Event(m_entityId, &MaterialComponentNotifications::OnMaterialsEdited);
AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast(
@@ -8,37 +8,52 @@
#pragma once
#include <AzCore/std/string/string.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/Asset/AssetCommon.h>
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
#include <Atom/Feature/Material/MaterialAssignment.h>
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
#include <AzCore/Asset/AssetCommon.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/string/string.h>
#include <QPixmap>
namespace AZ
{
namespace Render
{
static const size_t DefaultMaterialSlotIndex = std::numeric_limits<size_t>::max();
//! Details for a single editable material assignment
struct EditorMaterialComponentSlot final
{
AZ_RTTI(EditorMaterialComponentSlot, "{344066EB-7C3D-4E92-B53D-3C9EBD546488}");
AZ_CLASS_ALLOCATOR(EditorMaterialComponentSlot, SystemAllocator, 0);
static void Reflect(ReflectContext* context);
static bool ConvertVersion(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement);
static void Reflect(ReflectContext* context);
//! Get cached preview image as a buffer to use as an RPE attribute
//! If a cached image isn't avalible then a request will be made to render one
AZStd::vector<char> GetPreviewPixmapData() const;
//! Returns the overridden asset id if it's valid, otherwise gets the default asseet id
AZ::Data::AssetId GetActiveAssetId() const;
//! Returns the default asseet id of the material provded by the model
AZ::Data::AssetId GetDefaultAssetId() const;
//! Returns the display name of the material slot
AZStd::string GetLabel() const;
//! Returns true if the active material asset has a source material
bool HasSourceData() const;
//! Assign a new material override asset
void SetAsset(const Data::AssetId& assetId);
//! Assign a new material override asset
void SetAsset(const Data::Asset<RPI::MaterialAsset>& asset);
//! Remove material and prperty overrides
void Clear();
void ClearToDefaultAsset();
//! Remove prperty overrides
void ClearOverrides();
void OpenMaterialExporter();
@@ -54,6 +69,7 @@ namespace AZ
void OpenPopupMenu(const AZ::Data::AssetId& assetId, const AZ::Data::AssetType& assetType);
void OnMaterialChanged() const;
void OnDataChanged() const;
mutable bool m_updatePreview = true;
};
// Vector of slots for assignable or overridable material data.
@@ -62,8 +78,8 @@ namespace AZ
// Table containing all editable material data that is displayed in the edit context and inspector
// The vector represents all the LODs that can have material overrides.
// The container will be populated with every potential material slot on an associated model, using its default values.
// Whenever changes are made to this container, the modified values are copied into the controller configuration material assignment map
// as overrides that will be applied to material instances
// Whenever changes are made to this container, the modified values are copied into the controller configuration material assignment
// map as overrides that will be applied to material instances
using EditorMaterialComponentSlotsByLodContainer = AZStd::vector<EditorMaterialComponentSlotContainer>;
} // namespace Render
} // namespace AZ
@@ -6,7 +6,10 @@
*
*/
#include <AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentNotificationBus.h>
#include <Atom/RHI/Factory.h>
#include <Atom/RPI.Reflect/Asset/AssetUtils.h>
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentBus.h>
#include <AtomToolsFramework/Util/Util.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/EditContextConstants.inl>
@@ -16,11 +19,10 @@
#include <AzFramework/Application/Application.h>
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <AzToolsFramework/API/ViewPaneOptions.h>
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
#include <Editor/LyViewPaneNames.h>
#include <Material/EditorMaterialComponentInspector.h>
#include <Material/EditorMaterialSystemComponent.h>
#include <Material/MaterialThumbnail.h>
#include <SharedPreview/SharedPreviewContent.h>
// Disables warning messages triggered by the Qt library
// 4251: class needs to have dll-interface to be used by clients of class
@@ -30,6 +32,8 @@ AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option")
#include <QApplication>
#include <QDockWidget>
#include <QObject>
#include <QPixmap>
#include <QImage>
#include <QProcessEnvironment>
AZ_POP_DISABLE_WARNING
@@ -72,11 +76,6 @@ namespace AZ
incompatible.push_back(AZ_CRC("EditorMaterialSystem", 0x5c93bc4e));
}
void EditorMaterialSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
{
required.push_back(AZ_CRC("ThumbnailerService", 0x65422b97));
}
void EditorMaterialSystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
{
AZ_UNUSED(dependent);
@@ -89,25 +88,26 @@ namespace AZ
void EditorMaterialSystemComponent::Activate()
{
EditorMaterialSystemComponentNotificationBus::Handler::BusConnect();
EditorMaterialSystemComponentRequestBus::Handler::BusConnect();
AzFramework::ApplicationLifecycleEvents::Bus::Handler::BusConnect();
AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusConnect();
AzToolsFramework::EditorMenuNotificationBus::Handler::BusConnect();
AzToolsFramework::EditorEvents::Bus::Handler::BusConnect();
SetupThumbnails();
m_materialBrowserInteractions.reset(aznew MaterialBrowserInteractions);
AzFramework::AssetCatalogEventBus::Handler::BusConnect();
AzFramework::ApplicationLifecycleEvents::Bus::Handler::BusConnect();
}
void EditorMaterialSystemComponent::Deactivate()
{
EditorMaterialSystemComponentRequestBus::Handler::BusDisconnect();
AzFramework::ApplicationLifecycleEvents::Bus::Handler::BusDisconnect();
AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
EditorMaterialSystemComponentNotificationBus::Handler::BusDisconnect();
EditorMaterialSystemComponentRequestBus::Handler::BusDisconnect();
AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusDisconnect();
AzToolsFramework::EditorMenuNotificationBus::Handler::BusDisconnect();
AzToolsFramework::EditorEvents::Bus::Handler::BusDisconnect();
TeardownThumbnails();
m_previewRenderer.reset();
m_materialBrowserInteractions.reset();
if (m_openMaterialEditorAction)
@@ -154,11 +154,74 @@ namespace AZ
}
}
void EditorMaterialSystemComponent::OnApplicationAboutToStop()
void EditorMaterialSystemComponent::RenderMaterialPreview(
const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId)
{
TeardownThumbnails();
static constexpr const char* DefaultModelPath = "models/sphere.azmodel";
static constexpr const char* DefaultLightingPresetPath = "lightingpresets/thumbnail.lightingpreset.azasset";
if (m_previewRenderer)
{
AZ::Data::AssetId materialAssetId = {};
MaterialComponentRequestBus::EventResult(
materialAssetId, entityId, &MaterialComponentRequestBus::Events::GetMaterialOverride, materialAssignmentId);
if (!materialAssetId.IsValid())
{
MaterialComponentRequestBus::EventResult(
materialAssetId, entityId, &MaterialComponentRequestBus::Events::GetDefaultMaterialAssetId, materialAssignmentId);
if (!materialAssetId.IsValid())
{
return;
}
}
AZ::Render::MaterialPropertyOverrideMap propertyOverrides;
AZ::Render::MaterialComponentRequestBus::EventResult(
propertyOverrides, entityId, &AZ::Render::MaterialComponentRequestBus::Events::GetPropertyOverrides,
materialAssignmentId);
m_previewRenderer->AddCaptureRequest(
{ 128,
AZStd::make_shared<AZ::LyIntegration::SharedPreviewContent>(
m_previewRenderer->GetScene(), m_previewRenderer->GetView(), m_previewRenderer->GetEntityContextId(),
AZ::RPI::AssetUtils::GetAssetIdForProductPath(DefaultModelPath), materialAssetId,
AZ::RPI::AssetUtils::GetAssetIdForProductPath(DefaultLightingPresetPath), propertyOverrides),
[]()
{
// failed
},
[entityId, materialAssignmentId](const QPixmap& pixmap)
{
AZ::Render::EditorMaterialSystemComponentNotificationBus::Broadcast(
&AZ::Render::EditorMaterialSystemComponentNotificationBus::Events::OnRenderMaterialPreviewComplete, entityId,
materialAssignmentId, pixmap);
} });
}
}
QPixmap EditorMaterialSystemComponent::GetRenderedMaterialPreview(
const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId) const
{
const auto& itr1 = m_materialPreviews.find(entityId);
if (itr1 != m_materialPreviews.end())
{
const auto& itr2 = itr1->second.find(materialAssignmentId);
if (itr2 != itr1->second.end())
{
return itr2->second;
}
}
return QPixmap();
}
void EditorMaterialSystemComponent::OnRenderMaterialPreviewComplete(
[[maybe_unused]] const AZ::EntityId& entityId,
[[maybe_unused]] const AZ::Render::MaterialAssignmentId& materialAssignmentId,
[[maybe_unused]] const QPixmap& pixmap)
{
m_materialPreviews[entityId][materialAssignmentId] = pixmap;
}
void EditorMaterialSystemComponent::OnPopulateToolMenuItems()
{
if (!m_openMaterialEditorAction)
@@ -201,24 +264,19 @@ namespace AZ
"Material Property Inspector", LyViewPane::CategoryTools, inspectorOptions);
}
void EditorMaterialSystemComponent::SetupThumbnails()
void EditorMaterialSystemComponent::OnCatalogLoaded([[maybe_unused]] const char* catalogFile)
{
using namespace AzToolsFramework::Thumbnailer;
using namespace LyIntegration;
ThumbnailerRequestsBus::Broadcast(
&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(Thumbnails::MaterialThumbnailCache),
ThumbnailContext::DefaultContext);
AZ::TickBus::QueueFunction([this](){
m_materialBrowserInteractions.reset(aznew MaterialBrowserInteractions);
m_previewRenderer.reset(aznew AtomToolsFramework::PreviewRenderer(
"EditorMaterialSystemComponent Preview Scene", "EditorMaterialSystemComponent Preview Pipeline"));
});
}
void EditorMaterialSystemComponent::TeardownThumbnails()
void EditorMaterialSystemComponent::OnApplicationAboutToStop()
{
using namespace AzToolsFramework::Thumbnailer;
using namespace LyIntegration;
ThumbnailerRequestsBus::Broadcast(
&ThumbnailerRequests::UnregisterThumbnailProvider, Thumbnails::MaterialThumbnailCache::ProviderName,
ThumbnailContext::DefaultContext);
m_previewRenderer.reset();
m_materialBrowserInteractions.reset();
}
AzToolsFramework::AssetBrowser::SourceFileDetails EditorMaterialSystemComponent::GetSourceFileDetails(
@@ -7,29 +7,31 @@
*/
#pragma once
#include <AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentRequestBus.h>
#include <AtomToolsFramework/PreviewRenderer/PreviewRenderer.h>
#include <AzCore/Asset/AssetCommon.h>
#include <AzCore/Component/Component.h>
#include <AzFramework/Application/Application.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
#include <AzToolsFramework/Thumbnails/Thumbnail.h>
#include <AzToolsFramework/Viewport/ActionBus.h>
#include <AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentRequestBus.h>
#include <Material/MaterialBrowserInteractions.h>
#include <QPixmap>
namespace AZ
{
namespace Render
{
//! System component that manages launching and maintaining connections with the material editor.
class EditorMaterialSystemComponent
class EditorMaterialSystemComponent final
: public AZ::Component
, private EditorMaterialSystemComponentRequestBus::Handler
, private AzFramework::ApplicationLifecycleEvents::Bus::Handler
, private AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler
, private AzToolsFramework::EditorMenuNotificationBus::Handler
, private AzToolsFramework::EditorEvents::Bus::Handler
, public EditorMaterialSystemComponentNotificationBus::Handler
, public EditorMaterialSystemComponentRequestBus::Handler
, public AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler
, public AzToolsFramework::EditorMenuNotificationBus::Handler
, public AzToolsFramework::EditorEvents::Bus::Handler
, public AzFramework::AssetCatalogEventBus::Handler
, public AzFramework::ApplicationLifecycleEvents::Bus::Handler
{
public:
AZ_COMPONENT(EditorMaterialSystemComponent, "{96652157-DA0B-420F-B49C-0207C585144C}");
@@ -38,7 +40,6 @@ namespace AZ
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
protected:
@@ -51,9 +52,13 @@ namespace AZ
//! EditorMaterialSystemComponentRequestBus::Handler overrides...
void OpenMaterialEditor(const AZStd::string& sourcePath) override;
void OpenMaterialInspector(const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId) override;
void RenderMaterialPreview(const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId) override;
QPixmap GetRenderedMaterialPreview(
const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId) const override;
// AzFramework::ApplicationLifecycleEvents overrides...
void OnApplicationAboutToStop() override;
//! EditorMaterialSystemComponentNotificationBus::Handler overrides...
void OnRenderMaterialPreviewComplete(
const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId, const QPixmap& pixmap)override;
//! AssetBrowserInteractionNotificationBus::Handler overrides...
AzToolsFramework::AssetBrowser::SourceFileDetails GetSourceFileDetails(const char* fullSourceFileName) override;
@@ -65,12 +70,17 @@ namespace AZ
// AztoolsFramework::EditorEvents::Bus::Handler overrides...
void NotifyRegisterViews() override;
void SetupThumbnails();
void TeardownThumbnails();
// AzFramework::AssetCatalogEventBus::Handler overrides ...
void OnCatalogLoaded(const char* catalogFile) override;
// AzFramework::ApplicationLifecycleEvents overrides...
void OnApplicationAboutToStop() override;
QAction* m_openMaterialEditorAction = nullptr;
AZStd::unique_ptr<MaterialBrowserInteractions> m_materialBrowserInteractions;
AZStd::unique_ptr<AtomToolsFramework::PreviewRenderer> m_previewRenderer;
AZStd::unordered_map<AZ::EntityId, AZStd::unordered_map<AZ::Render::MaterialAssignmentId, QPixmap>> m_materialPreviews;
};
} // namespace Render
} // namespace AZ
@@ -1,112 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <QtConcurrent/QtConcurrent>
#include <Source/Material/MaterialThumbnail.h>
#include <Source/Thumbnails/ThumbnailUtils.h>
namespace AZ
{
namespace LyIntegration
{
namespace Thumbnails
{
static constexpr const int MaterialThumbnailSize = 512; // 512 is the default size in render to texture pass
//////////////////////////////////////////////////////////////////////////
// MaterialThumbnail
//////////////////////////////////////////////////////////////////////////
MaterialThumbnail::MaterialThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey key)
: Thumbnail(key)
{
m_assetId = GetAssetId(key, RPI::MaterialAsset::RTTI_Type());
if (!m_assetId.IsValid())
{
AZ_Error("MaterialThumbnail", false, "Failed to find matching assetId for the thumbnailKey.");
m_state = State::Failed;
return;
}
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Handler::BusConnect(key);
AzFramework::AssetCatalogEventBus::Handler::BusConnect();
}
void MaterialThumbnail::LoadThread()
{
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::QueueEvent(
RPI::MaterialAsset::RTTI_Type(),
&AzToolsFramework::Thumbnailer::ThumbnailerRendererRequests::RenderThumbnail,
m_key,
MaterialThumbnailSize);
// wait for response from thumbnail renderer
m_renderWait.acquire();
}
MaterialThumbnail::~MaterialThumbnail()
{
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Handler::BusDisconnect();
AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
}
void MaterialThumbnail::ThumbnailRendered(const QPixmap& thumbnailImage)
{
m_pixmap = thumbnailImage;
m_renderWait.release();
}
void MaterialThumbnail::ThumbnailFailedToRender()
{
m_state = State::Failed;
m_renderWait.release();
}
void MaterialThumbnail::OnCatalogAssetChanged([[maybe_unused]] const AZ::Data::AssetId& assetId)
{
if (m_assetId == assetId &&
m_state == State::Ready)
{
m_state = State::Unloaded;
Load();
}
}
//////////////////////////////////////////////////////////////////////////
// MaterialThumbnailCache
//////////////////////////////////////////////////////////////////////////
MaterialThumbnailCache::MaterialThumbnailCache()
: ThumbnailCache<MaterialThumbnail>()
{
}
MaterialThumbnailCache::~MaterialThumbnailCache() = default;
int MaterialThumbnailCache::GetPriority() const
{
// Material thumbnails override default source thumbnails, so carry higher priority
return 1;
}
const char* MaterialThumbnailCache::GetProviderName() const
{
return ProviderName;
}
bool MaterialThumbnailCache::IsSupportedThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey key) const
{
return
GetAssetId(key, RPI::MaterialAsset::RTTI_Type()).IsValid() &&
// in case it's a source scene file, it will contain both material and model products
// model thumbnails are handled by MeshThumbnail
!GetAssetId(key, RPI::ModelAsset::RTTI_Type()).IsValid();
}
} // namespace Thumbnails
} // namespace LyIntegration
} // namespace AZ
#include <Material/moc_MaterialThumbnail.cpp>
@@ -1,73 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#if !defined(Q_MOC_RUN)
#include <AzCore/std/parallel/binary_semaphore.h>
#include <AzFramework/Asset/AssetCatalogBus.h>
#include <AzToolsFramework/Thumbnails/Thumbnail.h>
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
#include <Thumbnails/Rendering/CommonThumbnailRenderer.h>
#endif
namespace AZ
{
namespace LyIntegration
{
namespace Thumbnails
{
/**
* Custom material or model thumbnail that detects when an asset changes and updates the thumbnail
*/
class MaterialThumbnail
: public AzToolsFramework::Thumbnailer::Thumbnail
, public AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Handler
, private AzFramework::AssetCatalogEventBus::Handler
{
Q_OBJECT
public:
MaterialThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey key);
~MaterialThumbnail() override;
//! AzToolsFramework::ThumbnailerRendererNotificationBus::Handler overrides...
void ThumbnailRendered(const QPixmap& thumbnailImage) override;
void ThumbnailFailedToRender() override;
protected:
void LoadThread() override;
private:
// AzFramework::AssetCatalogEventBus::Handler interface overrides...
void OnCatalogAssetChanged(const AZ::Data::AssetId& assetId) override;
AZStd::binary_semaphore m_renderWait;
Data::AssetId m_assetId;
};
/**
* Cache configuration for large material thumbnails
*/
class MaterialThumbnailCache
: public AzToolsFramework::Thumbnailer::ThumbnailCache<MaterialThumbnail>
{
public:
MaterialThumbnailCache();
~MaterialThumbnailCache() override;
int GetPriority() const override;
const char* GetProviderName() const override;
static constexpr const char* ProviderName = "Material Thumbnails";
protected:
bool IsSupportedThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey key) const override;
};
} // namespace Thumbnails
} // namespace LyIntegration
} // namespace AZ
@@ -6,13 +6,10 @@
*
*/
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/EditContextConstants.inl>
#include <AzCore/Utils/Utils.h>
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
#include <Source/Mesh/EditorMeshSystemComponent.h>
#include <Source/Mesh/MeshThumbnail.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <Mesh/EditorMeshSystemComponent.h>
namespace AZ
{
@@ -47,11 +44,6 @@ namespace AZ
incompatible.push_back(AZ_CRC_CE("EditorMeshSystem"));
}
void EditorMeshSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
{
required.push_back(AZ_CRC_CE("ThumbnailerService"));
}
void EditorMeshSystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
{
AZ_UNUSED(dependent);
@@ -59,39 +51,10 @@ namespace AZ
void EditorMeshSystemComponent::Activate()
{
AzFramework::ApplicationLifecycleEvents::Bus::Handler::BusConnect();
SetupThumbnails();
}
void EditorMeshSystemComponent::Deactivate()
{
TeardownThumbnails();
AzFramework::ApplicationLifecycleEvents::Bus::Handler::BusDisconnect();
}
void EditorMeshSystemComponent::OnApplicationAboutToStop()
{
TeardownThumbnails();
}
void EditorMeshSystemComponent::SetupThumbnails()
{
using namespace AzToolsFramework::Thumbnailer;
using namespace LyIntegration;
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider,
MAKE_TCACHE(Thumbnails::MeshThumbnailCache),
ThumbnailContext::DefaultContext);
}
void EditorMeshSystemComponent::TeardownThumbnails()
{
using namespace AzToolsFramework::Thumbnailer;
using namespace LyIntegration;
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::UnregisterThumbnailProvider,
Thumbnails::MeshThumbnailCache::ProviderName,
ThumbnailContext::DefaultContext);
}
} // namespace Render
} // namespace AZ
@@ -8,7 +8,6 @@
#pragma once
#include <AzCore/Component/Component.h>
#include <AzFramework/Application/Application.h>
namespace AZ
{
@@ -17,7 +16,6 @@ namespace AZ
//! System component that sets up necessary logic related to EditorMeshComponent.
class EditorMeshSystemComponent
: public AZ::Component
, private AzFramework::ApplicationLifecycleEvents::Bus::Handler
{
public:
AZ_COMPONENT(EditorMeshSystemComponent, "{4D332E3D-C4FC-410B-A915-8E234CBDD4EC}");
@@ -26,20 +24,12 @@ namespace AZ
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
protected:
// AZ::Component interface overrides...
void Activate() override;
void Deactivate() override;
private:
// AzFramework::ApplicationLifecycleEvents overrides...
void OnApplicationAboutToStop() override;
void SetupThumbnails();
void TeardownThumbnails();
};
} // namespace Render
} // namespace AZ
@@ -1,109 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <Atom/RPI.Reflect/Model/ModelAsset.h>
#include <QtConcurrent/QtConcurrent>
#include <Source/Mesh/MeshThumbnail.h>
#include <Source/Thumbnails/ThumbnailUtils.h>
namespace AZ
{
namespace LyIntegration
{
namespace Thumbnails
{
static constexpr const int MeshThumbnailSize = 512; // 512 is the default size in render to texture pass
//////////////////////////////////////////////////////////////////////////
// MeshThumbnail
//////////////////////////////////////////////////////////////////////////
MeshThumbnail::MeshThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey key)
: Thumbnail(key)
{
m_assetId = GetAssetId(key, RPI::ModelAsset::RTTI_Type());
if (!m_assetId.IsValid())
{
AZ_Error("MeshThumbnail", false, "Failed to find matching assetId for the thumbnailKey.");
m_state = State::Failed;
return;
}
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Handler::BusConnect(key);
AzFramework::AssetCatalogEventBus::Handler::BusConnect();
}
void MeshThumbnail::LoadThread()
{
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::QueueEvent(
RPI::ModelAsset::RTTI_Type(),
&AzToolsFramework::Thumbnailer::ThumbnailerRendererRequests::RenderThumbnail,
m_key,
MeshThumbnailSize);
// wait for response from thumbnail renderer
m_renderWait.acquire();
}
MeshThumbnail::~MeshThumbnail()
{
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Handler::BusDisconnect();
AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
}
void MeshThumbnail::ThumbnailRendered(const QPixmap& thumbnailImage)
{
m_pixmap = thumbnailImage;
m_renderWait.release();
}
void MeshThumbnail::ThumbnailFailedToRender()
{
m_state = State::Failed;
m_renderWait.release();
}
void MeshThumbnail::OnCatalogAssetChanged([[maybe_unused]] const AZ::Data::AssetId& assetId)
{
if (m_assetId == assetId &&
m_state == State::Ready)
{
m_state = State::Unloaded;
Load();
}
}
//////////////////////////////////////////////////////////////////////////
// MeshThumbnailCache
//////////////////////////////////////////////////////////////////////////
MeshThumbnailCache::MeshThumbnailCache()
: ThumbnailCache<MeshThumbnail>()
{
}
MeshThumbnailCache::~MeshThumbnailCache() = default;
int MeshThumbnailCache::GetPriority() const
{
// Material thumbnails override default source thumbnails, so carry higher priority
return 1;
}
const char* MeshThumbnailCache::GetProviderName() const
{
return ProviderName;
}
bool MeshThumbnailCache::IsSupportedThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey key) const
{
return GetAssetId(key, RPI::ModelAsset::RTTI_Type()).IsValid();
}
} // namespace Thumbnails
} // namespace LyIntegration
} // namespace AZ
#include <Mesh/moc_MeshThumbnail.cpp>
@@ -1,72 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#if !defined(Q_MOC_RUN)
#include <AzCore/std/parallel/binary_semaphore.h>
#include <AzFramework/Asset/AssetCatalogBus.h>
#include <AzToolsFramework/Thumbnails/Thumbnail.h>
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
#endif
namespace AZ
{
namespace LyIntegration
{
namespace Thumbnails
{
/**
* Custom material or model thumbnail that detects when an asset changes and updates the thumbnail
*/
class MeshThumbnail
: public AzToolsFramework::Thumbnailer::Thumbnail
, public AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Handler
, private AzFramework::AssetCatalogEventBus::Handler
{
Q_OBJECT
public:
MeshThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey key);
~MeshThumbnail() override;
//! AzToolsFramework::ThumbnailerRendererNotificationBus::Handler overrides...
void ThumbnailRendered(const QPixmap& thumbnailImage) override;
void ThumbnailFailedToRender() override;
protected:
void LoadThread() override;
private:
// AzFramework::AssetCatalogEventBus::Handler interface overrides...
void OnCatalogAssetChanged(const AZ::Data::AssetId& assetId) override;
AZStd::binary_semaphore m_renderWait;
Data::AssetId m_assetId;
};
/**
* Cache configuration for large material thumbnails
*/
class MeshThumbnailCache
: public AzToolsFramework::Thumbnailer::ThumbnailCache<MeshThumbnail>
{
public:
MeshThumbnailCache();
~MeshThumbnailCache() override;
int GetPriority() const override;
const char* GetProviderName() const override;
static constexpr const char* ProviderName = "Mesh Thumbnails";
protected:
bool IsSupportedThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey key) const override;
};
} // namespace Thumbnails
} // namespace LyIntegration
} // namespace AZ
@@ -0,0 +1,173 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <Atom/Feature/ImageBasedLights/ImageBasedLightFeatureProcessorInterface.h>
#include <Atom/Feature/PostProcess/PostProcessFeatureProcessorInterface.h>
#include <Atom/Feature/SkyBox/SkyBoxFeatureProcessorInterface.h>
#include <Atom/Feature/Utils/LightingPreset.h>
#include <Atom/RPI.Public/Scene.h>
#include <Atom/RPI.Reflect/Asset/AssetUtils.h>
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentBus.h>
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentConstants.h>
#include <AtomLyIntegration/CommonFeatures/Mesh/MeshComponentBus.h>
#include <AtomLyIntegration/CommonFeatures/Mesh/MeshComponentConstants.h>
#include <AzCore/Asset/AssetCommon.h>
#include <AzCore/Component/Entity.h>
#include <AzCore/Component/TransformBus.h>
#include <AzCore/Math/MatrixUtils.h>
#include <AzCore/Math/Transform.h>
#include <AzFramework/Components/TransformComponent.h>
#include <AzFramework/Entity/EntityContextBus.h>
#include <SharedPreview/SharedPreviewContent.h>
namespace AZ
{
namespace LyIntegration
{
SharedPreviewContent::SharedPreviewContent(
RPI::ScenePtr scene,
RPI::ViewPtr view,
AZ::Uuid entityContextId,
const Data::AssetId& modelAssetId,
const Data::AssetId& materialAssetId,
const Data::AssetId& lightingPresetAssetId,
const Render::MaterialPropertyOverrideMap& materialPropertyOverrides)
: m_scene(scene)
, m_view(view)
, m_entityContextId(entityContextId)
, m_materialPropertyOverrides(materialPropertyOverrides)
{
// Create preview model
AzFramework::EntityContextRequestBus::EventResult(
m_modelEntity, m_entityContextId, &AzFramework::EntityContextRequestBus::Events::CreateEntity, "SharedPreviewContentModel");
m_modelEntity->CreateComponent(Render::MeshComponentTypeId);
m_modelEntity->CreateComponent(Render::MaterialComponentTypeId);
m_modelEntity->CreateComponent(azrtti_typeid<AzFramework::TransformComponent>());
m_modelEntity->Init();
m_modelEntity->Activate();
m_modelAsset.Create(modelAssetId);
m_materialAsset.Create(materialAssetId);
m_lightingPresetAsset.Create(lightingPresetAssetId);
}
SharedPreviewContent::~SharedPreviewContent()
{
if (m_modelEntity)
{
m_modelEntity->Deactivate();
AzFramework::EntityContextRequestBus::Event(
m_entityContextId, &AzFramework::EntityContextRequestBus::Events::DestroyEntity, m_modelEntity);
m_modelEntity = nullptr;
}
}
void SharedPreviewContent::Load()
{
m_modelAsset.QueueLoad();
m_materialAsset.QueueLoad();
m_lightingPresetAsset.QueueLoad();
}
bool SharedPreviewContent::IsReady() const
{
return (!m_modelAsset.GetId().IsValid() || m_modelAsset.IsReady()) &&
(!m_materialAsset.GetId().IsValid() || m_materialAsset.IsReady()) &&
(!m_lightingPresetAsset.GetId().IsValid() || m_lightingPresetAsset.IsReady());
}
bool SharedPreviewContent::IsError() const
{
return m_modelAsset.IsError() || m_materialAsset.IsError() || m_lightingPresetAsset.IsError();
}
void SharedPreviewContent::ReportErrors()
{
AZ_Warning(
"SharedPreviewContent", !m_modelAsset.GetId().IsValid() || m_modelAsset.IsReady(), "Asset failed to load in time: %s",
m_modelAsset.ToString<AZStd::string>().c_str());
AZ_Warning(
"SharedPreviewContent", !m_materialAsset.GetId().IsValid() || m_materialAsset.IsReady(), "Asset failed to load in time: %s",
m_materialAsset.ToString<AZStd::string>().c_str());
AZ_Warning(
"SharedPreviewContent", !m_lightingPresetAsset.GetId().IsValid() || m_lightingPresetAsset.IsReady(),
"Asset failed to load in time: %s", m_lightingPresetAsset.ToString<AZStd::string>().c_str());
}
void SharedPreviewContent::Update()
{
UpdateModel();
UpdateLighting();
UpdateCamera();
}
void SharedPreviewContent::UpdateModel()
{
Render::MeshComponentRequestBus::Event(
m_modelEntity->GetId(), &Render::MeshComponentRequestBus::Events::SetModelAsset, m_modelAsset);
Render::MaterialComponentRequestBus::Event(
m_modelEntity->GetId(), &Render::MaterialComponentRequestBus::Events::SetMaterialOverride,
Render::DefaultMaterialAssignmentId, m_materialAsset.GetId());
Render::MaterialComponentRequestBus::Event(
m_modelEntity->GetId(), &Render::MaterialComponentRequestBus::Events::SetPropertyOverrides,
Render::DefaultMaterialAssignmentId, m_materialPropertyOverrides);
}
void SharedPreviewContent::UpdateLighting()
{
if (m_lightingPresetAsset.IsReady())
{
auto preset = m_lightingPresetAsset->GetDataAs<Render::LightingPreset>();
if (preset)
{
auto iblFeatureProcessor = m_scene->GetFeatureProcessor<Render::ImageBasedLightFeatureProcessorInterface>();
auto postProcessFeatureProcessor = m_scene->GetFeatureProcessor<Render::PostProcessFeatureProcessorInterface>();
auto postProcessSettingInterface = postProcessFeatureProcessor->GetOrCreateSettingsInterface(EntityId());
auto exposureControlSettingInterface = postProcessSettingInterface->GetOrCreateExposureControlSettingsInterface();
auto directionalLightFeatureProcessor =
m_scene->GetFeatureProcessor<Render::DirectionalLightFeatureProcessorInterface>();
auto skyboxFeatureProcessor = m_scene->GetFeatureProcessor<Render::SkyBoxFeatureProcessorInterface>();
skyboxFeatureProcessor->Enable(true);
skyboxFeatureProcessor->SetSkyboxMode(Render::SkyBoxMode::Cubemap);
Camera::Configuration cameraConfig;
cameraConfig.m_fovRadians = FieldOfView;
cameraConfig.m_nearClipDistance = NearDist;
cameraConfig.m_farClipDistance = FarDist;
cameraConfig.m_frustumWidth = 100.0f;
cameraConfig.m_frustumHeight = 100.0f;
AZStd::vector<Render::DirectionalLightFeatureProcessorInterface::LightHandle> lightHandles;
preset->ApplyLightingPreset(
iblFeatureProcessor, skyboxFeatureProcessor, exposureControlSettingInterface, directionalLightFeatureProcessor,
cameraConfig, lightHandles);
}
}
}
void SharedPreviewContent::UpdateCamera()
{
// Get bounding sphere of the model asset and estimate how far the camera needs to be see all of it
Vector3 center = {};
float radius = {};
if (m_modelAsset.IsReady())
{
m_modelAsset->GetAabb().GetAsSphere(center, radius);
}
const auto distance = radius + NearDist;
const auto cameraRotation = Quaternion::CreateFromAxisAngle(Vector3::CreateAxisZ(), CameraRotationAngle);
const auto cameraPosition = center + cameraRotation.TransformVector(Vector3(0.0f, distance, 0.0f));
const auto cameraTransform = Transform::CreateLookAt(cameraPosition, center);
m_view->SetCameraTransform(Matrix3x4::CreateFromTransform(cameraTransform));
}
} // namespace LyIntegration
} // namespace AZ
@@ -0,0 +1,67 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <Atom/Feature/Material/MaterialAssignment.h>
#include <Atom/RPI.Public/Base.h>
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
#include <Atom/RPI.Reflect/Model/ModelAsset.h>
#include <Atom/RPI.Reflect/System/AnyAsset.h>
#include <AtomToolsFramework/PreviewRenderer/PreviewContent.h>
namespace AZ
{
namespace LyIntegration
{
//! Creates a simple scene used for most previews and thumbnails
class SharedPreviewContent final : public AtomToolsFramework::PreviewContent
{
public:
AZ_CLASS_ALLOCATOR(SharedPreviewContent, AZ::SystemAllocator, 0);
SharedPreviewContent(
RPI::ScenePtr scene,
RPI::ViewPtr view,
AZ::Uuid entityContextId,
const Data::AssetId& modelAssetId,
const Data::AssetId& materialAssetId,
const Data::AssetId& lightingPresetAssetId,
const Render::MaterialPropertyOverrideMap& materialPropertyOverrides);
~SharedPreviewContent() override;
void Load() override;
bool IsReady() const override;
bool IsError() const override;
void ReportErrors() override;
void Update() override;
private:
void UpdateModel();
void UpdateLighting();
void UpdateCamera();
static constexpr float AspectRatio = 1.0f;
static constexpr float NearDist = 0.001f;
static constexpr float FarDist = 100.0f;
static constexpr float FieldOfView = Constants::HalfPi;
static constexpr float CameraRotationAngle = Constants::QuarterPi / 2.0f;
RPI::ScenePtr m_scene;
RPI::ViewPtr m_view;
AZ::Uuid m_entityContextId;
Entity* m_modelEntity = nullptr;
Data::Asset<RPI::ModelAsset> m_modelAsset;
Data::Asset<RPI::MaterialAsset> m_materialAsset;
Data::Asset<RPI::AnyAsset> m_lightingPresetAsset;
Render::MaterialPropertyOverrideMap m_materialPropertyOverrides;
};
} // namespace LyIntegration
} // namespace AZ
@@ -11,37 +11,42 @@
#include <AssetBrowser/Thumbnails/SourceThumbnail.h>
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
#include <Atom/RPI.Reflect/Model/ModelAsset.h>
#include <Thumbnails/ThumbnailUtils.h>
#include <Atom/RPI.Reflect/System/AnyAsset.h>
#include <SharedPreview/SharedPreviewUtils.h>
namespace AZ
{
namespace LyIntegration
{
namespace Thumbnails
namespace SharedPreviewUtils
{
Data::AssetId GetAssetId(AzToolsFramework::Thumbnailer::SharedThumbnailKey key, const Data::AssetType& assetType)
Data::AssetId GetAssetId(
AzToolsFramework::Thumbnailer::SharedThumbnailKey key,
const Data::AssetType& assetType,
const Data::AssetId& defaultAssetId)
{
static const Data::AssetId invalidAssetId;
// if it's a source thumbnail key, find first product with a matching asset type
auto sourceKey = azrtti_cast<const AzToolsFramework::AssetBrowser::SourceThumbnailKey*>(key.data());
if (sourceKey)
{
bool foundIt = false;
AZStd::vector<Data::AssetInfo> productsAssetInfo;
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(foundIt, &AzToolsFramework::AssetSystemRequestBus::Events::GetAssetsProducedBySourceUUID, sourceKey->GetSourceUuid(), productsAssetInfo);
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
foundIt, &AzToolsFramework::AssetSystemRequestBus::Events::GetAssetsProducedBySourceUUID,
sourceKey->GetSourceUuid(), productsAssetInfo);
if (!foundIt)
{
return invalidAssetId;
return defaultAssetId;
}
auto assetInfoIt = AZStd::find_if(productsAssetInfo.begin(), productsAssetInfo.end(),
auto assetInfoIt = AZStd::find_if(
productsAssetInfo.begin(), productsAssetInfo.end(),
[&assetType](const Data::AssetInfo& assetInfo)
{
return assetInfo.m_assetType == assetType;
});
if (assetInfoIt == productsAssetInfo.end())
{
return invalidAssetId;
return defaultAssetId;
}
return assetInfoIt->m_assetId;
@@ -53,10 +58,9 @@ namespace AZ
{
return productKey->GetAssetId();
}
return invalidAssetId;
return defaultAssetId;
}
QString WordWrap(const QString& string, int maxLength)
{
QString result;
@@ -81,6 +85,32 @@ namespace AZ
}
return result;
}
} // namespace Thumbnails
AZStd::unordered_set<AZ::Uuid> GetSupportedAssetTypes()
{
return { RPI::AnyAsset::RTTI_Type(), RPI::MaterialAsset::RTTI_Type(), RPI::ModelAsset::RTTI_Type() };
}
bool IsSupportedAssetType(AzToolsFramework::Thumbnailer::SharedThumbnailKey key)
{
for (const AZ::Uuid& typeId : SharedPreviewUtils::GetSupportedAssetTypes())
{
const AZ::Data::AssetId& assetId = SharedPreviewUtils::GetAssetId(key, typeId);
if (assetId.IsValid())
{
if (typeId == RPI::AnyAsset::RTTI_Type())
{
AZ::Data::AssetInfo assetInfo;
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
assetInfo, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetInfoById, assetId);
return AzFramework::StringFunc::EndsWith(assetInfo.m_relativePath.c_str(), "lightingpreset.azasset");
}
return true;
}
}
return false;
}
} // namespace SharedPreviewUtils
} // namespace LyIntegration
} // namespace AZ
@@ -18,13 +18,23 @@ namespace AZ
{
namespace LyIntegration
{
namespace Thumbnails
namespace SharedPreviewUtils
{
//! Get assetId by assetType that belongs to either source or product thumbnail key
Data::AssetId GetAssetId(AzToolsFramework::Thumbnailer::SharedThumbnailKey key, const Data::AssetType& assetType);
Data::AssetId GetAssetId(
AzToolsFramework::Thumbnailer::SharedThumbnailKey key,
const Data::AssetType& assetType,
const Data::AssetId& defaultAssetId = {});
//! Word wrap function for previewer QLabel, since by default it does not break long words such as filenames, so manual word wrap needed
//! Word wrap function for previewer QLabel, since by default it does not break long words such as filenames, so manual word
//! wrap needed
QString WordWrap(const QString& string, int maxLength);
} // namespace Thumbnails
//! Get the set of all asset types supported by the shared preview
AZStd::unordered_set<AZ::Uuid> GetSupportedAssetTypes();
//! Determine if a thumbnail key has an asset supported by the shared preview
bool IsSupportedAssetType(AzToolsFramework::Thumbnailer::SharedThumbnailKey key);
} // namespace SharedPreviewUtils
} // namespace LyIntegration
} // namespace AZ
@@ -7,23 +7,21 @@
*/
#include <AzCore/IO/FileIO.h>
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <AzToolsFramework/Thumbnails/Thumbnail.h>
#include <Source/Thumbnails/Preview/CommonPreviewer.h>
#include <Source/Thumbnails/ThumbnailUtils.h>
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
#include <SharedPreview/SharedPreviewUtils.h>
#include <SharedPreview/SharedPreviewer.h>
// Disables warning messages triggered by the Qt library
// 4251: class needs to have dll-interface to be used by clients of class
// 4251: class needs to have dll-interface to be used by clients of class
// 4800: forcing value to bool 'true' or 'false' (performance warning)
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option")
#include <Source/Thumbnails/Preview/ui_CommonPreviewer.h>
#include <QString>
#include <QResizeEvent>
#include <QString>
#include <SharedPreview/ui_SharedPreviewer.h>
AZ_POP_DISABLE_WARNING
namespace AZ
@@ -32,18 +30,22 @@ namespace AZ
{
static constexpr int CharWidth = 6;
CommonPreviewer::CommonPreviewer(QWidget* parent)
SharedPreviewer::SharedPreviewer(QWidget* parent)
: Previewer(parent)
, m_ui(new Ui::CommonPreviewerClass())
, m_ui(new Ui::SharedPreviewerClass())
{
m_ui->setupUi(this);
}
CommonPreviewer::~CommonPreviewer()
SharedPreviewer::~SharedPreviewer()
{
}
void CommonPreviewer::Display(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry)
void SharedPreviewer::Clear() const
{
}
void SharedPreviewer::Display(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry)
{
using namespace AzToolsFramework::AssetBrowser;
using namespace AzToolsFramework::Thumbnailer;
@@ -54,23 +56,23 @@ namespace AZ
UpdateFileInfo();
}
const QString& CommonPreviewer::GetName() const
const QString& SharedPreviewer::GetName() const
{
return m_name;
}
void CommonPreviewer::resizeEvent([[maybe_unused]] QResizeEvent* event)
void SharedPreviewer::resizeEvent([[maybe_unused]] QResizeEvent* event)
{
m_ui->m_previewWidget->setMaximumHeight(m_ui->m_previewWidget->width());
UpdateFileInfo();
}
void CommonPreviewer::UpdateFileInfo() const
void SharedPreviewer::UpdateFileInfo() const
{
m_ui->m_fileInfoLabel->setText(Thumbnails::WordWrap(m_fileInfo, m_ui->m_fileInfoLabel->width() / CharWidth));
m_ui->m_fileInfoLabel->setText(SharedPreviewUtils::WordWrap(m_fileInfo, m_ui->m_fileInfoLabel->width() / CharWidth));
}
} // namespace LyIntegration
} // namespace AZ
#include <Source/Thumbnails/Preview/moc_CommonPreviewer.cpp>
#include <SharedPreview/moc_SharedPreviewer.cpp>
@@ -5,22 +5,23 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#if !defined(Q_MOC_RUN)
#include <AzCore/Memory/SystemAllocator.h>
#include <AzCore/Asset/AssetCommon.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzToolsFramework/AssetBrowser/Previewer/Previewer.h>
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT
#include <QWidget>
#include <QScopedPointer>
#include <QWidget>
AZ_POP_DISABLE_WARNING
#endif
namespace Ui
{
class CommonPreviewerClass;
class SharedPreviewerClass;
}
namespace AzToolsFramework
@@ -30,8 +31,8 @@ namespace AzToolsFramework
class ProductAssetBrowserEntry;
class SourceAssetBrowserEntry;
class AssetBrowserEntry;
}
}
} // namespace AssetBrowser
} // namespace AzToolsFramework
class QResizeEvent;
@@ -39,18 +40,17 @@ namespace AZ
{
namespace LyIntegration
{
class CommonPreviewer final
: public AzToolsFramework::AssetBrowser::Previewer
class SharedPreviewer final : public AzToolsFramework::AssetBrowser::Previewer
{
Q_OBJECT
public:
AZ_CLASS_ALLOCATOR(CommonPreviewer, AZ::SystemAllocator, 0);
AZ_CLASS_ALLOCATOR(SharedPreviewer, AZ::SystemAllocator, 0);
explicit CommonPreviewer(QWidget* parent = nullptr);
~CommonPreviewer();
explicit SharedPreviewer(QWidget* parent = nullptr);
~SharedPreviewer();
// AzToolsFramework::AssetBrowser::Previewer overrides...
void Clear() const override {}
void Clear() const override;
void Display(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) override;
const QString& GetName() const override;
@@ -60,9 +60,9 @@ namespace AZ
private:
void UpdateFileInfo() const;
QScopedPointer<Ui::CommonPreviewerClass> m_ui;
QScopedPointer<Ui::SharedPreviewerClass> m_ui;
QString m_fileInfo;
QString m_name = "CommonPreviewer";
QString m_name = "SharedPreviewer";
};
} // namespace LyIntegration
} // namespace AZ
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CommonPreviewerClass</class>
<widget class="QWidget" name="CommonPreviewerClass">
<class>SharedPreviewerClass</class>
<widget class="QWidget" name="SharedPreviewerClass">
<property name="geometry">
<rect>
<x>0</x>
@@ -0,0 +1,33 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
#include <SharedPreview/SharedPreviewUtils.h>
#include <SharedPreview/SharedPreviewer.h>
#include <SharedPreview/SharedPreviewerFactory.h>
namespace AZ
{
namespace LyIntegration
{
AzToolsFramework::AssetBrowser::Previewer* SharedPreviewerFactory::CreatePreviewer(QWidget* parent) const
{
return new SharedPreviewer(parent);
}
bool SharedPreviewerFactory::IsEntrySupported(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) const
{
return SharedPreviewUtils::IsSupportedAssetType(entry->GetThumbnailKey());
}
const QString& SharedPreviewerFactory::GetName() const
{
return m_name;
}
} // namespace LyIntegration
} // namespace AZ

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