Merge branch 'upstream/development' into LYN-6770_AutomatedTestNetInputs

This commit is contained in:
Gene Walters
2021-10-15 09:30:58 -07:00
158 changed files with 3628 additions and 3419 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
@@ -71,5 +71,9 @@ class TestAutomation(EditorTestSuite):
class AtomEditorComponents_PostFXShapeWeightModifierAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_PostFxShapeWeightModifierAdded as test_module
@pytest.mark.test_case_id("C36525664")
class AtomEditorComponents_PostFXGradientWeightModifierAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_PostFXGradientWeightModifierAdded as test_module
class ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges(EditorSharedTest):
from Atom.tests import hydra_ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges as test_module
@@ -0,0 +1,179 @@
"""
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
"""
class Tests:
creation_undo = (
"UNDO Entity creation success",
"UNDO Entity creation failed")
creation_redo = (
"REDO Entity creation success",
"REDO Entity creation failed")
postfx_gradient_weight_creation = (
"PostFX Gradient Weight Modifier Entity successfully created",
"PostFX Gradient Weight Modifier Entity failed to be created")
postfx_gradient_weight_component = (
"Entity has a PostFX Gradient Weight Modifier component",
"Entity failed to find PostFX Gradient Weight Modifier component")
postfx_gradient_weight_disabled = (
"PostFX Gradient Weight Modifier component disabled",
"PostFX Gradient Weight Modifier component was not disabled.")
postfx_layer_component = (
"Entity has a PostFX Layer component",
"Entity did not have an PostFX Layer component")
postfx_gradient_weight_enabled = (
"PostFX Gradient Weight Modifier component enabled",
"PostFX Gradient Weight Modifier component was not enabled.")
enter_game_mode = (
"Entered game mode",
"Failed to enter game mode")
exit_game_mode = (
"Exited game mode",
"Couldn't exit game mode")
is_visible = (
"Entity is visible",
"Entity was not visible")
is_hidden = (
"Entity is hidden",
"Entity was not hidden")
entity_deleted = (
"Entity deleted",
"Entity was not deleted")
deletion_undo = (
"UNDO deletion success",
"UNDO deletion failed")
deletion_redo = (
"REDO deletion success",
"REDO deletion failed")
def AtomEditorComponents_PostFXGradientWeightModifier_AddedToEntity():
"""
Summary:
Tests the PostFX Gradient Weight Modifier component can be added to an entity and has the expected functionality.
Test setup:
- Wait for Editor idle loop.
- Open the "Base" level.
Expected Behavior:
The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
Creation and deletion undo/redo should also work.
Test Steps:
1) Create a PostFX Gradient Weight Modifier entity with no components.
2) Add a PostFX Gradient Weight Modifier component to PostFX Gradient Weight Modifier entity.
3) UNDO the entity creation and component addition.
4) REDO the entity creation and component addition.
5) Verify PostFX Gradient Weight Modifier component not enabled.
6) Add PostFX Layer component since it is required by the PostFX Gradient Weight Modifier component.
7) Verify PostFX Gradient Weight Modifier component is enabled.
8) Enter/Exit game mode.
9) Test IsHidden.
10) Test IsVisible.
11) Delete PostFX Gradient Weight Modifier entity.
12) UNDO deletion.
13) REDO deletion.
14) Look for errors.
:return: None
"""
import azlmbr.legacy.general as general
from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.utils import Report, Tracer, TestHelper
with Tracer() as error_tracer:
# Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle()
TestHelper.open_level("", "Base")
# Test steps begin.
# 1. Create a PostFX Gradient Weight Modifier entity with no components.
postfx_gradient_weight_name = "PostFX Gradient Weight Modifier"
postfx_gradient_weight_entity = EditorEntity.create_editor_entity(postfx_gradient_weight_name)
Report.critical_result(Tests.postfx_gradient_weight_creation, postfx_gradient_weight_entity.exists())
# 2. Add a PostFX Gradient Weight Modifier component to PostFX Gradient Weight Modifier entity.
postfx_gradient_weight_component = postfx_gradient_weight_entity.add_component(postfx_gradient_weight_name)
Report.critical_result(
Tests.postfx_gradient_weight_component,
postfx_gradient_weight_entity.has_component(postfx_gradient_weight_name))
# 3. UNDO the entity creation and component addition.
# -> UNDO component addition.
general.undo()
# -> UNDO naming entity.
general.undo()
# -> UNDO selecting entity.
general.undo()
# -> UNDO entity creation.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.creation_undo, not postfx_gradient_weight_entity.exists())
# 4. REDO the entity creation and component addition.
# -> REDO entity creation.
general.redo()
# -> REDO selecting entity.
general.redo()
# -> REDO naming entity.
general.redo()
# -> REDO component addition.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.creation_redo, postfx_gradient_weight_entity.exists())
# 5. Verify PostFX Gradient Weight Modifier component not enabled.
Report.result(Tests.postfx_gradient_weight_disabled, not postfx_gradient_weight_component.is_enabled())
# 6. Add PostFX Layer component since it is required by the PostFX Gradient Weight Modifier component.
postfx_layer_name = "PostFX Layer"
postfx_gradient_weight_entity.add_component(postfx_layer_name)
Report.result(Tests.postfx_layer_component, postfx_gradient_weight_entity.has_component(postfx_layer_name))
# 7. Verify PostFX Gradient Weight Modifier component is enabled.
Report.result(Tests.postfx_gradient_weight_enabled, postfx_gradient_weight_component.is_enabled())
# 8. Enter/Exit game mode.
TestHelper.enter_game_mode(Tests.enter_game_mode)
general.idle_wait_frames(1)
TestHelper.exit_game_mode(Tests.exit_game_mode)
# 9. Test IsHidden.
postfx_gradient_weight_entity.set_visibility_state(False)
Report.result(Tests.is_hidden, postfx_gradient_weight_entity.is_hidden() is True)
# 10. Test IsVisible.
postfx_gradient_weight_entity.set_visibility_state(True)
general.idle_wait_frames(1)
Report.result(Tests.is_visible, postfx_gradient_weight_entity.is_visible() is True)
# 11. Delete PostFX Gradient Weight Modifier entity.
postfx_gradient_weight_entity.delete()
Report.result(Tests.entity_deleted, not postfx_gradient_weight_entity.exists())
# 12. UNDO deletion.
general.undo()
Report.result(Tests.deletion_undo, postfx_gradient_weight_entity.exists())
# 13. REDO deletion.
general.redo()
Report.result(Tests.deletion_redo, not postfx_gradient_weight_entity.exists())
# 14. Look for errors or asserts.
TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
for error_info in error_tracer.errors:
Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
for assert_info in error_tracer.asserts:
Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(AtomEditorComponents_PostFXGradientWeightModifier_AddedToEntity)
+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;
@@ -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;
@@ -736,7 +736,10 @@ namespace UnitTest
auto& assetManager = AssetManager::Instance();
AssetBusCallbacks callbacks{};
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
callbacks.SetOnAssetReadyCallback([&, AssetNoRefB](const Asset<AssetData>&, AssetBusCallbacks&)
AZ_POP_DISABLE_WARNING
{
// This callback should run inside the "main thread" dispatch events loop
auto loadAsset = assetManager.GetAsset<AssetWithSerializedData>(AZ::Uuid(AssetNoRefB), AssetLoadBehavior::Default);
@@ -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)
@@ -109,7 +109,10 @@ namespace AZ::Debug
AZStd::thread threads[totalThreads];
for (size_t threadIndex = 0; threadIndex < totalThreads; ++threadIndex)
{
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
threads[threadIndex] = AZStd::thread([&startLogging, &messages]()
AZ_POP_DISABLE_WARNING
{
while (!startLogging)
{
@@ -226,7 +229,10 @@ namespace AZ::Debug
AZStd::thread threads[totalThreads];
for (size_t threadIndex = 0; threadIndex < totalThreads; ++threadIndex)
{
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
threads[threadIndex] = AZStd::thread([&startLogging, &message, &totalRecordsWritten]()
AZ_POP_DISABLE_WARNING
{
AZ_UNUSED(message);
@@ -597,7 +597,10 @@ namespace AZ::IO
path.InitFromAbsolutePath(m_dummyFilepath);
request->CreateRead(nullptr, buffer.get(), fileSize, path, 0, fileSize);
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
auto callback = [&fileSize, this](const FileRequest& request)
AZ_POP_DISABLE_WARNING
{
EXPECT_EQ(request.GetStatus(), AZ::IO::IStreamerTypes::RequestStatus::Completed);
auto& readRequest = AZStd::get<AZ::IO::FileRequest::ReadData>(request.GetCommand());
@@ -639,7 +642,10 @@ namespace AZ::IO
path.InitFromAbsolutePath(m_dummyFilepath);
request->CreateRead(nullptr, buffer, unalignedSize + 4, path, unalignedOffset, unalignedSize);
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
auto callback = [unalignedOffset, unalignedSize, this](const FileRequest& request)
AZ_POP_DISABLE_WARNING
{
EXPECT_EQ(request.GetStatus(), AZ::IO::IStreamerTypes::RequestStatus::Completed);
auto& readRequest = AZStd::get<AZ::IO::FileRequest::ReadData>(request.GetCommand());
@@ -784,7 +790,10 @@ namespace AZ::IO
requests[i] = m_context->GetNewInternalRequest();
requests[i]->CreateRead(nullptr, buffers[i].get(), chunkSize, path, i * chunkSize, chunkSize);
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
auto callback = [chunkSize, i](const FileRequest& request)
AZ_POP_DISABLE_WARNING
{
EXPECT_EQ(request.GetStatus(), AZ::IO::IStreamerTypes::RequestStatus::Completed);
auto& readRequest = AZStd::get<AZ::IO::FileRequest::ReadData>(request.GetCommand());
@@ -970,7 +979,10 @@ namespace AZ::IO
i * chunkSize
));
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
auto callback = [numChunks, &numCallbacks, &waitForReads](FileRequestHandle request)
AZ_POP_DISABLE_WARNING
{
IStreamer* streamer = Interface<IStreamer>::Get();
if (streamer)
@@ -1038,7 +1050,10 @@ namespace AZ::IO
i * chunkSize
));
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
auto callback = [numChunks, &waitForReads, &waitForSingleRead, &numReadCallbacks]([[maybe_unused]] FileRequestHandle request)
AZ_POP_DISABLE_WARNING
{
numReadCallbacks++;
if (numReadCallbacks == 1)
@@ -1059,7 +1074,10 @@ namespace AZ::IO
for (size_t i = 0; i < numChunks; ++i)
{
cancels.push_back(m_streamer->Cancel(requests[numChunks - i - 1]));
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
auto callback = [&numCancelCallbacks, &waitForCancels, numChunks](FileRequestHandle request)
AZ_POP_DISABLE_WARNING
{
auto result = Interface<IStreamer>::Get()->GetRequestStatus(request);
EXPECT_EQ(result, IStreamerTypes::RequestStatus::Completed);
@@ -363,7 +363,10 @@ namespace AZ
{
constexpr AZStd::array visitTokens = { "Hello", "World", "", "More", "", "", "Tokens" };
size_t visitIndex{};
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
auto visitor = [&visitIndex, &visitTokens](AZStd::string_view token)
AZ_POP_DISABLE_WARNING
{
if (visitIndex > visitTokens.size())
{
@@ -389,7 +392,10 @@ namespace AZ
{
constexpr AZStd::array visitTokens = { "Hello", "World", "", "More", "", "", "Tokens" };
size_t visitIndex = visitTokens.size() - 1;
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
auto visitor = [&visitIndex, &visitTokens](AZStd::string_view token)
AZ_POP_DISABLE_WARNING
{
if (visitIndex > visitTokens.size())
{
@@ -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,11 +569,12 @@ namespace UnitTest
FillSpawnable(NumEntities);
CreateEntityReferences(refScheme);
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);
};
@@ -591,11 +592,12 @@ namespace UnitTest
FillSpawnable(NumEntities);
CreateEntityReferences(refScheme);
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);
};
@@ -720,11 +722,12 @@ namespace UnitTest
FillSpawnable(NumEntities);
CreateEntityReferences(refScheme);
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 non-google parameters
@@ -160,7 +153,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);
@@ -281,7 +273,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)
@@ -1052,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);
@@ -1323,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());
{
@@ -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(
@@ -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();
@@ -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
@@ -5,6 +5,7 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Memory/SystemAllocator.h>
@@ -18,14 +19,13 @@ namespace AZ
{
namespace LyIntegration
{
class CommonPreviewerFactory final
: public AzToolsFramework::AssetBrowser::PreviewerFactory
class SharedPreviewerFactory final : public AzToolsFramework::AssetBrowser::PreviewerFactory
{
public:
AZ_CLASS_ALLOCATOR(CommonPreviewerFactory, AZ::SystemAllocator, 0);
AZ_CLASS_ALLOCATOR(SharedPreviewerFactory, AZ::SystemAllocator, 0);
CommonPreviewerFactory() = default;
~CommonPreviewerFactory() = default;
SharedPreviewerFactory() = default;
~SharedPreviewerFactory() = default;
// AzToolsFramework::AssetBrowser::PreviewerFactory overrides...
AzToolsFramework::AssetBrowser::Previewer* CreatePreviewer(QWidget* parent = nullptr) const override;
@@ -33,7 +33,7 @@ namespace AZ
const QString& GetName() const override;
private:
QString m_name = "CommonPreviewer";
QString m_name = "SharedPreviewer";
};
} // namespace LyIntegration
} // namespace AZ

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