Merge branch 'development' of https://github.com/o3de/o3de into sc-editor-asset-redux

This commit is contained in:
chcurran
2021-10-15 11:40:38 -07:00
269 changed files with 5715 additions and 4418 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)
+10
View File
@@ -57,6 +57,7 @@ AZ_POP_DISABLE_WARNING
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzFramework/Terrain/TerrainDataRequestBus.h>
#include <AzFramework/ProjectManager/ProjectManager.h>
#include <AzFramework/Spawnable/RootSpawnableInterface.h>
// AzToolsFramework
#include <AzToolsFramework/Component/EditorComponentAPIBus.h>
@@ -3021,6 +3022,15 @@ CCryEditApp::ECreateLevelResult CCryEditApp::CreateLevel(const QString& levelNam
bool bIsDocModified = GetIEditor()->GetDocument()->IsModified();
OnSwitchPhysics();
GetIEditor()->GetDocument()->SetModifiedFlag(bIsDocModified);
if (usePrefabSystemForLevels)
{
auto* rootSpawnableInterface = AzFramework::RootSpawnableInterface::Get();
if (rootSpawnableInterface)
{
rootSpawnableInterface->ProcessSpawnableQueue();
}
}
}
const QScopedValueRollback<bool> rollback(m_creatingNewLevel);
+3
View File
@@ -264,6 +264,9 @@ void EditorPreferencesDialog::SetFilter(const QString& filter)
else if (m_currentPageItem)
{
m_currentPageItem->UpdateEditorFilter(ui->propertyEditor, m_filter);
// Refresh the Stylesheet - when using search functionality.
AzQtComponents::StyleManager::repolishStyleSheet(this);
}
}
+12 -10
View File
@@ -14,6 +14,7 @@
// Editor
#include "Settings.h"
#include "EditorViewportSettings.h"
@@ -43,17 +44,16 @@ void CEditorPreferencesPage_Files::Reflect(AZ::SerializeContext& serialize)
->Field("MaxCount", &AutoBackup::m_maxCount)
->Field("RemindTime", &AutoBackup::m_remindTime);
serialize.Class<AssetBrowserSearch>()
serialize.Class<AssetBrowserSettings>()
->Version(1)
->Field("Max number of items displayed", &AssetBrowserSearch::m_maxNumberOfItemsShownInSearch);
->Field("MaxEntriesShownCount", &AssetBrowserSettings::m_maxNumberOfItemsShownInSearch);
serialize.Class<CEditorPreferencesPage_Files>()
->Version(1)
->Field("Files", &CEditorPreferencesPage_Files::m_files)
->Field("Editors", &CEditorPreferencesPage_Files::m_editors)
->Field("AutoBackup", &CEditorPreferencesPage_Files::m_autoBackup)
->Field("AssetBrowserSearch", &CEditorPreferencesPage_Files::m_assetBrowserSearch);
->Field("AssetBrowserSettings", &CEditorPreferencesPage_Files::m_assetBrowserSettings);
AZ::EditContext* editContext = serialize.GetEditContext();
if (editContext)
@@ -85,9 +85,10 @@ void CEditorPreferencesPage_Files::Reflect(AZ::SerializeContext& serialize)
->Attribute(AZ::Edit::Attributes::Max, 100)
->DataElement(AZ::Edit::UIHandlers::SpinBox, &AutoBackup::m_remindTime, "Remind Time", "Auto Remind Every (Minutes)");
editContext->Class<AssetBrowserSearch>("Asset Browser Search View", "Asset Browser Search View")
->DataElement(AZ::Edit::UIHandlers::SpinBox, &AssetBrowserSearch::m_maxNumberOfItemsShownInSearch, "Maximum number of displayed items",
"Maximum number of displayed items displayed in the Search View")
editContext->Class<AssetBrowserSettings>("Asset Browser Settings", "Asset Browser Settings")
->DataElement(
AZ::Edit::UIHandlers::SpinBox, &AssetBrowserSettings::m_maxNumberOfItemsShownInSearch, "Maximum number of displayed items",
"Maximum number of items to display in the Search View.")
->Attribute(AZ::Edit::Attributes::Min, 50)
->Attribute(AZ::Edit::Attributes::Max, 5000);
@@ -97,7 +98,7 @@ void CEditorPreferencesPage_Files::Reflect(AZ::SerializeContext& serialize)
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_Files::m_files, "Files", "File Preferences")
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_Files::m_editors, "External Editors", "External Editors")
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_Files::m_autoBackup, "Auto Backup", "Auto Backup")
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_Files::m_assetBrowserSearch, "Asset Browser Search", "Asset Browser Search");
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_Files::m_assetBrowserSettings, "Asset Browser Settings","Asset Browser Settings");
}
}
@@ -117,6 +118,7 @@ QIcon& CEditorPreferencesPage_Files::GetIcon()
void CEditorPreferencesPage_Files::OnApply()
{
using namespace AzToolsFramework::SliceUtilities;
auto sliceSettings = AZ::UserSettings::CreateFind<SliceUserSettings>(AZ_CRC("SliceUserSettings", 0x055b32eb), AZ::UserSettings::CT_LOCAL);
sliceSettings->m_autoNumber = m_files.m_autoNumberSlices;
sliceSettings->m_saveLocation = m_files.m_saveLocation;
@@ -137,7 +139,7 @@ void CEditorPreferencesPage_Files::OnApply()
gSettings.autoBackupMaxCount = m_autoBackup.m_maxCount;
gSettings.autoRemindTime = m_autoBackup.m_remindTime;
gSettings.maxNumberOfItemsShownInSearch = m_assetBrowserSearch.m_maxNumberOfItemsShownInSearch;
SandboxEditor::SetMaxItemsShownInAssetBrowserSearch(m_assetBrowserSettings.m_maxNumberOfItemsShownInSearch);
}
void CEditorPreferencesPage_Files::InitializeSettings()
@@ -163,5 +165,5 @@ void CEditorPreferencesPage_Files::InitializeSettings()
m_autoBackup.m_maxCount = gSettings.autoBackupMaxCount;
m_autoBackup.m_remindTime = gSettings.autoRemindTime;
m_assetBrowserSearch.m_maxNumberOfItemsShownInSearch = gSettings.maxNumberOfItemsShownInSearch;
m_assetBrowserSettings.m_maxNumberOfItemsShownInSearch = SandboxEditor::MaxItemsShownInAssetBrowserSearch();
}
+4 -7
View File
@@ -69,18 +69,15 @@ private:
int m_remindTime;
};
struct AssetBrowserSearch
struct AssetBrowserSettings
{
AZ_TYPE_INFO(AssetBrowserSearch, "{9FBFCD24-9452-49DF-99F4-2711443CEAAE}")
int m_maxNumberOfItemsShownInSearch;
AZ_TYPE_INFO(AssetBrowserSettings, "{5F407EC4-BBD1-4A87-92DB-D938D7127BB0}")
AZ::u64 m_maxNumberOfItemsShownInSearch;
};
Files m_files;
ExternalEditors m_editors;
AutoBackup m_autoBackup;
AssetBrowserSearch m_assetBrowserSearch;
AssetBrowserSettings m_assetBrowserSettings;
QIcon m_icon;
};
+11
View File
@@ -15,6 +15,7 @@
namespace SandboxEditor
{
constexpr AZStd::string_view AssetBrowserMaxItemsShownInSearchSetting = "/Amazon/Preferences/Editor/AssetBrowser/MaxItemsShowInSearch";
constexpr AZStd::string_view GridSnappingSetting = "/Amazon/Preferences/Editor/GridSnapping";
constexpr AZStd::string_view GridSizeSetting = "/Amazon/Preferences/Editor/GridSize";
constexpr AZStd::string_view AngleSnappingSetting = "/Amazon/Preferences/Editor/AngleSnapping";
@@ -110,6 +111,16 @@ namespace SandboxEditor
return AZStd::make_unique<EditorViewportSettingsCallbacksImpl>();
}
AZ::u64 MaxItemsShownInAssetBrowserSearch()
{
return GetRegistry(AssetBrowserMaxItemsShownInSearchSetting, aznumeric_cast<AZ::u64>(50));
}
void SetMaxItemsShownInAssetBrowserSearch(const AZ::u64 numberOfItemsShown)
{
SetRegistry(AssetBrowserMaxItemsShownInSearchSetting, numberOfItemsShown);
}
bool GridSnappingEnabled()
{
return GetRegistry(GridSnappingSetting, false);
+3
View File
@@ -32,6 +32,9 @@ namespace SandboxEditor
//! event will fire when a value in the settings registry (editorpreferences.setreg) is modified.
SANDBOX_API AZStd::unique_ptr<EditorViewportSettingsCallbacks> CreateEditorViewportSettingsCallbacks();
SANDBOX_API AZ::u64 MaxItemsShownInAssetBrowserSearch();
SANDBOX_API void SetMaxItemsShownInAssetBrowserSearch(AZ::u64 numberOfItemsShown);
SANDBOX_API bool GridSnappingEnabled();
SANDBOX_API void SetGridSnapping(bool enabled);
-35
View File
@@ -108,15 +108,11 @@ CObjectManager::CObjectManager()
m_objectsByName.reserve(1024);
LoadRegistry();
AzToolsFramework::ViewportEditorModeNotificationsBus::Handler::BusConnect(AzToolsFramework::GetEntityContextId());
}
//////////////////////////////////////////////////////////////////////////
CObjectManager::~CObjectManager()
{
AzToolsFramework::ViewportEditorModeNotificationsBus::Handler::BusDisconnect();
m_bExiting = true;
SaveRegistry();
DeleteAllObjects();
@@ -2307,37 +2303,6 @@ void CObjectManager::SelectObjectInRect(CBaseObject* pObj, CViewport* view, HitC
}
}
void CObjectManager::OnEditorModeActivated(
[[maybe_unused]] const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode)
{
if (mode == AzToolsFramework::ViewportEditorMode::Component)
{
// hide current gizmo for entity (translate/rotate/scale)
IGizmoManager* gizmoManager = GetGizmoManager();
const size_t gizmoCount = static_cast<size_t>(gizmoManager->GetGizmoCount());
for (size_t i = 0; i < gizmoCount; ++i)
{
gizmoManager->RemoveGizmo(gizmoManager->GetGizmoByIndex(static_cast<int>(i)));
}
}
}
void CObjectManager::OnEditorModeDeactivated(
[[maybe_unused]] const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode)
{
if (mode == AzToolsFramework::ViewportEditorMode::Component)
{
// show translate/rotate/scale gizmo again
if (IGizmoManager* gizmoManager = GetGizmoManager())
{
if (CBaseObject* selectedObject = GetIEditor()->GetSelectedObject())
{
gizmoManager->AddGizmo(new CAxisGizmo(selectedObject));
}
}
}
}
//////////////////////////////////////////////////////////////////////////
namespace
{
-8
View File
@@ -20,7 +20,6 @@
#include "ObjectManagerEventBus.h"
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <AzToolsFramework/API/ViewportEditorModeTrackerNotificationBus.h>
#include <AzCore/EBus/EBus.h>
#include <AzCore/Component/Component.h>
#include <Include/SandboxAPI.h>
@@ -59,7 +58,6 @@ public:
*/
class CObjectManager
: public IObjectManager
, private AzToolsFramework::ViewportEditorModeNotificationsBus::Handler
{
public:
//! Selection functor callback.
@@ -330,12 +328,6 @@ private:
void FindDisplayableObjects(DisplayContext& dc, bool bDisplay);
// ViewportEditorModeNotificationsBus overrides ...
void OnEditorModeActivated(
const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode) override;
void OnEditorModeDeactivated(
const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode) override;
private:
typedef std::map<GUID, CBaseObjectPtr, guid_less_predicate> Objects;
Objects m_objects;
+3 -4
View File
@@ -10,6 +10,7 @@
#include "EditorDefs.h"
#include "Settings.h"
#include "EditorViewportSettings.h"
// Qt
#include <QGuiApplication>
@@ -487,7 +488,6 @@ void SEditorSettings::Save()
SaveValue("Settings", "AutoBackupTime", autoBackupTime);
SaveValue("Settings", "AutoBackupMaxCount", autoBackupMaxCount);
SaveValue("Settings", "AutoRemindTime", autoRemindTime);
SaveValue("Settings", "MaxDisplayedItemsNumInSearch", maxNumberOfItemsShownInSearch);
SaveValue("Settings", "CameraMoveSpeed", cameraMoveSpeed);
SaveValue("Settings", "CameraRotateSpeed", cameraRotateSpeed);
SaveValue("Settings", "StylusMode", stylusMode);
@@ -682,7 +682,6 @@ void SEditorSettings::Load()
LoadValue("Settings", "AutoBackupTime", autoBackupTime);
LoadValue("Settings", "AutoBackupMaxCount", autoBackupMaxCount);
LoadValue("Settings", "AutoRemindTime", autoRemindTime);
LoadValue("Settings", "MaxDisplayedItemsNumInSearch", maxNumberOfItemsShownInSearch);
LoadValue("Settings", "CameraMoveSpeed", cameraMoveSpeed);
LoadValue("Settings", "CameraRotateSpeed", cameraRotateSpeed);
LoadValue("Settings", "StylusMode", stylusMode);
@@ -1174,7 +1173,7 @@ AzToolsFramework::ConsoleColorTheme SEditorSettings::GetConsoleColorTheme() cons
return consoleBackgroundColorTheme;
}
int SEditorSettings::GetMaxNumberOfItemsShownInSearchView() const
AZ::u64 SEditorSettings::GetMaxNumberOfItemsShownInSearchView() const
{
return SEditorSettings::maxNumberOfItemsShownInSearch;
return SandboxEditor::MaxItemsShownInAssetBrowserSearch();
}
+1 -9
View File
@@ -279,7 +279,7 @@ AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
SettingOutcome GetValue(const AZStd::string_view path) override;
SettingOutcome SetValue(const AZStd::string_view path, const AZStd::any& value) override;
AzToolsFramework::ConsoleColorTheme GetConsoleColorTheme() const override;
int GetMaxNumberOfItemsShownInSearchView() const override;
AZ::u64 GetMaxNumberOfItemsShownInSearchView() const override;
void ConvertPath(const AZStd::string_view sourcePath, AZStd::string& category, AZStd::string& attribute);
@@ -353,14 +353,6 @@ AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
int autoRemindTime;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// Asset Browser Search View.
//////////////////////////////////////////////////////////////////////////
//! Current maximum number of items that can be displayed in the AssetBrowser Search View.
int maxNumberOfItemsShownInSearch;
//////////////////////////////////////////////////////////////////////////
//! If true preview windows is displayed when browsing geometries.
bool bPreviewGeometryWindow;
+2 -2
View File
@@ -1195,7 +1195,7 @@ bool CFileUtil::IsFileExclusivelyAccessable(const QString& strFilePath)
//////////////////////////////////////////////////////////////////////////
bool CFileUtil::CreatePath(const QString& strPath)
{
#if defined(AZ_PLATFORM_MAC)
#if !AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS
bool pathCreated = true;
QString cleanPath = QDir::cleanPath(strPath);
@@ -1252,7 +1252,7 @@ bool CFileUtil::CreatePath(const QString& strPath)
}
return true;
#endif
#endif // !AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS
}
//////////////////////////////////////////////////////////////////////////
@@ -225,8 +225,16 @@ namespace AZ
ConsoleCommandContainer commandSubset;
for (ConsoleFunctorBase* curr = m_head; curr != nullptr; curr = curr->m_next)
for (const auto& functor : m_commands)
{
if (functor.second.empty())
{
continue;
}
// Filter functors registered with the same name
const ConsoleFunctorBase* curr = functor.second.front();
if ((curr->GetFlags() & ConsoleFunctorFlags::IsInvisible) == ConsoleFunctorFlags::IsInvisible)
{
// Filter functors marked as invisible
@@ -236,7 +244,12 @@ namespace AZ
if (StringFunc::StartsWith(curr->m_name, command, false))
{
AZLOG_INFO("- %s : %s\n", curr->m_name, curr->m_desc);
commandSubset.push_back(curr->m_name);
if (commandSubset.size() < MaxConsoleCommandPlusArgsLength)
{
commandSubset.push_back(curr->m_name);
}
if (matches)
{
matches->push_back(curr->m_name);
@@ -271,7 +284,10 @@ namespace AZ
{
for (auto& curr : m_commands)
{
visitor(curr.second.front());
if (!curr.second.empty())
{
visitor(curr.second.front());
}
}
}
@@ -336,6 +352,11 @@ namespace AZ
{
iter->second.erase(iter2);
}
if (iter->second.empty())
{
m_commands.erase(iter);
}
}
functor->Unlink(m_head);
functor->m_console = nullptr;
@@ -15,7 +15,7 @@ using namespace Intersect;
// IntersectSegmentTriangleCCW
// [10/21/2009]
//=========================================================================
int Intersect::IntersectSegmentTriangleCCW(
bool Intersect::IntersectSegmentTriangleCCW(
const Vector3& p, const Vector3& q, const Vector3& a, const Vector3& b, const Vector3& c,
/*float &u, float &v, float &w,*/ Vector3& normal, float& t)
{
@@ -34,7 +34,7 @@ int Intersect::IntersectSegmentTriangleCCW(
float d = qp.Dot(normal);
if (d <= 0.0f)
{
return 0;
return false;
}
// Compute intersection t value of pq with plane of triangle. A ray
@@ -46,7 +46,7 @@ int Intersect::IntersectSegmentTriangleCCW(
// range segment check t[0,1] (it this case [0,d])
if (t < 0.0f || t > d)
{
return 0;
return false;
}
// Compute barycentric coordinate components and test if within bounds
@@ -54,12 +54,12 @@ int Intersect::IntersectSegmentTriangleCCW(
v = ac.Dot(e);
if (v < 0.0f || v > d)
{
return 0;
return false;
}
w = -ab.Dot(e);
if (w < 0.0f || v + w > d)
{
return 0;
return false;
}
// Segment/ray intersects triangle. Perform delayed division and
@@ -72,14 +72,14 @@ int Intersect::IntersectSegmentTriangleCCW(
normal.Normalize();
return 1;
return true;
}
//=========================================================================
// IntersectSegmentTriangle
// [10/21/2009]
//=========================================================================
int
bool
Intersect::IntersectSegmentTriangle(
const Vector3& p, const Vector3& q, const Vector3& a, const Vector3& b, const Vector3& c,
/*float &u, float &v, float &w,*/ Vector3& normal, float& t)
@@ -111,7 +111,7 @@ Intersect::IntersectSegmentTriangle(
// so either have a parallel ray or our normal is flipped
if (d >= -Constants::FloatEpsilon)
{
return 0; // parallel
return false; // parallel
}
d = -d;
e = ap.Cross(qp);
@@ -125,19 +125,19 @@ Intersect::IntersectSegmentTriangle(
// range segment check t[0,1] (it this case [0,d])
if (t < 0.0f || t > d)
{
return 0;
return false;
}
// Compute barycentric coordinate components and test if within bounds
v = ac.Dot(e);
if (v < 0.0f || v > d)
{
return 0;
return false;
}
w = -ab.Dot(e);
if (w < 0.0f || v + w > d)
{
return 0;
return false;
}
// Segment/ray intersects the triangle. Perform delayed division and
@@ -150,14 +150,14 @@ Intersect::IntersectSegmentTriangle(
normal.Normalize();
return 1;
return true;
}
//=========================================================================
// TestSegmentAABBOrigin
// [10/21/2009]
//=========================================================================
int
bool
AZ::Intersect::TestSegmentAABBOrigin(const Vector3& midPoint, const Vector3& halfVector, const Vector3& aabbExtends)
{
const Vector3 EPSILON(0.001f); // \todo this is slow load move to a const
@@ -168,7 +168,7 @@ AZ::Intersect::TestSegmentAABBOrigin(const Vector3& midPoint, const Vector3& hal
// Try world coordinate axes as separating axes
if (!absMidpoint.IsLessEqualThan(absHalfMidpoint))
{
return 0;
return false;
}
// Add in an epsilon term to counteract arithmetic errors when segment is
@@ -188,11 +188,11 @@ AZ::Intersect::TestSegmentAABBOrigin(const Vector3& midPoint, const Vector3& hal
Vector3 ead(ey * adz + ez * ady, ex * adz + ez * adx, ex * ady + ey * adx);
if (!absMDCross.IsLessEqualThan(ead))
{
return 0;
return false;
}
// No separating axis found; segment must be overlapping AABB
return 1;
return true;
}
@@ -200,7 +200,7 @@ AZ::Intersect::TestSegmentAABBOrigin(const Vector3& midPoint, const Vector3& hal
// IntersectRayAABB
// [10/21/2009]
//=========================================================================
int
RayAABBIsectTypes
AZ::Intersect::IntersectRayAABB(
const Vector3& rayStart, const Vector3& dir, const Vector3& dirRCP, const Aabb& aabb,
float& tStart, float& tEnd, Vector3& startNormal /*, Vector3& inter*/)
@@ -356,7 +356,7 @@ AZ::Intersect::IntersectRayAABB(
// IntersectRayAABB2
// [2/18/2011]
//=========================================================================
int
RayAABBIsectTypes
AZ::Intersect::IntersectRayAABB2(const Vector3& rayStart, const Vector3& dirRCP, const Aabb& aabb, float& start, float& end)
{
float tmin, tmax, tymin, tymax, tzmin, tzmax;
@@ -408,7 +408,7 @@ AZ::Intersect::IntersectRayAABB2(const Vector3& rayStart, const Vector3& dirRCP,
return ISECT_RAY_AABB_ISECT;
}
int AZ::Intersect::IntersectRayDisk(
bool AZ::Intersect::IntersectRayDisk(
const Vector3& rayOrigin, const Vector3& rayDir, const Vector3& diskCenter, const float diskRadius, const Vector3& diskNormal, float& t)
{
// First intersect with the plane of the disk
@@ -421,10 +421,10 @@ int AZ::Intersect::IntersectRayDisk(
if (pointOnPlane.GetDistance(diskCenter) < diskRadius)
{
t = planeIntersectionDistance;
return 1;
return true;
}
}
return 0;
return false;
}
// Reference: Real-Time Collision Detection - 5.3.7 Intersecting Ray or Segment Against Cylinder, and the book's errata.
@@ -1012,7 +1012,7 @@ int AZ::Intersect::IntersectRayQuad(
}
// reference: Real-Time Collision Detection, 5.3.3 Intersecting Ray or Segment Against Box
int AZ::Intersect::IntersectRayBox(
bool AZ::Intersect::IntersectRayBox(
const Vector3& rayOrigin, const Vector3& rayDir, const Vector3& boxCenter, const Vector3& boxAxis1,
const Vector3& boxAxis2, const Vector3& boxAxis3, float boxHalfExtent1, float boxHalfExtent2, float boxHalfExtent3, float& t)
{
@@ -1044,7 +1044,7 @@ int AZ::Intersect::IntersectRayBox(
// If the ray is parallel to the slab and the ray origin is outside, return no intersection.
if (tp < 0.0f || tn < 0.0f)
{
return 0;
return false;
}
}
else
@@ -1065,7 +1065,7 @@ int AZ::Intersect::IntersectRayBox(
tmax = AZ::GetMin(tmax, t2);
if (tmin > tmax)
{
return 0;
return false;
}
}
@@ -1085,7 +1085,7 @@ int AZ::Intersect::IntersectRayBox(
// If the ray is parallel to the slab and the ray origin is outside, return no intersection.
if (tp < 0.0f || tn < 0.0f)
{
return 0;
return false;
}
}
else
@@ -1106,7 +1106,7 @@ int AZ::Intersect::IntersectRayBox(
tmax = AZ::GetMin(tmax, t2);
if (tmin > tmax)
{
return 0;
return false;
}
}
@@ -1126,7 +1126,7 @@ int AZ::Intersect::IntersectRayBox(
// If the ray is parallel to the slab and the ray origin is outside, return no intersection.
if (tp < 0.0f || tn < 0.0f)
{
return 0;
return false;
}
}
else
@@ -1147,15 +1147,15 @@ int AZ::Intersect::IntersectRayBox(
tmax = AZ::GetMin(tmax, t2);
if (tmin > tmax)
{
return 0;
return false;
}
}
t = (isRayOriginInsideBox ? tmax : tmin);
return 1;
return true;
}
int AZ::Intersect::IntersectRayObb(const Vector3& rayOrigin, const Vector3& rayDir, const Obb& obb, float& t)
bool AZ::Intersect::IntersectRayObb(const Vector3& rayOrigin, const Vector3& rayDir, const Obb& obb, float& t)
{
return AZ::Intersect::IntersectRayBox(rayOrigin, rayDir, obb.GetPosition(),
obb.GetAxisX(), obb.GetAxisY(), obb.GetAxisZ(),
@@ -1166,7 +1166,7 @@ int AZ::Intersect::IntersectRayObb(const Vector3& rayOrigin, const Vector3& rayD
// IntersectSegmentCylinder
// [10/21/2009]
//=========================================================================
int
CylinderIsectTypes
AZ::Intersect::IntersectSegmentCylinder(
const Vector3& sa, const Vector3& dir, const Vector3& p, const Vector3& q, const float r, float& t)
{
@@ -1225,7 +1225,7 @@ AZ::Intersect::IntersectSegmentCylinder(
return RR_ISECT_RAY_CYL_NONE; // No real roots; no intersection
}
t = (-b - Sqrt(discr)) / a;
int result = RR_ISECT_RAY_CYL_PQ; // default along the PQ segment
CylinderIsectTypes result = RR_ISECT_RAY_CYL_PQ; // default along the PQ segment
if (md + t * nd < 0.0f)
{
@@ -1294,7 +1294,7 @@ AZ::Intersect::IntersectSegmentCylinder(
// IntersectSegmentCapsule
// [10/21/2009]
//=========================================================================
int
CapsuleIsectTypes
AZ::Intersect::IntersectSegmentCapsule(const Vector3& sa, const Vector3& dir, const Vector3& p, const Vector3& q, const float r, float& t)
{
int result = IntersectSegmentCylinder(sa, dir, p, q, r, t);
@@ -1361,13 +1361,13 @@ AZ::Intersect::IntersectSegmentCapsule(const Vector3& sa, const Vector3& dir, co
// IntersectSegmentPolyhedron
// [10/21/2009]
//=========================================================================
int
bool
AZ::Intersect::IntersectSegmentPolyhedron(
const Vector3& sa, const Vector3& sBA, const Plane p[], int numPlanes,
const Vector3& sa, const Vector3& dir, const Plane p[], int numPlanes,
float& tfirst, float& tlast, int& iFirstPlane, int& iLastPlane)
{
// Compute direction vector for the segment
Vector3 d = /*b - a*/ sBA;
Vector3 d = /*b - a*/ dir;
// Set initial interval to being the whole segment. For a ray, tlast should be
// set to +RR_FLT_MAX. For a line, additionally tfirst should be set to -RR_FLT_MAX
tfirst = 0.0f;
@@ -1388,7 +1388,7 @@ AZ::Intersect::IntersectSegmentPolyhedron(
// If so, return "no intersection" if segment lies outside plane
if (dist < 0.0f)
{
return 0;
return false;
}
}
else
@@ -1417,7 +1417,7 @@ AZ::Intersect::IntersectSegmentPolyhedron(
// Exit with "no intersection" if intersection becomes empty
if (tfirst > tlast)
{
return 0;
return false;
}
}
}
@@ -1425,11 +1425,11 @@ AZ::Intersect::IntersectSegmentPolyhedron(
//DBG_Assert(iFirstPlane!=-1&&iLastPlane!=-1,("We have some bad border case to have only one plane, fix this function!"));
if (iFirstPlane == -1 && iLastPlane == -1)
{
return 0;
return false;
}
// A nonzero logical intersection, so the segment intersects the polyhedron
return 1;
return true;
}
//=========================================================================
@@ -1442,7 +1442,7 @@ AZ::Intersect::ClosestSegmentSegment(
const Vector3& segment2Start, const Vector3& segment2End,
float& segment1Proportion, float& segment2Proportion,
Vector3& closestPointSegment1, Vector3& closestPointSegment2,
float epsilon /*= 1e-4f*/ )
float epsilon)
{
const Vector3 segment1 = segment1End - segment1Start;
const Vector3 segment2 = segment2End - segment2Start;
@@ -5,363 +5,398 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef AZCORE_MATH_SEGMENT_INTERSECTION_H
#define AZCORE_MATH_SEGMENT_INTERSECTION_H
#pragma once
#include <AzCore/Math/Vector3.h>
#include <AzCore/Math/Aabb.h>
#include <AzCore/Math/Obb.h>
#include <AzCore/Math/Plane.h>
/// \file isect_segment.h
#include <AzCore/Math/Vector3.h>
namespace AZ
{
namespace Intersect
{
//! LineToPointDistanceTime computes the time of the shortest distance from point 'p' to segment (s1,s2).
//! To calculate the point of intersection:
//! P = s1 + u (s2 - s1)
//! @param s1 segment start point
//! @param s2 segment end point
//! @param p point to find the closest time to.
//! @return time (on the segment) for the shortest distance from 'p' to (s1,s2) [0.0f (s1),1.0f (s2)]
inline float LineToPointDistanceTime(const Vector3& s1, const Vector3& s21, const Vector3& p)
{
// so u = (p.x - s1.x)*(s2.x - s1.x) + (p.y - s1.y)*(s2.y - s1.y) + (p.z-s1.z)*(s2.z-s1.z) / |s2-s1|^2
return s21.Dot(p - s1) / s21.Dot(s21);
}
//! To calculate the point of intersection: P = s1 + u (s2 - s1)
//! @param s1 Segment start point.
//! @param s2 Segment end point.
//! @param p Point to find the closest time to.
//! @return Time (on the segment) for the shortest distance from 'p' to (s1,s2) [0.0f (s1),1.0f (s2)]
float LineToPointDistanceTime(const Vector3& s1, const Vector3& s21, const Vector3& p);
//! LineToPointDistance computes the closest point to 'p' from a segment (s1,s2).
//! @param s1 segment start point
//! @param s2 segment end point
//! @param p point to find the closest time to.
//! @param u time (on the segment) for the shortest distance from 'p' to (s1,s2) [0.0f (s1),1.0f (s2)]
//! @return the closest point
inline Vector3 LineToPointDistance(const Vector3& s1, const Vector3& s2, const Vector3& p, float& u)
{
const Vector3 s21 = s2 - s1;
// we assume seg1 and seg2 are NOT coincident
AZ_MATH_ASSERT(!s21.IsClose(Vector3(0.0f), 1e-4f), "OK we agreed that we will pass valid segments! (s1 != s2)");
u = LineToPointDistanceTime(s1, s21, p);
return s1 + u * s21;
}
//! @param s1 Segment start point
//! @param s2 Segment end point
//! @param p Point to find the closest time to.
//! @param u Time (on the segment) for the shortest distance from 'p' to (s1,s2) [0.0f (s1),1.0f (s2)]
//! @return The closest point
Vector3 LineToPointDistance(const Vector3& s1, const Vector3& s2, const Vector3& p, float& u);
//! Given segment pq and triangle abc (CCW), returns whether segment intersects
//! triangle and if so, also returns the barycentric coordinates (u,v,w)
//! of the intersection point.
//! @param p segment start point
//! @param q segment end point
//! @param a triangle point 1
//! @param b triangle point 2
//! @param c triangle point 3
//! @param normal at the intersection point.
//! @param t time of intersection along the segment [0.0 (p), 1.0 (q)]
//! @return 1 if the segment intersects the triangle otherwise 0
int IntersectSegmentTriangleCCW(
const Vector3& p, const Vector3& q, const Vector3& a, const Vector3& b, const Vector3& c,
/*float &u, float &v, float &w,*/ Vector3& normal, float& t);
//! @param p Segment start point.
//! @param q Segment end point.
//! @param a Triangle point 1.
//! @param b Triangle point 2.
//! @param c Triangle point 3.
//! @param normal At the intersection point.
//! @param t Time of intersection along the segment [0.0 (p), 1.0 (q)].
//! @return true if the segments intersects the triangle otherwise false.
bool IntersectSegmentTriangleCCW(
const Vector3& p, const Vector3& q, const Vector3& a, const Vector3& b, const Vector3& c, Vector3& normal, float& t);
//! Same as \ref IntersectSegmentTriangleCCW without respecting the triangle (a,b,c) vertex order (double sided).
int IntersectSegmentTriangle(
const Vector3& p, const Vector3& q, const Vector3& a, const Vector3& b, const Vector3& c,
/*float &u, float &v, float &w,*/ Vector3& normal, float& t);
//! @param p Segment start point.
//! @param q Segment end point.
//! @param a Triangle point 1.
//! @param b Triangle point 2.
//! @param c Triangle point 3.
//! @param normal At the intersection point.
//! @param t Time of intersection along the segment [0.0 (p), 1.0 (q)].
//! @return True if the segments intersects the triangle otherwise false.
bool IntersectSegmentTriangle(
const Vector3& p, const Vector3& q, const Vector3& a, const Vector3& b, const Vector3& c, Vector3& normal, float& t);
//! Ray aabb intersection result types.
enum RayAABBIsectTypes
enum RayAABBIsectTypes : AZ::s32
{
ISECT_RAY_AABB_NONE = 0, ///< no intersection
ISECT_RAY_AABB_SA_INSIDE, ///< the ray starts inside the aabb
ISECT_RAY_AABB_ISECT, ///< intersects along the PQ segment
ISECT_RAY_AABB_NONE = 0, ///< no intersection
ISECT_RAY_AABB_SA_INSIDE, ///< the ray starts inside the aabb
ISECT_RAY_AABB_ISECT, ///< intersects along the PQ segment
};
//! Intersect ray R(t) = rayStart + t*d against AABB a. When intersecting,
//! return intersection distance tmin and point q of intersection.
//! @param rayStart ray starting point
//! @param dir ray direction and length (dir = rayEnd - rayStart)
//! @param dirRCP 1/dir (reciprocal direction - we cache this result very often so we don't need to compute it multiple times, otherwise just use dir.GetReciprocal())
//! @param rayStart Ray starting point
//! @param dir Ray direction and length (dir = rayEnd - rayStart)
//! @param dirRCP 1/dir (reciprocal direction - we cache this result very often so we don't need to compute it multiple times,
//! otherwise just use dir.GetReciprocal())
//! @param aabb Axis aligned bounding box to intersect against
//! @param tStart time on ray of the first intersection [0,1] or 0 if the ray starts inside the aabb - check the return value
//! @param tEnd time of the of the second intersection [0,1] (it can be > 1 if intersects after the rayEnd)
//! @param startNormal normal at the start point.
//! @param tStart Time on ray of the first intersection [0,1] or 0 if the ray starts inside the aabb - check the return value
//! @param tEnd Time of the of the second intersection [0,1] (it can be > 1 if intersects after the rayEnd)
//! @param startNormal Normal at the start point.
//! @return \ref RayAABBIsectTypes
int IntersectRayAABB(
const Vector3& rayStart, const Vector3& dir, const Vector3& dirRCP, const Aabb& aabb,
float& tStart, float& tEnd, Vector3& startNormal /*, Vector3& inter*/);
RayAABBIsectTypes IntersectRayAABB(
const Vector3& rayStart,
const Vector3& dir,
const Vector3& dirRCP,
const Aabb& aabb,
float& tStart,
float& tEnd,
Vector3& startNormal);
//! Intersect ray against AABB.
//! @param rayStart ray starting point.
//! @param dir ray reciprocal direction.
//! @param rayStart Ray starting point.
//! @param dir Ray reciprocal direction.
//! @param aabb Axis aligned bounding box to intersect against.
//! @param start length on ray of the first intersection.
//! @param end length of the of the second intersection.
//! @return \ref RayAABBIsectTypes In this faster version than IntersectRayAABB we return only ISECT_RAY_AABB_NONE and ISECT_RAY_AABB_ISECT.
//! You can check yourself for that case.
int IntersectRayAABB2(
const Vector3& rayStart, const Vector3& dirRCP, const Aabb& aabb,
float& start, float& end);
//! @param start Length on ray of the first intersection.
//! @param end Length of the of the second intersection.
//! @return \ref RayAABBIsectTypes In this faster version than IntersectRayAABB we return only ISECT_RAY_AABB_NONE and
//! ISECT_RAY_AABB_ISECT. You can check yourself for that case.
RayAABBIsectTypes IntersectRayAABB2(const Vector3& rayStart, const Vector3& dirRCP, const Aabb& aabb, float& start, float& end);
//! Clip a ray to an aabb. return true if ray was clipped. The ray
//! can be inside so don't use the result if the ray intersect the box.
inline int ClipRayWithAabb(
const Aabb& aabb, Vector3& rayStart, Vector3& rayEnd, float& tClipStart, float& tClipEnd)
{
Vector3 startNormal;
float tStart, tEnd;
Vector3 dirLen = rayEnd - rayStart;
if (IntersectRayAABB(rayStart, dirLen, dirLen.GetReciprocal(), aabb, tStart, tEnd, startNormal) != ISECT_RAY_AABB_NONE)
{
// clip the ray with the box
if (tStart > 0.0f)
{
rayStart = rayStart + tStart * dirLen;
tClipStart = tStart;
}
if (tEnd < 1.0f)
{
rayEnd = rayStart + tEnd * dirLen;
tClipEnd = tEnd;
}
return 1;
}
return 0;
}
//! @param aabb Bounds to test against.
//! @param rayStart The start of the ray.
//! @param rayEnd The end of the ray.
//! @param[out] tClipStart The proportion where the ray enters the \ref Aabb.
//! @param[out] tClipEnd The proportion where the ray exits the \ref Aabb.
//! @return True if the ray was clipped, otherwise false.
bool ClipRayWithAabb(const Aabb& aabb, Vector3& rayStart, Vector3& rayEnd, float& tClipStart, float& tClipEnd);
//! Test segment and aabb where the segment is defined by midpoint
//! midPoint = (p1-p0) * 0.5f and half vector halfVector = p1 - midPoint.
//! the aabb is at the origin and defined by half extents only.
//! @return 1 if the intersect, otherwise 0.
int TestSegmentAABBOrigin(const Vector3& midPoint, const Vector3& halfVector, const Vector3& aabbExtends);
//! @param midPoint Midpoint of a line segment.
//! @param halfVector Half vector of an aabb.
//! @param aabbExtends The extends of a bounded box.
//! @return True if the segment and AABB intersect, otherwise false
bool TestSegmentAABBOrigin(const Vector3& midPoint, const Vector3& halfVector, const Vector3& aabbExtends);
//! Test if segment specified by points p0 and p1 intersects AABB. \ref TestSegmentAABBOrigin
//! @return 1 if the segment and AABB intersect, otherwise 0.
inline int TestSegmentAABB(const Vector3& p0, const Vector3& p1, const Aabb& aabb)
{
Vector3 e = aabb.GetExtents();
Vector3 d = p1 - p0;
Vector3 m = p0 + p1 - aabb.GetMin() - aabb.GetMax();
return TestSegmentAABBOrigin(m, d, e);
}
//! Test if segment specified by points p0 and p1 intersects AABB. \ref TestSegmentAABBOrigin.
//! @param p0 Segment start point.
//! @param p1 Segment end point.
//! @param aabb Bounded box to test against.
//! @return True if the segment and AABB intersect, otherwise false.
bool TestSegmentAABB(const Vector3& p0, const Vector3& p1, const Aabb& aabb);
//! Ray sphere intersection result types.
enum SphereIsectTypes
enum SphereIsectTypes : AZ::s32
{
ISECT_RAY_SPHERE_SA_INSIDE = -1, // the ray starts inside the cylinder
ISECT_RAY_SPHERE_NONE, // no intersection
ISECT_RAY_SPHERE_ISECT, // along the PQ segment
ISECT_RAY_SPHERE_SA_INSIDE = -1, //!< The ray starts inside the cylinder
ISECT_RAY_SPHERE_NONE, //!< No intersection
ISECT_RAY_SPHERE_ISECT, //!< Along the PQ segment
};
//! IntersectRaySphereOrigin
//! return time t>=0 but not limited, so if you check a segment make sure
//! t <= segmentLen
//! @param rayStart ray start point
//! t <= segmentLen.
//! @param rayStart ray start point.
//! @param rayDirNormalized ray direction normalized.
//! @param shereRadius sphere radius
//! @param shereRadius Radius of sphere at origin.
//! @param time of closest intersection [0,+INF] in relation to the normalized direction.
//! @return \ref SphereIsectTypes
AZ_INLINE int IntersectRaySphereOrigin(
const Vector3& rayStart, const Vector3& rayDirNormalized,
const float sphereRadius, float& t)
{
Vector3 m = rayStart;
float b = m.Dot(rayDirNormalized);
float c = m.Dot(m) - sphereRadius * sphereRadius;
// Exit if r's origin outside s (c > 0)and r pointing away from s (b > 0)
if (c > 0.0f && b > 0.0f)
{
return ISECT_RAY_SPHERE_NONE;
}
float discr = b * b - c;
// A negative discriminant corresponds to ray missing sphere
if (discr < 0.0f)
{
return ISECT_RAY_SPHERE_NONE;
}
// Ray now found to intersect sphere, compute smallest t value of intersection
t = -b - Sqrt(discr);
// If t is negative, ray started inside sphere so clamp t to zero
if (t < 0.0f)
{
// t = 0.0f;
return ISECT_RAY_SPHERE_SA_INSIDE; // no hit if inside
}
//q = p + t * d;
return ISECT_RAY_SPHERE_ISECT;
}
//! @return \ref SphereIsectTypes.
SphereIsectTypes IntersectRaySphereOrigin(
const Vector3& rayStart, const Vector3& rayDirNormalized, const float sphereRadius, float& t);
//! Intersect ray (rayStart,rayDirNormalized) and sphere (sphereCenter,sphereRadius) \ref IntersectRaySphereOrigin
inline int IntersectRaySphere(
const Vector3& rayStart, const Vector3& rayDirNormalized, const Vector3& sphereCenter, const float sphereRadius, float& t)
{
return IntersectRaySphereOrigin(rayStart - sphereCenter, rayDirNormalized, sphereRadius, t);
}
//! @param rayStart The start of the ray.
//! @param rayDirNormalized The direction of the ray normalized.
//! @param sphereCenter The center of the sphere.
//! @param sphereRadius Radius of the sphere.
//! @param[out] t Coefficient in the ray's explicit equation from which an
//! intersecting point is calculated as "rayOrigin + t1 * rayDir".
//! @return SphereIsectTypes
SphereIsectTypes IntersectRaySphere(
const Vector3& rayStart, const Vector3& rayDirNormalized, const Vector3& sphereCenter, const float sphereRadius, float& t);
//! @param rayOrigin The origin of the ray to test.
//! @param rayDir The direction of the ray to test. It has to be unit length.
//! @param diskCenter Center point of the disk
//! @param diskRadius Radius of the disk
//! @param diskNormal A normal perpendicular to the disk
//! @param[out] t If returning 1 (indicating a hit), this contains distance from rayOrigin along the normalized rayDir that the hit occured at.
//! @return The number of intersecting points.
int IntersectRayDisk(
const Vector3& rayOrigin, const Vector3& rayDir, const Vector3& diskCenter, const float diskRadius, const AZ::Vector3& diskNormal, float& t);
//! Intersect ray (rayStarty, rayDirNormalized) and disk (center, radius, normal)
//! @param rayOrigin The origin of the ray to test.
//! @param rayDir The direction of the ray to test. It has to be unit length.
//! @param diskCenter Center point of the disk.
//! @param diskRadius Radius of the disk.
//! @param diskNormal A normal perpendicular to the disk.
//! @param[out] t If returning 1 (indicating a hit), this contains distance from rayOrigin along the normalized rayDir
//! that the hit occured at.
//! @return False if not interesecting and true if intersecting
bool IntersectRayDisk(
const Vector3& rayOrigin,
const Vector3& rayDir,
const Vector3& diskCenter,
const float diskRadius,
const AZ::Vector3& diskNormal,
float& t);
//! If there is only one intersecting point, the coefficient is stored in \ref t1.
//! @param rayOrigin The origin of the ray to test.
//! @param rayDir The direction of the ray to test. It has to be unit length.
//! @param cylinderEnd1 The center of the circle on one end of the cylinder.
//! @param cylinderDir The direction pointing from \ref cylinderEnd1 to the other end of the cylinder. It has to be unit length.
//! @param cylinderHeight The distance between two centers of the circles on two ends of the cylinder respectively.
//! @param[out] t1 A possible coefficient in the ray's explicit equation from which an intersecting point is calculated as "rayOrigin + t1 * rayDir".
//! @param[out] t2 A possible coefficient in the ray's explicit equation from which an intersecting point is calculated as "rayOrigin + t2 * rayDir".
//! @return The number of intersecting points.
//! @param rayOrigin The origin of the ray to test.
//! @param rayDir The direction of the ray to test. It has to be unit length.
//! @param cylinderEnd1 The center of the circle on one end of the cylinder.
//! @param cylinderDir The direction pointing from \ref cylinderEnd1 to the other end of the cylinder. It has to be unit length.
//! @param cylinderHeight The distance between two centers of the circles on two ends of the cylinder respectively.
//! @param[out] t1 A possible coefficient in the ray's explicit equation from which an intersecting point is calculated as "rayOrigin + t1 * rayDir".
//! @param[out] t2 A possible coefficient in the ray's explicit equation from which an intersecting point is calculated as "rayOrigin + t2 * rayDir".
//! @return The number of intersecting points.
int IntersectRayCappedCylinder(
const Vector3& rayOrigin, const Vector3& rayDir,
const Vector3& cylinderEnd1, const Vector3& cylinderDir, float cylinderHeight, float cylinderRadius,
float& t1, float& t2);
const Vector3& rayOrigin,
const Vector3& rayDir,
const Vector3& cylinderEnd1,
const Vector3& cylinderDir,
float cylinderHeight,
float cylinderRadius,
float& t1,
float& t2);
//! If there is only one intersecting point, the coefficient is stored in \ref t1.
//! @param rayOrigin The origin of the ray to test.
//! @param rayDir The direction of the ray to test. It has to be unit length.
//! @param coneApex The apex of the cone.
//! @param coneDir The unit-length direction from the apex to the base.
//! @param coneHeight The height of the cone, from the apex to the base.
//! @param coneBaseRadius The radius of the cone base circle.
//! @param[out] t1 A possible coefficient in the ray's explicit equation from which an intersecting point is calculated as "rayOrigin + t1 * rayDir".
//! @param[out] t2 A possible coefficient in the ray's explicit equation from which an intersecting point is calculated as "rayOrigin + t2 * rayDir".
//! @return The number of intersecting points.
//! @param rayOrigin The origin of the ray to test.
//! @param rayDir The direction of the ray to test. It has to be unit length.
//! @param coneApex The apex of the cone.
//! @param coneDir The unit-length direction from the apex to the base.
//! @param coneHeight The height of the cone, from the apex to the base.
//! @param coneBaseRadius The radius of the cone base circle.
//! @param[out] t1 A possible coefficient in the ray's explicit equation from which an intersecting point is calculated as "rayOrigin + t1 * rayDir".
//! @param[out] t2 A possible coefficient in the ray's explicit equation from which an intersecting point is calculated as "rayOrigin + t2 * rayDir".
//! @return The number of intersecting points.
int IntersectRayCone(
const Vector3& rayOrigin, const Vector3& rayDir,
const Vector3& coneApex, const Vector3& coneDir, float coneHeight, float coneBaseRadius,
float& t1, float& t2);
const Vector3& rayOrigin,
const Vector3& rayDir,
const Vector3& coneApex,
const Vector3& coneDir,
float coneHeight,
float coneBaseRadius,
float& t1,
float& t2);
//! Test intersection between a ray and a plane in 3D.
//! @param rayOrigin The origin of the ray to test intersection with.
//! @param rayDir The direction of the ray to test intersection with.
//! @param planePos A point on the plane to test intersection with.
//! @param planeNormal The normal of the plane to test intersection with.
//! @param t[out] The coefficient in the ray's explicit equation from which the intersecting point is calculated as "rayOrigin + t * rayDirection".
//! @return The number of intersection point.
//! @param rayOrigin The origin of the ray to test intersection with.
//! @param rayDir The direction of the ray to test intersection with.
//! @param planePos A point on the plane to test intersection with.
//! @param planeNormal The normal of the plane to test intersection with.
//! @param[out] t The coefficient in the ray's explicit equation from which the intersecting point is calculated as "rayOrigin + t * rayDirection".
//! @return The number of intersection point.
int IntersectRayPlane(
const Vector3& rayOrigin, const Vector3& rayDir, const Vector3& planePos,
const Vector3& planeNormal, float& t);
const Vector3& rayOrigin, const Vector3& rayDir, const Vector3& planePos, const Vector3& planeNormal, float& t);
//! Test intersection between a ray and a two-sided quadrilateral defined by four points in 3D.
//! The four points that define the quadrilateral could be passed in with either counter clock-wise
//! The four points that define the quadrilateral could be passed in with either counter clock-wise
//! winding or clock-wise winding.
//! @param rayOrigin The origin of the ray to test intersection with.
//! @param rayDir The direction of the ray to test intersection with.
//! @param vertexA One of the four points that define the quadrilateral.
//! @param vertexB One of the four points that define the quadrilateral.
//! @param vertexC One of the four points that define the quadrilateral.
//! @param vertexD One of the four points that define the quadrilateral.
//! @param t[out] The coefficient in the ray's explicit equation from which the intersecting point is calculated as "rayOrigin + t * rayDirection".
//! @return The number of intersection point.
//! @param rayOrigin The origin of the ray to test intersection with.
//! @param rayDir The direction of the ray to test intersection with.
//! @param vertexA One of the four points that define the quadrilateral.
//! @param vertexB One of the four points that define the quadrilateral.
//! @param vertexC One of the four points that define the quadrilateral.
//! @param vertexD One of the four points that define the quadrilateral.
//! @param[out] t The coefficient in the ray's explicit equation from which the
//! intersecting point is calculated as "rayOrigin + t * rayDirection".
//! @return The number of intersection point.
int IntersectRayQuad(
const Vector3& rayOrigin, const Vector3& rayDir, const Vector3& vertexA,
const Vector3& vertexB, const Vector3& vertexC, const Vector3& vertexD, float& t);
const Vector3& rayOrigin,
const Vector3& rayDir,
const Vector3& vertexA,
const Vector3& vertexB,
const Vector3& vertexC,
const Vector3& vertexD,
float& t);
//! Test intersection between a ray and an oriented box in 3D.
//! @param rayOrigin The origin of the ray to test intersection with.
//! @param rayDir The direction of the ray to test intersection with.
//! @param boxCenter The position of the center of the box.
//! @param boxAxis1 An axis along one dimension of the oriented box.
//! @param boxAxis2 An axis along one dimension of the oriented box.
//! @param boxAxis3 An axis along one dimension of the oriented box.
//! @param boxHalfExtent1 The half extent of the box on the dimension of \ref boxAxis1.
//! @param boxHalfExtent2 The half extent of the box on the dimension of \ref boxAxis2.
//! @param boxHalfExtent3 The half extent of the box on the dimension of \ref boxAxis3.
//! @param t[out] The coefficient in the ray's explicit equation from which the intersecting point is calculated as "rayOrigin + t * rayDirection".
//! @return 1 if there is an intersection, 0 otherwise.
int IntersectRayBox(
const Vector3& rayOrigin, const Vector3& rayDir, const Vector3& boxCenter, const Vector3& boxAxis1,
const Vector3& boxAxis2, const Vector3& boxAxis3, float boxHalfExtent1, float boxHalfExtent2, float boxHalfExtent3,
//! Test intersection between a ray and an oriented box in 3D.
//! @param rayOrigin The origin of the ray to test intersection with.
//! @param rayDir The direction of the ray to test intersection with.
//! @param boxCenter The position of the center of the box.
//! @param boxAxis1 An axis along one dimension of the oriented box.
//! @param boxAxis2 An axis along one dimension of the oriented box.
//! @param boxAxis3 An axis along one dimension of the oriented box.
//! @param boxHalfExtent1 The half extent of the box on the dimension of \ref boxAxis1.
//! @param boxHalfExtent2 The half extent of the box on the dimension of \ref boxAxis2.
//! @param boxHalfExtent3 The half extent of the box on the dimension of \ref boxAxis3.
//! @param[out] t The coefficient in the ray's explicit equation from which the intersecting point is calculated as "rayOrigin + t * rayDirection".
//! @return true if there is an intersection, false otherwise.
bool IntersectRayBox(
const Vector3& rayOrigin,
const Vector3& rayDir,
const Vector3& boxCenter,
const Vector3& boxAxis1,
const Vector3& boxAxis2,
const Vector3& boxAxis3,
float boxHalfExtent1,
float boxHalfExtent2,
float boxHalfExtent3,
float& t);
//! Test intersection between a ray and an OBB.
//! @param rayOrigin The origin of the ray to test intersection with.
//! @param rayDir The direction of the ray to test intersection with.
//! @param obb The OBB to test for intersection with the ray.
//! @param t[out] The coefficient in the ray's explicit equation from which the intersecting point is calculated as "rayOrigin + t * rayDirection".
//! @return 1 if there is an intersection, 0 otherwise.
int IntersectRayObb(const Vector3& rayOrigin, const Vector3& rayDir, const Obb& obb, float& t);
//! @param[out] t The coefficient in the ray's explicit equation from which the intersecting point is calculated as "rayOrigin + t * rayDirection".
//! @return True if there is an intersection, false otherwise.
bool IntersectRayObb(const Vector3& rayOrigin, const Vector3& rayDir, const Obb& obb, float& t);
//! Ray cylinder intersection types.
enum CylinderIsectTypes
enum CylinderIsectTypes : AZ::s32
{
RR_ISECT_RAY_CYL_SA_INSIDE = -1, // the ray starts inside the cylinder
RR_ISECT_RAY_CYL_NONE, // no intersection
RR_ISECT_RAY_CYL_PQ, // along the PQ segment
RR_ISECT_RAY_CYL_P_SIDE, // on the P side
RR_ISECT_RAY_CYL_Q_SIDE, // on the Q side
RR_ISECT_RAY_CYL_SA_INSIDE = -1, //!< the ray starts inside the cylinder
RR_ISECT_RAY_CYL_NONE, //!< no intersection
RR_ISECT_RAY_CYL_PQ, //!< along the PQ segment
RR_ISECT_RAY_CYL_P_SIDE, //!< on the P side
RR_ISECT_RAY_CYL_Q_SIDE, //!< on the Q side
};
//! Reference: Real-Time Collision Detection - 5.3.7 Intersecting Ray or Segment Against Cylinder
//! Intersect segment S(t)=sa+t(dir), 0<=t<=1 against cylinder specified by p, q and r.
int IntersectSegmentCylinder(
const Vector3& sa, const Vector3& dir, const Vector3& p, const Vector3& q,
const float r, float& t);
//! @param sa The initial point.
//! @param dir Magnitude and direction for sa.
//! @param p Center point of side 1 cylinder.
//! @param q Center point of side 2 cylinder.
//! @param r Radius of cylinder.
//! @param[out] t Proporition along line segment.
//! @return CylinderIsectTypes
CylinderIsectTypes IntersectSegmentCylinder(
const Vector3& sa, const Vector3& dir, const Vector3& p, const Vector3& q, const float r, float& t);
//! Capsule ray intersect types.
enum CapsuleIsectTypes
{
ISECT_RAY_CAPSULE_SA_INSIDE = -1, // the ray starts inside the cylinder
ISECT_RAY_CAPSULE_NONE, // no intersection
ISECT_RAY_CAPSULE_PQ, // along the PQ segment
ISECT_RAY_CAPSULE_P_SIDE, // on the P side
ISECT_RAY_CAPSULE_Q_SIDE, // on the Q side
ISECT_RAY_CAPSULE_SA_INSIDE = -1, //!< The ray starts inside the cylinder
ISECT_RAY_CAPSULE_NONE, //!< No intersection
ISECT_RAY_CAPSULE_PQ, //!< Along the PQ segment
ISECT_RAY_CAPSULE_P_SIDE, //!< On the P side
ISECT_RAY_CAPSULE_Q_SIDE, //!< On the Q side
};
//! This is a quick implementation of segment capsule based on segment cylinder \ref IntersectSegmentCylinder
//! segment sphere intersection. We can optimize it a lot once we fix the ray
//! cylinder intersection.
int IntersectSegmentCapsule(
const Vector3& sa, const Vector3& dir, const Vector3& p,
const Vector3& q, const float r, float& t);
//! @param sa The beginning of the line segment.
//! @param dir The direction and length of the segment.
//! @param p Center point of side 1 capsule.
//! @param q Center point of side 1 capsule.
//! @param r The radius of the capsule.
//! @param[out] t Proporition along line segment.
//! @return CapsuleIsectTypes
CapsuleIsectTypes IntersectSegmentCapsule(
const Vector3& sa, const Vector3& dir, const Vector3& p, const Vector3& q, const float r, float& t);
//! Intersect segment S(t)=A+t(B-A), 0<=t<=1 against convex polyhedron specified
//! by the n halfspaces defined by the planes p[]. On exit tfirst and tlast
//! define the intersection, if any.
int IntersectSegmentPolyhedron(
const Vector3& sa, const Vector3& sBA, const Plane p[], int numPlanes,
float& tfirst, float& tlast, int& iFirstPlane, int& iLastPlane);
//! @param sa The beggining of the line segment.
//! @param dir The direction and length of the segment.
//! @param p Planes that compose a convex ponvex polyhedron.
//! @param numPlanes number of planes.
//! @param[out] tfirst Proportion along the line segment where the line enters.
//! @param[out] tlast Proportion along the line segment where the line exits.
//! @param[out] iFirstPlane The plane where the line enters.
//! @param[out] iLastPlane The plane where the line exits.
//! @return True if intersects else false.
bool IntersectSegmentPolyhedron(
const Vector3& sa,
const Vector3& dir,
const Plane p[],
int numPlanes,
float& tfirst,
float& tlast,
int& iFirstPlane,
int& iLastPlane);
//! Calculate the line segment closestPointSegment1<->closestPointSegment2 that is the shortest route between
//! two segments segment1Start<->segment1End and segment2Start<->segment2End. Also calculate the values of segment1Proportion and segment2Proportion where
//! closestPointSegment1 = segment1Start + (segment1Proportion * (segment1End - segment1Start))
//! two segments segment1Start<->segment1End and segment2Start<->segment2End. Also calculate the values of segment1Proportion and
//! segment2Proportion where closestPointSegment1 = segment1Start + (segment1Proportion * (segment1End - segment1Start))
//! closestPointSegment2 = segment2Start + (segment2Proportion * (segment2End - segment2Start))
//! If segments are parallel returns a solution.
//! @param segment1Start Start of segment 1.
//! @param segment1End End of segment 1.
//! @param segment2Start Start of segment 2.
//! @param segment2End End of segment 2.
//! @param[out] segment1Proportion The proporition along segment 1 [0..1]
//! @param[out] segment2Proportion The proporition along segment 2 [0..1]
//! @param[out] closestPointSegment1 Closest point on segment 1.
//! @param[out] closestPointSegment2 Closest point on segment 2.
//! @param epsilon The minimum square distance where a line segment can be treated as a single point.
void ClosestSegmentSegment(
const Vector3& segment1Start, const Vector3& segment1End,
const Vector3& segment2Start, const Vector3& segment2End,
float& segment1Proportion, float& segment2Proportion,
Vector3& closestPointSegment1, Vector3& closestPointSegment2,
const Vector3& segment1Start,
const Vector3& segment1End,
const Vector3& segment2Start,
const Vector3& segment2End,
float& segment1Proportion,
float& segment2Proportion,
Vector3& closestPointSegment1,
Vector3& closestPointSegment2,
float epsilon = 1e-4f);
//! Calculate the line segment closestPointSegment1<->closestPointSegment2 that is the shortest route between
//! two segments segment1Start<->segment1End and segment2Start<->segment2End.
//! If segments are parallel returns a solution.
//! @param segment1Start Start of segment 1.
//! @param segment1End End of segment 1.
//! @param segment2Start Start of segment 2.
//! @param segment2End End of segment 2.
//! @param[out] closestPointSegment1 Closest point on segment 1.
//! @param[out] closestPointSegment2 Closest point on segment 2.
//! @param epsilon The minimum square distance where a line segment can be treated as a single point.
void ClosestSegmentSegment(
const Vector3& segment1Start, const Vector3& segment1End,
const Vector3& segment2Start, const Vector3& segment2End,
Vector3& closestPointSegment1, Vector3& closestPointSegment2,
const Vector3& segment1Start,
const Vector3& segment1End,
const Vector3& segment2Start,
const Vector3& segment2End,
Vector3& closestPointSegment1,
Vector3& closestPointSegment2,
float epsilon = 1e-4f);
//! Calculate the point (closestPointOnSegment) that is the closest point on
//! segment segmentStart/segmentEnd to point. Also calculate the value of proportion where
//! closestPointOnSegment = segmentStart + (proportion * (segmentEnd - segmentStart))
//! @param point The point to test
//! @param segmentStart The start of the segment
//! @param segmentEnd The end of the segment
//! @param[out] proportion The proportion of the segment L(t) = (end - start) * t
//! @param[out] closestPointOnSegment The point along the line segment
void ClosestPointSegment(
const Vector3& point, const Vector3& segmentStart, const Vector3& segmentEnd,
float& proportion, Vector3& closestPointOnSegment);
}
}
const Vector3& point,
const Vector3& segmentStart,
const Vector3& segmentEnd,
float& proportion,
Vector3& closestPointOnSegment);
} // namespace Intersect
} // namespace AZ
#endif // AZCORE_MATH_SEGMENT_INTERSECTION_H
#pragma once
#include <AzCore/Math/IntersectSegment.inl>
@@ -0,0 +1,101 @@
/*
* 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
*
*/
namespace AZ
{
namespace Intersect
{
AZ_MATH_INLINE bool ClipRayWithAabb(const Aabb& aabb, Vector3& rayStart, Vector3& rayEnd, float& tClipStart, float& tClipEnd)
{
Vector3 startNormal;
float tStart, tEnd;
Vector3 dirLen = rayEnd - rayStart;
if (IntersectRayAABB(rayStart, dirLen, dirLen.GetReciprocal(), aabb, tStart, tEnd, startNormal) != ISECT_RAY_AABB_NONE)
{
// clip the ray with the box
if (tStart > 0.0f)
{
rayStart = rayStart + tStart * dirLen;
tClipStart = tStart;
}
if (tEnd < 1.0f)
{
rayEnd = rayStart + tEnd * dirLen;
tClipEnd = tEnd;
}
return true;
}
return false;
}
AZ_MATH_INLINE SphereIsectTypes
IntersectRaySphereOrigin(const Vector3& rayStart, const Vector3& rayDirNormalized, const float sphereRadius, float& t)
{
Vector3 m = rayStart;
float b = m.Dot(rayDirNormalized);
float c = m.Dot(m) - sphereRadius * sphereRadius;
// Exit if r's origin outside s (c > 0)and r pointing away from s (b > 0)
if (c > 0.0f && b > 0.0f)
{
return ISECT_RAY_SPHERE_NONE;
}
float discr = b * b - c;
// A negative discriminant corresponds to ray missing sphere
if (discr < 0.0f)
{
return ISECT_RAY_SPHERE_NONE;
}
// Ray now found to intersect sphere, compute smallest t value of intersection
t = -b - Sqrt(discr);
// If t is negative, ray started inside sphere so clamp t to zero
if (t < 0.0f)
{
// t = 0.0f;
return ISECT_RAY_SPHERE_SA_INSIDE; // no hit if inside
}
// q = p + t * d;
return ISECT_RAY_SPHERE_ISECT;
}
AZ_MATH_INLINE SphereIsectTypes IntersectRaySphere(const Vector3& rayStart, const Vector3& rayDirNormalized, const Vector3& sphereCenter, const float sphereRadius, float& t)
{
return IntersectRaySphereOrigin(rayStart - sphereCenter, rayDirNormalized, sphereRadius, t);
}
AZ_MATH_INLINE Vector3 LineToPointDistance(const Vector3& s1, const Vector3& s2, const Vector3& p, float& u)
{
const Vector3 s21 = s2 - s1;
// we assume seg1 and seg2 are NOT coincident
AZ_MATH_ASSERT(!s21.IsClose(Vector3(0.0f), 1e-4f), "OK we agreed that we will pass valid segments! (s1 != s2)");
u = LineToPointDistanceTime(s1, s21, p);
return s1 + u * s21;
}
AZ_MATH_INLINE float LineToPointDistanceTime(const Vector3& s1, const Vector3& s21, const Vector3& p)
{
// so u = (p.x - s1.x)*(s2.x - s1.x) + (p.y - s1.y)*(s2.y - s1.y) + (p.z-s1.z)*(s2.z-s1.z) / |s2-s1|^2
return s21.Dot(p - s1) / s21.Dot(s21);
}
AZ_MATH_INLINE bool TestSegmentAABB(const Vector3& p0, const Vector3& p1, const Aabb& aabb)
{
Vector3 e = aabb.GetExtents();
Vector3 d = p1 - p0;
Vector3 m = p0 + p1 - aabb.GetMin() - aabb.GetMax();
return TestSegmentAABBOrigin(m, d, e);
}
} // namespace Intersect
} // namespace AZ
@@ -282,6 +282,7 @@ set(FILES
Math/Internal/VertexContainer.inl
Math/InterpolationSample.h
Math/IntersectPoint.h
Math/IntersectSegment.inl
Math/IntersectSegment.cpp
Math/IntersectSegment.h
Math/MathIntrinsics.h
@@ -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
@@ -61,6 +61,10 @@ namespace AzFramework
//! be deleted and the spawnable asset to be released. This call is automatically done when
//! AssignRootSpawnable is called while a root spawnable is assigned.
virtual void ReleaseRootSpawnable() = 0;
//! Force processing all SpawnableEntitiesManager requests immediately
//! This is useful when loading a different level while SpawnableEntitiesManager still has
//! pending requests
virtual void ProcessSpawnableQueue() = 0;
};
using RootSpawnableInterface = AZ::Interface<RootSpawnableDefinition>;
@@ -45,8 +45,7 @@ namespace AzFramework
void SpawnableSystemComponent::OnTick(float /*deltaTime*/, AZ::ScriptTimePoint /*time*/)
{
m_entitiesManager.ProcessQueue(
SpawnableEntitiesManager::CommandQueuePriority::High | SpawnableEntitiesManager::CommandQueuePriority::Regular);
ProcessSpawnableQueue();
RootSpawnableNotificationBus::ExecuteQueuedEvents();
}
@@ -121,6 +120,12 @@ namespace AzFramework
m_rootSpawnableId = AZ::Data::AssetId();
}
void SpawnableSystemComponent::ProcessSpawnableQueue()
{
m_entitiesManager.ProcessQueue(
SpawnableEntitiesManager::CommandQueuePriority::High | SpawnableEntitiesManager::CommandQueuePriority::Regular);
}
void SpawnableSystemComponent::OnRootSpawnableAssigned([[maybe_unused]] AZ::Data::Asset<Spawnable> rootSpawnable,
[[maybe_unused]] uint32_t generation)
{
@@ -161,6 +166,8 @@ namespace AzFramework
void SpawnableSystemComponent::Deactivate()
{
ProcessSpawnableQueue();
m_registryChangeHandler.Disconnect();
AZ::TickBus::Handler::BusDisconnect();
@@ -75,6 +75,7 @@ namespace AzFramework
uint64_t AssignRootSpawnable(AZ::Data::Asset<Spawnable> rootSpawnable) override;
void ReleaseRootSpawnable() override;
void ProcessSpawnableQueue() override;
//
// RootSpawnbleNotificationBus
@@ -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)
@@ -116,7 +116,7 @@ namespace AzToolsFramework
{
return AZ::Intersect::IntersectRayBox(
rayOrigin, rayDirection, m_center, m_axis1, m_axis2, m_axis3, m_halfExtents.GetX(), m_halfExtents.GetY(),
m_halfExtents.GetZ(), rayIntersectionDistance) > 0;
m_halfExtents.GetZ(), rayIntersectionDistance);
}
void ManipulatorBoundBox::SetShapeData(const BoundRequestShapeBase& shapeData)
@@ -262,7 +262,7 @@ namespace AzToolsFramework
if (assetId.IsValid())
{
asset.Create(assetId, true);
asset.Create(assetId, false);
}
}
};
@@ -43,6 +43,12 @@ namespace AzToolsFramework
m_instanceToTemplateInterface = AZ::Interface<InstanceToTemplateInterface>::Get();
AZ_Assert(m_instanceToTemplateInterface, "PrefabPublicHandler - Could not retrieve instance of InstanceToTemplateInterface");
m_prefabFocusInterface = AZ::Interface<PrefabFocusInterface>::Get();
AZ_Assert(m_prefabFocusInterface, "Could not get PrefabFocusInterface on PrefabPublicHandler construction.");
m_prefabFocusPublicInterface = AZ::Interface<PrefabFocusPublicInterface>::Get();
AZ_Assert(m_prefabFocusPublicInterface, "Could not get PrefabFocusPublicInterface on PrefabPublicHandler construction.");
m_prefabLoaderInterface = AZ::Interface<PrefabLoaderInterface>::Get();
AZ_Assert(m_prefabLoaderInterface, "Could not get PrefabLoaderInterface on PrefabPublicHandler construction.");
@@ -552,6 +558,13 @@ namespace AzToolsFramework
PrefabEntityResult PrefabPublicHandler::CreateEntity(AZ::EntityId parentId, const AZ::Vector3& position)
{
// If the parent is invalid, parent to the container of the currently focused prefab.
if (!parentId.IsValid())
{
AzFramework::EntityContextId editorEntityContextId = AzToolsFramework::GetEntityContextId();
parentId = m_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId);
}
InstanceOptionalReference owningInstanceOfParentEntity = GetOwnerInstanceByEntityId(parentId);
if (!owningInstanceOfParentEntity)
{
@@ -968,13 +981,13 @@ namespace AzToolsFramework
return AZ::Failure(AZStd::string("No entities to duplicate."));
}
const EntityIdList entityIdsNoLevelInstance = GenerateEntityIdListWithoutLevelInstance(entityIds);
if (entityIdsNoLevelInstance.empty())
const EntityIdList entityIdsNoFocusContainer = GenerateEntityIdListWithoutFocusedInstanceContainer(entityIds);
if (entityIdsNoFocusContainer.empty())
{
return AZ::Failure(AZStd::string("No entities to duplicate because only instance selected is the level instance."));
return AZ::Failure(AZStd::string("No entities to duplicate because only instance selected is the container entity of the focused instance."));
}
if (!EntitiesBelongToSameInstance(entityIdsNoLevelInstance))
if (!EntitiesBelongToSameInstance(entityIdsNoFocusContainer))
{
return AZ::Failure(AZStd::string("Cannot duplicate multiple entities belonging to different instances with one operation."
"Change your selection to contain entities in the same instance."));
@@ -982,7 +995,7 @@ namespace AzToolsFramework
// We've already verified the entities are all owned by the same instance,
// so we can just retrieve our instance from the first entity in the list.
AZ::EntityId firstEntityIdToDuplicate = entityIdsNoLevelInstance[0];
AZ::EntityId firstEntityIdToDuplicate = entityIdsNoFocusContainer[0];
InstanceOptionalReference commonOwningInstance = GetOwnerInstanceByEntityId(firstEntityIdToDuplicate);
if (!commonOwningInstance.has_value())
{
@@ -1002,7 +1015,7 @@ namespace AzToolsFramework
// This will cull out any entities that have ancestors in the list, since we will end up duplicating
// the full nested hierarchy with what is returned from RetrieveAndSortPrefabEntitiesAndInstances
AzToolsFramework::EntityIdSet duplicationSet = AzToolsFramework::GetCulledEntityHierarchy(entityIdsNoLevelInstance);
AzToolsFramework::EntityIdSet duplicationSet = AzToolsFramework::GetCulledEntityHierarchy(entityIdsNoFocusContainer);
AZ_PROFILE_FUNCTION(AzToolsFramework);
@@ -1039,10 +1052,10 @@ namespace AzToolsFramework
DuplicateNestedEntitiesInInstance(commonOwningInstance->get(),
entities, instanceDomAfter, duplicatedEntityAndInstanceIds, duplicateEntityAliasMap);
PrefabUndoInstance* command = aznew PrefabUndoInstance("Entity/Instance duplication");
PrefabUndoInstance* command = aznew PrefabUndoInstance("Entity/Instance duplication", false);
command->SetParent(undoBatch.GetUndoBatch());
command->Capture(instanceDomBefore, instanceDomAfter, commonOwningInstance->get().GetTemplateId());
command->RedoBatched();
command->Redo();
DuplicateNestedInstancesInInstance(commonOwningInstance->get(),
instances, instanceDomAfter, duplicatedEntityAndInstanceIds, newInstanceAliasToOldInstanceMap);
@@ -1106,19 +1119,21 @@ namespace AzToolsFramework
PrefabOperationResult PrefabPublicHandler::DeleteFromInstance(const EntityIdList& entityIds, bool deleteDescendants)
{
const EntityIdList entityIdsNoLevelInstance = GenerateEntityIdListWithoutLevelInstance(entityIds);
// Remove the container entity of the focused prefab from the list, if it is included.
const EntityIdList entityIdsNoFocusContainer = GenerateEntityIdListWithoutFocusedInstanceContainer(entityIds);
if (entityIdsNoLevelInstance.empty())
if (entityIdsNoFocusContainer.empty())
{
return AZ::Success();
}
if (!EntitiesBelongToSameInstance(entityIdsNoLevelInstance))
// All entities in this list need to belong to the same prefab instance for the operation to be valid.
if (!EntitiesBelongToSameInstance(entityIdsNoFocusContainer))
{
return AZ::Failure(AZStd::string("Cannot delete multiple entities belonging to different instances with one operation."));
}
AZ::EntityId firstEntityIdToDelete = entityIdsNoLevelInstance[0];
AZ::EntityId firstEntityIdToDelete = entityIdsNoFocusContainer[0];
InstanceOptionalReference commonOwningInstance = GetOwnerInstanceByEntityId(firstEntityIdToDelete);
// If the first entity id is a container entity id, then we need to mark its parent as the common owning instance because you
@@ -1128,8 +1143,15 @@ namespace AzToolsFramework
commonOwningInstance = commonOwningInstance->get().GetParentInstance();
}
// We only allow explicit deletions for entities inside the currently focused prefab.
AzFramework::EntityContextId editorEntityContextId = AzToolsFramework::GetEntityContextId();
if (&m_prefabFocusInterface->GetFocusedPrefabInstance(editorEntityContextId)->get() != &commonOwningInstance->get())
{
return AZ::Failure(AZStd::string("Cannot delete entities belonging to an instance that is not being edited."));
}
// Retrieve entityList from entityIds
EntityList inputEntityList = EntityIdListToEntityList(entityIdsNoLevelInstance);
EntityList inputEntityList = EntityIdListToEntityList(entityIdsNoFocusContainer);
AZ_PROFILE_FUNCTION(AzToolsFramework);
@@ -1186,7 +1208,7 @@ namespace AzToolsFramework
}
else
{
for (AZ::EntityId entityId : entityIdsNoLevelInstance)
for (AZ::EntityId entityId : entityIdsNoFocusContainer)
{
InstanceOptionalReference owningInstance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
// If this is the container entity, it actually represents the instance so get its owner
@@ -1227,9 +1249,12 @@ namespace AzToolsFramework
return AZ::Failure(AZStd::string("Cannot detach Prefab Instance with invalid container entity."));
}
if (IsLevelInstanceContainerEntity(containerEntityId))
auto editorEntityContextId = AzFramework::EntityContextId::CreateNull();
EditorEntityContextRequestBus::BroadcastResult(editorEntityContextId, &EditorEntityContextRequests::GetEditorEntityContextId);
if (containerEntityId == m_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId))
{
return AZ::Failure(AZStd::string("Cannot detach level Prefab Instance."));
return AZ::Failure(AZStd::string("Cannot detach focused Prefab Instance."));
}
InstanceOptionalReference owningInstance = GetOwnerInstanceByEntityId(containerEntityId);
@@ -1298,7 +1323,7 @@ namespace AzToolsFramework
Prefab::PrefabDom instanceDomAfter;
m_instanceToTemplateInterface->GenerateDomForInstance(instanceDomAfter, parentInstance);
PrefabUndoInstance* command = aznew PrefabUndoInstance("Instance detachment");
PrefabUndoInstance* command = aznew PrefabUndoInstance("Instance detachment", false);
command->Capture(instanceDomBefore, instanceDomAfter, parentTemplateId);
command->SetParent(undoBatch.GetUndoBatch());
{
@@ -1452,9 +1477,14 @@ namespace AzToolsFramework
AZStd::queue<AZ::Entity*> entityQueue;
auto editorEntityContextId = AzFramework::EntityContextId::CreateNull();
EditorEntityContextRequestBus::BroadcastResult(editorEntityContextId, &EditorEntityContextRequests::GetEditorEntityContextId);
AZ::EntityId focusedPrefabContainerEntityId =
m_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId);
for (auto inputEntity : inputEntities)
{
if (inputEntity && !IsLevelInstanceContainerEntity(inputEntity->GetId()))
if (inputEntity && inputEntity->GetId() != focusedPrefabContainerEntityId)
{
entityQueue.push(inputEntity);
}
@@ -1548,19 +1578,19 @@ namespace AzToolsFramework
return AZ::Success();
}
EntityIdList PrefabPublicHandler::GenerateEntityIdListWithoutLevelInstance(
EntityIdList PrefabPublicHandler::GenerateEntityIdListWithoutFocusedInstanceContainer(
const EntityIdList& entityIds) const
{
EntityIdList outEntityIds;
outEntityIds.reserve(entityIds.size()); // Actual size could be smaller.
EntityIdList outEntityIds(entityIds);
for (const AZ::EntityId& entityId : entityIds)
AzFramework::EntityContextId editorEntityContextId = AzToolsFramework::GetEntityContextId();
AZ::EntityId focusedInstanceContainerEntityId = m_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId);
if (auto iter = AZStd::find(outEntityIds.begin(), outEntityIds.end(), focusedInstanceContainerEntityId); iter != outEntityIds.end())
{
if (!IsLevelInstanceContainerEntity(entityId))
{
outEntityIds.emplace_back(entityId);
}
outEntityIds.erase(iter);
}
return outEntityIds;
}
@@ -74,7 +74,7 @@ namespace AzToolsFramework
Instance& commonRootEntityOwningInstance,
EntityList& outEntities,
AZStd::vector<Instance*>& outInstances) const;
EntityIdList GenerateEntityIdListWithoutLevelInstance(const EntityIdList& entityIds) const;
EntityIdList GenerateEntityIdListWithoutFocusedInstanceContainer(const EntityIdList& entityIds) const;
InstanceOptionalReference GetOwnerInstanceByEntityId(AZ::EntityId entityId) const;
bool EntitiesBelongToSameInstance(const EntityIdList& entityIds) const;
@@ -187,6 +187,8 @@ namespace AzToolsFramework
InstanceEntityMapperInterface* m_instanceEntityMapperInterface = nullptr;
InstanceToTemplateInterface* m_instanceToTemplateInterface = nullptr;
PrefabFocusInterface* m_prefabFocusInterface = nullptr;
PrefabFocusPublicInterface* m_prefabFocusPublicInterface = nullptr;
PrefabLoaderInterface* m_prefabLoaderInterface = nullptr;
PrefabSystemComponentInterface* m_prefabSystemComponentInterface = nullptr;
@@ -6,11 +6,14 @@
*
*/
#include <API/ToolsApplicationAPI.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <Prefab/PrefabSystemComponentInterface.h>
#include <Prefab/PrefabSystemScriptingHandler.h>
#include <AzCore/Component/Entity.h>
#include <AzCore/Component/TransformBus.h>
#include <ToolsComponents/TransformComponent.h>
namespace AzToolsFramework::Prefab
{
@@ -61,9 +64,29 @@ namespace AzToolsFramework::Prefab
entities.push_back(entity);
}
}
auto prefab = m_prefabSystemComponentInterface->CreatePrefab(entities, {}, AZ::IO::PathView(AZStd::string_view(filePath)));
bool result = false;
[[maybe_unused]] AZ::EntityId commonRoot;
EntityList topLevelEntities;
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(result, &AzToolsFramework::ToolsApplicationRequestBus::Events::FindCommonRootInactive,
entities, commonRoot, &topLevelEntities);
auto containerEntity = AZStd::make_unique<AZ::Entity>();
for (AZ::Entity* entity : topLevelEntities)
{
AzToolsFramework::Components::TransformComponent* transformComponent =
entity->FindComponent<AzToolsFramework::Components::TransformComponent>();
if (transformComponent)
{
transformComponent->SetParent(containerEntity->GetId());
}
}
auto prefab = m_prefabSystemComponentInterface->CreatePrefab(
entities, {}, AZ::IO::PathView(AZStd::string_view(filePath)), AZStd::move(containerEntity));
if (!prefab)
{
AZ_Error("PrefabSystemComponenent", false, "Failed to create prefab %s", filePath.c_str());
@@ -17,17 +17,16 @@ namespace AzToolsFramework
{
PrefabUndoBase::PrefabUndoBase(const AZStd::string& undoOperationName)
: UndoSystem::URSequencePoint(undoOperationName)
, m_changed(true)
, m_templateId(InvalidTemplateId)
{
m_instanceToTemplateInterface = AZ::Interface<InstanceToTemplateInterface>::Get();
AZ_Assert(m_instanceToTemplateInterface, "Failed to grab instance to template interface");
}
//PrefabInstanceUndo
PrefabUndoInstance::PrefabUndoInstance(const AZStd::string& undoOperationName)
PrefabUndoInstance::PrefabUndoInstance(const AZStd::string& undoOperationName, const bool useImmediatePropagation)
: PrefabUndoBase(undoOperationName)
{
m_useImmediatePropagation = useImmediatePropagation;
}
void PrefabUndoInstance::Capture(
@@ -43,17 +42,12 @@ namespace AzToolsFramework
void PrefabUndoInstance::Undo()
{
m_instanceToTemplateInterface->PatchTemplate(m_undoPatch, m_templateId, true);
m_instanceToTemplateInterface->PatchTemplate(m_undoPatch, m_templateId, m_useImmediatePropagation);
}
void PrefabUndoInstance::Redo()
{
m_instanceToTemplateInterface->PatchTemplate(m_redoPatch, m_templateId, true);
}
void PrefabUndoInstance::RedoBatched()
{
m_instanceToTemplateInterface->PatchTemplate(m_redoPatch, m_templateId);
m_instanceToTemplateInterface->PatchTemplate(m_redoPatch, m_templateId, m_useImmediatePropagation);
}
@@ -29,14 +29,15 @@ namespace AzToolsFramework
bool Changed() const override { return m_changed; }
protected:
TemplateId m_templateId;
TemplateId m_templateId = InvalidTemplateId;
PrefabDom m_redoPatch;
PrefabDom m_undoPatch;
InstanceToTemplateInterface* m_instanceToTemplateInterface = nullptr;
bool m_changed;
bool m_changed = true;
bool m_useImmediatePropagation = true;
};
//! handles the addition and removal of entities from instances
@@ -44,7 +45,7 @@ namespace AzToolsFramework
: public PrefabUndoBase
{
public:
explicit PrefabUndoInstance(const AZStd::string& undoOperationName);
explicit PrefabUndoInstance(const AZStd::string& undoOperationName, const bool useImmediatePropagation = true);
void Capture(
const PrefabDom& initialState,
@@ -53,7 +54,6 @@ namespace AzToolsFramework
void Undo() override;
void Redo() override;
void RedoBatched();
};
//! handles entity updates, such as when the values on an entity change
@@ -23,10 +23,10 @@ namespace AzToolsFramework
PrefabDom instanceDomAfterUpdate;
PrefabDomUtils::StoreInstanceInPrefabDom(instance, instanceDomAfterUpdate);
PrefabUndoInstance* state = aznew Prefab::PrefabUndoInstance(undoMessage);
PrefabUndoInstance* state = aznew Prefab::PrefabUndoInstance(undoMessage, false);
state->Capture(instanceDomBeforeUpdate, instanceDomAfterUpdate, instance.GetTemplateId());
state->SetParent(undoBatch);
state->RedoBatched();
state->Redo();
}
LinkId CreateLink(
@@ -24,6 +24,7 @@
#include <AzToolsFramework/AssetBrowser/AssetSelectionModel.h>
#include <AzToolsFramework/AssetBrowser/Entries/SourceAssetBrowserEntry.h>
#include <AzToolsFramework/ContainerEntity/ContainerEntityInterface.h>
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <AzToolsFramework/Prefab/EditorPrefabComponent.h>
#include <AzToolsFramework/Prefab/Instance/InstanceEntityMapperInterface.h>
#include <AzToolsFramework/Prefab/PrefabFocusPublicInterface.h>
@@ -175,12 +176,16 @@ namespace AzToolsFramework
AzFramework::ApplicationRequests::Bus::BroadcastResult(
prefabWipFeaturesEnabled, &AzFramework::ApplicationRequests::ArePrefabWipFeaturesEnabled);
auto editorEntityContextId = AzFramework::EntityContextId::CreateNull();
EditorEntityContextRequestBus::BroadcastResult(editorEntityContextId, &EditorEntityContextRequests::GetEditorEntityContextId);
// Create Prefab
{
if (!selectedEntities.empty())
{
// Hide if the only selected entity is the Level Container
if (selectedEntities.size() > 1 || !s_prefabPublicInterface->IsLevelInstanceContainerEntity(selectedEntities[0]))
// Hide if the only selected entity is the Focused Instance Container
if (selectedEntities.size() > 1 ||
selectedEntities[0] != s_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId))
{
bool layerInSelection = false;
@@ -247,14 +252,14 @@ namespace AzToolsFramework
// Edit Prefab
if (prefabWipFeaturesEnabled && !s_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(selectedEntity))
{
QAction* editAction = menu->addAction(QObject::tr("Edit Prefab"));
editAction->setToolTip(QObject::tr("Edit the prefab in focus mode."));
QAction* editAction = menu->addAction(QObject::tr("Edit Prefab"));
editAction->setToolTip(QObject::tr("Edit the prefab in focus mode."));
QObject::connect(editAction, &QAction::triggered, editAction, [selectedEntity] {
ContextMenu_EditPrefab(selectedEntity);
});
QObject::connect(editAction, &QAction::triggered, editAction, [selectedEntity] {
ContextMenu_EditPrefab(selectedEntity);
});
itemWasShown = true;
itemWasShown = true;
}
// Save Prefab
@@ -283,8 +288,9 @@ namespace AzToolsFramework
QAction* deleteAction = menu->addAction(QObject::tr("Delete"));
QObject::connect(deleteAction, &QAction::triggered, deleteAction, [] { ContextMenu_DeleteSelected(); });
if (selectedEntities.size() == 0 ||
(selectedEntities.size() == 1 && s_prefabPublicInterface->IsLevelInstanceContainerEntity(selectedEntities[0])))
if (selectedEntities.empty() ||
(selectedEntities.size() == 1 && selectedEntities[0] == s_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId)))
{
deleteAction->setDisabled(true);
}
@@ -292,17 +298,17 @@ namespace AzToolsFramework
// Detach Prefab
if (selectedEntities.size() == 1)
{
AZ::EntityId selectedEntity = selectedEntities[0];
AZ::EntityId selectedEntityId = selectedEntities[0];
if (s_prefabPublicInterface->IsInstanceContainerEntity(selectedEntity) &&
!s_prefabPublicInterface->IsLevelInstanceContainerEntity(selectedEntity))
if (s_prefabPublicInterface->IsInstanceContainerEntity(selectedEntityId) &&
selectedEntityId != s_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId))
{
QAction* detachPrefabAction = menu->addAction(QObject::tr("Detach Prefab..."));
QObject::connect(
detachPrefabAction, &QAction::triggered, detachPrefabAction,
[selectedEntity]
[selectedEntityId]
{
ContextMenu_DetachPrefab(selectedEntity);
ContextMenu_DetachPrefab(selectedEntityId);
});
}
}
@@ -331,13 +337,21 @@ namespace AzToolsFramework
QWidget* activeWindow = QApplication::activeWindow();
const AZStd::string prefabFilesPath = "@projectroot@/Prefabs";
// Remove Level entity if it's part of the list
auto levelContainerIter =
AZStd::find(selectedEntities.begin(), selectedEntities.end(), s_prefabPublicInterface->GetLevelInstanceContainerEntityId());
if (levelContainerIter != selectedEntities.end())
// Remove focused instance container entity if it's part of the list
auto editorEntityContextId = AzFramework::EntityContextId::CreateNull();
EditorEntityContextRequestBus::BroadcastResult(editorEntityContextId, &EditorEntityContextRequests::GetEditorEntityContextId);
auto focusedContainerIter = AZStd::find(
selectedEntities.begin(), selectedEntities.end(),
s_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId));
if (focusedContainerIter != selectedEntities.end())
{
selectedEntities.erase(levelContainerIter);
selectedEntities.erase(focusedContainerIter);
}
if (selectedEntities.empty())
{
return;
}
// Set default folder for prefabs
@@ -178,12 +178,6 @@ namespace AzToolsFramework
AZ::EntityId entityId(index.data(EntityOutlinerListModel::EntityIdRole).value<AZ::u64>());
// We hide the root instance container entity from the Outliner, so avoid drawing its full container on children
if (m_prefabPublicInterface->IsLevelInstanceContainerEntity(entityId))
{
return;
}
const QTreeView* outlinerTreeView(qobject_cast<const QTreeView*>(option.widget));
const int ancestorLeft = outlinerTreeView->visualRect(index).left() + (m_prefabBorderThickness / 2) - 1;
const int curveRectSize = m_prefabCapsuleRadius * 2;
@@ -9,6 +9,7 @@
#include "EditorHelpers.h"
#include <AzCore/Console/Console.h>
#include <AzCore/Math/VectorConversions.h>
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
#include <AzFramework/Viewport/CameraState.h>
#include <AzFramework/Viewport/ViewportScreen.h>
@@ -123,6 +124,11 @@ namespace AzToolsFramework
"EditorHelpers - "
"Focus Mode Interface could not be found. "
"Check that it is being correctly initialized.");
AZStd::vector<AZStd::unique_ptr<InvalidClick>> invalidClicks;
invalidClicks.push_back(AZStd::make_unique<FadingText>("Not in focus"));
invalidClicks.push_back(AZStd::make_unique<ExpandingFadingCircles>());
m_invalidClicks = AZStd::make_unique<InvalidClicks>(AZStd::move(invalidClicks));
}
AZ::EntityId EditorHelpers::HandleMouseInteraction(
@@ -186,13 +192,20 @@ namespace AzToolsFramework
}
}
// Verify if the entity Id corresponds to an entity that is focused; if not, halt selection.
if (!IsSelectableAccordingToFocusMode(entityIdUnderCursor))
// verify if the entity Id corresponds to an entity that is focused; if not, halt selection.
if (entityIdUnderCursor.IsValid() && !IsSelectableAccordingToFocusMode(entityIdUnderCursor))
{
if (mouseInteraction.m_mouseInteraction.m_mouseButtons.Left() &&
mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::Down ||
mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::DoubleClick)
{
m_invalidClicks->AddInvalidClick(mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates);
}
return AZ::EntityId();
}
// Container Entity support - if the entity that is being selected is part of a closed container,
// container entity support - if the entity that is being selected is part of a closed container,
// change the selection to the container instead.
if (ContainerEntityInterface* containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get())
{
@@ -202,6 +215,12 @@ namespace AzToolsFramework
return entityIdUnderCursor;
}
void EditorHelpers::Display2d(
[[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay)
{
m_invalidClicks->Display2d(viewportInfo, debugDisplay);
}
void EditorHelpers::DisplayHelpers(
const AzFramework::ViewportInfo& viewportInfo,
const AzFramework::CameraState& cameraState,
@@ -263,19 +282,19 @@ namespace AzToolsFramework
}
}
bool EditorHelpers::IsSelectableInViewport(AZ::EntityId entityId)
bool EditorHelpers::IsSelectableInViewport(const AZ::EntityId entityId) const
{
return IsSelectableAccordingToFocusMode(entityId) && IsSelectableAccordingToContainerEntities(entityId);
}
bool EditorHelpers::IsSelectableAccordingToFocusMode(AZ::EntityId entityId)
bool EditorHelpers::IsSelectableAccordingToFocusMode(const AZ::EntityId entityId) const
{
return m_focusModeInterface->IsInFocusSubTree(entityId);
}
bool EditorHelpers::IsSelectableAccordingToContainerEntities(AZ::EntityId entityId)
bool EditorHelpers::IsSelectableAccordingToContainerEntities(const AZ::EntityId entityId) const
{
if (ContainerEntityInterface* containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get())
if (const auto* containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get())
{
return !containerEntityInterface->IsUnderClosedContainerEntity(entityId);
}
@@ -11,6 +11,9 @@
#include <AzCore/Component/EntityId.h>
#include <AzCore/Memory/Memory.h>
#include <AzCore/std/functional.h>
#include <AzCore/std/containers/vector.h>
#include <AzFramework/Viewport/ScreenGeometry.h>
#include <AzToolsFramework/ViewportSelection/InvalidClicks.h>
namespace AzFramework
{
@@ -58,20 +61,27 @@ namespace AzToolsFramework
AzFramework::DebugDisplayRequests& debugDisplay,
const AZStd::function<bool(AZ::EntityId)>& showIconCheck);
//! Handle 2d drawing for EditorHelper functionality.
void Display2d(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay);
//! Returns whether the entityId can be selected in the viewport according
//! to the current Editor Focus Mode and Container Entity setup.
bool IsSelectableInViewport(AZ::EntityId entityId);
bool IsSelectableInViewport(AZ::EntityId entityId) const;
private:
//! Returns whether the entityId can be selected in the viewport according
//! to the current Editor Focus Mode setup.
bool IsSelectableAccordingToFocusMode(AZ::EntityId entityId);
bool IsSelectableAccordingToFocusMode(AZ::EntityId entityId) const;
//! Returns whether the entityId can be selected in the viewport according
//! to the current Container Entityu setup.
bool IsSelectableAccordingToContainerEntities(AZ::EntityId entityId);
//! to the current Container Entity setup.
bool IsSelectableAccordingToContainerEntities(AZ::EntityId entityId) const;
AZStd::unique_ptr<InvalidClicks> m_invalidClicks; //!< Display for invalid click behavior.
const EditorVisibleEntityDataCache* m_entityDataCache = nullptr; //!< Entity Data queried by the EditorHelpers.
const FocusModeInterface* m_focusModeInterface = nullptr;
const FocusModeInterface* m_focusModeInterface = nullptr; //!< API to interact with focus mode functionality.
};
} // namespace AzToolsFramework
@@ -3560,6 +3560,8 @@ namespace AzToolsFramework
DrawAxisGizmo(viewportInfo, debugDisplay);
m_boxSelect.Display2d(viewportInfo, debugDisplay);
m_editorHelpers->Display2d(viewportInfo, debugDisplay);
}
void EditorTransformComponentSelection::RefreshSelectedEntityIds()
@@ -3663,26 +3665,63 @@ namespace AzToolsFramework
void EditorTransformComponentSelection::OnEditorModeActivated(
[[maybe_unused]] const ViewportEditorModesInterface& editorModeState, ViewportEditorMode mode)
{
if (mode == ViewportEditorMode::Component)
switch (mode)
{
SetAllViewportUiVisible(false);
case ViewportEditorMode::Component:
{
SetAllViewportUiVisible(false);
EditorEntityLockComponentNotificationBus::Router::BusRouterDisconnect();
EditorEntityVisibilityNotificationBus::Router::BusRouterDisconnect();
ToolsApplicationNotificationBus::Handler::BusDisconnect();
EditorEntityLockComponentNotificationBus::Router::BusRouterDisconnect();
EditorEntityVisibilityNotificationBus::Router::BusRouterDisconnect();
ToolsApplicationNotificationBus::Handler::BusDisconnect();
}
break;
case ViewportEditorMode::Focus:
{
ViewportUi::ViewportUiRequestBus::Event(
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder, "Focus Mode");
}
break;
case ViewportEditorMode::Default:
case ViewportEditorMode::Pick:
// noop
break;
}
}
void EditorTransformComponentSelection::OnEditorModeDeactivated(
[[maybe_unused]] const ViewportEditorModesInterface& editorModeState, ViewportEditorMode mode)
const ViewportEditorModesInterface& editorModeState, const ViewportEditorMode mode)
{
if (mode == ViewportEditorMode::Component)
switch (mode)
{
SetAllViewportUiVisible(true);
case ViewportEditorMode::Component:
{
SetAllViewportUiVisible(true);
ToolsApplicationNotificationBus::Handler::BusConnect();
EditorEntityVisibilityNotificationBus::Router::BusRouterConnect();
EditorEntityLockComponentNotificationBus::Router::BusRouterConnect();
ToolsApplicationNotificationBus::Handler::BusConnect();
EditorEntityVisibilityNotificationBus::Router::BusRouterConnect();
EditorEntityLockComponentNotificationBus::Router::BusRouterConnect();
// note: when leaving component mode, we check if we're still in focus mode (i.e. component mode was
// started from within focus mode), if we are, ensure we create/update the viewport border (as leaving
// component mode will attempt to remove it)
if (editorModeState.IsModeActive(ViewportEditorMode::Focus))
{
ViewportUi::ViewportUiRequestBus::Event(
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder, "Focus Mode");
}
}
break;
case ViewportEditorMode::Focus:
{
ViewportUi::ViewportUiRequestBus::Event(
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::RemoveViewportBorder);
}
break;
case ViewportEditorMode::Default:
case ViewportEditorMode::Pick:
// noop
break;
}
}
@@ -0,0 +1,142 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/Console/Console.h>
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
#include <AzToolsFramework/Viewport/ViewportTypes.h>
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
#include <AzToolsFramework/ViewportSelection/InvalidClicks.h>
AZ_CVAR(float, ed_invalidClickRadius, 10.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "Maximum invalid click radius to expand to");
AZ_CVAR(float, ed_invalidClickDuration, 1.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "Duration to display the invalid click feedback");
AZ_CVAR(float, ed_invalidClickMessageSize, 0.8f, nullptr, AZ::ConsoleFunctorFlags::Null, "Size of text for invalid message");
AZ_CVAR(
float,
ed_invalidClickMessageVerticalOffset,
30.0f,
nullptr,
AZ::ConsoleFunctorFlags::Null,
"Vertical offset from cursor of invalid click message");
namespace AzToolsFramework
{
void ExpandingFadingCircles::Begin(const AzFramework::ScreenPoint& screenPoint)
{
FadingCircle fadingCircle;
fadingCircle.m_position = screenPoint;
fadingCircle.m_opacity = 1.0f;
fadingCircle.m_radius = 0.0f;
m_fadingCircles.push_back(fadingCircle);
}
void ExpandingFadingCircles::Update(const float deltaTime)
{
for (auto& fadingCircle : m_fadingCircles)
{
fadingCircle.m_opacity = AZStd::max(fadingCircle.m_opacity - (deltaTime / ed_invalidClickDuration), 0.0f);
fadingCircle.m_radius += deltaTime * ed_invalidClickRadius;
}
m_fadingCircles.erase(
AZStd::remove_if(
m_fadingCircles.begin(), m_fadingCircles.end(),
[](const FadingCircle& fadingCircle)
{
return fadingCircle.m_opacity <= 0.0f;
}),
m_fadingCircles.end());
}
bool ExpandingFadingCircles::Updating()
{
return !m_fadingCircles.empty();
}
void ExpandingFadingCircles::Display(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay)
{
const AZ::Vector2 viewportSize = AzToolsFramework::GetCameraState(viewportInfo.m_viewportId).m_viewportSize;
for (const auto& fadingCircle : m_fadingCircles)
{
const auto position = AzFramework::Vector2FromScreenPoint(fadingCircle.m_position) / viewportSize;
debugDisplay.SetColor(AZ::Color(1.0f, 1.0f, 1.0f, fadingCircle.m_opacity));
debugDisplay.DrawWireCircle2d(position, fadingCircle.m_radius * 0.005f, 0.0f);
}
}
void FadingText::Begin(const AzFramework::ScreenPoint& screenPoint)
{
m_opacity = 1.0f;
m_invalidClickPosition = screenPoint;
}
void FadingText::Update(const float deltaTime)
{
m_opacity -= deltaTime / ed_invalidClickDuration;
}
bool FadingText::Updating()
{
return m_opacity >= 0.0f;
}
void FadingText::Display(
[[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay)
{
if (constexpr float MinOpacity = 0.05f; m_opacity >= MinOpacity)
{
debugDisplay.SetColor(AZ::Color(1.0f, 1.0f, 1.0f, m_opacity));
debugDisplay.Draw2dTextLabel(
aznumeric_cast<float>(m_invalidClickPosition.m_x),
aznumeric_cast<float>(m_invalidClickPosition.m_y) - ed_invalidClickMessageVerticalOffset, ed_invalidClickMessageSize,
m_message.c_str(), true);
}
}
void InvalidClicks::AddInvalidClick(const AzFramework::ScreenPoint& screenPoint)
{
AZ::TickBus::Handler::BusConnect();
for (auto& invalidClickBehavior : m_invalidClickBehaviors)
{
invalidClickBehavior->Begin(screenPoint);
}
}
void InvalidClicks::OnTick(const float deltaTime, [[maybe_unused]] const AZ::ScriptTimePoint time)
{
for (auto& invalidClickBehavior : m_invalidClickBehaviors)
{
invalidClickBehavior->Update(deltaTime);
}
const auto updating = AZStd::any_of(
m_invalidClickBehaviors.begin(), m_invalidClickBehaviors.end(),
[](const auto& invalidClickBehavior)
{
return invalidClickBehavior->Updating();
});
if (!updating && AZ::TickBus::Handler::BusIsConnected())
{
AZ::TickBus::Handler::BusDisconnect();
}
}
void InvalidClicks::Display2d(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay)
{
debugDisplay.DepthTestOff();
for (const auto& invalidClickBehavior : m_invalidClickBehaviors)
{
invalidClickBehavior->Display(viewportInfo, debugDisplay);
}
debugDisplay.DepthTestOn();
}
} // namespace AzToolsFramework
@@ -0,0 +1,108 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Component/TickBus.h>
#include <AzFramework/Viewport/ScreenGeometry.h>
namespace AzFramework
{
class DebugDisplayRequests;
struct ViewportInfo;
} // namespace AzFramework
namespace AzToolsFramework
{
namespace ViewportInteraction
{
struct MouseInteractionEvent;
}
//! An interface to provide invalid click feedback in the editor viewport.
class InvalidClick
{
public:
virtual ~InvalidClick() = default;
//! Begin the feedback.
//! @param screenPoint The position of the click in screen coordinates.
virtual void Begin(const AzFramework::ScreenPoint& screenPoint) = 0;
//! Update the invalid click feedback
virtual void Update(float deltaTime) = 0;
//! Report if the click feedback is running or not (returning false will signal the TickBus can be disconnected from).
virtual bool Updating() = 0;
//! Display the click feedback in the viewport.
virtual void Display(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) = 0;
};
//! Display expanding fading circles for every click of the mouse that is invalid.
class ExpandingFadingCircles : public InvalidClick
{
public:
void Begin(const AzFramework::ScreenPoint& screenPoint) override;
void Update(float deltaTime) override;
bool Updating() override;
void Display(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override;
private:
//! Stores a circle representation with a lifetime to grow and fade out over time.
struct FadingCircle
{
AzFramework::ScreenPoint m_position;
float m_radius;
float m_opacity;
};
using FadingCircles = AZStd::vector<FadingCircle>;
FadingCircles m_fadingCircles; //!< Collection of fading circles to draw for clicks that have no effect.
};
//! Display fading text where an invalid click happened.
//! @note There is only one fading text, each click will update its position.
class FadingText : public InvalidClick
{
public:
explicit FadingText(AZStd::string message)
: m_message(AZStd::move(message))
{
}
void Begin(const AzFramework::ScreenPoint& screenPoint) override;
void Update(float deltaTime) override;
bool Updating() override;
void Display(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override;
private:
AZStd::string m_message; //!< Message to display for fading text.
float m_opacity = 1.0f; //!< The opacity of the invalid click message.
AzFramework::ScreenPoint m_invalidClickPosition; //!< The position to display the invalid click message.
};
//! Interface to begin invalid click feedback (will run all added InvalidClick behaviors).
class InvalidClicks : private AZ::TickBus::Handler
{
public:
explicit InvalidClicks(AZStd::vector<AZStd::unique_ptr<InvalidClick>> invalidClickBehaviors)
: m_invalidClickBehaviors(AZStd::move(invalidClickBehaviors))
{
}
//! Add an invalid click and activate one or more of the added invalid click behaviors.
void AddInvalidClick(const AzFramework::ScreenPoint& screenPoint);
//! Handle 2d drawing for EditorHelper functionality.
void Display2d(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay);
private:
//! AZ::TickBus overrides ...
void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
AZStd::vector<AZStd::unique_ptr<InvalidClick>> m_invalidClickBehaviors; //!< Invalid click behaviors to run.
};
} // namespace AzToolsFramework
@@ -290,9 +290,9 @@ namespace AzToolsFramework::ViewportUi::Internal
return false;
}
void ViewportUiDisplay::CreateComponentModeBorder(const AZStd::string& borderTitle)
void ViewportUiDisplay::CreateViewportBorder(const AZStd::string& borderTitle)
{
AZStd::string styleSheet = AZStd::string::format(
const AZStd::string styleSheet = AZStd::string::format(
"border: %dpx solid %s; border-top: %dpx solid %s;", HighlightBorderSize, HighlightBorderColor, TopHighlightBorderSize,
HighlightBorderColor);
m_uiOverlay.setStyleSheet(styleSheet.c_str());
@@ -303,7 +303,7 @@ namespace AzToolsFramework::ViewportUi::Internal
m_componentModeBorderText.setText(borderTitle.c_str());
}
void ViewportUiDisplay::RemoveComponentModeBorder()
void ViewportUiDisplay::RemoveViewportBorder()
{
m_componentModeBorderText.setVisible(false);
m_uiOverlay.setStyleSheet("border: none;");
@@ -420,6 +420,7 @@ namespace AzToolsFramework::ViewportUi::Internal
m_uiMainWindow.setVisible(true);
m_uiOverlay.setVisible(true);
}
m_uiMainWindow.setMask(region);
}
@@ -437,6 +438,7 @@ namespace AzToolsFramework::ViewportUi::Internal
{
return element->second;
}
return ViewportUiElementInfo{ nullptr, InvalidViewportUiElementId, false };
}
@@ -89,8 +89,8 @@ namespace AzToolsFramework::ViewportUi::Internal
AZStd::shared_ptr<QWidget> GetViewportUiElement(ViewportUiElementId elementId);
bool IsViewportUiElementVisible(ViewportUiElementId elementId);
void CreateComponentModeBorder(const AZStd::string& borderTitle);
void RemoveComponentModeBorder();
void CreateViewportBorder(const AZStd::string& borderTitle);
void RemoveViewportBorder();
private:
void PrepareWidgetForViewportUi(QPointer<QWidget> widget);
@@ -240,14 +240,14 @@ namespace AzToolsFramework::ViewportUi
}
}
void ViewportUiManager::CreateComponentModeBorder(const AZStd::string& borderTitle)
void ViewportUiManager::CreateViewportBorder(const AZStd::string& borderTitle)
{
m_viewportUi->CreateComponentModeBorder(borderTitle);
m_viewportUi->CreateViewportBorder(borderTitle);
}
void ViewportUiManager::RemoveComponentModeBorder()
void ViewportUiManager::RemoveViewportBorder()
{
m_viewportUi->RemoveComponentModeBorder();
m_viewportUi->RemoveViewportBorder();
}
void ViewportUiManager::PressButton(ClusterId clusterId, ButtonId buttonId)
@@ -50,8 +50,8 @@ namespace AzToolsFramework::ViewportUi
void RegisterTextFieldCallback(TextFieldId textFieldId, AZ::Event<AZStd::string>::Handler& handler) override;
void RemoveTextField(TextFieldId textFieldId) override;
void SetTextFieldVisible(TextFieldId textFieldId, bool visible) override;
void CreateComponentModeBorder(const AZStd::string& borderTitle) override;
void RemoveComponentModeBorder() override;
void CreateViewportBorder(const AZStd::string& borderTitle) override;
void RemoveViewportBorder() override;
void PressButton(ClusterId clusterId, ButtonId buttonId) override;
void PressButton(SwitcherId switcherId, ButtonId buttonId) override;
@@ -78,7 +78,7 @@ namespace AzToolsFramework::ViewportUi
virtual void RegisterSwitcherEventHandler(SwitcherId switcherId, AZ::Event<ButtonId>::Handler& handler) = 0;
//! Removes a cluster from the Viewport UI system.
virtual void RemoveCluster(ClusterId clusterId) = 0;
//!
//! Removes a switcher from the Viewport UI system.
virtual void RemoveSwitcher(SwitcherId switcherId) = 0;
//! Sets the visibility of the cluster.
virtual void SetClusterVisible(ClusterId clusterId, bool visible) = 0;
@@ -96,12 +96,12 @@ namespace AzToolsFramework::ViewportUi
//! Sets the visibility of the text field.
virtual void SetTextFieldVisible(TextFieldId textFieldId, bool visible) = 0;
//! Create the highlight border for Component Mode.
virtual void CreateComponentModeBorder(const AZStd::string& borderTitle) = 0;
virtual void CreateViewportBorder(const AZStd::string& borderTitle) = 0;
//! Remove the highlight border for Component Mode.
virtual void RemoveComponentModeBorder() = 0;
//! Invoke a button press in a cluster.
virtual void RemoveViewportBorder() = 0;
//! Invoke a button press on a cluster.
virtual void PressButton(ClusterId clusterId, ButtonId buttonId) = 0;
//!
//! Invoke a button press on a switcher.
virtual void PressButton(SwitcherId switcherId, ButtonId buttonId) = 0;
};
@@ -553,6 +553,8 @@ set(FILES
ViewportSelection/EditorTransformComponentSelectionRequestBus.cpp
ViewportSelection/EditorVisibleEntityDataCache.h
ViewportSelection/EditorVisibleEntityDataCache.cpp
ViewportSelection/InvalidClicks.h
ViewportSelection/InvalidClicks.cpp
ViewportSelection/ViewportEditorModeTracker.cpp
ViewportSelection/ViewportEditorModeTracker.h
ToolsFileUtils/ToolsFileUtils.h
+40 -40
View File
@@ -333,7 +333,7 @@ namespace UnitTest
};
template<class SocketProvider = SocketDriverProvider>
class Integ_CarrierAsyncHandshakeTestTemplate
class CarrierAsyncHandshakeTestTemplate
: public GridMateMPTestFixture
, protected SocketProvider
{
@@ -761,7 +761,7 @@ namespace UnitTest
};
template<class SocketProvider = SocketDriverProvider>
class Integ_CarrierDisconnectDetectionTestTemplate
class CarrierDisconnectDetectionTestTemplate
: public GridMateMPTestFixture
, protected SocketProvider
{
@@ -846,7 +846,7 @@ namespace UnitTest
* Sends reliable messages across different channels to each other
*/
template<class SocketProvider = SocketDriverProvider>
class Integ_CarrierMultiChannelTestTemplate
class CarrierMultiChannelTestTemplate
: public GridMateMPTestFixture
, protected SocketProvider
{
@@ -950,7 +950,7 @@ namespace UnitTest
* Stress tests multiple simultaneous Carriers
*/
template<class SocketProvider = SocketDriverProvider>
class Integ_CarrierMultiStressTestTemplate
class CarrierMultiStressTestTemplate
: public GridMateMPTestFixture
, protected SocketProvider
{
@@ -977,7 +977,7 @@ namespace UnitTest
public:
void run()
{
AZ_TracePrintf("GridMate", "Integ_CarrierMultiStressTest\n\n");
AZ_TracePrintf("GridMate", "CarrierMultiStressTest\n\n");
// initialize transport
const int k_numChannels = 1;
@@ -1108,7 +1108,7 @@ namespace UnitTest
/*** Congestion control back pressure test */
template<class SocketProvider = SocketDriverProvider>
class Integ_CarrierBackpressureTestTemplate
class CarrierBackpressureTestTemplate
: public GridMateMPTestFixture
, protected SocketProvider
, public CarrierEventBus::Handler
@@ -1380,7 +1380,7 @@ namespace UnitTest
};
template<class SocketProvider = SocketDriverProvider>
class Integ_CarrierACKTestTemplate
class CarrierACKTestTemplate
: public GridMateMPTestFixture
, protected SocketProvider
{
@@ -1544,13 +1544,13 @@ namespace UnitTest
//Create specific tests
using CarrierBasicTest = CarrierBasicTestTemplate<>;
using CarrierTest = CarrierTestTemplate<>;
using Integ_CarrierDisconnectDetectionTest = Integ_CarrierDisconnectDetectionTestTemplate<>;
using Integ_CarrierAsyncHandshakeTest = Integ_CarrierAsyncHandshakeTestTemplate<>;
using Integ_CarrierStressTest = CarrierStressTestTemplate<>;
using Integ_CarrierMultiChannelTest = Integ_CarrierMultiChannelTestTemplate<>;
using Integ_CarrierMultiStressTest = Integ_CarrierMultiStressTestTemplate<>;
using Integ_CarrierBackpressureTest = Integ_CarrierBackpressureTestTemplate<>;
using Integ_CarrierACKTest = Integ_CarrierACKTestTemplate<>;
using DISABLED_CarrierDisconnectDetectionTest = CarrierDisconnectDetectionTestTemplate<>;
using DISABLED_CarrierAsyncHandshakeTest = CarrierAsyncHandshakeTestTemplate<>;
using DISABLED_CarrierStressTest = CarrierStressTestTemplate<>;
using DISABLED_CarrierMultiChannelTest = CarrierMultiChannelTestTemplate<>;
using DISABLED_CarrierMultiStressTest = CarrierMultiStressTestTemplate<>;
using DISABLED_CarrierBackpressureTest = CarrierBackpressureTestTemplate<>;
using DISABLED_CarrierACKTest = CarrierACKTestTemplate<>;
#if AZ_TRAIT_GRIDMATE_TEST_WITH_SECURE_SOCKET_DRIVER
@@ -1658,20 +1658,20 @@ namespace UnitTest
using SecureProviderBadHost = SecureDriverProvider<SecureSocketDriver, SecureSocketHandshakeDrop<false>>;
using SecureProviderBadBoth = SecureDriverProvider<SecureSocketHandshakeDrop<true>, SecureSocketHandshakeDrop<false>>;
using Integ_CarrierSecureSocketHandshakeTestClient = CarrierBasicTestTemplate<SecureProviderBadClient, 200>;
using Integ_CarrierSecureSocketHandshakeTestHost = CarrierBasicTestTemplate<SecureProviderBadHost, 200>;
using Integ_CarrierSecureSocketHandshakeTestBoth = CarrierBasicTestTemplate<SecureProviderBadBoth, 200>;
using DISABLED_CarrierSecureSocketHandshakeTestClient = CarrierBasicTestTemplate<SecureProviderBadClient, 200>;
using DISABLED_CarrierSecureSocketHandshakeTestHost = CarrierBasicTestTemplate<SecureProviderBadHost, 200>;
using DISABLED_CarrierSecureSocketHandshakeTestBoth = CarrierBasicTestTemplate<SecureProviderBadBoth, 200>;
//Create secure socket variants of tests
using CarrierBasicTestSecure = CarrierBasicTestTemplate<SecureDriverProvider<>>;
using CarrierTestSecure = CarrierTestTemplate<SecureDriverProvider<>>;
using Integ_CarrierDisconnectDetectionTestSecure = Integ_CarrierDisconnectDetectionTestTemplate<SecureDriverProvider<>>;
using Integ_CarrierAsyncHandshakeTestSecure = Integ_CarrierAsyncHandshakeTestTemplate<SecureDriverProvider<>>;
using Integ_CarrierStressTestSecure = CarrierStressTestTemplate<SecureDriverProvider<>>;
using Integ_CarrierMultiChannelTestSecure = Integ_CarrierMultiChannelTestTemplate<SecureDriverProvider<>>;
using Integ_CarrierMultiStressTestSecure = Integ_CarrierMultiStressTestTemplate<SecureDriverProvider<>>;
using Integ_CarrierBackpressureTestSecure = Integ_CarrierBackpressureTestTemplate<SecureDriverProvider<>>;
using Integ_CarrierACKTestSecure = Integ_CarrierACKTestTemplate<SecureDriverProvider<>>;
using DISABLED_CarrierDisconnectDetectionTestSecure = CarrierDisconnectDetectionTestTemplate<SecureDriverProvider<>>;
using DISABLED_CarrierAsyncHandshakeTestSecure = CarrierAsyncHandshakeTestTemplate<SecureDriverProvider<>>;
using DISABLED_CarrierStressTestSecure = CarrierStressTestTemplate<SecureDriverProvider<>>;
using DISABLED_CarrierMultiChannelTestSecure = CarrierMultiChannelTestTemplate<SecureDriverProvider<>>;
using DISABLED_CarrierMultiStressTestSecure = CarrierMultiStressTestTemplate<SecureDriverProvider<>>;
using DISABLED_CarrierBackpressureTestSecure = CarrierBackpressureTestTemplate<SecureDriverProvider<>>;
using DISABLED_CarrierACKTestSecure = CarrierACKTestTemplate<SecureDriverProvider<>>;
#endif
}
@@ -1720,30 +1720,30 @@ GM_TEST_SUITE(CarrierSuite)
GM_TEST(CarrierBasicTest)
GM_TEST(CarrierTest)
#endif //AZ_TRAIT_GRIDMATE_UNIT_TEST_DISABLE_CARRIER_SESSION_TESTS
GM_TEST(Integ_CarrierAsyncHandshakeTest)
GM_TEST(DISABLED_CarrierAsyncHandshakeTest)
#if !defined(AZ_DEBUG_BUILD) // this test is a little slow for debug
GM_TEST(Integ_CarrierStressTest)
GM_TEST(Integ_CarrierMultiStressTest)
GM_TEST(DISABLED_CarrierStressTest)
GM_TEST(DISABLED_CarrierMultiStressTest)
#endif
GM_TEST(Integ_CarrierMultiChannelTest)
GM_TEST(Integ_CarrierBackpressureTest)
GM_TEST(Integ_CarrierACKTest)
GM_TEST(DISABLED_CarrierMultiChannelTest)
GM_TEST(DISABLED_CarrierBackpressureTest)
GM_TEST(DISABLED_CarrierACKTest)
#if AZ_TRAIT_GRIDMATE_TEST_WITH_SECURE_SOCKET_DRIVER
GM_TEST(CarrierBasicTestSecure)
GM_TEST(Integ_CarrierSecureSocketHandshakeTestClient)
GM_TEST(Integ_CarrierSecureSocketHandshakeTestHost)
GM_TEST(Integ_CarrierSecureSocketHandshakeTestBoth)
GM_TEST(DISABLED_CarrierBasicTestSecure)
GM_TEST(DISABLED_CarrierSecureSocketHandshakeTestClient)
GM_TEST(DISABLED_CarrierSecureSocketHandshakeTestHost)
GM_TEST(DISABLED_CarrierSecureSocketHandshakeTestBoth)
GM_TEST(CarrierTestSecure)
GM_TEST(Integ_CarrierAsyncHandshakeTestSecure)
GM_TEST(DISABLED_CarrierAsyncHandshakeTestSecure)
#if !defined(AZ_DEBUG_BUILD) // this test is a little slow for debug
GM_TEST(Integ_CarrierStressTestSecure)
GM_TEST(Integ_CarrierMultiStressTestSecure)
GM_TEST(DISABLED_CarrierStressTestSecure)
GM_TEST(DISABLED_CarrierMultiStressTestSecure)
#endif
GM_TEST(Integ_CarrierMultiChannelTestSecure)
GM_TEST(Integ_CarrierBackpressureTestSecure)
GM_TEST(Integ_CarrierACKTestSecure)
GM_TEST(DISABLED_CarrierMultiChannelTestSecure)
GM_TEST(DISABLED_CarrierBackpressureTestSecure)
GM_TEST(DISABLED_CarrierACKTestSecure)
#endif
@@ -172,7 +172,7 @@ public:
namespace UnitTest
{
class Integ_CarrierStreamBasicTest
class DISABLED_CarrierStreamBasicTest
: public GridMateMPTestFixture
, protected SocketDriverSupplier
{
@@ -330,7 +330,7 @@ namespace UnitTest
}
};
class Integ_CarrierStreamAsyncHandshakeTest
class DISABLED_CarrierStreamAsyncHandshakeTest
: public GridMateMPTestFixture
, protected SocketDriverSupplier
{
@@ -462,7 +462,7 @@ namespace UnitTest
}
};
class Integ_CarrierStreamStressTest
class CarrierStreamStressTest
: public GridMateMPTestFixture
, protected SocketDriverSupplier
, public ::testing::Test
@@ -470,7 +470,7 @@ namespace UnitTest
public:
};
TEST_F(Integ_CarrierStreamStressTest, Stress_Test)
TEST_F(CarrierStreamStressTest, DISABLED_Stress_Test)
{
CarrierStreamCallbacksHandler clientCB, serverCB;
UnitTest::TestCarrierDesc serverCarrierDesc, clientCarrierDesc;
@@ -581,7 +581,7 @@ namespace UnitTest
//////////////////////////////////////////////////////////////////////////
}
class Integ_CarrierStreamTest
class DISABLED_CarrierStreamTest
: public GridMateMPTestFixture
, protected SocketDriverSupplier
{
@@ -783,7 +783,7 @@ namespace UnitTest
}
};
class Integ_CarrierStreamDisconnectDetectionTest
class DISABLED_CarrierStreamDisconnectDetectionTest
: public GridMateMPTestFixture
, protected SocketDriverSupplier
{
@@ -873,7 +873,7 @@ namespace UnitTest
}
};
class Integ_CarrierStreamMultiChannelTest
class DISABLED_CarrierStreamMultiChannelTest
: public GridMateMPTestFixture
, protected SocketDriverSupplier
{
@@ -999,8 +999,8 @@ namespace UnitTest
}
GM_TEST_SUITE(CarrierStreamSuite)
GM_TEST(Integ_CarrierStreamBasicTest)
GM_TEST(Integ_CarrierStreamTest)
GM_TEST(Integ_CarrierStreamAsyncHandshakeTest)
GM_TEST(Integ_CarrierStreamMultiChannelTest)
GM_TEST(DISABLED_CarrierStreamBasicTest)
GM_TEST(DISABLED_CarrierStreamTest)
GM_TEST(DISABLED_CarrierStreamAsyncHandshakeTest)
GM_TEST(DISABLED_CarrierStreamMultiChannelTest)
GM_TEST_SUITE_END()
+47 -48
View File
@@ -6,7 +6,6 @@
*
*/
#include "Tests.h"
#include "TestProfiler.h"
#include <GridMate/Replica/ReplicaFunctions.h>
@@ -1888,12 +1887,12 @@ protected:
};
//-----------------------------------------------------------------------------
class Integ_ReplicaGMTest
class ReplicaGMTest
: public UnitTest::GridMateMPTestFixture
, public ::testing::Test
{};
TEST_F(Integ_ReplicaGMTest, ReplicaTest)
TEST_F(ReplicaGMTest, DISABLED_ReplicaTest)
{
ReplicaChunkDescriptorTable::Get().RegisterChunkType<MigratableReplica, MigratableReplica::Descriptor>();
ReplicaChunkDescriptorTable::Get().RegisterChunkType<NonMigratableReplica>();
@@ -2157,7 +2156,7 @@ TEST_F(Integ_ReplicaGMTest, ReplicaTest)
}
}
class Integ_ForcedReplicaMigrationTest
class ForcedReplicaMigrationTest
: public UnitTest::GridMateMPTestFixture
, public ReplicaMgrCallbackBus::Handler
, public MigratableReplica::MigratableReplicaDebugMsgs::EBus::Handler
@@ -2186,8 +2185,8 @@ class Integ_ForcedReplicaMigrationTest
}
public:
Integ_ForcedReplicaMigrationTest() { ReplicaMgrCallbackBus::Handler::BusConnect(m_gridMate); }
~Integ_ForcedReplicaMigrationTest() { ReplicaMgrCallbackBus::Handler::BusDisconnect(); }
ForcedReplicaMigrationTest() { ReplicaMgrCallbackBus::Handler::BusConnect(m_gridMate); }
~ForcedReplicaMigrationTest() { ReplicaMgrCallbackBus::Handler::BusDisconnect(); }
enum
@@ -2205,11 +2204,11 @@ public:
AZStd::unordered_map<ReplicaId, ReplicaManager*> m_replicaOwnership;
};
const int Integ_ForcedReplicaMigrationTest::k_frameTimePerNodeMs;
const int Integ_ForcedReplicaMigrationTest::k_numFramesToRun;
const int Integ_ForcedReplicaMigrationTest::k_hostSendRateMs;
const int ForcedReplicaMigrationTest::k_frameTimePerNodeMs;
const int ForcedReplicaMigrationTest::k_numFramesToRun;
const int ForcedReplicaMigrationTest::k_hostSendRateMs;
TEST_F(Integ_ForcedReplicaMigrationTest, ForcedReplicaMigrationTest)
TEST_F(ForcedReplicaMigrationTest, DISABLED_ForcedReplicaMigrationTest)
{
ReplicaChunkDescriptorTable::Get().RegisterChunkType<MigratableReplica, MigratableReplica::Descriptor>();
ReplicaChunkDescriptorTable::Get().RegisterChunkType<NonMigratableReplica>();
@@ -2360,7 +2359,7 @@ TEST_F(Integ_ForcedReplicaMigrationTest, ForcedReplicaMigrationTest)
MigratableReplica::MigratableReplicaDebugMsgs::EBus::Handler::BusDisconnect();
}
class Integ_ReplicaMigrationRequestTest
class ReplicaMigrationRequestTest
: public UnitTest::GridMateMPTestFixture
, public ::testing::Test
{
@@ -2516,7 +2515,7 @@ public:
static const int k_hostSendTimeMs = k_frameTimePerNodeMs * TotalNodes * 4; // limiting host send rate to be x4 times slower than tick
};
TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest)
TEST_F(ReplicaMigrationRequestTest, DISABLED_ReplicaMigrationRequestTest)
{
/*
Topology:
@@ -2837,11 +2836,11 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest)
}
}
const int Integ_ReplicaMigrationRequestTest::k_frameTimePerNodeMs;
const int Integ_ReplicaMigrationRequestTest::k_hostSendTimeMs;
const int ReplicaMigrationRequestTest::k_frameTimePerNodeMs;
const int ReplicaMigrationRequestTest::k_hostSendTimeMs;
class Integ_PeerRejoinTest
class PeerRejoinTest
: public UnitTest::GridMateMPTestFixture
, public ReplicaMgrCallbackBus::Handler
, public ::testing::Test
@@ -2860,11 +2859,11 @@ class Integ_PeerRejoinTest
}
public:
Integ_PeerRejoinTest() { ReplicaMgrCallbackBus::Handler::BusConnect(m_gridMate); }
~Integ_PeerRejoinTest() { ReplicaMgrCallbackBus::Handler::BusDisconnect(); }
PeerRejoinTest() { ReplicaMgrCallbackBus::Handler::BusConnect(m_gridMate); }
~PeerRejoinTest() { ReplicaMgrCallbackBus::Handler::BusDisconnect(); }
};
TEST_F(Integ_PeerRejoinTest, PeerRejoinTest)
TEST_F(PeerRejoinTest, DISABLED_PeerRejoinTest)
{
ReplicaChunkDescriptorTable::Get().RegisterChunkType<MigratableReplica, MigratableReplica::Descriptor>();
ReplicaChunkDescriptorTable::Get().RegisterChunkType<NonMigratableReplica>();
@@ -3011,7 +3010,7 @@ TEST_F(Integ_PeerRejoinTest, PeerRejoinTest)
}
}
class Integ_ReplicationSecurityOptionsTest
class ReplicationSecurityOptionsTest
: public UnitTest::GridMateMPTestFixture
, public ::testing::Test
{
@@ -3156,7 +3155,7 @@ public:
using TestChunkPtr = AZStd::intrusive_ptr<TestChunk> ;
};
TEST_F(Integ_ReplicationSecurityOptionsTest, ReplicationSecurityOptionsTest)
TEST_F(ReplicationSecurityOptionsTest, DISABLED_ReplicationSecurityOptionsTest)
{
AZ_TracePrintf("GridMate", "\n");
@@ -3356,7 +3355,7 @@ TEST_F(Integ_ReplicationSecurityOptionsTest, ReplicationSecurityOptionsTest)
Replica update time (msec): avg=4.94, min=1, max=9 (peers=40, replicas=16000, freq=10%, samples=4000)
Replica update time (msec): avg=8.05, min=6, max=15 (peers=40, replicas=16000, freq=100%, samples=4000)
*/
class Integ_ReplicaStressTest
class DISABLED_ReplicaStressTest
: public UnitTest::GridMateMPTestFixture
{
public:
@@ -3388,7 +3387,7 @@ public:
static const int BASE_PORT = 44270;
// TODO: Reduce the size or disable the test for platforms which can't allocate 2 GiB
Integ_ReplicaStressTest()
DISABLED_ReplicaStressTest()
: UnitTest::GridMateMPTestFixture(2000u * 1024u * 1024u)
{}
@@ -3516,33 +3515,33 @@ public:
virtual void RunStressTests(MPSession* sessions, vector<AZStd::pair<ReplicaPtr, StressTestReplica::Ptr> >& replicas)
{
// testing 3 cases & waiting for system to settle in between
TestProfiler::StartProfiling();
//TestProfiler::StartProfiling();
Wait(sessions, replicas, 50, FRAME_TIME);
TestProfiler::PrintProfilingTotal("GridMate");
//TestProfiler::PrintProfilingTotal("GridMate");
Wait(sessions, replicas, 20, FRAME_TIME);
TestProfiler::StartProfiling();
//TestProfiler::StartProfiling();
TestReplicas(sessions, replicas, 100, FRAME_TIME, 0.0); // no replicas are dirty
TestProfiler::PrintProfilingTotal("GridMate");
//TestProfiler::PrintProfilingTotal("GridMate");
Wait(sessions, replicas, 20, FRAME_TIME);
TestProfiler::StartProfiling();
//TestProfiler::StartProfiling();
TestReplicas(sessions, replicas, 1, FRAME_TIME, 1.0); // single burst dirty replicas
Wait(sessions, replicas, 2, FRAME_TIME);
TestProfiler::PrintProfilingTotal("GridMate");
//TestProfiler::PrintProfilingTotal("GridMate");
Wait(sessions, replicas, 20, FRAME_TIME);
TestProfiler::StartProfiling();
//TestProfiler::StartProfiling();
TestReplicas(sessions, replicas, 100, FRAME_TIME, 0.1); // 10% of replicas are marked dirty every frame
TestProfiler::PrintProfilingTotal("GridMate");
//TestProfiler::PrintProfilingTotal("GridMate");
Wait(sessions, replicas, 20, FRAME_TIME);
TestProfiler::StartProfiling();
//TestProfiler::StartProfiling();
TestReplicas(sessions, replicas, 100, FRAME_TIME, 1.0); // every replica is marked dirty every frame
TestProfiler::PrintProfilingTotal("GridMate");
TestProfiler::PrintProfilingSelf("GridMate");
//TestProfiler::PrintProfilingTotal("GridMate");
//TestProfiler::PrintProfilingSelf("GridMate");
TestProfiler::StopProfiling();
//TestProfiler::StopProfiling();
}
virtual void MarkChanging(vector<AZStd::pair<ReplicaPtr, StressTestReplica::Ptr> >& replicas, double freq)
@@ -3623,8 +3622,8 @@ public:
Replica update time (msec): avg=2.01, min=1, max=5 (peers=40, replicas=16000, freq=10%, samples=4000)
Replica update time (msec): avg=4.61, min=3, max=10 (peers=40, replicas=16000, freq=50%, samples=4000)
*/
class Integ_ReplicaStableStressTest
: public Integ_ReplicaStressTest
class DISABLED_ReplicaStableStressTest
: public DISABLED_ReplicaStressTest
{
public:
@@ -3636,21 +3635,21 @@ public:
void RunStressTests(MPSession* sessions, vector<AZStd::pair<ReplicaPtr, StressTestReplica::Ptr> >& replicas) override
{
Integ_ReplicaStressTest::MarkChanging(replicas, 0.1); // picks 10% of replicas
DISABLED_ReplicaStressTest::MarkChanging(replicas, 0.1); // picks 10% of replicas
Wait(sessions, replicas, 20, FRAME_TIME);
TestProfiler::StartProfiling();
//TestProfiler::StartProfiling();
TestReplicas(sessions, replicas, 100, FRAME_TIME, 0.1);
TestProfiler::PrintProfilingTotal("GridMate");
TestProfiler::PrintProfilingSelf("GridMate");
/*TestProfiler::PrintProfilingTotal("GridMate");
TestProfiler::PrintProfilingSelf("GridMate");*/
Integ_ReplicaStressTest::MarkChanging(replicas, 0.5); // picks 50% of replicas
DISABLED_ReplicaStressTest::MarkChanging(replicas, 0.5); // picks 50% of replicas
Wait(sessions, replicas, 20, FRAME_TIME);
TestProfiler::StartProfiling();
//TestProfiler::StartProfiling();
TestReplicas(sessions, replicas, 100, FRAME_TIME, 0.5);
TestProfiler::PrintProfilingTotal("GridMate");
/*TestProfiler::PrintProfilingTotal("GridMate");
TestProfiler::PrintProfilingSelf("GridMate");
TestProfiler::StopProfiling();
TestProfiler::StopProfiling();*/
}
};
@@ -3666,7 +3665,7 @@ public:
* expected |none |brst | capped |under cap |brst | capped |
*
*/
class Integ_ReplicaBandiwdthTest
class DISABLED_ReplicaBandiwdthTest
: public UnitTest::GridMateMPTestFixture
{
public:
@@ -3944,9 +3943,9 @@ GM_TEST_SUITE(ReplicaSuite)
GM_TEST(InterpolatorTest)
#if !defined(AZ_DEBUG_BUILD) // these tests are a little slow for debug
GM_TEST(Integ_ReplicaBandiwdthTest)
GM_TEST(Integ_ReplicaStressTest)
GM_TEST(Integ_ReplicaStableStressTest)
GM_TEST(DISABLED_ReplicaBandiwdthTest)
GM_TEST(DISABLED_ReplicaStressTest)
GM_TEST(DISABLED_ReplicaStableStressTest)
#endif
GM_TEST_SUITE_END()
@@ -457,13 +457,13 @@ namespace ReplicaBehavior {
Completed,
};
class Integ_SimpleBehaviorTest
class SimpleBehaviorTest
: public UnitTest::GridMateMPTestFixture
{
public:
//GM_CLASS_ALLOCATOR(SimpleBehaviorTest);
Integ_SimpleBehaviorTest()
SimpleBehaviorTest()
: m_sessionCount(0) { }
virtual int GetNumSessions() { return 0; }
@@ -654,11 +654,11 @@ namespace ReplicaBehavior {
*
* This is a simple sanity check to ensure the logic sends the update when it's necessary.
*/
class Integ_Replica_DontSendDataSets_WithNoDiffFromCtorData
: public Integ_SimpleBehaviorTest
class Replica_DontSendDataSets_WithNoDiffFromCtorData
: public SimpleBehaviorTest
{
public:
Integ_Replica_DontSendDataSets_WithNoDiffFromCtorData()
Replica_DontSendDataSets_WithNoDiffFromCtorData()
: m_replicaIdDefault(InvalidReplicaId), m_replicaIdModified(InvalidReplicaId)
{
}
@@ -774,9 +774,9 @@ namespace ReplicaBehavior {
FilteredHook<LargeChunkWithDefaults> m_driller;
};
TEST(Integ_Replica_DontSendDataSets_WithNoDiffFromCtorData, Integ_Replica_DontSendDataSets_WithNoDiffFromCtorData)
TEST(Replica_DontSendDataSets_WithNoDiffFromCtorData, DISABLED_Replica_DontSendDataSets_WithNoDiffFromCtorData)
{
Integ_Replica_DontSendDataSets_WithNoDiffFromCtorData tester;
Replica_DontSendDataSets_WithNoDiffFromCtorData tester;
tester.run();
}
@@ -784,11 +784,11 @@ namespace ReplicaBehavior {
* This test checks the actual size of the replica as marshalled in the binary payload.
* The assessment of the payload size is done using driller EBus.
*/
class Integ_ReplicaDefaultDataSetDriller
: public Integ_SimpleBehaviorTest
class ReplicaDefaultDataSetDriller
: public SimpleBehaviorTest
{
public:
Integ_ReplicaDefaultDataSetDriller()
ReplicaDefaultDataSetDriller()
: m_replicaId(InvalidReplicaId)
{
}
@@ -815,7 +815,7 @@ namespace ReplicaBehavior {
m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica);
}
~Integ_ReplicaDefaultDataSetDriller() override
~ReplicaDefaultDataSetDriller() override
{
m_driller.BusDisconnect();
}
@@ -880,11 +880,11 @@ namespace ReplicaBehavior {
ReplicaId m_replicaId;
};
const int Integ_ReplicaDefaultDataSetDriller::NonDefaultValue;
const int ReplicaDefaultDataSetDriller::NonDefaultValue;
TEST(Integ_ReplicaDefaultDataSetDriller, Integ_ReplicaDefaultDataSetDriller)
TEST(ReplicaDefaultDataSetDriller, DISABLED_ReplicaDefaultDataSetDriller)
{
Integ_ReplicaDefaultDataSetDriller tester;
ReplicaDefaultDataSetDriller tester;
tester.run();
}
@@ -892,11 +892,11 @@ namespace ReplicaBehavior {
* This test checks the actual size of the replica as marshalled in the binary payload.
* The assessment of the payload size is done using driller EBus.
*/
class Integ_Replica_ComparePackingBoolsVsU8
: public Integ_SimpleBehaviorTest
class Replica_ComparePackingBoolsVsU8
: public SimpleBehaviorTest
{
public:
Integ_Replica_ComparePackingBoolsVsU8()
Replica_ComparePackingBoolsVsU8()
: m_replicaBoolsId(InvalidReplicaId)
, m_replicaU8Id(InvalidReplicaId)
{
@@ -928,7 +928,7 @@ namespace ReplicaBehavior {
m_replicaU8Id = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica2);
}
~Integ_Replica_ComparePackingBoolsVsU8() override
~Replica_ComparePackingBoolsVsU8() override
{
m_driller.BusDisconnect();
}
@@ -1020,17 +1020,17 @@ namespace ReplicaBehavior {
ReplicaId m_replicaU8Id;
};
TEST(Integ_Replica_ComparePackingBoolsVsU8, Integ_Replica_ComparePackingBoolsVsU8)
TEST(Replica_ComparePackingBoolsVsU8, DISABLED_Replica_ComparePackingBoolsVsU8)
{
Integ_Replica_ComparePackingBoolsVsU8 tester;
Replica_ComparePackingBoolsVsU8 tester;
tester.run();
}
class Integ_CheckDataSetStreamIsntWrittenMoreThanNecessary
: public Integ_SimpleBehaviorTest
class CheckDataSetStreamIsntWrittenMoreThanNecessary
: public SimpleBehaviorTest
{
public:
Integ_CheckDataSetStreamIsntWrittenMoreThanNecessary()
CheckDataSetStreamIsntWrittenMoreThanNecessary()
: m_replicaId(InvalidReplicaId)
{
}
@@ -1057,7 +1057,7 @@ namespace ReplicaBehavior {
m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica);
}
~Integ_CheckDataSetStreamIsntWrittenMoreThanNecessary() override
~CheckDataSetStreamIsntWrittenMoreThanNecessary() override
{
m_driller.BusDisconnect();
}
@@ -1117,17 +1117,17 @@ namespace ReplicaBehavior {
ReplicaId m_replicaId;
};
TEST(Integ_CheckDataSetStreamIsntWrittenMoreThanNecessary, Integ_CheckDataSetStreamIsntWrittenMoreThanNecessary)
TEST(CheckDataSetStreamIsntWrittenMoreThanNecessary, DISABLED_CheckDataSetStreamIsntWrittenMoreThanNecessary)
{
Integ_CheckDataSetStreamIsntWrittenMoreThanNecessary tester;
CheckDataSetStreamIsntWrittenMoreThanNecessary tester;
tester.run();
}
class Integ_CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty
: public Integ_SimpleBehaviorTest
class CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty
: public SimpleBehaviorTest
{
public:
Integ_CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty()
CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty()
: m_replicaId(InvalidReplicaId)
{
}
@@ -1154,7 +1154,7 @@ namespace ReplicaBehavior {
m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica);
}
~Integ_CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty() override
~CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty() override
{
m_driller.BusDisconnect();
}
@@ -1213,17 +1213,17 @@ namespace ReplicaBehavior {
ReplicaId m_replicaId;
};
TEST(Integ_CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty, Integ_CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty)
TEST(CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty, DISABLED_CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty)
{
Integ_CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty tester;
CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty tester;
tester.run();
}
class Integ_CheckReplicaIsntSentWithNoChanges
: public Integ_SimpleBehaviorTest
class CheckReplicaIsntSentWithNoChanges
: public SimpleBehaviorTest
{
public:
Integ_CheckReplicaIsntSentWithNoChanges()
CheckReplicaIsntSentWithNoChanges()
: m_replicaId(InvalidReplicaId)
{
}
@@ -1248,7 +1248,7 @@ namespace ReplicaBehavior {
m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica);
}
~Integ_CheckReplicaIsntSentWithNoChanges() override
~CheckReplicaIsntSentWithNoChanges() override
{
m_driller.BusDisconnect();
}
@@ -1323,17 +1323,17 @@ namespace ReplicaBehavior {
ReplicaId m_replicaId;
};
TEST(Integ_CheckReplicaIsntSentWithNoChanges, Integ_CheckReplicaIsntSentWithNoChanges)
TEST(CheckReplicaIsntSentWithNoChanges, DISABLED_CheckReplicaIsntSentWithNoChanges)
{
Integ_CheckReplicaIsntSentWithNoChanges tester;
CheckReplicaIsntSentWithNoChanges tester;
tester.run();
}
class Integ_CheckEntityScriptReplicaIsntSentWithNoChanges
: public Integ_SimpleBehaviorTest
class CheckEntityScriptReplicaIsntSentWithNoChanges
: public SimpleBehaviorTest
{
public:
Integ_CheckEntityScriptReplicaIsntSentWithNoChanges()
CheckEntityScriptReplicaIsntSentWithNoChanges()
: m_replicaId(InvalidReplicaId)
{
}
@@ -1359,7 +1359,7 @@ namespace ReplicaBehavior {
m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica);
}
~Integ_CheckEntityScriptReplicaIsntSentWithNoChanges() override
~CheckEntityScriptReplicaIsntSentWithNoChanges() override
{
m_driller.BusDisconnect();
}
@@ -1410,9 +1410,9 @@ namespace ReplicaBehavior {
ReplicaId m_replicaId;
};
TEST(Integ_CheckEntityScriptReplicaIsntSentWithNoChanges, Integ_CheckEntityScriptReplicaIsntSentWithNoChanges)
TEST(CheckEntityScriptReplicaIsntSentWithNoChanges, DISABLED_CheckEntityScriptReplicaIsntSentWithNoChanges)
{
Integ_CheckEntityScriptReplicaIsntSentWithNoChanges tester;
CheckEntityScriptReplicaIsntSentWithNoChanges tester;
tester.run();
}
+80 -80
View File
@@ -596,12 +596,12 @@ public:
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
class MPSession
class MPSessionMedium
: public CarrierEventBus::Handler
{
public:
~MPSession() override
~MPSessionMedium() override
{
CarrierEventBus::Handler::BusDisconnect();
}
@@ -708,14 +708,14 @@ enum class TestStatus
Completed,
};
class Integ_SimpleTest
class SimpleTest
: public UnitTest::GridMateMPTestFixture
, public ::testing::Test
{
public:
//GM_CLASS_ALLOCATOR(Integ_SimpleTest);
//GM_CLASS_ALLOCATOR(SimpleTest);
Integ_SimpleTest()
SimpleTest()
: m_sessionCount(0) { }
virtual int GetNumSessions() { return 0; }
@@ -858,15 +858,15 @@ public:
}
int m_sessionCount;
AZStd::array<MPSession, 10> m_sessions;
AZStd::array<MPSessionMedium, 10> m_sessions;
AZStd::unique_ptr<DefaultSimulator> m_defaultSimulator;
};
class Integ_ReplicaChunkRPCExec
: public Integ_SimpleTest
class ReplicaChunkRPCExec
: public SimpleTest
{
public:
Integ_ReplicaChunkRPCExec()
ReplicaChunkRPCExec()
: m_chunk(nullptr)
, m_replicaId(0)
{ }
@@ -893,7 +893,7 @@ public:
ReplicaId m_replicaId;
};
TEST_F(Integ_ReplicaChunkRPCExec, ReplicaChunkRPCExec)
TEST_F(ReplicaChunkRPCExec, DISABLED_ReplicaChunkRPCExec)
{
RunTickLoop([this](int tick) -> TestStatus
{
@@ -1050,8 +1050,8 @@ int DestroyRPCChunk::s_afterDestroyFromPrimaryCalls = 0;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
class Integ_ReplicaDestroyedInRPC
: public Integ_SimpleTest
class ReplicaDestroyedInRPC
: public SimpleTest
{
public:
enum
@@ -1080,7 +1080,7 @@ public:
ReplicaId m_repId[2];
};
TEST_F(Integ_ReplicaDestroyedInRPC, ReplicaDestroyedInRPC)
TEST_F(ReplicaDestroyedInRPC, DISABLED_ReplicaDestroyedInRPC)
{
RunTickLoop([this](int tick)->TestStatus
{
@@ -1129,11 +1129,11 @@ TEST_F(Integ_ReplicaDestroyedInRPC, ReplicaDestroyedInRPC)
});
}
class Integ_ReplicaChunkAddWhileReplicated
: public Integ_SimpleTest
class ReplicaChunkAddWhileReplicated
: public SimpleTest
{
public:
Integ_ReplicaChunkAddWhileReplicated()
ReplicaChunkAddWhileReplicated()
: m_replica(nullptr)
, m_chunk(nullptr)
, m_replicaId(0)
@@ -1161,7 +1161,7 @@ public:
ReplicaId m_replicaId;
};
TEST_F(Integ_ReplicaChunkAddWhileReplicated, ReplicaChunkAddWhileReplicated)
TEST_F(ReplicaChunkAddWhileReplicated, DISABLED_ReplicaChunkAddWhileReplicated)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -1203,11 +1203,11 @@ TEST_F(Integ_ReplicaChunkAddWhileReplicated, ReplicaChunkAddWhileReplicated)
}
class Integ_ReplicaRPCValues
: public Integ_SimpleTest
class ReplicaRPCValues
: public SimpleTest
{
public:
Integ_ReplicaRPCValues()
ReplicaRPCValues()
: m_replica(nullptr)
, m_chunk(nullptr)
, m_replicaId(0)
@@ -1236,7 +1236,7 @@ public:
ReplicaId m_replicaId;
};
TEST_F(Integ_ReplicaRPCValues, ReplicaRPCValues)
TEST_F(ReplicaRPCValues, DISABLED_ReplicaRPCValues)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -1257,11 +1257,11 @@ TEST_F(Integ_ReplicaRPCValues, ReplicaRPCValues)
});
}
class Integ_FullRPCValues
: public Integ_SimpleTest
class FullRPCValues
: public SimpleTest
{
public:
Integ_FullRPCValues()
FullRPCValues()
: m_replica(nullptr)
, m_chunk(nullptr)
, m_replicaId(0)
@@ -1290,7 +1290,7 @@ public:
ReplicaId m_replicaId;
};
TEST_F(Integ_FullRPCValues, FullRPCValues)
TEST_F(FullRPCValues, DISABLED_FullRPCValues)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -1364,11 +1364,11 @@ TEST_F(Integ_FullRPCValues, FullRPCValues)
}
class Integ_ReplicaRemoveProxy
: public Integ_SimpleTest
class ReplicaRemoveProxy
: public SimpleTest
{
public:
Integ_ReplicaRemoveProxy()
ReplicaRemoveProxy()
: m_replica(nullptr)
, m_replicaId(0)
{
@@ -1395,7 +1395,7 @@ public:
ReplicaId m_replicaId;
};
TEST_F(Integ_ReplicaRemoveProxy, ReplicaRemoveProxy)
TEST_F(ReplicaRemoveProxy, DISABLED_ReplicaRemoveProxy)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -1424,11 +1424,11 @@ TEST_F(Integ_ReplicaRemoveProxy, ReplicaRemoveProxy)
}
class Integ_ReplicaChunkEvents
: public Integ_SimpleTest
class ReplicaChunkEvents
: public SimpleTest
{
public:
Integ_ReplicaChunkEvents()
ReplicaChunkEvents()
: m_replicaId(InvalidReplicaId)
, m_chunk(nullptr)
, m_proxyChunk(nullptr)
@@ -1463,7 +1463,7 @@ public:
AllEventChunk::Ptr m_proxyChunk;
};
TEST_F(Integ_ReplicaChunkEvents, ReplicaChunkEvents)
TEST_F(ReplicaChunkEvents, DISABLED_ReplicaChunkEvents)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -1501,11 +1501,11 @@ TEST_F(Integ_ReplicaChunkEvents, ReplicaChunkEvents)
}
class Integ_ReplicaChunksBeyond32
: public Integ_SimpleTest
class ReplicaChunksBeyond32
: public SimpleTest
{
public:
Integ_ReplicaChunksBeyond32()
ReplicaChunksBeyond32()
: m_replicaId(InvalidReplicaId)
{
}
@@ -1537,7 +1537,7 @@ public:
ReplicaId m_replicaId;
};
TEST_F(Integ_ReplicaChunksBeyond32, ReplicaChunksBeyond32)
TEST_F(ReplicaChunksBeyond32, DISABLED_ReplicaChunksBeyond32)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -1565,11 +1565,11 @@ TEST_F(Integ_ReplicaChunksBeyond32, ReplicaChunksBeyond32)
}
class Integ_ReplicaChunkEventsDeactivate
: public Integ_SimpleTest
class ReplicaChunkEventsDeactivate
: public SimpleTest
{
public:
Integ_ReplicaChunkEventsDeactivate()
ReplicaChunkEventsDeactivate()
: m_replica(nullptr)
, m_replicaId(0)
, m_chunk(nullptr)
@@ -1604,7 +1604,7 @@ public:
AllEventChunk::Ptr m_proxyChunk;
};
TEST_F(Integ_ReplicaChunkEventsDeactivate, ReplicaChunkEventsDeactivate)
TEST_F(ReplicaChunkEventsDeactivate, DISABLED_ReplicaChunkEventsDeactivate)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -1649,11 +1649,11 @@ TEST_F(Integ_ReplicaChunkEventsDeactivate, ReplicaChunkEventsDeactivate)
}
class Integ_ReplicaDriller
: public Integ_SimpleTest
class ReplicaDriller
: public SimpleTest
{
public:
Integ_ReplicaDriller()
ReplicaDriller()
: m_replicaId(InvalidReplicaId)
{
}
@@ -2007,7 +2007,7 @@ public:
m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica);
}
~Integ_ReplicaDriller() override
~ReplicaDriller() override
{
m_driller.BusDisconnect();
}
@@ -2016,7 +2016,7 @@ public:
ReplicaId m_replicaId;
};
TEST_F(Integ_ReplicaDriller, ReplicaDriller)
TEST_F(ReplicaDriller, DISABLED_ReplicaDriller)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -2082,11 +2082,11 @@ TEST_F(Integ_ReplicaDriller, ReplicaDriller)
}
class Integ_DataSetChangedTest
: public Integ_SimpleTest
class DataSetChangedTest
: public SimpleTest
{
public:
Integ_DataSetChangedTest()
DataSetChangedTest()
: m_replica(nullptr)
, m_replicaId(0)
, m_chunk(nullptr)
@@ -2115,7 +2115,7 @@ public:
DataSetChunk::Ptr m_chunk;
};
TEST_F(Integ_DataSetChangedTest, DataSetChangedTest)
TEST_F(DataSetChangedTest, DISABLED_DataSetChangedTest)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -2144,11 +2144,11 @@ TEST_F(Integ_DataSetChangedTest, DataSetChangedTest)
}
class Integ_CustomHandlerTest
: public Integ_SimpleTest
class CustomHandlerTest
: public SimpleTest
{
public:
Integ_CustomHandlerTest()
CustomHandlerTest()
: m_replica(nullptr)
, m_replicaId(0)
, m_chunk(nullptr)
@@ -2181,7 +2181,7 @@ public:
AZStd::scoped_ptr<CustomHandler> m_proxyHandler;
};
TEST_F(Integ_CustomHandlerTest, CustomHandlerTest)
TEST_F(CustomHandlerTest, DISABLED_CustomHandlerTest)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -2234,11 +2234,11 @@ TEST_F(Integ_CustomHandlerTest, CustomHandlerTest)
}
class Integ_NonConstMarshalerTest
: public Integ_SimpleTest
class NonConstMarshalerTest
: public SimpleTest
{
public:
Integ_NonConstMarshalerTest()
NonConstMarshalerTest()
: m_replica(nullptr)
, m_replicaId(0)
, m_chunk(nullptr)
@@ -2266,7 +2266,7 @@ public:
NonConstMarshalerChunk::Ptr m_chunk;
};
TEST_F(Integ_NonConstMarshalerTest, NonConstMarshalerTest)
TEST_F(NonConstMarshalerTest, DISABLED_NonConstMarshalerTest)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -2309,11 +2309,11 @@ TEST_F(Integ_NonConstMarshalerTest, NonConstMarshalerTest)
}
class Integ_SourcePeerTest
: public Integ_SimpleTest
class SourcePeerTest
: public SimpleTest
{
public:
Integ_SourcePeerTest()
SourcePeerTest()
: m_replica(nullptr)
, m_replicaId(0)
, m_chunk(nullptr)
@@ -2343,7 +2343,7 @@ public:
SourcePeerChunk::Ptr m_chunk2;
};
TEST_F(Integ_SourcePeerTest, SourcePeerTest)
TEST_F(SourcePeerTest, DISABLED_SourcePeerTest)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -2404,8 +2404,8 @@ TEST_F(Integ_SourcePeerTest, SourcePeerTest)
}
class Integ_SendWithPriority
: public Integ_SimpleTest
class SendWithPriority
: public SimpleTest
{
public:
enum
@@ -2438,8 +2438,8 @@ public:
{
public:
ReplicaDrillerHook()
: m_expectedSendValue(Integ_SendWithPriority::kNumReplicas)
, m_expectedRecvValue(Integ_SendWithPriority::kNumReplicas)
: m_expectedSendValue(SendWithPriority::kNumReplicas)
, m_expectedRecvValue(SendWithPriority::kNumReplicas)
{
}
@@ -2495,7 +2495,7 @@ public:
PriorityChunk::Ptr m_chunks[kNumReplicas];
};
TEST_F(Integ_SendWithPriority, SendWithPriority)
TEST_F(SendWithPriority, DISABLED_SendWithPriority)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -2511,8 +2511,8 @@ TEST_F(Integ_SendWithPriority, SendWithPriority)
}
class Integ_SuspendUpdatesTest
: public Integ_SimpleTest
class SuspendUpdatesTest
: public SimpleTest
{
public:
enum
@@ -2597,7 +2597,7 @@ public:
unsigned int m_numRpcCalled = 0;
};
TEST_F(Integ_SuspendUpdatesTest, SuspendUpdatesTest)
TEST_F(SuspendUpdatesTest, DISABLED_SuspendUpdatesTest)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -2657,7 +2657,7 @@ TEST_F(Integ_SuspendUpdatesTest, SuspendUpdatesTest)
}
class Integ_BasicHostChunkDescriptorTest
class BasicHostChunkDescriptorTest
: public UnitTest::GridMateMPTestFixture
, public ::testing::Test
{
@@ -2694,17 +2694,17 @@ public:
static int nProxyActivations;
};
};
int Integ_BasicHostChunkDescriptorTest::HostChunk::nPrimaryActivations = 0;
int Integ_BasicHostChunkDescriptorTest::HostChunk::nProxyActivations = 0;
int BasicHostChunkDescriptorTest::HostChunk::nPrimaryActivations = 0;
int BasicHostChunkDescriptorTest::HostChunk::nProxyActivations = 0;
TEST_F(Integ_BasicHostChunkDescriptorTest, BasicHostChunkDescriptorTest)
TEST_F(BasicHostChunkDescriptorTest, DISABLED_BasicHostChunkDescriptorTest)
{
AZ_TracePrintf("GridMate", "\n");
// Register test chunks
ReplicaChunkDescriptorTable::Get().RegisterChunkType<HostChunk, GridMate::BasicHostChunkDescriptor<HostChunk>>();
MPSession nodes[nNodes];
MPSessionMedium nodes[nNodes];
// initialize transport
int basePort = 4427;
@@ -2791,8 +2791,8 @@ TEST_F(Integ_BasicHostChunkDescriptorTest, BasicHostChunkDescriptorTest)
* Create and immedietly destroy primary replica
* Test that it does not result in any network sync
*/
class Integ_CreateDestroyPrimary
: public Integ_SimpleTest
class CreateDestroyPrimary
: public SimpleTest
, public Debug::ReplicaDrillerBus::Handler
{
public:
@@ -2827,7 +2827,7 @@ public:
}
};
TEST_F(Integ_CreateDestroyPrimary, CreateDestroyPrimary)
TEST_F(CreateDestroyPrimary, DISABLED_CreateDestroyPrimary)
{
RunTickLoop([this](int tick)-> TestStatus
{
@@ -2861,7 +2861,7 @@ TEST_F(Integ_CreateDestroyPrimary, CreateDestroyPrimary)
* The ReplicaTarget will prevent sending more updates.
*/
class ReplicaACKfeedbackTestFixture
: public Integ_SimpleTest
: public SimpleTest
{
public:
ReplicaACKfeedbackTestFixture()
@@ -2900,7 +2900,7 @@ public:
size_t m_replicaBytesSentPrev = 0;
ReplicaId m_replicaId;
Integ_ReplicaDriller::ReplicaDrillerHook m_driller;
ReplicaDriller::ReplicaDrillerHook m_driller;
};
TEST_F(ReplicaACKfeedbackTestFixture, ReplicaACKfeedbackTest)
+30 -30
View File
@@ -40,7 +40,7 @@ namespace UnitTest
}
}
class Integ_LANSessionMatchmakingParamsTest
class DISABLED_LANSessionMatchmakingParamsTest
: public GridMateMPTestFixture
, public SessionEventBus::MultiHandler
{
@@ -52,7 +52,7 @@ namespace UnitTest
}
public:
Integ_LANSessionMatchmakingParamsTest(bool useIPv6 = false)
DISABLED_LANSessionMatchmakingParamsTest(bool useIPv6 = false)
: m_hostSession(nullptr)
, m_clientGridMate(nullptr)
{
@@ -71,7 +71,7 @@ namespace UnitTest
AZ_TEST_ASSERT(GridMate::LANSessionServiceBus::FindFirstHandler(m_clientGridMate) != nullptr);
//////////////////////////////////////////////////////////////////////////
}
~Integ_LANSessionMatchmakingParamsTest() override
~DISABLED_LANSessionMatchmakingParamsTest() override
{
SessionEventBus::MultiHandler::BusDisconnect(m_gridMate);
SessionEventBus::MultiHandler::BusDisconnect(m_clientGridMate);
@@ -192,7 +192,7 @@ namespace UnitTest
IGridMate* m_clientGridMate;
};
class Integ_LANSessionTest
class DISABLED_LANSessionTest
: public GridMateMPTestFixture
{
class TestPeerInfo
@@ -264,7 +264,7 @@ namespace UnitTest
};
public:
Integ_LANSessionTest(bool useIPv6 = false)
DISABLED_LANSessionTest(bool useIPv6 = false)
{
m_driverType = useIPv6 ? Driver::BSD_AF_INET6 : Driver::BSD_AF_INET;
m_doSessionParamsTest = k_numMachines > 1;
@@ -290,7 +290,7 @@ namespace UnitTest
AZ_TEST_ASSERT(LANSessionServiceBus::FindFirstHandler(m_peers[i].m_gridMate) != nullptr);
}
}
~Integ_LANSessionTest() override
~DISABLED_LANSessionTest() override
{
StopGridMateService<LANSessionService>(m_peers[0].m_gridMate);
@@ -555,15 +555,15 @@ namespace UnitTest
bool m_doSessionParamsTest;
};
class Integ_LANSessionTestIPv6
: public Integ_LANSessionTest
class DISABLED_LANSessionTestIPv6
: public DISABLED_LANSessionTest
{
public:
Integ_LANSessionTestIPv6()
: Integ_LANSessionTest(true) {}
DISABLED_LANSessionTestIPv6()
: DISABLED_LANSessionTest(true) {}
};
class Integ_LANMultipleSessionTest
class DISABLED_LANMultipleSessionTest
: public GridMateMPTestFixture
, public SessionEventBus::Handler
{
@@ -620,7 +620,7 @@ namespace UnitTest
m_sessions[i] = nullptr;
}
Integ_LANMultipleSessionTest()
DISABLED_LANMultipleSessionTest()
: GridMateMPTestFixture(200 * 1024 * 1024)
{
//////////////////////////////////////////////////////////////////////////
@@ -645,7 +645,7 @@ namespace UnitTest
}
}
~Integ_LANMultipleSessionTest() override
~DISABLED_LANMultipleSessionTest() override
{
GridMate::StopGridMateService<GridMate::LANSessionService>(m_gridMates[0]);
@@ -799,7 +799,7 @@ namespace UnitTest
* Testing session with low latency. This is special mode usually used by tools and communication channels
* where we try to response instantly on messages.
*/
class Integ_LANLatencySessionTest
class DISABLED_LANLatencySessionTest
: public GridMateMPTestFixture
, public SessionEventBus::Handler
{
@@ -857,7 +857,7 @@ namespace UnitTest
m_sessions[i] = nullptr;
}
Integ_LANLatencySessionTest()
DISABLED_LANLatencySessionTest()
#ifdef AZ_TEST_LANLATENCY_ENABLE_MONSTER_BUFFER
: GridMateMPTestFixture(50 * 1024 * 1024)
#endif
@@ -884,7 +884,7 @@ namespace UnitTest
}
}
~Integ_LANLatencySessionTest() override
~DISABLED_LANLatencySessionTest() override
{
StopGridMateService<LANSessionService>(m_gridMates[0]);
@@ -1162,7 +1162,7 @@ namespace UnitTest
* 5. After host migration we drop the new host again. (after migration we have 3 members).
* Session should be fully operational at the end with 3 members left.
*/
class Integ_LANSessionMigarationTestTest
class LANSessionMigarationTestTest
: public SessionEventBus::Handler
, public GridMateMPTestFixture
{
@@ -1257,7 +1257,7 @@ namespace UnitTest
}
}
Integ_LANSessionMigarationTestTest()
LANSessionMigarationTestTest()
{
//////////////////////////////////////////////////////////////////////////
// Create all grid mates
@@ -1283,7 +1283,7 @@ namespace UnitTest
//StartDrilling("lanmigration");
}
~Integ_LANSessionMigarationTestTest() override
~LANSessionMigarationTestTest() override
{
StopGridMateService<LANSessionService>(m_gridMates[0]);
@@ -1476,7 +1476,7 @@ namespace UnitTest
* 5. We join a 2 new members to the session.
* Session should be fully operational at the end with 4 members in it.
*/
class Integ_LANSessionMigarationTestTest2
class LANSessionMigarationTestTest2
: public SessionEventBus::Handler
, public GridMateMPTestFixture
{
@@ -1571,7 +1571,7 @@ namespace UnitTest
}
}
}
Integ_LANSessionMigarationTestTest2()
LANSessionMigarationTestTest2()
{
//////////////////////////////////////////////////////////////////////////
// Create all grid mates
@@ -1597,7 +1597,7 @@ namespace UnitTest
//StartDrilling("lanmigration2");
}
~Integ_LANSessionMigarationTestTest2() override
~LANSessionMigarationTestTest2() override
{
StopGridMateService<LANSessionService>(m_gridMates[0]);
@@ -1816,7 +1816,7 @@ namespace UnitTest
* 3. Add 2 new joins to the original session.
* Original session should remain fully operational with 4 members in it.
*/
class Integ_LANSessionMigarationTestTest3
class LANSessionMigarationTestTest3
: public SessionEventBus::Handler
, public GridMateMPTestFixture
{
@@ -1910,7 +1910,7 @@ namespace UnitTest
}
}
}
Integ_LANSessionMigarationTestTest3()
LANSessionMigarationTestTest3()
{
//////////////////////////////////////////////////////////////////////////
// Create all grid mates
@@ -1936,7 +1936,7 @@ namespace UnitTest
//StartDrilling("lanmigration2");
}
~Integ_LANSessionMigarationTestTest3() override
~LANSessionMigarationTestTest3() override
{
StopGridMateService<LANSessionService>(m_gridMates[0]);
@@ -2122,13 +2122,13 @@ namespace UnitTest
}
GM_TEST_SUITE(SessionSuite)
GM_TEST(Integ_LANSessionMatchmakingParamsTest)
GM_TEST(Integ_LANSessionTest)
GM_TEST(DISABLED_LANSessionMatchmakingParamsTest)
GM_TEST(DISABLED_LANSessionTest)
#if (AZ_TRAIT_GRIDMATE_TEST_SOCKET_IPV6_SUPPORT_ENABLED)
GM_TEST(Integ_LANSessionTestIPv6)
GM_TEST(DISABLED_LANSessionTestIPv6)
#endif
GM_TEST(Integ_LANMultipleSessionTest)
GM_TEST(Integ_LANLatencySessionTest)
GM_TEST(DISABLED_LANMultipleSessionTest)
GM_TEST(DISABLED_LANLatencySessionTest)
// Manually enabled tests (require 2+ machines and online services)
//GM_TEST(LANSessionMigarationTestTest)
@@ -110,7 +110,7 @@ namespace UnitTest
std::array<char, SIZE> m_buffer;
};
class Integ_StreamSecureSocketDriverTestsBindSocketEmpty
class DISABLED_StreamSecureSocketDriverTestsBindSocketEmpty
: public GridMateMPTestFixture
{
public:
@@ -134,7 +134,7 @@ namespace UnitTest
}
};
class Integ_StreamSecureSocketDriverTestsConnection
class DISABLED_StreamSecureSocketDriverTestsConnection
: public GridMateMPTestFixture
{
public:
@@ -146,7 +146,7 @@ namespace UnitTest
}
};
class Integ_StreamSecureSocketDriverTestsConnectionAndHelloWorld
class DISABLED_StreamSecureSocketDriverTestsConnectionAndHelloWorld
: public GridMateMPTestFixture
{
public:
@@ -190,7 +190,7 @@ namespace UnitTest
}
};
class Integ_StreamSecureSocketDriverTestsPingPong
class DISABLED_StreamSecureSocketDriverTestsPingPong
: public GridMateMPTestFixture
{
public:
@@ -425,13 +425,13 @@ namespace UnitTest
void BuildStateMachine()
{
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_TOP), AZ::HSM::StateHandler(this, &Integ_StreamSecureSocketDriverTestsPingPong::OnStateTop), AZ::HSM::InvalidStateId, TS_START);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_START), AZ::HSM::StateHandler(this, &Integ_StreamSecureSocketDriverTestsPingPong::OnStateStart), TS_TOP);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_SERVER_GET_PING), AZ::HSM::StateHandler(this, &Integ_StreamSecureSocketDriverTestsPingPong::OnStateServerGetPing), TS_TOP);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_PING_GET_SERVER), AZ::HSM::StateHandler(this, &Integ_StreamSecureSocketDriverTestsPingPong::OnStatePingGetServer), TS_TOP);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_SERVER_GET_PONG), AZ::HSM::StateHandler(this, &Integ_StreamSecureSocketDriverTestsPingPong::OnStateServerGetPong), TS_TOP);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_PONG_GET_SERVER), AZ::HSM::StateHandler(this, &Integ_StreamSecureSocketDriverTestsPingPong::OnStatePongGetServer), TS_TOP);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_IN_ERROR), AZ::HSM::StateHandler(this, &Integ_StreamSecureSocketDriverTestsPingPong::OnStateInError), TS_TOP);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_TOP), AZ::HSM::StateHandler(this, &DISABLED_StreamSecureSocketDriverTestsPingPong::OnStateTop), AZ::HSM::InvalidStateId, TS_START);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_START), AZ::HSM::StateHandler(this, &DISABLED_StreamSecureSocketDriverTestsPingPong::OnStateStart), TS_TOP);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_SERVER_GET_PING), AZ::HSM::StateHandler(this, &DISABLED_StreamSecureSocketDriverTestsPingPong::OnStateServerGetPing), TS_TOP);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_PING_GET_SERVER), AZ::HSM::StateHandler(this, &DISABLED_StreamSecureSocketDriverTestsPingPong::OnStatePingGetServer), TS_TOP);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_SERVER_GET_PONG), AZ::HSM::StateHandler(this, &DISABLED_StreamSecureSocketDriverTestsPingPong::OnStateServerGetPong), TS_TOP);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_PONG_GET_SERVER), AZ::HSM::StateHandler(this, &DISABLED_StreamSecureSocketDriverTestsPingPong::OnStatePongGetServer), TS_TOP);
m_stateMachine.SetStateHandler(AZ_HSM_STATE_NAME(TS_IN_ERROR), AZ::HSM::StateHandler(this, &DISABLED_StreamSecureSocketDriverTestsPingPong::OnStateInError), TS_TOP);
m_stateMachine.Start();
}
@@ -486,10 +486,10 @@ namespace UnitTest
}
GM_TEST_SUITE(StreamSecureSocketDriverTests)
GM_TEST(Integ_StreamSecureSocketDriverTestsBindSocketEmpty);
GM_TEST(Integ_StreamSecureSocketDriverTestsConnection);
GM_TEST(Integ_StreamSecureSocketDriverTestsConnectionAndHelloWorld);
GM_TEST(Integ_StreamSecureSocketDriverTestsPingPong);
GM_TEST(DISABLED_StreamSecureSocketDriverTestsBindSocketEmpty);
GM_TEST(DISABLED_StreamSecureSocketDriverTestsConnection);
GM_TEST(DISABLED_StreamSecureSocketDriverTestsConnectionAndHelloWorld);
GM_TEST(DISABLED_StreamSecureSocketDriverTestsPingPong);
GM_TEST_SUITE_END()
#endif // AZ_TRAIT_GRIDMATE_ENABLE_OPENSSL
@@ -308,7 +308,7 @@ namespace UnitTest
}
};
class Integ_StreamSocketDriverTestsTooManyConnections
class DISABLED_StreamSocketDriverTestsTooManyConnections
: public GridMateMPTestFixture
{
public:
@@ -529,7 +529,7 @@ GM_TEST_SUITE(StreamSocketDriverTests)
GM_TEST(StreamSocketDriverTestsSimpleLockStepConnection);
GM_TEST(StreamSocketDriverTestsEstablishConnectAndSend);
GM_TEST(StreamSocketDriverTestsManyRandomPackets);
GM_TEST(Integ_StreamSocketDriverTestsTooManyConnections);
GM_TEST(DISABLED_StreamSocketDriverTestsTooManyConnections);
GM_TEST(StreamSocketDriverTestsClientToInvalidServer);
GM_TEST(StreamSocketDriverTestsManySends);
@@ -1,244 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "Tests.h"
#include "TestProfiler.h"
#include <AzCore/Debug/Profiler.h>
#include <AzCore/Math/Crc.h>
#include <GridMate/Containers/set.h>
#include <GridMate/Containers/unordered_set.h>
using namespace GridMate;
typedef set<const AZ::Debug::ProfilerRegister*> ProfilerSet;
static bool CollectPerformanceCounters(const AZ::Debug::ProfilerRegister& reg, const AZStd::thread_id&, ProfilerSet& profilers, const char* systemId)
{
if (reg.m_type != AZ::Debug::ProfilerRegister::PRT_TIME)
{
return true;
}
if (reg.m_systemId != AZ::Crc32(systemId))
{
return true;
}
const AZ::Debug::ProfilerRegister* profReg = &reg;
profilers.insert(profReg);
return true;
}
static AZStd::string FormatString(const AZStd::string& pre, const AZStd::string& name, const AZStd::string& post, AZ::u64 time, AZ::u64 calls)
{
AZStd::string units = "us";
if (AZ::u64 divtime = time / 1000)
{
time = divtime;
units = "ms";
}
return AZStd::string::format("%s%s %s %10llu%s (%llu calls)\n", pre.c_str(), name.c_str(), post.c_str(), time, units.c_str(), calls);
}
struct TotalSortContainer
{
TotalSortContainer(const AZ::Debug::ProfilerRegister* self = nullptr)
{
m_self = self;
}
void Print(AZ::s32 level, const char* systemId)
{
if (m_self && level >= 0)
{
AZStd::string levelIndent;
for (AZ::s32 i = 0; i < level; i++)
{
levelIndent += (i == level - 1) ? "+---" : "| ";
}
AZStd::string name = m_self->m_name ? m_self->m_name : m_self->m_function;
AZStd::string outputTotal = FormatString(levelIndent, name, " Total:", m_self->m_timeData.m_time, m_self->m_timeData.m_calls);
AZ_Printf(systemId, outputTotal.c_str());
if (m_self->m_timeData.m_childrenTime || m_self->m_timeData.m_childrenCalls)
{
AZStd::string childIndent = levelIndent;
for (auto i = name.begin(); i != name.end(); ++i)
{
childIndent += " ";
}
childIndent[level * 4] = '|';
AZStd::string outputChild = FormatString(childIndent, "", "Child:", m_self->m_timeData.m_childrenTime, m_self->m_timeData.m_childrenCalls);
AZ_Printf(systemId, outputChild.c_str());
AZStd::string outputSelf = FormatString(childIndent, "", "Self :", m_self->m_timeData.m_time - m_self->m_timeData.m_childrenTime, m_self->m_timeData.m_calls);
AZ_Printf(systemId, outputSelf.c_str());
}
}
for (auto i = m_children.begin(); i != m_children.end(); ++i)
{
i->Print(level + 1, systemId);
}
}
TotalSortContainer* Find(const AZ::Debug::ProfilerRegister* obj)
{
if (m_self == obj)
{
return this;
}
for (TotalSortContainer& child : m_children)
{
TotalSortContainer* found = child.Find(obj);
if (found)
{
return found;
}
}
return nullptr;
}
struct TotalSorter
{
bool operator()(const TotalSortContainer& a, const TotalSortContainer& b) const
{
if (a.m_self->m_timeData.m_time == b.m_self->m_timeData.m_time)
{
return a.m_self > b.m_self;
}
return a.m_self->m_timeData.m_time > b.m_self->m_timeData.m_time;
}
};
set<TotalSortContainer, TotalSorter> m_children;
const AZ::Debug::ProfilerRegister* m_self;
};
void TestProfiler::StartProfiling()
{
StopProfiling();
AZ::Debug::Profiler::Create();
}
void TestProfiler::StopProfiling()
{
if (AZ::Debug::Profiler::IsReady())
{
AZ::Debug::Profiler::Destroy();
}
}
void TestProfiler::PrintProfilingTotal(const char* systemId)
{
if (!AZ::Debug::Profiler::IsReady())
{
return;
}
ProfilerSet profilers;
AZ::Debug::Profiler::Instance().ReadRegisterValues(AZStd::bind(&CollectPerformanceCounters, AZStd::placeholders::_1, AZStd::placeholders::_2, AZStd::ref(profilers), systemId));
// Validate we wont get stuck in an infinite loop
TotalSortContainer root;
for (auto i = profilers.begin(); i != profilers.end(); )
{
const AZ::Debug::ProfilerRegister* profile = *i;
if (profile->m_timeData.m_lastParent)
{
auto parent = profilers.find(profile->m_timeData.m_lastParent);
if (parent == profilers.end())
{
// Error, just ignore this entry
i = profilers.erase(i);
continue;
}
}
++i;
}
// Put all root nodes into the final list
for (auto i = profilers.begin(); i != profilers.end(); )
{
const AZ::Debug::ProfilerRegister* profile = *i;
if (!profile->m_timeData.m_lastParent)
{
root.m_children.insert(profile);
i = profilers.erase(i);
}
else
{
++i;
}
}
// Put all non-root nodes into the final list
while (!profilers.empty())
{
for (auto i = profilers.begin(); i != profilers.end(); )
{
const AZ::Debug::ProfilerRegister* profile = *i;
TotalSortContainer* found = root.Find(profile->m_timeData.m_lastParent);
if (found)
{
found->m_children.insert(profile);
i = profilers.erase(i);
}
else
{
++i;
}
}
}
AZ_Printf(systemId, "Profiling timers by total execution time:\n");
root.Print(-1, systemId);
}
void TestProfiler::PrintProfilingSelf(const char* systemId)
{
if (!AZ::Debug::Profiler::IsReady())
{
return;
}
ProfilerSet profilers;
AZ::Debug::Profiler::Instance().ReadRegisterValues(AZStd::bind(&CollectPerformanceCounters, AZStd::placeholders::_1, AZStd::placeholders::_2, AZStd::ref(profilers), systemId));
struct SelfSorter
{
bool operator()(const AZ::Debug::ProfilerRegister* a, const AZ::Debug::ProfilerRegister* b) const
{
auto aTime = a->m_timeData.m_time - a->m_timeData.m_childrenTime;
auto bTime = b->m_timeData.m_time - b->m_timeData.m_childrenTime;
if (aTime == bTime)
{
return a > b;
}
return aTime > bTime;
}
};
set<const AZ::Debug::ProfilerRegister*, SelfSorter> selfSorted;
for (auto& profiler : profilers)
{
selfSorted.insert(profiler);
}
AZ_Printf(systemId, "Profiling timers by exclusive execution time:\n");
for (auto profiler : selfSorted)
{
AZStd::string str = FormatString("", profiler->m_name ? profiler->m_name : profiler->m_function, "Self Time:",
profiler->m_timeData.m_time - profiler->m_timeData.m_childrenTime, profiler->m_timeData.m_calls);
AZ_Printf(systemId, str.c_str());
}
}
@@ -1,24 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef GM_TEST_PROFILER_H
#define GM_TEST_PROFILER_H
namespace GridMate
{
class TestProfiler
{
public:
static void StartProfiling();
static void StopProfiling();
static void PrintProfilingTotal(const char* systemId);
static void PrintProfilingSelf(const char* systemId);
};
}
#endif
@@ -12,6 +12,7 @@ set(FILES
Session.cpp
Serialize.cpp
Certificates.cpp
Replica.cpp
ReplicaSmall.cpp
ReplicaMedium.cpp
ReplicaBehavior.cpp
+5 -74
View File
@@ -18,45 +18,35 @@ namespace AzTestRunner
const int LIB_NOT_FOUND = 102;
const int SYMBOL_NOT_FOUND = 103;
// note that MODULE_SKIPPED is not an error condition, but not 0 to indicate its not the
// same as successfully running tests and finding them.
const int MODULE_SKIPPED = 104;
const char* INTEG_BOOTSTRAP = "AzTestIntegBootstrap";
//! display proper usage of the application
void usage([[maybe_unused]] AZ::Test::Platform& platform)
{
std::stringstream ss;
ss <<
"AzTestRunner\n"
"Runs AZ unit and integration tests. Exit code is the result from GoogleTest.\n"
"Runs AZ tests. Exit code is the result from GoogleTest.\n"
"\n"
"Usage:\n"
" AzTestRunner.exe <lib> (AzRunUnitTests|AzRunIntegTests) [--integ] [--wait-for-debugger] [--pause-on-completion] [google-test-args]\n"
" AzTestRunner.exe <lib> (AzRunUnitTests|AzRunBenchmarks) [--wait-for-debugger] [--pause-on-completion] [google-test-args]\n"
"\n"
"Options:\n"
" <lib>: the module to test\n"
" <hook>: the name of the aztest hook function to run in the <lib>\n"
" 'AzRunUnitTests' will hook into unit tests\n"
" 'AzRunIntegTests' will hook into integration tests\n"
" --integ: tells runner to bootstrap the engine, needed for integration tests\n"
" Note: you can run unit tests with a bootstrapped engine (AzRunUnitTests --integ),\n"
" but running integration tests without a bootstrapped engine (AzRunIntegTests w/ no --integ) might not work.\n"
" 'AzRunBenchmarks' will hook into benchmark tests\n"
" --wait-for-debugger: tells runner to wait for debugger to attach to process (on supported platforms)\n"
" --pause-on-completion: tells the runner to pause after running the tests\n"
" --quiet: disables stdout for minimal output while running tests\n"
"\n"
"Example:\n"
" AzTestRunner.exe CrySystem.dll AzRunUnitTests --pause-on-completion\n"
" AzTestRunner.exe CrySystem.dll AzRunIntegTests --integ\n"
" AzTestRunner.exe AzCore.Tests.dll AzRunUnitTests --pause-on-completion\n"
"\n"
"Exit Codes:\n"
" 0 - all tests pass\n"
" 1 - test failure\n"
<< " " << INCORRECT_USAGE << " - incorrect usage (see above)\n"
<< " " << LIB_NOT_FOUND << " - library/dll could not be loaded\n"
<< " " << SYMBOL_NOT_FOUND << " - export symbol not found\n"
<< " " << MODULE_SKIPPED << " - non-integ module was skipped (not an error)\n";
<< " " << SYMBOL_NOT_FOUND << " - export symbol not found\n";
std::cerr << ss.str() << std::endl;
}
@@ -82,7 +72,6 @@ namespace AzTestRunner
// capture optional arguments
bool waitForDebugger = false;
bool isInteg = false;
bool pauseOnCompletion = false;
bool quiet = false;
for (int i = 0; i < argc; i++)
@@ -93,12 +82,6 @@ namespace AzTestRunner
AZ::Test::RemoveParameters(argc, argv, i, i);
i--;
}
else if (strcmp(argv[i], "--integ") == 0)
{
isInteg = true;
AZ::Test::RemoveParameters(argc, argv, i, i);
i--;
}
else if (strcmp(argv[i], "--pause-on-completion") == 0)
{
pauseOnCompletion = true;
@@ -172,47 +155,11 @@ namespace AzTestRunner
if (result != 0)
{
module.reset();
if ((isInteg) && (result == SYMBOL_NOT_FOUND))
{
// special case: It is not required to put an INTEG test inside every DLL - so if
// we failed to find the INTEG entry point in this DLL, its not an error.
// its only an error if we find it and there are no tests, or we find it and tests actually
// fail.
std::cerr << "INTEG module has no entry point and will be skipped: " << lib << std::endl;
return MODULE_SKIPPED;
}
return result;
}
platform.SuppressPopupWindows();
// Grab a bootstrapper library if requested
std::shared_ptr<AZ::Test::IModuleHandle> bootstrap;
if (isInteg)
{
bootstrap = platform.GetModule(INTEG_BOOTSTRAP);
if (!bootstrap->IsValid())
{
std::cerr << "FAILED to load bootstrapper" << std::endl;
return LIB_NOT_FOUND;
}
// Initialize the bootstrapper
auto init = bootstrap->GetFunction("Initialize");
if (init->IsValid())
{
int initResult = (*init)();
if (initResult != 0)
{
std::cerr << "Bootstrapper Initialize failed with code " << initResult << ", exiting" << std::endl;
return initResult;
}
}
}
// run the test main function.
if (testMainFunction->IsValid())
{
@@ -231,22 +178,6 @@ namespace AzTestRunner
// system allocator / etc.
module.reset();
// Shutdown the bootstrapper
if (bootstrap)
{
auto shutdown = bootstrap->GetFunction("Shutdown");
if (shutdown->IsValid())
{
int shutdownResult = (*shutdown)();
if (shutdownResult != 0)
{
std::cerr << "Bootstrapper shutdown failed with code " << shutdownResult << ", exiting" << std::endl;
return shutdownResult;
}
}
bootstrap.reset();
}
if (pauseOnCompletion)
{
AzTestRunner::pause_on_completion();
@@ -10,7 +10,6 @@
#include <scenesrg.srgi>
#include <viewsrg.srgi>
#include "JitterTablePcf.azsli"
#include "Shadow.azsli"
#include "ShadowmapAtlasLib.azsli"
#include "BicubicPcfFilters.azsli"
@@ -82,12 +81,6 @@ class DirectionalLightShadow
// result.y == true if the given coordinate is in shadow.
bool2 IsShadowed(float3 shadowCoord, uint indexOfCascade);
// This checks if the point is shadowed or not for the given center coordinate and jitter.
bool IsShadowedWithJitter(
float3 jitterUnit,
float jitterDepthDiffBase,
uint jitterIndex);
// This outputs visibility ratio (from 0.0 to 1.0) of the given coordinate
// from the light origin without filtering.
float GetVisibilityFromLightNoFilter();
@@ -189,75 +182,6 @@ bool2 DirectionalLightShadow::IsShadowed(float3 shadowCoord, uint indexOfCascade
return bool2(false, false);
}
bool DirectionalLightShadow::IsShadowedWithJitter(
float3 jitterUnit,
float jitterDepthDiffBase,
uint jitterIndex)
{
const uint cascadeCount = ViewSrg::m_directionalLightShadows[m_lightIndex].m_cascadeCount;
const float4x4 worldToLightViewMatrices[ViewSrg::MaxCascadeCount] =
ViewSrg::m_directionalLightShadows[m_lightIndex].m_worldToLightViewMatrices;
const float4x4 lightViewToShadowmapMatrices[ViewSrg::MaxCascadeCount] =
ViewSrg::m_directionalLightShadows[m_lightIndex].m_lightViewToShadowmapMatrices;
const float boundaryScale =
ViewSrg::m_directionalLightShadows[m_lightIndex].m_boundaryScale;
const float2 jitterXY = g_jitterTablePcf[jitterIndex];
// jitterLightView is the jittering diff vector from the lighted point on the surface
// in the light view space. It is remarked as "v_J" in the comment
// named "Calculate depth adjusting diff for jittered samples"
// just before the function GetJitterUnitVectorDepthDiffBase.
const float4 jitterLightView = float4(jitterXY, 0., 0.) * boundaryScale;
// It checks the jittered point is lit or shadowed from the detailed cascade
// to the less detailed one.
for (uint indexOfCascade = 0; indexOfCascade < cascadeCount; ++indexOfCascade)
{
// jitterShadowmap is the jittering diff vector in the shadowmap space.
const float4 jitterShadowmap = mul(lightViewToShadowmapMatrices[indexOfCascade], jitterLightView);
// Calculation of the jittering for Z-coordinate (light direction) is required
// to check lit/shadowed for the jittered point.
// jitterDepthDiff is the Z-coordinate of the jittering diff vector
// in the shadowmap space.
float jitterDepthDiff = 0.;
// jitterDepthDiffBase is "1/tan(theta)" in the comment.
if (jitterDepthDiffBase != 0.)
{
// jitterUnitLightView is the unit vector in the light view space
// noted as "v_M" in the comment.
const float3 jitterUnitLightView =
normalize(mul(worldToLightViewMatrices[indexOfCascade], float4(jitterUnit, 0.)).xyz);
const float lightViewToShadowmapZScale = -lightViewToShadowmapMatrices[indexOfCascade]._m22;
// jitterDepthDiff is the "d" in the note, and it is calculated by
// d = (v_J . v_M) / tan(theta)
// in the light view space. Furthermore it have to be converted
// to the light clip space, which can be done by lightViewToShadowmapZScale.
jitterDepthDiff =
dot(jitterLightView.xyz, jitterUnitLightView) * jitterDepthDiffBase *
lightViewToShadowmapZScale;
}
// jitteredCoord is the coordinate of the jittered point in the shadowmap space.
const float3 jitteredCoord =
m_shadowCoords[indexOfCascade] + float3(jitterShadowmap.xy, jitterDepthDiff);
// Check for the jittered point is lit or shadowed.
const bool2 checkedShadowed = IsShadowed(
jitteredCoord,
indexOfCascade);
// If check is done, return the lit/shadowed flag.
// Otherwise make it pend to the next cascade.
if (checkedShadowed.x)
{
m_debugInfo.m_cascadeIndex = indexOfCascade;
return checkedShadowed.y;
}
}
m_debugInfo.m_cascadeIndex = cascadeCount;
return false;
}
float DirectionalLightShadow::GetVisibilityFromLightNoFilter()
{
const uint cascadeCount = ViewSrg::m_directionalLightShadows[m_lightIndex].m_cascadeCount;
@@ -1,185 +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
*
*/
/*
The following is the output of
$ python3 pcf_jitter_table.py 6 g_jitterTablePcf 0
where pcf_jitter_table.py has the following contents.
@code
#!/usr/bin/env python3
import random
import sys
import math
""" Returns if a point in the range
[radius_min, radius_sup)*[angle_min, angle_sup)
is contained in the tuple polar coordinates.
"""
def is_point_include(radius_min, radius_sup, angle_min, angle_sup, polars):
for polar in polars:
if (radius_min <= polar[0] and polar[0] < radius_sup and
angle_min <= polar[1] and polar[1] < angle_sup):
return True
return False
""" Insert a randomly generated polar coordianted point in each
range [r0, r1)*[a0, a1) if there has not been such a point
in tuple coords yet, where [0, 1)*[0, 2pi) is divided
into the rad_count*agl_count ranges.
"""
def add_jitter_coords(radius_count, angle_count, polars):
radius_base = 1.0 / math.sqrt(radius_count)
for radius_index in range(radius_count):
# range of radius
radius_min = math.sqrt(radius_index) * radius_base
radius_sup = math.sqrt(radius_index + 1) * radius_base
# randomize angle order
random_state = random.getstate()
angle_indices = list(range(angle_count))
random.shuffle(angle_indices)
random.setstate(random_state)
for angle_index in angle_indices:
# range of angle
angle_min = 2 * math.pi * angle_index / angle_count
angle_sup = 2 * math.pi * (angle_index + 1) / angle_count
# if no point in the radius/angle range, add a new point
if not is_point_include(radius_min, radius_sup,
angle_min, angle_sup,
polars):
radius = radius_min + (radius_sup - radius_min) * random.random()
angle = angle_min + (angle_sup - angle_min) * random.random()
polars += [[radius, angle]]
""" Return a formatted string readable as an array of
orthogonal coordinated points which are in inside of the unit disk.
"""
def conv_array_string(polars):
result = "{\n"
for [radius, angle] in polars:
x = radius * math.cos(angle)
y = radius * math.sin(angle)
result += str.format(" float2({: 1.20e}, {: 1.20e}),\n", x, y)
result = result.rstrip(",\n") + "\n};\n"
return result
if __name__ == "__main__":
rad_size = 1
ang_size = 1
if len(sys.argv) > 3:
random_seed = int(sys.argv[3])
else:
random_seed = 0
if len(sys.argv) > 2:
array_name = sys.argv[2]
else:
array_name = False
if len(sys.argv) > 1:
len_log = int(sys.argv[1])
else:
print(" usage: {} array_len_log2 [array_file_name] [random_seed]".format(__file__))
print(" array_len_log2 = 2 -> array length = 4")
print(" array_len_log2 = 6 -> array length = 64")
sys.exit()
random.seed(random_seed)
coords = []
add_jitter_coords(rad_size, ang_size, coords)
for index in range(len_log):
if index % 2 == 0:
rad_size *= 2
else:
ang_size *= 2
add_jitter_coords(rad_size, ang_size, coords)
if array_name:
print(str.format("static const float2 {}[{}] =", array_name, len(coords)))
print(conv_array_string(coords))
@endcode
*/
#pragma once
static const float2 g_jitterTablePcf[64] =
{
float2( 4.21857815578105532772e-02, -8.43367430701083664601e-01),
float2(-1.66526814909220763350e-02, 2.96922406531470617352e-01),
float2(-1.06374665780382349212e-01, -3.45521852905696924552e-01),
float2( 5.42648241814168375008e-01, 7.63475573328278533936e-01),
float2(-1.55045122122251910479e-01, 5.78282315712970729216e-01),
float2( 1.01310018770242576264e-02, -6.88001749851880561870e-01),
float2(-5.41276603451248283783e-01, 5.21888233660957712168e-01),
float2(-6.69885071867917680777e-01, -6.72019666097878665134e-01),
float2( 1.22985029409499718039e-02, 4.54706838949524849713e-01),
float2( 4.00334354168925599105e-01, -6.20112671104014120949e-02),
float2( 2.32326155804074424571e-01, 5.14183027524470093184e-01),
float2(-3.26788693165450228051e-01, -6.03339478694129849323e-01),
float2( 7.72374386126136736053e-01, 1.23204314299169448432e-01),
float2(-4.45379212004159807936e-01, -6.35591042627205338178e-01),
float2( 9.86986293787213919693e-01, -5.18195017297516449806e-02),
float2(-9.09197225477999193544e-01, 1.95281945570711268356e-01),
float2( 8.78123785413316704229e-02, -2.77671865082058690055e-02),
float2( 1.93947312440399088906e-01, 4.27852204081567363825e-03),
float2(-2.06133675819526185347e-01, -1.49183652412411493771e-01),
float2(-4.11351098583102647854e-01, 2.36214692717993696158e-01),
float2( 3.50058750095615767162e-01, -3.57193658067260721989e-01),
float2(-5.54174780014121681759e-01, -2.23361040823672196698e-01),
float2(-6.29913348094886860196e-01, 1.29962593232600148729e-01),
float2( 3.96119563669521335125e-01, 4.90495219155295036906e-01),
float2( 7.26077464944819728210e-01, -3.70531027878536270426e-02),
float2(-5.50726266551596621568e-01, 6.48997654184258587762e-01),
float2(-6.98067624269093189859e-01, -3.83843898992943299842e-01),
float2( 8.72900706885875177221e-02, 8.24287559846993866941e-01),
float2( 6.65413234189638491678e-01, -5.66029707430476647367e-01),
float2(-5.97071574457786802270e-01, -6.93417220711863180327e-01),
float2( 6.09778569514949131403e-01, 6.92279483269558570946e-01),
float2(-8.10051800827623957879e-01, 5.82366304247235455627e-01),
float2(-8.77200948157437071506e-02, -1.88326609190753474499e-01),
float2( 9.79306884403889771340e-02, 1.86693151785678163046e-01),
float2( 4.60071424048798319206e-02, -1.98255149016034859510e-01),
float2(-5.37585860722621794450e-02, 3.99205315590760584366e-02),
float2( 2.18621803321778829243e-01, -3.85632280444686503795e-01),
float2(-2.98409571230789372187e-02, 4.22286693608096730390e-01),
float2( 3.58654757584850270025e-01, 2.95175871390239985548e-01),
float2(-3.85631921979480485341e-01, -3.00322047091407640096e-01),
float2( 4.49800763439369810648e-01, 3.98492182500493397068e-01),
float2(-4.97878650048238891035e-01, 2.57984038389083569776e-01),
float2(-3.12055242602567339816e-01, -4.88013525550807125697e-01),
float2( 5.87078632117718268724e-01, -6.97256834327608099322e-02),
float2( 6.23692403999373534695e-01, 3.11519734097943645779e-01),
float2( 6.64426445690903810792e-01, -2.27661844509491811950e-01),
float2(-3.24662942872471160793e-01, 5.68939932480760024447e-01),
float2(-5.31263995010459511015e-01, -4.66108719959298256619e-01),
float2( 5.10323549430644951563e-01, 5.81027848262460677731e-01),
float2( 2.82695533021593392586e-01, -7.03582425015577883620e-01),
float2(-5.98419541732174709026e-01, -4.68015982003612274198e-01),
float2(-3.95281650646674975746e-01, 6.10614720709622194050e-01),
float2( 7.87454411900813555647e-01, 1.37726315874787758053e-01),
float2(-7.36310249594224086600e-01, 4.25723821775386646049e-01),
float2( 6.48232481978769037312e-01, -5.53108138515975955585e-01),
float2(-1.88558544306507869237e-01, -7.79120748356531223067e-01),
float2(-3.78614630625567993860e-01, 7.82366459873827913007e-01),
float2(-8.48582606942172357201e-01, -3.78504015913022351381e-01),
float2( 1.91472859899175090748e-02, -9.13050020447597532325e-01),
float2( 8.08826910050883585157e-01, 4.17202663034078935489e-01),
float2(-9.27062588380768493046e-01, -2.94160352051227980130e-01),
float2( 6.67882607007592055126e-01, -6.88642020601400450808e-01),
float2(-1.59349274307943010454e-02, 9.37629353656756814317e-01),
float2( 9.86975590293644233775e-01, 1.44401793964158337014e-01)
};
@@ -13,7 +13,6 @@
#include <Atom/Features/Shadow/ShadowmapAtlasLib.azsli>
#include <Atom/RPI/Math.azsli>
#include "BicubicPcfFilters.azsli"
#include "JitterTablePcf.azsli"
#include "Shadow.azsli"
// ProjectedShadow calculates shadowed area projected from a light.
@@ -44,11 +43,6 @@ class ProjectedShadow
float GetThickness();
bool IsShadowed(float3 shadowPosition);
bool IsShadowedWithJitter(
float3 jitterUnitX,
float3 jitterUnitY,
float jitterDepthDiffBase,
uint jitterIndex);
void SetShadowPosition();
float3 GetAtlasPosition(float2 texturePosition);
static float UnprojectDepth(uint shadowIndex, float depthBufferValue);
@@ -321,35 +315,6 @@ bool ProjectedShadow::IsShadowed(float3 shadowPosition)
return false;
}
bool ProjectedShadow::IsShadowedWithJitter(
float3 jitterUnitX,
float3 jitterUnitY,
float jitterDepthDiffBase,
uint jitterIndex)
{
ViewSrg::ProjectedShadow shadow = ViewSrg::m_projectedShadows[m_shadowIndex];
const float4x4 depthBiasMatrix = shadow.m_depthBiasMatrix;
const float boundaryScale = shadow.m_boundaryScale;
const float2 jitterXY = g_jitterTablePcf[jitterIndex];
const float dist = distance(m_worldPosition, m_viewPosition);
const float boundaryRadius = dist * tan(boundaryScale);
// jitterWorldXY is the jittering diff vector from the lighted point on the surface
// in the world space. It is remarked as "v_J" in the comment
// named "Calculate depth adjusting diff for jittered samples"
// just before the function GetJitterUnitVectorDepthDiffBase.
const float3 jitterWorldXY = jitterUnitX * (jitterXY.x * boundaryRadius) + jitterUnitY * (jitterXY.y * boundaryRadius);
// The adjusting diff of depth ("d" in the comment) is calculated by
// jitterXY.y * boundaryRadius * jitterDepthDiffBase.
const float3 jitterWorldZ = m_lightDirection * (jitterXY.y * boundaryRadius * jitterDepthDiffBase);
const float3 jitteredWorldPosition = m_worldPosition + jitterWorldXY + jitterWorldZ;
const float4 jitteredShadowmapHomogeneous = mul(depthBiasMatrix, float4(jitteredWorldPosition, 1));
return IsShadowed(jitteredShadowmapHomogeneous.xyz / jitteredShadowmapHomogeneous.w);
}
void ProjectedShadow::SetShadowPosition()
{
const float4x4 depthBiasMatrix = ViewSrg::m_projectedShadows[m_shadowIndex].m_depthBiasMatrix;
@@ -23,14 +23,11 @@ struct FilterParameter
uint m_isEnabled;
uint2 m_shadowmapOriginInSlice;
uint m_shadowmapSize;
uint m_parameterOffset;
uint m_parameterCount;
float m_lightDistanceOfCameraViewFrustum;
float m_n_f_n; // n / (f - n)
float m_n_f; // n - f
float m_f; // f
// where n: nearDepth, f: farDepth.
float2 m_padding; // explicit padding
};
class Shadow
@@ -22,14 +22,11 @@ partial ShaderResourceGroup ViewSrg
uint m_isEnabled;
uint2 m_shadowmapOriginInSlice;
uint m_shadowmapSize;
uint m_parameterOffset;
uint m_parameterCount;
float m_lightDistanceOfCameraViewFrustum;
float m_n_f_n; // n / (f - n)
float m_n_f; // n - f
float m_f; // f
// where n: nearDepth, f: farDepth.
float2 m_padding; // explicit padding
};
// Simple Point Lights
@@ -286,7 +286,6 @@ set(FILES
ShaderLib/Atom/Features/ScreenSpace/ScreenSpaceUtil.azsli
ShaderLib/Atom/Features/Shadow/BicubicPcfFilters.azsli
ShaderLib/Atom/Features/Shadow/DirectionalLightShadow.azsli
ShaderLib/Atom/Features/Shadow/JitterTablePcf.azsli
ShaderLib/Atom/Features/Shadow/ProjectedShadow.azsli
ShaderLib/Atom/Features/Shadow/Shadow.azsli
ShaderLib/Atom/Features/Shadow/ShadowmapAtlasLib.azsli
@@ -154,12 +154,6 @@ namespace AZ
//! @param count Sample Count for filtering (up to 64)
virtual void SetFilteringSampleCount(LightHandle handle, uint16_t count) = 0;
//! This specifies the width of boundary between shadowed area and lit area.
//! @param handle the light handle.
//! @param width Boundary width. The shadow is gradually changed the degree of shadowed.
//! If width == 0, softening edge is disabled. Units are in meters.
virtual void SetShadowBoundaryWidth(LightHandle handle, float boundaryWidth) = 0;
//! Sets whether the directional shadowmap should use receiver plane bias.
//! This attempts to reduce shadow acne when using large pcf filters.
virtual void SetShadowReceiverPlaneBiasEnabled(LightHandle handle, bool enable) = 0;
@@ -90,8 +90,6 @@ namespace AZ
virtual void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) = 0;
//! Specifies filter method of shadows.
virtual void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) = 0;
//! Specifies the width of boundary between shadowed area and lit area in radians. The degree ofshadowed gradually changes on the boundary. 0 disables softening.
virtual void SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians) = 0;
//! Sets sample count for filtering of shadow boundary (up to 64)
virtual void SetFilteringSampleCount(LightHandle handle, uint16_t count) = 0;
//! Sets the Esm exponent to use. Higher values produce a steeper falloff in the border areas between light and shadow.
@@ -70,9 +70,6 @@ namespace AZ
virtual void SetShadowBias(LightHandle handle, float bias) = 0;
//! Specifies filter method of shadows.
virtual void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) = 0;
//! Specifies the width of boundary between shadowed area and lit area in radians. The degree ofshadowed gradually changes on
//! the boundary. 0 disables softening.
virtual void SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians) = 0;
//! Sets sample count for filtering of shadow boundary (up to 64)
virtual void SetFilteringSampleCount(LightHandle handle, uint16_t count) = 0;
//! Sets the Esm exponent to use. Higher values produce a steeper falloff in the border areas between light and shadow.
@@ -42,7 +42,6 @@ namespace AZ
// [GFX TODO][ATOM-2408] Make the max number of cascade modifiable at runtime.
static constexpr uint16_t MaxNumberOfCascades = 4;
static constexpr uint16_t MaxPcfSamplingCount = 64;
static constexpr float MaxSofteningBoundaryWidth = 0.1f;
} // namespace Shadow
} // namespace Render
@@ -54,8 +54,6 @@ namespace AZ::Render
virtual void SetShadowBias(ShadowId id, float bias) = 0;
//! Sets the shadow filter method
virtual void SetShadowFilterMethod(ShadowId id, ShadowFilterMethod method) = 0;
//! Sets the width of boundary between shadowed area and lit area.
virtual void SetSofteningBoundaryWidthAngle(ShadowId id, float boundaryWidthRadians) = 0;
//! Sets the sample count for filtering of the shadow boundary, max 64.
virtual void SetFilteringSampleCount(ShadowId id, uint16_t count) = 0;
//! Sets all of the shadow properites in one call
@@ -584,15 +584,6 @@ namespace AZ
m_shadowBufferNeedsUpdate = true;
}
void DirectionalLightFeatureProcessor::SetShadowBoundaryWidth(LightHandle handle, float boundaryWidth)
{
for (auto& it : m_shadowData)
{
it.second.GetData(handle.GetIndex()).m_boundaryScale = boundaryWidth / 2.f;
}
m_shadowBufferNeedsUpdate = true;
}
void DirectionalLightFeatureProcessor::SetShadowReceiverPlaneBiasEnabled(LightHandle handle, bool enable)
{
m_shadowProperties.GetData(handle.GetIndex()).m_isReceiverPlaneBiasEnabled = enable;
@@ -1116,50 +1107,13 @@ namespace AZ
for (const auto& passIt : m_esmShadowmapsPasses)
{
const RPI::View* cameraView = passIt.second.front()->GetRenderPipeline()->GetDefaultView().get();
UpdateStandardDeviations(handle, cameraView);
UpdateFilterOffsetsCounts(handle, cameraView);
UpdateFilterEnabled(handle, cameraView);
UpdateShadowmapPositionInAtlas(handle, cameraView);
SetFilterParameterToPass(handle, cameraView);
}
}
void DirectionalLightFeatureProcessor::UpdateStandardDeviations(LightHandle handle, const RPI::View* cameraView)
{
if (handle != m_shadowingLightHandle)
{
return;
}
const DirectionalLightShadowData& data = m_shadowData.at(cameraView).GetData(handle.GetIndex());
const ShadowProperty& property = m_shadowProperties.GetData(handle.GetIndex());
AZStd::fixed_vector<float, Shadow::MaxNumberOfCascades> standardDeviations;
for (size_t cascadeIndex = 0; cascadeIndex < property.m_segments.at(cameraView).size(); ++cascadeIndex)
{
const Aabb& aabb = property.m_segments.at(cameraView)[cascadeIndex].m_aabb;
const float aabbDiameter = AZStd::GetMax(
aabb.GetMax().GetX() - aabb.GetMin().GetX(),
aabb.GetMax().GetZ() - aabb.GetMin().GetZ());
float standardDeviation = 0.f;
if (aabbDiameter > 0.f)
{
const float boundaryWidth = data.m_boundaryScale * 2.f;
const float ratioToAabbWidth = boundaryWidth / aabbDiameter;
const float widthInPixels = ratioToAabbWidth * data.m_shadowmapSize;
standardDeviation = widthInPixels / (2 * GaussianMathFilter::ReliableSectionFactor);
}
standardDeviations.push_back(standardDeviation);
}
for (const RPI::RenderPipelineId& pipelineId : m_renderPipelineIdsForPersistentView.at(cameraView))
{
for (EsmShadowmapsPass* esmPass : m_esmShadowmapsPasses.at(pipelineId))
{
esmPass->SetFilterParameters(standardDeviations);
}
}
}
void DirectionalLightFeatureProcessor::UpdateFilterOffsetsCounts(LightHandle handle, const RPI::View* cameraView)
void DirectionalLightFeatureProcessor::UpdateFilterEnabled(LightHandle handle, const RPI::View* cameraView)
{
if (handle != m_shadowingLightHandle)
{
@@ -1170,29 +1124,11 @@ namespace AZ
if (shadowData.m_shadowFilterMethod == aznumeric_cast<uint32_t>(ShadowFilterMethod::Esm) ||
(shadowData.m_shadowFilterMethod == aznumeric_cast<uint32_t>(ShadowFilterMethod::EsmPcf)))
{
// Get array of filter counts for the camera view.
const RPI::RenderPipelineId& pipelineId = m_renderPipelineIdsForPersistentView.at(cameraView).front();
AZ_Assert(!m_esmShadowmapsPasses.at(pipelineId).empty(), "Cannot find a EsmShadowmapsPass.");
const AZStd::array_view<uint32_t> filterCounts = m_esmShadowmapsPasses.at(pipelineId).front()->GetFilterCounts();
AZ_Assert(filterCounts.size() == GetCascadeCount(handle), "FilterCounts differs with cascade count.");
// Create array of filter offsets
AZStd::vector<uint32_t> filterOffsets;
filterOffsets.reserve(filterCounts.size());
uint32_t filterOffset = 0;
for (const uint32_t count : filterCounts)
{
filterOffsets.push_back(filterOffset);
filterOffset += count;
}
// Write filter offsets and filter counts to ESM data
for (uint16_t index = 0; index < GetCascadeCount(handle); ++index)
{
EsmShadowmapsPass::FilterParameter& filterParameter = m_esmParameterData.at(cameraView).GetData(index);
filterParameter.m_isEnabled = true;
filterParameter.m_parameterOffset = filterOffsets[index];
filterParameter.m_parameterCount = filterCounts[index];
}
}
else
@@ -1202,8 +1138,6 @@ namespace AZ
{
EsmShadowmapsPass::FilterParameter& filterParameter = m_esmParameterData.at(cameraView).GetData(index);
filterParameter.m_isEnabled = false;
filterParameter.m_parameterOffset = 0;
filterParameter.m_parameterCount = 0;
}
}
}
@@ -217,7 +217,6 @@ namespace AZ
void SetDebugFlags(LightHandle handle, DebugDrawFlags flags) override;
void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) override;
void SetFilteringSampleCount(LightHandle handle, uint16_t count) override;
void SetShadowBoundaryWidth(LightHandle handle, float boundaryWidth) override;
void SetShadowReceiverPlaneBiasEnabled(LightHandle handle, bool enable) override;
const Data::Instance<RPI::Buffer> GetLightBuffer() const;
@@ -278,10 +277,8 @@ namespace AZ
//! This updates the parameter of Gaussian filter used in ESM.
void UpdateFilterParameters(LightHandle handle);
//! This updates standard deviations for each cascade.
void UpdateStandardDeviations(LightHandle handle, const RPI::View* cameraView);
//! This updates filter offset and size for each cascade.
void UpdateFilterOffsetsCounts(LightHandle handle, const RPI::View* cameraView);
//! This updates if the filter is enabled.
void UpdateFilterEnabled(LightHandle handle, const RPI::View* cameraView);
//! This updates shadowmap position(origin and size) in the atlas for each cascade.
void UpdateShadowmapPositionInAtlas(LightHandle handle, const RPI::View* cameraView);
//! This set filter parameters to passes which execute filtering.
@@ -322,11 +322,6 @@ namespace AZ
{
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetShadowFilterMethod, method);
}
void DiskLightFeatureProcessor::SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians)
{
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetSofteningBoundaryWidthAngle, boundaryWidthRadians);
}
void DiskLightFeatureProcessor::SetFilteringSampleCount(LightHandle handle, uint16_t count)
{
@@ -53,7 +53,6 @@ namespace AZ
void SetShadowBias(LightHandle handle, float bias) override;
void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) override;
void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) override;
void SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians) override;
void SetFilteringSampleCount(LightHandle handle, uint16_t count) override;
void SetEsmExponent(LightHandle handle, float esmExponent) override;
@@ -42,28 +42,6 @@ namespace AZ
return m_lightTypeName;
}
void EsmShadowmapsPass::SetFilterParameters(const AZStd::array_view<float>& standardDeviations)
{
// Set descriptor for Gaussian filters for given set of standard deviations.
MathFilterDescriptor descriptor;
descriptor.m_kind = MathFilterKind::Gaussian;
descriptor.m_gaussians.reserve(standardDeviations.size());
for (const float standardDeviation : standardDeviations)
{
descriptor.m_gaussians.emplace_back(GaussianFilterDescriptor{ standardDeviation });
}
// Set filter paramter buffer along with element counts for each filter.
MathFilter::BufferWithElementCounts bufferCounts = MathFilter::FindOrCreateFilterBuffer(descriptor);
m_filterTableBuffer = bufferCounts.first;
m_filterCounts = AZStd::move(bufferCounts.second);
}
AZStd::array_view<uint32_t> EsmShadowmapsPass::GetFilterCounts() const
{
return m_filterCounts;
}
void EsmShadowmapsPass::SetShadowmapIndexTableBuffer(const Data::Instance<RPI::Buffer>& tableBuffer)
{
m_shadowmapIndexTableBuffer = tableBuffer;
@@ -50,14 +50,11 @@ namespace AZ
uint32_t m_isEnabled = false;
AZStd::array<uint32_t, 2> m_shadowmapOriginInSlice = { {0, 0 } }; // shadowmap origin in the slice of the atlas.
uint32_t m_shadowmapSize = static_cast<uint32_t>(ShadowmapSize::None); // width and height of shadowmap.
uint32_t m_parameterOffset; // offset of the filter parameter.
uint32_t m_parameterCount; // element count of the filter parameter.
float m_lightDistanceOfCameraViewFrustum = 0.f;
float m_n_f_n = 0.f; // n / (f - n)
float m_n_f = 0.f; // n - f
float m_f = 0.f; // f
// where n: nearDepth, f: farDepth.
AZStd::array<float, 2> m_padding = {{0.f, 0.f}}; // explicit padding
};
virtual ~EsmShadowmapsPass() = default;
@@ -65,13 +62,6 @@ namespace AZ
const Name& GetLightTypeName() const;
//! This sets the standard deviations of the Gaussian filter
//! for each cascade.
void SetFilterParameters(const AZStd::array_view<float>& standardDeviations);
//! This returns element count of filters.
AZStd::array_view<uint32_t> GetFilterCounts() const;
//! This sets the buffer of the table which enable to get shadowmap index
//! from the coordinate in the atlas.
//! Note that shadowmpa index is shader light index for a spot light
@@ -292,11 +292,6 @@ namespace AZ
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetShadowFilterMethod, method);
}
void PointLightFeatureProcessor::SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians)
{
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetSofteningBoundaryWidthAngle, boundaryWidthRadians);
}
void PointLightFeatureProcessor::SetFilteringSampleCount(LightHandle handle, uint16_t count)
{
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetFilteringSampleCount, count);
@@ -50,7 +50,6 @@ namespace AZ
void SetShadowBias(LightHandle handle, float bias) override;
void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) override;
void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) override;
void SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians) override;
void SetFilteringSampleCount(LightHandle handle, uint16_t count) override;
void SetEsmExponent(LightHandle handle, float esmExponent) override;
void SetPointData(LightHandle handle, const PointLightData& data) override;
@@ -186,17 +186,6 @@ namespace AZ::Render
m_filterParameterNeedsUpdate = true;
}
void ProjectedShadowFeatureProcessor::SetSofteningBoundaryWidthAngle(ShadowId id, float boundaryWidthRadians)
{
AZ_Assert(id.IsValid(), "Invalid ShadowId passed to ProjectedShadowFeatureProcessor::SetShadowBoundaryWidthAngle().");
ShadowData& shadowData = m_shadowData.GetElement<ShadowDataIndex>(id.GetIndex());
shadowData.m_boundaryScale = boundaryWidthRadians / 2.0f;
m_shadowmapPassNeedsUpdate = true;
m_filterParameterNeedsUpdate = true;
}
void ProjectedShadowFeatureProcessor::SetFilteringSampleCount(ShadowId id, uint16_t count)
{
AZ_Assert(id.IsValid(), "Invalid ShadowId passed to ProjectedShadowFeatureProcessor::SetFilteringSampleCount().");
@@ -368,14 +357,13 @@ namespace AZ::Render
{
if (m_filterParameterNeedsUpdate)
{
UpdateStandardDeviations();
UpdateFilterOffsetsCounts();
UpdateEsmPassEnabled();
SetFilterParameterToPass();
m_filterParameterNeedsUpdate = false;
}
}
void ProjectedShadowFeatureProcessor::UpdateStandardDeviations()
void ProjectedShadowFeatureProcessor::UpdateEsmPassEnabled()
{
if (m_esmShadowmapsPasses.empty())
{
@@ -383,24 +371,7 @@ namespace AZ::Render
return;
}
AZStd::vector<float> standardDeviations(m_shadowProperties.GetDataCount());
for (uint32_t i = 0; i < m_shadowProperties.GetDataCount(); ++i)
{
ShadowProperty& shadowProperty = m_shadowProperties.GetDataVector().at(i);
const ShadowData& shadow = m_shadowData.GetElement<ShadowDataIndex>(shadowProperty.m_shadowId.GetIndex());
if (!FilterMethodIsEsm(shadow))
{
continue;
}
const FilterParameter& filter = m_shadowData.GetElement<FilterParamIndex>(shadowProperty.m_shadowId.GetIndex());
const float boundaryWidthAngle = shadow.m_boundaryScale * 2.0f;
const float fieldOfView = GetMax(shadowProperty.m_desc.m_fieldOfViewYRadians, MinimumFieldOfView);
const float ratioToEntireWidth = boundaryWidthAngle / fieldOfView;
const float widthInPixels = ratioToEntireWidth * filter.m_shadowmapSize;
standardDeviations.at(i) = widthInPixels / (2.0f * GaussianMathFilter::ReliableSectionFactor);
}
if (standardDeviations.empty())
if (m_shadowProperties.GetDataCount() == 0)
{
for (EsmShadowmapsPass* esmPass : m_esmShadowmapsPasses)
{
@@ -411,50 +382,6 @@ namespace AZ::Render
for (EsmShadowmapsPass* esmPass : m_esmShadowmapsPasses)
{
esmPass->SetEnabledComputation(true);
esmPass->SetFilterParameters(standardDeviations);
}
}
void ProjectedShadowFeatureProcessor::UpdateFilterOffsetsCounts()
{
if (m_esmShadowmapsPasses.empty())
{
AZ_Error("ProjectedShadowFeatureProcessor", false, "Cannot find a required pass.");
return;
}
// Get array of filter counts for the camera view.
const AZStd::array_view<uint32_t> filterCounts = m_esmShadowmapsPasses.front()->GetFilterCounts();
// Create array of filter offsets.
AZStd::vector<uint32_t> filterOffsets;
filterOffsets.reserve(filterCounts.size());
uint32_t filterOffset = 0;
for (const uint32_t count : filterCounts)
{
filterOffsets.push_back(filterOffset);
filterOffset += count;
}
auto& shadowProperties = m_shadowProperties.GetDataVector();
for (uint32_t i = 0; i < shadowProperties.size(); ++i)
{
ShadowProperty& shadowProperty = shadowProperties.at(i);
const ShadowId shadowId = shadowProperty.m_shadowId;
ShadowData& shadowData = m_shadowData.GetElement<ShadowDataIndex>(shadowId.GetIndex());
FilterParameter& filterData = m_shadowData.GetElement<FilterParamIndex>(shadowId.GetIndex());
if (FilterMethodIsEsm(shadowData))
{
filterData.m_parameterOffset = filterOffsets[i];
filterData.m_parameterCount = filterCounts[i];
}
else
{
// If filter is not required, reset offsets and counts of filter in ESM data.
filterData.m_parameterOffset = 0;
filterData.m_parameterCount = 0;
}
}
}
@@ -49,7 +49,6 @@ namespace AZ::Render
void SetShadowmapMaxResolution(ShadowId id, ShadowmapSize size) override;
void SetShadowBias(ShadowId id, float bias) override;
void SetShadowFilterMethod(ShadowId id, ShadowFilterMethod method) override;
void SetSofteningBoundaryWidthAngle(ShadowId id, float boundaryWidthRadians) override;
void SetFilteringSampleCount(ShadowId id, uint16_t count) override;
void SetShadowProperties(ShadowId id, const ProjectedShadowDescriptor& descriptor) override;
const ProjectedShadowDescriptor& GetShadowProperties(ShadowId id) override;
@@ -101,8 +100,7 @@ namespace AZ::Render
//! Functions to update the parameter of Gaussian filter used in ESM.
void UpdateFilterParameters();
void UpdateStandardDeviations();
void UpdateFilterOffsetsCounts();
void UpdateEsmPassEnabled();
void SetFilterParameterToPass();
bool FilterMethodIsEsm(const ShadowData& shadowData) const;
-1
View File
@@ -10,6 +10,5 @@ ly_add_external_target(
NAME renderdoc
3RDPARTY_ROOT_DIRECTORY "${LY_RENDERDOC_PATH}"
VERSION
INCLUDE_DIRECTORIES .
COMPILE_DEFINITIONS USE_RENDERDOC
)
@@ -6,4 +6,5 @@
#
#
set(RENDERDOC_RUNTIME_DEPENDENCIES "${BASE_PATH}/librenderdoc.so")
set(RENDERDOC_RUNTIME_DEPENDENCIES "${BASE_PATH}/lib/librenderdoc.so")
set(RENDERDOC_INCLUDE_DIRECTORIES "include")
@@ -7,3 +7,4 @@
#
set(RENDERDOC_RUNTIME_DEPENDENCIES "${BASE_PATH}/renderdoc.dll")
set(RENDERDOC_INCLUDE_DIRECTORIES ".")
@@ -36,6 +36,7 @@ ly_add_target(
Gem::Atom_RPI.Edit
Gem::Atom_RPI.Public
Gem::Atom_RHI.Reflect
Gem::Atom_Feature_Common.Static
Gem::Atom_Bootstrap.Headers
)
@@ -0,0 +1,39 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Memory/Memory.h>
namespace AtomToolsFramework
{
//! Interface for describing scene content that will be rendered using the PreviewRenderer
class PreviewContent
{
public:
AZ_CLASS_ALLOCATOR(PreviewContent, AZ::SystemAllocator, 0);
PreviewContent() = default;
virtual ~PreviewContent() = default;
//! Initiate loading of scene content, models, materials, etc
virtual void Load() = 0;
//! Return true if content is loaded and ready to render
virtual bool IsReady() const = 0;
//! Return true if content failed to load
virtual bool IsError() const = 0;
//! Report any issues encountered while loading
virtual void ReportErrors() = 0;
//! Prepare or pose content before rendering
virtual void Update() = 0;
};
} // namespace AtomToolsFramework
@@ -0,0 +1,85 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <Atom/RPI.Public/Base.h>
#include <Atom/RPI.Public/Pass/AttachmentReadback.h>
#include <AtomToolsFramework/PreviewRenderer/PreviewContent.h>
#include <AtomToolsFramework/PreviewRenderer/PreviewRendererState.h>
#include <AtomToolsFramework/PreviewRenderer/PreviewerFeatureProcessorProviderBus.h>
#include <AzFramework/Entity/GameEntityContextComponent.h>
namespace AzFramework
{
class Scene;
}
class QPixmap;
namespace AtomToolsFramework
{
//! Processes requests for setting up content that gets rendered to a texture and captured to an image
class PreviewRenderer final : public PreviewerFeatureProcessorProviderBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(PreviewRenderer, AZ::SystemAllocator, 0);
PreviewRenderer(const AZStd::string& sceneName, const AZStd::string& pipelineName);
~PreviewRenderer();
struct CaptureRequest final
{
int m_size = 512;
AZStd::shared_ptr<PreviewContent> m_content;
AZStd::function<void()> m_captureFailedCallback;
AZStd::function<void(const QPixmap&)> m_captureCompleteCallback;
};
void AddCaptureRequest(const CaptureRequest& captureRequest);
AZ::RPI::ScenePtr GetScene() const;
AZ::RPI::ViewPtr GetView() const;
AZ::Uuid GetEntityContextId() const;
void ProcessCaptureRequests();
void CancelCaptureRequest();
void CompleteCaptureRequest();
void LoadContent();
void UpdateLoadContent();
void CancelLoadContent();
void PoseContent();
bool StartCapture();
void EndCapture();
private:
//! AZ::Render::PreviewerFeatureProcessorProviderBus::Handler interface overrides...
void GetRequiredFeatureProcessors(AZStd::unordered_set<AZStd::string>& featureProcessors) const override;
static constexpr float AspectRatio = 1.0f;
static constexpr float NearDist = 0.001f;
static constexpr float FarDist = 100.0f;
static constexpr float FieldOfView = AZ::Constants::HalfPi;
AZ::RPI::ScenePtr m_scene;
AZStd::shared_ptr<AzFramework::Scene> m_frameworkScene;
AZ::RPI::RenderPipelinePtr m_renderPipeline;
AZ::RPI::ViewPtr m_view;
AZStd::vector<AZStd::string> m_passHierarchy;
AZStd::unique_ptr<AzFramework::EntityContext> m_entityContext;
//! Incoming requests are appended to this queue and processed one at a time in OnTick function.
AZStd::queue<CaptureRequest> m_captureRequestQueue;
CaptureRequest m_currentCaptureRequest;
AZStd::unique_ptr<PreviewRendererState> m_state;
};
} // namespace AtomToolsFramework
@@ -0,0 +1,29 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
namespace AtomToolsFramework
{
class PreviewRenderer;
//! PreviewRendererState decouples PreviewRenderer logic into easy-to-understand and debug pieces
class PreviewRendererState
{
public:
explicit PreviewRendererState(PreviewRenderer* renderer)
: m_renderer(renderer)
{
}
virtual ~PreviewRendererState() = default;
protected:
PreviewRenderer* m_renderer = {};
};
} // namespace AtomToolsFramework
@@ -0,0 +1,25 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/std/containers/unordered_set.h>
#include <AzCore/std/string/string.h>
namespace AtomToolsFramework
{
//! PreviewerFeatureProcessorProviderRequests allows registering custom Feature Processors for preview image generation
class PreviewerFeatureProcessorProviderRequests : public AZ::EBusTraits
{
public:
//! Get a list of custom feature processors to register with preview image renderer
virtual void GetRequiredFeatureProcessors(AZStd::unordered_set<AZStd::string>& featureProcessors) const = 0;
};
using PreviewerFeatureProcessorProviderBus = AZ::EBus<PreviewerFeatureProcessorProviderRequests>;
} // namespace AtomToolsFramework

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