Merge branch 'development' of https://github.com/o3de/o3de into cgalvan/DraftStreamingImageAssetPixelAPI

This commit is contained in:
Chris Galvan
2022-01-12 11:21:45 -06:00
84 changed files with 1260 additions and 609 deletions
@@ -4,10 +4,18 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import logging
import os
import pytest
import ly_test_tools.environment.file_system as file_system
import editor_python_test_tools.hydra_test_utils as hydra
from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite
logger = logging.getLogger(__name__)
TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests")
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@@ -114,3 +122,73 @@ class TestAutomation(EditorTestSuite):
class ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges(EditorSharedTest):
from Atom.tests import hydra_ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges as test_module
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("launcher_platform", ['windows_generic'])
class TestMaterialEditorBasicTests(object):
@pytest.fixture(autouse=True)
def setup_teardown(self, request, workspace, project):
def delete_files():
file_system.delete(
[
os.path.join(workspace.paths.project(), "Materials", "test_material.material"),
os.path.join(workspace.paths.project(), "Materials", "test_material_1.material"),
os.path.join(workspace.paths.project(), "Materials", "test_material_2.material"),
],
True,
True,
)
# Cleanup our newly created materials
delete_files()
def teardown():
# Cleanup our newly created materials
delete_files()
request.addfinalizer(teardown)
@pytest.mark.parametrize("exe_file_name", ["MaterialEditor"])
@pytest.mark.test_case_id("C34448113") # Creating a New Asset.
@pytest.mark.test_case_id("C34448114") # Opening an Existing Asset.
@pytest.mark.test_case_id("C34448115") # Closing Selected Material.
@pytest.mark.test_case_id("C34448116") # Closing All Materials.
@pytest.mark.test_case_id("C34448117") # Closing all but Selected Material.
@pytest.mark.test_case_id("C34448118") # Saving Material.
@pytest.mark.test_case_id("C34448119") # Saving as a New Material.
@pytest.mark.test_case_id("C34448120") # Saving as a Child Material.
@pytest.mark.test_case_id("C34448121") # Saving all Open Materials.
def test_MaterialEditorBasicTests(
self, request, workspace, project, launcher_platform, generic_launcher, exe_file_name):
expected_lines = [
"Material opened: True",
"Test asset doesn't exist initially: True",
"New asset created: True",
"New Material opened: True",
"Material closed: True",
"All documents closed: True",
"Close All Except Selected worked as expected: True",
"Actual Document saved with changes: True",
"Document saved as copy is saved with changes: True",
"Document saved as child is saved with changes: True",
"Save All worked as expected: True",
]
unexpected_lines = [
"Traceback (most recent call last):"
]
hydra.launch_and_validate_results(
request,
TEST_DIRECTORY,
generic_launcher,
"hydra_AtomMaterialEditor_BasicTests.py",
run_python="--runpython",
timeout=43,
expected_lines=expected_lines,
unexpected_lines=unexpected_lines,
halt_on_unexpected=True,
null_renderer=True,
log_file_name="MaterialEditor.log",
enable_prefab_system=False,
)
@@ -83,77 +83,6 @@ class TestAtomEditorComponentsMain(object):
)
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("launcher_platform", ['windows_generic'])
@pytest.mark.system
class TestMaterialEditorBasicTests(object):
@pytest.fixture(autouse=True)
def setup_teardown(self, request, workspace, project):
def delete_files():
file_system.delete(
[
os.path.join(workspace.paths.project(), "Materials", "test_material.material"),
os.path.join(workspace.paths.project(), "Materials", "test_material_1.material"),
os.path.join(workspace.paths.project(), "Materials", "test_material_2.material"),
],
True,
True,
)
# Cleanup our newly created materials
delete_files()
def teardown():
# Cleanup our newly created materials
delete_files()
request.addfinalizer(teardown)
@pytest.mark.parametrize("exe_file_name", ["MaterialEditor"])
@pytest.mark.test_case_id("C34448113") # Creating a New Asset.
@pytest.mark.test_case_id("C34448114") # Opening an Existing Asset.
@pytest.mark.test_case_id("C34448115") # Closing Selected Material.
@pytest.mark.test_case_id("C34448116") # Closing All Materials.
@pytest.mark.test_case_id("C34448117") # Closing all but Selected Material.
@pytest.mark.test_case_id("C34448118") # Saving Material.
@pytest.mark.test_case_id("C34448119") # Saving as a New Material.
@pytest.mark.test_case_id("C34448120") # Saving as a Child Material.
@pytest.mark.test_case_id("C34448121") # Saving all Open Materials.
def test_MaterialEditorBasicTests(
self, request, workspace, project, launcher_platform, generic_launcher, exe_file_name):
expected_lines = [
"Material opened: True",
"Test asset doesn't exist initially: True",
"New asset created: True",
"New Material opened: True",
"Material closed: True",
"All documents closed: True",
"Close All Except Selected worked as expected: True",
"Actual Document saved with changes: True",
"Document saved as copy is saved with changes: True",
"Document saved as child is saved with changes: True",
"Save All worked as expected: True",
]
unexpected_lines = [
"Traceback (most recent call last):"
]
hydra.launch_and_validate_results(
request,
TEST_DIRECTORY,
generic_launcher,
"hydra_AtomMaterialEditor_BasicTests.py",
run_python="--runpython",
timeout=120,
expected_lines=expected_lines,
unexpected_lines=unexpected_lines,
halt_on_unexpected=True,
null_renderer=True,
log_file_name="MaterialEditor.log",
enable_prefab_system=False,
)
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
class TestAutomation(EditorTestSuite):
@@ -162,6 +162,13 @@ def select_model_config(configname):
azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, "SelectModelPresetByName", configname)
def destroy_main_window():
"""
Closes the Material Editor window
"""
azlmbr.atomtools.AtomToolsMainWindowFactoryRequestBus(azlmbr.bus.Broadcast, "DestroyMainWindow")
def wait_for_condition(function, timeout_in_seconds=1.0):
# type: (function, float) -> bool
"""
@@ -186,6 +186,11 @@ def run():
material_editor.set_property(document2_id, property2_name, initial_color)
material_editor.save_all()
material_editor.close_all_documents()
material_editor.wait_for_condition(lambda:
(not material_editor.is_open(document1_id)) and
(not material_editor.is_open(document2_id)) and
(not material_editor.is_open(document3_id)), 2.0)
material_editor.destroy_main_window()
if __name__ == "__main__":
@@ -110,7 +110,8 @@ def DynamicSliceInstanceSpawner_Embedded_E2E():
general.save_level()
general.export_to_engine()
pak_path = os.path.join(paths.products, "levels", lvl_name, "level.pak")
Report.result(Tests.saved_and_exported, os.path.exists(pak_path))
success = helper.wait_for_condition(lambda: os.path.exists(pak_path), 10.0)
Report.result(Tests.saved_and_exported, success)
if __name__ == "__main__":
@@ -132,7 +132,8 @@ def DynamicSliceInstanceSpawner_External_E2E():
general.save_level()
general.export_to_engine()
pak_path = os.path.join(paths.products, "levels", lvl_name, "level.pak")
Report.result(Tests.saved_and_exported, os.path.exists(pak_path))
success = helper.wait_for_condition(lambda: os.path.exists(pak_path), 10.0)
Report.result(Tests.saved_and_exported, success)
if __name__ == "__main__":
@@ -156,7 +156,8 @@ def LayerBlender_E2E_Editor():
general.save_level()
general.export_to_engine()
pak_path = os.path.join(paths.products, "levels", lvl_name, "level.pak")
Report.result(Tests.saved_and_exported, os.path.exists(pak_path))
success = helper.wait_for_condition(lambda: os.path.exists(pak_path), 10.0)
Report.result(Tests.saved_and_exported, success)
if __name__ == "__main__":
@@ -73,7 +73,7 @@ def SpawnerSlices_SliceCreationAndVisibilityToggleWorks():
slice.SliceRequestBus(bus.Broadcast, "CreateNewSlice", veg_1.id, slice_path)
# 2.3) Verify if the slice has been created successfully
spawner_slice_success = helper.wait_for_condition(lambda: path_is_valid_asset(slice_path), 5.0)
spawner_slice_success = helper.wait_for_condition(lambda: path_is_valid_asset(slice_path), 10.0)
Report.result(Tests.spawner_slice_created, spawner_slice_success)
# 3) C2627904: Hiding a slice containing the component clears any visuals from the Viewport
@@ -1474,9 +1474,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{1FD47684-2E9E-5525-BBCA-251795F9033C}"
"guid": "{12B5A321-3D64-5DF6-9E15-D8F447229EC1}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m00_r00.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r00.azmaterial"
}
}
}
@@ -1569,9 +1569,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{B5660D78-818E-5273-AF3D-EC8189E2E6CB}"
"guid": "{EB8B9C49-D6F4-5098-AC97-543381E2554A}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m00_r01.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r01.azmaterial"
}
}
}
@@ -1824,9 +1824,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{512443BD-9511-5F13-A84A-3ED5DB9E9B5A}"
"guid": "{CAA9CAFC-8A48-5406-BE26-448E5AA1A5B0}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m00_r02.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r02.azmaterial"
}
}
}
@@ -1926,9 +1926,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{E28A5CC5-4B8B-5B90-877A-3D92C75DC75A}"
"guid": "{2F338C0B-EF86-5AC4-AEE6-28A26BB9E97E}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m00_r03.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r03.azmaterial"
}
}
}
@@ -2028,9 +2028,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{1495BCCF-3F96-5D0B-8176-228DB22CEC82}"
"guid": "{9BF4E656-0D4F-5746-A256-32740742712B}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m00_r04.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r04.azmaterial"
}
}
}
@@ -2130,9 +2130,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{40494612-0ABF-55B5-9C56-E968763FCFDE}"
"guid": "{850398D7-386A-56C6-AEB2-95E4F64368B1}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m00_r05.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r05.azmaterial"
}
}
}
@@ -2232,9 +2232,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{76CF9D4A-009F-5494-83AB-6E3D4D1B4A36}"
"guid": "{74784C2A-A713-5C6A-8B3D-B66CAE3DD055}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m00_r06.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r06.azmaterial"
}
}
}
@@ -2334,9 +2334,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{8431B792-E6CC-51DD-B82E-F3E4A12FCB4A}"
"guid": "{4F9F91F7-7E22-5A14-856D-194CC258E70D}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m00_r07.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r07.azmaterial"
}
}
}
@@ -2436,9 +2436,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{4B1F29FF-7971-5524-AA1B-0DC2392A33C4}"
"guid": "{842AE870-802B-5934-997F-0965F960ECB9}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m00_r08.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r08.azmaterial"
}
}
}
@@ -2538,9 +2538,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{785BE6DE-C0EB-5B47-9438-4F9ECFC34A96}"
"guid": "{0184CF10-E675-5C33-B1B9-009C383AB463}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m00_r09.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r09.azmaterial"
}
}
}
@@ -2640,9 +2640,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{C40DE9AE-6756-57E7-B3B4-FB0542B5CD0F}"
"guid": "{6DDA0761-C165-58CC-B45E-03C29F0CF598}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m00_r10.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m00_r10.azmaterial"
}
}
}
@@ -2896,9 +2896,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{251C4C29-4ECD-5763-AF4F-20675EAC048B}"
"guid": "{101AB53A-3B3E-5ACF-841C-65DB2BFBF305}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m10_r04.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r04.azmaterial"
}
}
}
@@ -2998,9 +2998,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{02D082C4-5032-57CC-A081-BC4D8518BCF0}"
"guid": "{B82B96D6-7511-5E22-A36E-FFF682B3236B}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m10_r05.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r05.azmaterial"
}
}
}
@@ -3100,9 +3100,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{FA9D8842-95B2-5371-8352-CBEEEAABE676}"
"guid": "{DBED5292-3E17-5038-9974-80A8BB1F79E8}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m10_r06.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r06.azmaterial"
}
}
}
@@ -3202,9 +3202,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{522A9626-FF4C-561A-A44A-64B68F7274D2}"
"guid": "{25F07733-365C-5826-AEE3-E92FBE807555}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m10_r07.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r07.azmaterial"
}
}
}
@@ -3304,9 +3304,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{06DDFD66-D7F5-5D55-8972-6D61276E88F6}"
"guid": "{C9A7B916-CF71-5A34-B9B9-54FE8CB058DC}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m10_r00.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r00.azmaterial"
}
}
}
@@ -3399,9 +3399,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{060EF1B7-1029-5227-B03B-1415C74E9D65}"
"guid": "{85C8DFC5-358D-579D-B922-14FA1B401571}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m10_r08.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r08.azmaterial"
}
}
}
@@ -3501,9 +3501,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{7B7BC6F8-150A-518F-816E-2F7DBE786461}"
"guid": "{51924281-7A06-5654-B783-A4F5759063ED}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m10_r01.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r01.azmaterial"
}
}
}
@@ -3603,9 +3603,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{270881B6-21E9-509D-A6CD-1046674FB0BE}"
"guid": "{7877F64E-26E3-558C-B6D9-B609ED6E43BF}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m10_r09.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r09.azmaterial"
}
}
}
@@ -3705,9 +3705,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{C0538953-C56E-5C1A-BBE2-E6BE04764C20}"
"guid": "{6CC3C6B9-EE05-5A77-A12D-7085D93D89DB}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m10_r02.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r02.azmaterial"
}
}
}
@@ -3874,9 +3874,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{5EA26E09-E3D6-5181-8E7A-F2E98A24247C}"
"guid": "{E6E15876-EEF3-555D-BD80-1B9D5A7ECC7D}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m10_r10.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r10.azmaterial"
}
}
}
@@ -3976,9 +3976,9 @@
"{}": {
"MaterialAsset": {
"assetId": {
"guid": "{E1A5D708-7A49-5CCA-81C3-4CB337C47703}"
"guid": "{83179EEC-BAC7-5D39-9788-37D33E9584B1}"
},
"assetHint": "levels/pbrmaterialchart/materials/basic_m10_r03.azmaterial"
"assetHint": "levels/graphics/pbrmaterialchart/materials/basic_m10_r03.azmaterial"
}
}
}
-1
View File
@@ -115,7 +115,6 @@ CNewLevelDialog::~CNewLevelDialog()
void CNewLevelDialog::OnStartup()
{
UpdateData(false);
setFocus();
}
void CNewLevelDialog::UpdateData(bool fromUi)
+3
View File
@@ -133,6 +133,9 @@
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>LEVEL</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
@@ -349,8 +349,12 @@ namespace AzToolsFramework
instanceToParentUnder = *m_rootInstance;
}
AZStd::unique_ptr<Prefab::Instance> instantiatedPrefabInstance =
m_prefabSystemComponent->InstantiatePrefab(filePath, instanceToParentUnder);
AZStd::unique_ptr<Prefab::Instance> instantiatedPrefabInstance = m_prefabSystemComponent->InstantiatePrefab(
filePath, instanceToParentUnder,
[this](const EntityList& entities)
{
HandleEntitiesAdded(entities);
});
if (instantiatedPrefabInstance)
{
@@ -277,7 +277,7 @@ namespace AzToolsFramework
}
AZStd::unique_ptr<Instance> PrefabSystemComponent::InstantiatePrefab(
AZ::IO::PathView filePath, InstanceOptionalReference parent)
AZ::IO::PathView filePath, InstanceOptionalReference parent, const InstantiatedEntitiesCallback& instantiatedEntitiesCallback)
{
// Retrieve the template id for the source prefab filepath
Prefab::TemplateId templateId = GetTemplateIdFromFilePath(filePath);
@@ -297,11 +297,11 @@ namespace AzToolsFramework
return nullptr;
}
return InstantiatePrefab(templateId, parent);
return InstantiatePrefab(templateId, parent, instantiatedEntitiesCallback);
}
AZStd::unique_ptr<Instance> PrefabSystemComponent::InstantiatePrefab(
TemplateId templateId, InstanceOptionalReference parent)
TemplateId templateId, InstanceOptionalReference parent, const InstantiatedEntitiesCallback& instantiatedEntitiesCallback)
{
TemplateReference instantiatingTemplate = FindTemplate(templateId);
@@ -324,8 +324,10 @@ namespace AzToolsFramework
return nullptr;
}
AzToolsFramework::EditorEntityContextRequestBus::Broadcast(
&AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded, newEntities);
if (instantiatedEntitiesCallback)
{
instantiatedEntitiesCallback(newEntities);
}
return newInstance;
}
@@ -124,19 +124,25 @@ namespace AzToolsFramework
* Generates a new Prefab Instance based on the Template whose source is stored in filepath.
* @param filePath The path to the prefab source file containing the template being instantiated.
* @param parent Reference of the target instance the instantiated instance will be placed under.
* @param instantiatedEntitiesCallback An optional callback that can be used to modify the instantiated entities.
* @return A unique_ptr to the newly instantiated instance. Null if operation failed.
*/
AZStd::unique_ptr<Instance> InstantiatePrefab(
AZ::IO::PathView filePath, InstanceOptionalReference parent = AZStd::nullopt) override;
AZ::IO::PathView filePath,
InstanceOptionalReference parent = AZStd::nullopt,
const InstantiatedEntitiesCallback& instantiatedEntitiesCallback = {}) override;
/**
* Generates a new Prefab Instance based on the Template referenced by templateId.
* @param templateId The id of the template being instantiated.
* @param parent Reference of the target instance the instantiated instance will be placed under.
* @param instantiatedEntitiesCallback An optional callback that can be used to modify the instantiated entities.
* @return A unique_ptr to the newly instantiated instance. Null if operation failed.
*/
AZStd::unique_ptr<Instance> InstantiatePrefab(
TemplateId templateId, InstanceOptionalReference parent = AZStd::nullopt) override;
TemplateId templateId,
InstanceOptionalReference parent = AZStd::nullopt,
const InstantiatedEntitiesCallback& instantiatedEntitiesCallback = {}) override;
/**
* Add a new Link into Prefab System Component and create a unique id for it.
@@ -27,6 +27,9 @@ namespace AzToolsFramework
class PrefabSystemComponentInterface
{
public:
using InstantiatedEntitiesCallback = AZStd::function<void(AZStd::vector<AZ::Entity*>&)>;
AZ_RTTI(PrefabSystemComponentInterface, "{8E95A029-67F9-4F74-895F-DDBFE29516A0}");
virtual TemplateReference FindTemplate(TemplateId id) = 0;
@@ -70,9 +73,13 @@ namespace AzToolsFramework
virtual void PropagateTemplateChanges(TemplateId templateId, InstanceOptionalConstReference instanceToExclude = AZStd::nullopt) = 0;
virtual AZStd::unique_ptr<Instance> InstantiatePrefab(
AZ::IO::PathView filePath, InstanceOptionalReference parent = AZStd::nullopt) = 0;
AZ::IO::PathView filePath,
InstanceOptionalReference parent = AZStd::nullopt,
const InstantiatedEntitiesCallback& instantiatedEntitiesCallback = {}) = 0;
virtual AZStd::unique_ptr<Instance> InstantiatePrefab(
TemplateId templateId, InstanceOptionalReference parent = AZStd::nullopt) = 0;
TemplateId templateId,
InstanceOptionalReference parent = AZStd::nullopt,
const InstantiatedEntitiesCallback& instantiatedEntitiesCallback = {}) = 0;
virtual AZStd::unique_ptr<Instance> CreatePrefab(const AZStd::vector<AZ::Entity*>& entities,
AZStd::vector<AZStd::unique_ptr<Instance>>&& instancesToConsume, AZ::IO::PathView filePath,
AZStd::unique_ptr<AZ::Entity> containerEntity = nullptr, InstanceOptionalReference parent = AZStd::nullopt,
@@ -170,7 +170,14 @@ namespace UnitTest
m_instanceUpdateExecutorInterface->UpdateTemplateInstancesInQueue();
//instantiate a new nested instance
nestedInstance = m_prefabSystemComponent->InstantiatePrefab(nestedTemplateId);
nestedInstance = m_prefabSystemComponent->InstantiatePrefab(
nestedTemplateId, AZStd::nullopt,
[](const AzToolsFramework::EntityList& entities)
{
AzToolsFramework::EditorEntityContextRequestBus::Broadcast(
&AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded, entities);
});
nestedContainerEntityId = nestedInstance->GetContainerEntityId();
AZ::ComponentApplicationBus::BroadcastResult(nestedContainerEntity, &AZ::ComponentApplicationBus::Events::FindEntity, nestedContainerEntityId);
ASSERT_TRUE(nestedContainerEntity);
@@ -198,7 +205,13 @@ namespace UnitTest
LinkId linkId = undoInstanceLinkNode.GetLinkId();
rootInstance = m_prefabSystemComponent->InstantiatePrefab(rootTemplateId);
rootInstance = m_prefabSystemComponent->InstantiatePrefab(
rootTemplateId, AZStd::nullopt,
[](const AzToolsFramework::EntityList& entities)
{
AzToolsFramework::EditorEntityContextRequestBus::Broadcast(
&AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded, entities);
});
aliases = rootInstance->GetNestedInstanceAliases(nestedTemplateId);
//verify the link was created
@@ -228,7 +241,13 @@ namespace UnitTest
m_instanceUpdateExecutorInterface->UpdateTemplateInstancesInQueue();
//verify the update worked
rootInstance = m_prefabSystemComponent->InstantiatePrefab(rootTemplateId);
rootInstance = m_prefabSystemComponent->InstantiatePrefab(
rootTemplateId, AZStd::nullopt,
[](const AzToolsFramework::EntityList& entities)
{
AzToolsFramework::EditorEntityContextRequestBus::Broadcast(
&AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded, entities);
});
aliases = rootInstance->GetNestedInstanceAliases(nestedTemplateId);
nestedInstanceRef = rootInstance->FindNestedInstance(aliases[0]);
nestedContainerEntityId = nestedInstanceRef->get().GetContainerEntityId();
@@ -244,7 +263,13 @@ namespace UnitTest
m_instanceUpdateExecutorInterface->UpdateTemplateInstancesInQueue();
//verify the undo update worked
rootInstance = m_prefabSystemComponent->InstantiatePrefab(rootTemplateId);
rootInstance = m_prefabSystemComponent->InstantiatePrefab(
rootTemplateId, AZStd::nullopt,
[](const AzToolsFramework::EntityList& entities)
{
AzToolsFramework::EditorEntityContextRequestBus::Broadcast(
&AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded, entities);
});
aliases = rootInstance->GetNestedInstanceAliases(nestedTemplateId);
nestedInstanceRef = rootInstance->FindNestedInstance(aliases[0]);
nestedContainerEntityId = nestedInstanceRef->get().GetContainerEntityId();
@@ -259,7 +284,13 @@ namespace UnitTest
undoLinkUpdateNode.Redo();
m_instanceUpdateExecutorInterface->UpdateTemplateInstancesInQueue();
rootInstance = m_prefabSystemComponent->InstantiatePrefab(rootTemplateId);
rootInstance = m_prefabSystemComponent->InstantiatePrefab(
rootTemplateId, AZStd::nullopt,
[](const AzToolsFramework::EntityList& entities)
{
AzToolsFramework::EditorEntityContextRequestBus::Broadcast(
&AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded, entities);
});
aliases = rootInstance->GetNestedInstanceAliases(nestedTemplateId);
nestedInstanceRef = rootInstance->FindNestedInstance(aliases[0]);
nestedContainerEntityId = nestedInstanceRef->get().GetContainerEntityId();
@@ -287,7 +318,13 @@ namespace UnitTest
m_instanceUpdateExecutorInterface->UpdateTemplateInstancesInQueue();
//verify the update worked
rootInstance = m_prefabSystemComponent->InstantiatePrefab(rootTemplateId);
rootInstance = m_prefabSystemComponent->InstantiatePrefab(
rootTemplateId, AZStd::nullopt,
[](const AzToolsFramework::EntityList& entities)
{
AzToolsFramework::EditorEntityContextRequestBus::Broadcast(
&AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded, entities);
});
aliases = rootInstance->GetNestedInstanceAliases(nestedTemplateId);
nestedInstanceRef = rootInstance->FindNestedInstance(aliases[0]);
nestedContainerEntityId = nestedInstanceRef->get().GetContainerEntityId();
@@ -79,7 +79,14 @@ namespace UnitTest
// verify template updated correctly
//instantiate second instance for checking if propogation works
AZStd::unique_ptr<Instance> secondInstance = m_prefabSystemComponent->InstantiatePrefab(templateId);
AZStd::unique_ptr<Instance> secondInstance = m_prefabSystemComponent->InstantiatePrefab(
templateId, AZStd::nullopt,
[](const AzToolsFramework::EntityList& entities)
{
AzToolsFramework::EditorEntityContextRequestBus::Broadcast(
&AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded, entities);
});
ASSERT_TRUE(secondInstance);
ValidateInstanceEntitiesActive(*secondInstance);
@@ -7,4 +7,4 @@
*/
#pragma once
#define AWSCORE_BACKWARD_INCOMPATIBLE_CHANGE 0
#define AWSCORE_BACKWARD_INCOMPATIBLE_CHANGE 1
@@ -63,7 +63,7 @@ VSDepthOutput MainVS(VSInput IN)
struct PSDepthOutput
{
float m_depth : SV_Depth;
precise float m_depth : SV_Depth;
};
PSDepthOutput MainPS(VSDepthOutput IN, bool isFrontFace : SV_IsFrontFace)
@@ -72,7 +72,7 @@ namespace AZ
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->DataElement(AZ::Edit::UIHandlers::Default, &LightConfig::m_direction, "Direction", "")
->DataElement(Edit::UIHandlers::Color, &LightConfig::m_color, "Color", "Color of the light")
->Attribute("ColorEditorConfiguration", AZ::RPI::ColorUtils::GetLinearRgbEditorConfig())
->Attribute("ColorEditorConfiguration", AZ::RPI::ColorUtils::GetRgbEditorConfig())
->DataElement(Edit::UIHandlers::Default, &LightConfig::m_intensity, "Intensity", "Intensity of the light in the set photometric unit.")
->ClassElement(AZ::Edit::ClassElements::Group, "Shadow")
@@ -19,6 +19,8 @@ namespace AZ
//[GFX TODO][ATOM-4462] Replace this to use data driven color management system
//! Return a ColorEditorConfiguration for editing a Linear sRGB color in sRGB space.
AzToolsFramework::ColorEditorConfiguration GetLinearRgbEditorConfig();
//! Return a ColorEditorConfiguration for editing a sRGB color in sRGB space.
AzToolsFramework::ColorEditorConfiguration GetRgbEditorConfig();
} // namespace PropertyColorConfigs
} // namespace RPI
@@ -14,14 +14,14 @@ namespace AZ
{
namespace ColorUtils
{
enum ColorSpace : uint32_t
{
LinearSRGB,
SRGB
};
AzToolsFramework::ColorEditorConfiguration GetLinearRgbEditorConfig()
{
enum ColorSpace : uint32_t
{
LinearSRGB,
SRGB
};
AzToolsFramework::ColorEditorConfiguration configuration;
configuration.m_colorPickerDialogConfiguration = AzQtComponents::ColorPicker::Configuration::RGB;
@@ -59,6 +59,15 @@ namespace AZ
return configuration;
}
AzToolsFramework::ColorEditorConfiguration GetRgbEditorConfig()
{
AzToolsFramework::ColorEditorConfiguration configuration = GetLinearRgbEditorConfig();
configuration.m_propertyColorSpaceId = ColorSpace::SRGB;
return configuration;
}
} // namespace ColorPropertyEditorConfigurations
} // namespace RPI
} // namespace AZ
@@ -11,7 +11,7 @@
0.29372090101242068,
1.0
],
"textureMap": "Objects/Lucy/Lucy_bronze_BaseColor.png",
"textureMap": "Objects/Hermanubis/Hermanubis_bronze_BaseColor.png",
"useTexture": false
},
"detailLayerGroup": {
@@ -30,14 +30,14 @@
},
"normal": {
"flipY": true,
"textureMap": "Objects/Lucy/Lucy_Normal.png"
"textureMap": "Objects/Hermanubis/Hermanubis_Normal.png"
},
"subsurfaceScattering": {
"enableSubsurfaceScattering": true,
"influenceMap": "Objects/Lucy/Lucy_thickness.tif",
"influenceMap": "Objects/Hermanubis/Hermanubis_thickness.tif",
"scatterDistance": 15.0,
"subsurfaceScatterFactor": 0.4300000071525574,
"thicknessMap": "Objects/Lucy/Lucy_thickness.tif",
"thicknessMap": "Objects/Hermanubis/Hermanubis_thickness.tif",
"transmissionAttenuation": 15.0,
"transmissionDistortion": 0.3499999940395355,
"transmissionMode": "ThickObject",
@@ -29,14 +29,14 @@
},
"normal": {
"flipY": true,
"textureMap": "Objects/Lucy/Lucy_Normal.png"
"textureMap": "Objects/Hermanubis/Hermanubis_Normal.png"
},
"subsurfaceScattering": {
"enableSubsurfaceScattering": true,
"influenceMap": "TestData/Textures/checker8x8_gray_512.png",
"scatterDistance": 15.0,
"subsurfaceScatterFactor": 0.4300000071525574,
"thicknessMap": "Objects/Lucy/Lucy_thickness.tif",
"thicknessMap": "Objects/Hermanubis/Hermanubis_thickness.tif",
"transmissionAttenuation": 15.0,
"transmissionDistortion": 0.3499999940395355,
"transmissionMode": "ThickObject",
@@ -5,7 +5,7 @@
"propertyLayoutVersion": 3,
"properties": {
"baseColor": {
"textureMap": "Objects/Lucy/Lucy_bronze_BaseColor.png",
"textureMap": "Objects/Hermanubis/Hermanubis_bronze_BaseColor.png",
"textureMapUv": "Unwrapped"
},
"detailUV": {
@@ -15,16 +15,16 @@
]
},
"metallic": {
"textureMap": "Objects/Lucy/Lucy_bronze_Metallic.png",
"textureMap": "Objects/Hermanubis/Hermanubis_bronze_Metallic.png",
"textureMapUv": "Unwrapped"
},
"normal": {
"flipY": true,
"textureMap": "Objects/Lucy/Lucy_Normal.png",
"textureMap": "Objects/Hermanubis/Hermanubis_Normal.png",
"textureMapUv": "Unwrapped"
},
"roughness": {
"textureMap": "Objects/Lucy/Lucy_bronze_Roughness.png",
"textureMap": "Objects/Hermanubis/Hermanubis_bronze_Roughness.png",
"textureMapUv": "Unwrapped"
}
}
@@ -5,12 +5,12 @@
"propertyLayoutVersion": 3,
"properties": {
"baseColor": {
"textureMap": "Objects/Lucy/Lucy_bronze_BaseColor.png",
"textureMap": "Objects/Hermanubis/Hermanubis_bronze_BaseColor.png",
"textureMapUv": "Unwrapped"
},
"detailLayerGroup": {
"baseColorDetailMap": "TestData/Textures/cc0/Concrete019_1K_Color.jpg",
"blendDetailMask": "Objects/Lucy/Lucy_ao.tif",
"blendDetailMask": "Objects/Hermanubis/Hermanubis_ao.tif",
"blendDetailMaskUv": "Unwrapped",
"enableBaseColor": true,
"enableDetailLayer": true,
@@ -26,16 +26,16 @@
"scale": 10.0
},
"metallic": {
"textureMap": "Objects/Lucy/Lucy_bronze_Metallic.png",
"textureMap": "Objects/Hermanubis/Hermanubis_bronze_Metallic.png",
"textureMapUv": "Unwrapped"
},
"normal": {
"flipY": true,
"textureMap": "Objects/Lucy/Lucy_Normal.png",
"textureMap": "Objects/Hermanubis/Hermanubis_Normal.png",
"textureMapUv": "Unwrapped"
},
"roughness": {
"textureMap": "Objects/Lucy/Lucy_bronze_Roughness.png",
"textureMap": "Objects/Hermanubis/Hermanubis_bronze_Roughness.png",
"textureMapUv": "Unwrapped"
}
}
@@ -1,7 +1,7 @@
{
"description": "",
"materialType": "Materials/Types/EnhancedPBR.materialtype",
"parentMaterial": "TestData/Materials/StandardPbrTestCases/101_DetailMaps_LucyBaseNoDetailMaps.material",
"parentMaterial": "TestData/Materials/StandardPbrTestCases/101_DetailMaps_BaseNoDetailMaps.material",
"propertyLayoutVersion": 3,
"properties": {
"detailLayerGroup": {
@@ -1,7 +1,7 @@
{
"description": "",
"materialType": "Materials/Types/EnhancedPBR.materialtype",
"parentMaterial": "TestData/Materials/StandardPbrTestCases/101_DetailMaps_LucyBaseNoDetailMaps.material",
"parentMaterial": "TestData/Materials/StandardPbrTestCases/101_DetailMaps_BaseNoDetailMaps.material",
"propertyLayoutVersion": 3,
"properties": {
"detailLayerGroup": {
@@ -5,7 +5,7 @@
"propertyLayoutVersion": 3,
"properties": {
"baseColor": {
"textureMap": "Objects/Lucy/Lucy_bronze_BaseColor.png",
"textureMap": "Objects/Hermanubis/Hermanubis_bronze_BaseColor.png",
"textureMapUv": "Unwrapped"
},
"detailLayerGroup": {
@@ -25,16 +25,16 @@
"scale": 10.0
},
"metallic": {
"textureMap": "Objects/Lucy/Lucy_bronze_Metallic.png",
"textureMap": "Objects/Hermanubis/Hermanubis_bronze_Metallic.png",
"textureMapUv": "Unwrapped"
},
"normal": {
"flipY": true,
"textureMap": "Objects/Lucy/Lucy_Normal.png",
"textureMap": "Objects/Hermanubis/Hermanubis_Normal.png",
"textureMapUv": "Unwrapped"
},
"roughness": {
"textureMap": "Objects/Lucy/Lucy_bronze_Roughness.png",
"textureMap": "Objects/Hermanubis/Hermanubis_bronze_Roughness.png",
"textureMapUv": "Unwrapped"
}
}
@@ -160,7 +160,7 @@ namespace AtomToolsFramework
ApplyRangeEditDataAttributes<float>();
break;
case DynamicPropertyType::Color:
AddEditDataAttribute(AZ_CRC("ColorEditorConfiguration", 0xc8b9510e), AZ::RPI::ColorUtils::GetLinearRgbEditorConfig());
AddEditDataAttribute(AZ_CRC("ColorEditorConfiguration", 0xc8b9510e), AZ::RPI::ColorUtils::GetRgbEditorConfig());
break;
case DynamicPropertyType::Enum:
m_editData.m_elementId = AZ::Edit::UIHandlers::ComboBox;
@@ -75,7 +75,7 @@ namespace AZ
->DataElement(Edit::UIHandlers::Color, &AreaLightComponentConfig::m_color, "Color", "Color of the light")
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::LightTypeIsSelected)
->Attribute("ColorEditorConfiguration", RPI::ColorUtils::GetLinearRgbEditorConfig())
->Attribute("ColorEditorConfiguration", RPI::ColorUtils::GetRgbEditorConfig())
->DataElement(Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_intensityMode, "Intensity mode", "Allows specifying which photometric unit to work in.")
->Attribute(AZ::Edit::Attributes::EnumValues, &AreaLightComponentConfig::GetValidPhotometricUnits)
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::LightTypeIsSelected)
@@ -59,7 +59,7 @@ namespace AZ
->ClassElement(Edit::ClassElements::EditorData, "")
->DataElement(Edit::UIHandlers::Color, &DirectionalLightComponentConfig::m_color, "Color", "Color of the light")
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
->Attribute("ColorEditorConfiguration", AZ::RPI::ColorUtils::GetLinearRgbEditorConfig())
->Attribute("ColorEditorConfiguration", AZ::RPI::ColorUtils::GetRgbEditorConfig())
->DataElement(Edit::UIHandlers::ComboBox, &DirectionalLightComponentConfig::m_intensityMode, "Intensity mode", "Allows specifying light values in lux or Ev100")
->EnumAttribute(PhotometricUnit::Lux, "Lux")
->EnumAttribute(PhotometricUnit::Ev100Illuminance, "Ev100")
@@ -38,6 +38,12 @@ namespace EMotionFX
m_node = node;
}
void AnimGraphNodeNameLineEdit::focusInEvent([[maybe_unused]] QFocusEvent* event)
{
selectAll();
QLineEdit::focusInEvent(event);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------
AnimGraphNodeNameHandler::AnimGraphNodeNameHandler()
@@ -29,7 +29,8 @@ namespace EMotionFX
~AnimGraphNodeNameLineEdit() = default;
void SetNode(AnimGraphNode* node);
private:
void focusInEvent(QFocusEvent* event) override;
private:
AnimGraphNode* m_node;
};
@@ -405,6 +405,7 @@ namespace EMotionFX
ActorNotificationBus::Handler::BusConnect(GetEntityId());
AnimAudioComponentNotificationBus::Handler::BusConnect(GetEntityId());
AnimAudioComponentRequestBus::Handler::BusConnect(GetEntityId());
}
void AnimAudioComponent::Deactivate()
@@ -421,6 +422,7 @@ namespace EMotionFX
ActorNotificationBus::Handler::BusDisconnect(GetEntityId());
AnimAudioComponentNotificationBus::Handler::BusDisconnect(GetEntityId());
AnimAudioComponentRequestBus::Handler::BusDisconnect(GetEntityId());
}
void AnimAudioComponent::OnTick(float deltaTime, AZ::ScriptTimePoint time)
+3
View File
@@ -142,6 +142,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
AZ::AzTestShared
Gem::GradientSignal.Static
Gem::LmbrCentral
Gem::LmbrCentral.Mocks
Gem::GradientSignal.Mocks
)
@@ -161,6 +162,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
Gem::GradientSignal.Tests.Static
Gem::GradientSignal.Static
Gem::LmbrCentral
Gem::LmbrCentral.Mocks
Gem::GradientSignal.Mocks
)
ly_add_googletest(
@@ -191,6 +193,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
Gem::GradientSignal.Static
Gem::GradientSignal.Editor.Static
Gem::LmbrCentral.Editor
Gem::LmbrCentral.Mocks
)
ly_add_googletest(
NAME Gem::GradientSignal.Editor.Tests
@@ -62,22 +62,21 @@ namespace GradientSignal
// Reference implementation of GetValues for any gradients that don't have their own optimized implementations.
// This is 10%-60% faster than calling GetValue via EBus many times due to the per-call EBus overhead.
AZ_Assert(
positions.size() == outValues.size(), "input and output lists are different sizes (%zu vs %zu).",
positions.size(), outValues.size());
if (positions.size() == outValues.size())
if (positions.size() != outValues.size())
{
GradientSampleParams sampleParams;
for (size_t index = 0; index < positions.size(); index++)
{
sampleParams.m_position = positions[index];
AZ_Assert(false, "input and output lists are different sizes (%zu vs %zu).", positions.size(), outValues.size());
return;
}
// The const_cast is necessary for now since array_view currently only supports const entries.
// If/when array_view is fixed to support non-const, or AZStd::span gets created, the const_cast can get removed.
auto& outValue = const_cast<float&>(outValues[index]);
outValue = GetValue(sampleParams);
}
GradientSampleParams sampleParams;
for (size_t index = 0; index < positions.size(); index++)
{
sampleParams.m_position = positions[index];
// The const_cast is necessary for now since array_view currently only supports const entries.
// If/when array_view is fixed to support non-const, or AZStd::span gets created, the const_cast can get removed.
auto& outValue = const_cast<float&>(outValues[index]);
outValue = GetValue(sampleParams);
}
}
@@ -120,7 +120,7 @@ namespace GradientSignal
if (m_isRequestInProgress)
{
AZ_ErrorOnce("GradientSignal", !m_isRequestInProgress, "Detected cyclic dependences with gradient entity references");
AZ_ErrorOnce("GradientSignal", !m_isRequestInProgress, "Detected cyclic dependencies with gradient entity references");
}
else
{
@@ -197,7 +197,7 @@ namespace GradientSignal
if (m_isRequestInProgress)
{
AZ_ErrorOnce("GradientSignal", !m_isRequestInProgress, "Detected cyclic dependences with gradient entity references");
AZ_ErrorOnce("GradientSignal", !m_isRequestInProgress, "Detected cyclic dependencies with gradient entity references");
ClearOutputValues(outValues);
return;
}
@@ -16,162 +16,337 @@
#include <AzCore/UnitTest/TestTypes.h>
#include <AzFramework/Asset/AssetCatalogBus.h>
#include <GradientSignal/Components/ImageGradientComponent.h>
#include <GradientSignal/Components/PerlinGradientComponent.h>
#include <GradientSignal/Components/RandomGradientComponent.h>
#include <GradientSignal/Components/GradientTransformComponent.h>
namespace UnitTest
{
BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_ImageGradientEBusGetValue)(benchmark::State& state)
class GradientGetValues : public GradientSignalBenchmarkFixture
{
CreateTestImageGradient(m_testEntity.get());
RunEBusGetValueBenchmark(state);
}
public:
// We use an enum to list out the different types of GetValue() benchmarks to run so that way we can condense our test cases
// to just take the value in as a benchmark argument and switch on it. Otherwise, we would need to write a different benchmark
// function for each test case for each gradient.
enum GetValuePermutation : int64_t
{
EBUS_GET_VALUE,
EBUS_GET_VALUES,
SAMPLER_GET_VALUE,
SAMPLER_GET_VALUES,
};
BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_ImageGradientEBusGetValue)
->Args({ 1024, 1024 })
->Args({ 2048, 2048 })
->Args({ 4096, 4096 })
// Create an arbitrary size shape for creating our gradients for benchmark runs.
const float TestShapeHalfBounds = 128.0f;
void FillQueryPositions(AZStd::vector<AZ::Vector3>& positions, float height, float width)
{
size_t index = 0;
for (float y = 0.0f; y < height; y += 1.0f)
{
for (float x = 0.0f; x < width; x += 1.0f)
{
positions[index++] = AZ::Vector3(x, y, 0.0f);
}
}
}
void RunEBusGetValueBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange)
{
AZ_PROFILE_FUNCTION(Entity);
GradientSignal::GradientSampleParams params;
// Get the height and width ranges for querying from our benchmark parameters
const float height = aznumeric_cast<float>(queryRange);
const float width = aznumeric_cast<float>(queryRange);
// Call GetValue() on the EBus for every height and width in our ranges.
for (auto _ : state)
{
for (float y = 0.0f; y < height; y += 1.0f)
{
for (float x = 0.0f; x < width; x += 1.0f)
{
float value = 0.0f;
params.m_position = AZ::Vector3(x, y, 0.0f);
GradientSignal::GradientRequestBus::EventResult(
value, gradientId, &GradientSignal::GradientRequestBus::Events::GetValue, params);
benchmark::DoNotOptimize(value);
}
}
}
}
void RunEBusGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange)
{
AZ_PROFILE_FUNCTION(Entity);
// Get the height and width ranges for querying from our benchmark parameters
float height = aznumeric_cast<float>(queryRange);
float width = aznumeric_cast<float>(queryRange);
int64_t totalQueryPoints = queryRange * queryRange;
// Call GetValues() for every height and width in our ranges.
for (auto _ : state)
{
// Set up our vector of query positions. This is done inside the benchmark timing since we're counting the work to create
// each query position in the single GetValue() call benchmarks, and will make the timing more directly comparable.
AZStd::vector<AZ::Vector3> positions(totalQueryPoints);
FillQueryPositions(positions, height, width);
// Query and get the results.
AZStd::vector<float> results(totalQueryPoints);
GradientSignal::GradientRequestBus::Event(
gradientId, &GradientSignal::GradientRequestBus::Events::GetValues, positions, results);
}
}
void RunSamplerGetValueBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange)
{
AZ_PROFILE_FUNCTION(Entity);
// Create a gradient sampler to use for querying our gradient.
GradientSignal::GradientSampler gradientSampler;
gradientSampler.m_gradientId = gradientId;
// Get the height and width ranges for querying from our benchmark parameters
const float height = aznumeric_cast<float>(queryRange);
const float width = aznumeric_cast<float>(queryRange);
// Call GetValue() through the GradientSampler for every height and width in our ranges.
for (auto _ : state)
{
for (float y = 0.0f; y < height; y += 1.0f)
{
for (float x = 0.0f; x < width; x += 1.0f)
{
GradientSignal::GradientSampleParams params;
params.m_position = AZ::Vector3(x, y, 0.0f);
float value = gradientSampler.GetValue(params);
benchmark::DoNotOptimize(value);
}
}
}
}
void RunSamplerGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange)
{
AZ_PROFILE_FUNCTION(Entity);
// Create a gradient sampler to use for querying our gradient.
GradientSignal::GradientSampler gradientSampler;
gradientSampler.m_gradientId = gradientId;
// Get the height and width ranges for querying from our benchmark parameters
const float height = aznumeric_cast<float>(queryRange);
const float width = aznumeric_cast<float>(queryRange);
const int64_t totalQueryPoints = queryRange * queryRange;
// Call GetValues() through the GradientSampler for every height and width in our ranges.
for (auto _ : state)
{
// Set up our vector of query positions. This is done inside the benchmark timing since we're counting the work to create
// each query position in the single GetValue() call benchmarks, and will make the timing more directly comparable.
AZStd::vector<AZ::Vector3> positions(totalQueryPoints);
FillQueryPositions(positions, height, width);
// Query and get the results.
AZStd::vector<float> results(totalQueryPoints);
gradientSampler.GetValues(positions, results);
}
}
void RunGetValueOrGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId)
{
switch (state.range(0))
{
case GetValuePermutation::EBUS_GET_VALUE:
RunEBusGetValueBenchmark(state, gradientId, state.range(1));
break;
case GetValuePermutation::EBUS_GET_VALUES:
RunEBusGetValuesBenchmark(state, gradientId, state.range(1));
break;
case GetValuePermutation::SAMPLER_GET_VALUE:
RunSamplerGetValueBenchmark(state, gradientId, state.range(1));
break;
case GetValuePermutation::SAMPLER_GET_VALUES:
RunSamplerGetValuesBenchmark(state, gradientId, state.range(1));
break;
default:
AZ_Assert(false, "Benchmark permutation type not supported.");
}
}
};
// Because there's no good way to label different enums in the output results (they just appear as integer values), we work around it by
// registering one set of benchmark runs for each enum value and use ArgNames() to give it a friendly name in the results.
#define GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(Fixture, Func) \
BENCHMARK_REGISTER_F(Fixture, Func) \
->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUE, 1024 }) \
->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUE, 2048 }) \
->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUE, 4096 }) \
->ArgNames({ "EbusGetValue", "size" }) \
->Unit(::benchmark::kMillisecond); \
BENCHMARK_REGISTER_F(Fixture, Func) \
->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUES, 1024 }) \
->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUES, 2048 }) \
->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUES, 4096 }) \
->ArgNames({ "EbusGetValues", "size" }) \
->Unit(::benchmark::kMillisecond); \
BENCHMARK_REGISTER_F(Fixture, Func) \
->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUE, 1024 }) \
->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUE, 2048 }) \
->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUE, 4096 }) \
->ArgNames({ "SamplerGetValue", "size" }) \
->Unit(::benchmark::kMillisecond); \
BENCHMARK_REGISTER_F(Fixture, Func) \
->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUES, 1024 }) \
->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUES, 2048 }) \
->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUES, 4096 }) \
->ArgNames({ "SamplerGetValues", "size" }) \
->Unit(::benchmark::kMillisecond);
BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_ImageGradientEBusGetValues)(benchmark::State& state)
// --------------------------------------------------------------------------------------
// Base Gradients
BENCHMARK_DEFINE_F(GradientGetValues, BM_ConstantGradient)(benchmark::State& state)
{
CreateTestImageGradient(m_testEntity.get());
RunEBusGetValuesBenchmark(state);
auto entity = BuildTestConstantGradient(TestShapeHalfBounds);
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_ImageGradientEBusGetValues)
->Args({ 1024, 1024 })
->Args({ 2048, 2048 })
->Args({ 4096, 4096 })
->Unit(::benchmark::kMillisecond);
BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_ImageGradientSamplerGetValue)(benchmark::State& state)
BENCHMARK_DEFINE_F(GradientGetValues, BM_ImageGradient)(benchmark::State& state)
{
CreateTestImageGradient(m_testEntity.get());
RunSamplerGetValueBenchmark(state);
auto entity = BuildTestImageGradient(TestShapeHalfBounds);
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_ImageGradientSamplerGetValue)
->Args({ 1024, 1024 })
->Args({ 2048, 2048 })
->Args({ 4096, 4096 })
->Unit(::benchmark::kMillisecond);
BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_ImageGradientSamplerGetValues)(benchmark::State& state)
BENCHMARK_DEFINE_F(GradientGetValues, BM_PerlinGradient)(benchmark::State& state)
{
CreateTestImageGradient(m_testEntity.get());
RunSamplerGetValuesBenchmark(state);
auto entity = BuildTestPerlinGradient(TestShapeHalfBounds);
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_ImageGradientSamplerGetValues)
->Args({ 1024, 1024 })
->Args({ 2048, 2048 })
->Args({ 4096, 4096 })
->Unit(::benchmark::kMillisecond);
BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_PerlinGradientEBusGetValue)(benchmark::State& state)
BENCHMARK_DEFINE_F(GradientGetValues, BM_RandomGradient)(benchmark::State& state)
{
CreateTestPerlinGradient(m_testEntity.get());
RunEBusGetValueBenchmark(state);
auto entity = BuildTestRandomGradient(TestShapeHalfBounds);
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_PerlinGradientEBusGetValue)
->Args({ 1024, 1024 })
->Args({ 2048, 2048 })
->Args({ 4096, 4096 })
->Unit(::benchmark::kMillisecond);
BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_PerlinGradientEBusGetValues)(benchmark::State& state)
BENCHMARK_DEFINE_F(GradientGetValues, BM_ShapeAreaFalloffGradient)(benchmark::State& state)
{
CreateTestPerlinGradient(m_testEntity.get());
RunEBusGetValuesBenchmark(state);
auto entity = BuildTestShapeAreaFalloffGradient(TestShapeHalfBounds);
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_PerlinGradientEBusGetValues)
->Args({ 1024, 1024 })
->Args({ 2048, 2048 })
->Args({ 4096, 4096 })
->Unit(::benchmark::kMillisecond);
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_ConstantGradient);
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_ImageGradient);
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_PerlinGradient);
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_RandomGradient);
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_ShapeAreaFalloffGradient);
BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_PerlinGradientSamplerGetValue)(benchmark::State& state)
// --------------------------------------------------------------------------------------
// Gradient Modifiers
BENCHMARK_DEFINE_F(GradientGetValues, BM_DitherGradient)(benchmark::State& state)
{
CreateTestPerlinGradient(m_testEntity.get());
RunSamplerGetValueBenchmark(state);
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestDitherGradient(TestShapeHalfBounds, baseEntity->GetId());
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_PerlinGradientSamplerGetValue)
->Args({ 1024, 1024 })
->Args({ 2048, 2048 })
->Args({ 4096, 4096 })
->Unit(::benchmark::kMillisecond);
BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_PerlinGradientSamplerGetValues)(benchmark::State& state)
BENCHMARK_DEFINE_F(GradientGetValues, BM_InvertGradient)(benchmark::State& state)
{
CreateTestPerlinGradient(m_testEntity.get());
RunSamplerGetValuesBenchmark(state);
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestDitherGradient(TestShapeHalfBounds, baseEntity->GetId());
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_PerlinGradientSamplerGetValues)
->Args({ 1024, 1024 })
->Args({ 2048, 2048 })
->Args({ 4096, 4096 })
->Unit(::benchmark::kMillisecond);
BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_RandomGradientEBusGetValue)(benchmark::State& state)
BENCHMARK_DEFINE_F(GradientGetValues, BM_LevelsGradient)(benchmark::State& state)
{
CreateTestRandomGradient(m_testEntity.get());
RunEBusGetValueBenchmark(state);
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestLevelsGradient(TestShapeHalfBounds, baseEntity->GetId());
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_RandomGradientEBusGetValue)
->Args({ 1024, 1024 })
->Args({ 2048, 2048 })
->Args({ 4096, 4096 })
->Unit(::benchmark::kMillisecond);
BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_RandomGradientEBusGetValues)(benchmark::State& state)
BENCHMARK_DEFINE_F(GradientGetValues, BM_MixedGradient)(benchmark::State& state)
{
CreateTestRandomGradient(m_testEntity.get());
RunEBusGetValuesBenchmark(state);
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto mixedEntity = BuildTestConstantGradient(TestShapeHalfBounds);
auto entity = BuildTestMixedGradient(TestShapeHalfBounds, baseEntity->GetId(), mixedEntity->GetId());
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_RandomGradientEBusGetValues)
->Args({ 1024, 1024 })
->Args({ 2048, 2048 })
->Args({ 4096, 4096 })
->Unit(::benchmark::kMillisecond);
BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_RandomGradientSamplerGetValue)(benchmark::State& state)
BENCHMARK_DEFINE_F(GradientGetValues, BM_PosterizeGradient)(benchmark::State& state)
{
CreateTestRandomGradient(m_testEntity.get());
RunSamplerGetValueBenchmark(state);
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestPosterizeGradient(TestShapeHalfBounds, baseEntity->GetId());
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_RandomGradientSamplerGetValue)
->Args({ 1024, 1024 })
->Args({ 2048, 2048 })
->Args({ 4096, 4096 })
->Unit(::benchmark::kMillisecond);
BENCHMARK_DEFINE_F(GradientSignalBenchmarkFixture, BM_RandomGradientSamplerGetValues)(benchmark::State& state)
BENCHMARK_DEFINE_F(GradientGetValues, BM_ReferenceGradient)(benchmark::State& state)
{
CreateTestRandomGradient(m_testEntity.get());
RunSamplerGetValuesBenchmark(state);
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestReferenceGradient(TestShapeHalfBounds, baseEntity->GetId());
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_REGISTER_F(GradientSignalBenchmarkFixture, BM_RandomGradientSamplerGetValues)
->Args({ 1024, 1024 })
->Args({ 2048, 2048 })
->Args({ 4096, 4096 })
->Unit(::benchmark::kMillisecond);
BENCHMARK_DEFINE_F(GradientGetValues, BM_SmoothStepGradient)(benchmark::State& state)
{
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestSmoothStepGradient(TestShapeHalfBounds, baseEntity->GetId());
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_DEFINE_F(GradientGetValues, BM_ThresholdGradient)(benchmark::State& state)
{
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestThresholdGradient(TestShapeHalfBounds, baseEntity->GetId());
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_DitherGradient);
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_InvertGradient);
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_LevelsGradient);
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_MixedGradient);
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_PosterizeGradient);
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_ReferenceGradient);
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_SmoothStepGradient);
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_ThresholdGradient);
// --------------------------------------------------------------------------------------
// Surface Gradients
BENCHMARK_DEFINE_F(GradientGetValues, BM_SurfaceAltitudeGradient)(benchmark::State& state)
{
auto mockSurfaceDataSystem =
CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds)));
auto entity = BuildTestSurfaceAltitudeGradient(TestShapeHalfBounds);
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_DEFINE_F(GradientGetValues, BM_SurfaceMaskGradient)(benchmark::State& state)
{
auto mockSurfaceDataSystem =
CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds)));
auto entity = BuildTestSurfaceMaskGradient(TestShapeHalfBounds);
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_DEFINE_F(GradientGetValues, BM_SurfaceSlopeGradient)(benchmark::State& state)
{
auto mockSurfaceDataSystem =
CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds)));
auto entity = BuildTestSurfaceSlopeGradient(TestShapeHalfBounds);
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_SurfaceAltitudeGradient);
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_SurfaceMaskGradient);
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_SurfaceSlopeGradient);
#endif
}
@@ -0,0 +1,182 @@
/*
* 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/GradientSignalTestFixtures.h>
#include <AzTest/AzTest.h>
namespace UnitTest
{
struct GradientSignalGetValuesTestsFixture
: public GradientSignalTest
{
// Create an arbitrary size shape for comparing values within. It should be large enough that we detect any value anomalies
// but small enough that the tests run quickly.
const float TestShapeHalfBounds = 128.0f;
void CompareGetValueAndGetValues(AZ::EntityId gradientEntityId)
{
// Create a gradient sampler and run through a series of points to see if they match expectations.
const AZ::Aabb queryRegion = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds));
const AZ::Vector2 stepSize(1.0f, 1.0f);
GradientSignal::GradientSampler gradientSampler;
gradientSampler.m_gradientId = gradientEntityId;
const size_t numSamplesX = aznumeric_cast<size_t>(ceil(queryRegion.GetExtents().GetX() / stepSize.GetX()));
const size_t numSamplesY = aznumeric_cast<size_t>(ceil(queryRegion.GetExtents().GetY() / stepSize.GetY()));
// Build up the list of positions to query.
AZStd::vector<AZ::Vector3> positions(numSamplesX * numSamplesY);
size_t index = 0;
for (size_t yIndex = 0; yIndex < numSamplesY; yIndex++)
{
float y = queryRegion.GetMin().GetY() + (stepSize.GetY() * yIndex);
for (size_t xIndex = 0; xIndex < numSamplesX; xIndex++)
{
float x = queryRegion.GetMin().GetX() + (stepSize.GetX() * xIndex);
positions[index++] = AZ::Vector3(x, y, 0.0f);
}
}
// Get the results from GetValues
AZStd::vector<float> results(numSamplesX * numSamplesY);
gradientSampler.GetValues(positions, results);
// For each position, call GetValue and verify that the values match.
for (size_t positionIndex = 0; positionIndex < positions.size(); positionIndex++)
{
GradientSignal::GradientSampleParams params;
params.m_position = positions[positionIndex];
float value = gradientSampler.GetValue(params);
// We use ASSERT_EQ instead of EXPECT_EQ because if one value doesn't match, they probably all won't, so there's no reason
// to keep running and printing failures for every value.
ASSERT_EQ(value, results[positionIndex]);
}
}
};
TEST_F(GradientSignalGetValuesTestsFixture, ImageGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto entity = BuildTestImageGradient(TestShapeHalfBounds);
CompareGetValueAndGetValues(entity->GetId());
}
TEST_F(GradientSignalGetValuesTestsFixture, PerlinGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto entity = BuildTestPerlinGradient(TestShapeHalfBounds);
CompareGetValueAndGetValues(entity->GetId());
}
TEST_F(GradientSignalGetValuesTestsFixture, RandomGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto entity = BuildTestRandomGradient(TestShapeHalfBounds);
CompareGetValueAndGetValues(entity->GetId());
}
TEST_F(GradientSignalGetValuesTestsFixture, ConstantGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto entity = BuildTestConstantGradient(TestShapeHalfBounds);
CompareGetValueAndGetValues(entity->GetId());
}
TEST_F(GradientSignalGetValuesTestsFixture, ShapeAreaFalloffGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto entity = BuildTestShapeAreaFalloffGradient(TestShapeHalfBounds);
CompareGetValueAndGetValues(entity->GetId());
}
TEST_F(GradientSignalGetValuesTestsFixture, DitherGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestDitherGradient(TestShapeHalfBounds, baseEntity->GetId());
CompareGetValueAndGetValues(entity->GetId());
}
TEST_F(GradientSignalGetValuesTestsFixture, InvertGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestInvertGradient(TestShapeHalfBounds, baseEntity->GetId());
CompareGetValueAndGetValues(entity->GetId());
}
TEST_F(GradientSignalGetValuesTestsFixture, LevelsGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestLevelsGradient(TestShapeHalfBounds, baseEntity->GetId());
CompareGetValueAndGetValues(entity->GetId());
}
TEST_F(GradientSignalGetValuesTestsFixture, MixedGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto mixedEntity = BuildTestConstantGradient(TestShapeHalfBounds);
auto entity = BuildTestMixedGradient(TestShapeHalfBounds, baseEntity->GetId(), mixedEntity->GetId());
CompareGetValueAndGetValues(entity->GetId());
}
TEST_F(GradientSignalGetValuesTestsFixture, PosterizeGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestPosterizeGradient(TestShapeHalfBounds, baseEntity->GetId());
CompareGetValueAndGetValues(entity->GetId());
}
TEST_F(GradientSignalGetValuesTestsFixture, ReferenceGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestReferenceGradient(TestShapeHalfBounds, baseEntity->GetId());
CompareGetValueAndGetValues(entity->GetId());
}
TEST_F(GradientSignalGetValuesTestsFixture, SmoothStepGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestSmoothStepGradient(TestShapeHalfBounds, baseEntity->GetId());
CompareGetValueAndGetValues(entity->GetId());
}
TEST_F(GradientSignalGetValuesTestsFixture, ThresholdGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestThresholdGradient(TestShapeHalfBounds, baseEntity->GetId());
CompareGetValueAndGetValues(entity->GetId());
}
TEST_F(GradientSignalGetValuesTestsFixture, SurfaceAltitudeGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto mockSurfaceDataSystem =
CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds)));
auto entity = BuildTestSurfaceAltitudeGradient(TestShapeHalfBounds);
CompareGetValueAndGetValues(entity->GetId());
}
TEST_F(GradientSignalGetValuesTestsFixture, SurfaceMaskGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto mockSurfaceDataSystem =
CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds)));
auto entity = BuildTestSurfaceMaskGradient(TestShapeHalfBounds);
CompareGetValueAndGetValues(entity->GetId());
}
TEST_F(GradientSignalGetValuesTestsFixture, SurfaceSlopeGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto mockSurfaceDataSystem =
CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds)));
auto entity = BuildTestSurfaceSlopeGradient(TestShapeHalfBounds);
CompareGetValueAndGetValues(entity->GetId());
}
}
@@ -417,7 +417,6 @@ namespace UnitTest
TestFixedDataSampler(expectedOutput, dataSize, entity->GetId());
}
}
}
@@ -371,12 +371,9 @@ namespace UnitTest
const AZ::EntityId id = mockReference->GetId();
MockGradientArrayRequestsBus mockGradientRequestsBus(id, inputData, dataSize);
GradientSignal::ReferenceGradientConfig config;
config.m_gradientSampler.m_gradientId = mockReference->GetId();
auto entity = CreateEntity();
CreateComponent<GradientSignal::ReferenceGradientComponent>(entity.get(), config);
ActivateEntity(entity.get());
// Create a reference gradient with an arbitrary box shape on it.
const float HalfBounds = 64.0f;
auto entity = BuildTestReferenceGradient(HalfBounds, mockReference->GetId());
TestFixedDataSampler(expectedOutput, dataSize, entity->GetId());
}
@@ -385,10 +382,9 @@ namespace UnitTest
{
// Verify that gradient references can validate and disconnect cyclic connections
auto constantGradientEntity = CreateEntity();
GradientSignal::ConstantGradientConfig constantGradientConfig;
CreateComponent<GradientSignal::ConstantGradientComponent>(constantGradientEntity.get(), constantGradientConfig);
ActivateEntity(constantGradientEntity.get());
// Create a constant gradient with an arbitrary box shape on it.
const float HalfBounds = 64.0f;
auto constantGradientEntity = BuildTestConstantGradient(HalfBounds);
// Verify cyclic reference test passes when pointing to gradient generator entity
auto referenceGradientEntity1 = CreateEntity();
@@ -212,12 +212,9 @@ namespace UnitTest
const AZ::EntityId id = entityMock->GetId();
UnitTest::MockGradientArrayRequestsBus mockGradientRequestsBus(id, inputData, dataSize);
GradientSignal::InvertGradientConfig config;
config.m_gradientSampler.m_gradientId = entityMock->GetId();
auto entity = CreateEntity();
CreateComponent<GradientSignal::InvertGradientComponent>(entity.get(), config);
ActivateEntity(entity.get());
// Create the entity with an arbitrarily-sized box.
const float HalfBounds = 64.0f;
auto entity = BuildTestInvertGradient(HalfBounds, entityMock->GetId());
TestFixedDataSampler(expectedOutput, dataSize, entity->GetId());
}
@@ -9,10 +9,30 @@
#include <Tests/GradientSignalTestFixtures.h>
#include <AzFramework/Components/TransformComponent.h>
#include <GradientSignal/Components/GradientTransformComponent.h>
// Base gradient components
#include <GradientSignal/Components/ConstantGradientComponent.h>
#include <GradientSignal/Components/ImageGradientComponent.h>
#include <GradientSignal/Components/PerlinGradientComponent.h>
#include <GradientSignal/Components/RandomGradientComponent.h>
#include <GradientSignal/Components/ShapeAreaFalloffGradientComponent.h>
// Gradient modifier components
#include <GradientSignal/Components/DitherGradientComponent.h>
#include <GradientSignal/Components/InvertGradientComponent.h>
#include <GradientSignal/Components/LevelsGradientComponent.h>
#include <GradientSignal/Components/MixedGradientComponent.h>
#include <GradientSignal/Components/PosterizeGradientComponent.h>
#include <GradientSignal/Components/ReferenceGradientComponent.h>
#include <GradientSignal/Components/SmoothStepGradientComponent.h>
#include <GradientSignal/Components/ThresholdGradientComponent.h>
// Gradient surface data components
#include <GradientSignal/Components/SurfaceAltitudeGradientComponent.h>
#include <GradientSignal/Components/SurfaceMaskGradientComponent.h>
#include <GradientSignal/Components/SurfaceSlopeGradientComponent.h>
namespace UnitTest
{
@@ -32,12 +52,18 @@ namespace UnitTest
AZ::Data::AssetManager::Create(desc);
m_mockHandler = new ImageAssetMockAssetHandler();
AZ::Data::AssetManager::Instance().RegisterHandler(m_mockHandler, azrtti_typeid<GradientSignal::ImageAsset>());
m_mockShapeHandlers = new AZStd::vector<AZStd::unique_ptr<testing::NiceMock<UnitTest::MockShapeComponentRequests>>>();
}
void GradientSignalBaseFixture::TearDownCoreSystems()
{
// Clear any mock shape handlers that we've created for our test entities.
delete m_mockShapeHandlers;
AZ::Data::AssetManager::Instance().UnregisterHandler(m_mockHandler);
delete m_mockHandler; // delete after removing from the asset manager
AzFramework::LegacyAssetEventBus::ClearQueuedEvents();
AZ::Data::AssetManager::Destroy();
AZ::AllocatorInstance<AZ::ThreadPoolAllocator>::Destroy();
@@ -47,6 +73,338 @@ namespace UnitTest
m_systemEntity = nullptr;
}
AZStd::unique_ptr<testing::NiceMock<UnitTest::MockShapeComponentRequests>> GradientSignalBaseFixture::CreateMockShape(
const AZ::Aabb& spawnerBox, const AZ::EntityId& shapeEntityId)
{
AZStd::unique_ptr<testing::NiceMock<UnitTest::MockShapeComponentRequests>> mockShape =
AZStd::make_unique<testing::NiceMock<UnitTest::MockShapeComponentRequests>>(shapeEntityId);
ON_CALL(*mockShape, GetEncompassingAabb).WillByDefault(testing::Return(spawnerBox));
ON_CALL(*mockShape, GetTransformAndLocalBounds)
.WillByDefault(
[spawnerBox](AZ::Transform& transform, AZ::Aabb& bounds)
{
transform = AZ::Transform::CreateTranslation(spawnerBox.GetCenter());
bounds = spawnerBox.GetTranslated(-spawnerBox.GetCenter());
});
ON_CALL(*mockShape, IsPointInside)
.WillByDefault(
[spawnerBox](const AZ::Vector3& point) -> bool
{
return spawnerBox.Contains(point);
});
return mockShape;
}
AZStd::unique_ptr<MockSurfaceDataSystem> GradientSignalBaseFixture::CreateMockSurfaceDataSystem(const AZ::Aabb& spawnerBox)
{
SurfaceData::SurfacePoint point;
AZStd::unique_ptr<MockSurfaceDataSystem> mockSurfaceDataSystem = AZStd::make_unique<MockSurfaceDataSystem>();
// Give the mock surface data a bunch of fake point values to return.
for (float y = spawnerBox.GetMin().GetY(); y < spawnerBox.GetMax().GetY(); y+= 1.0f)
{
for (float x = spawnerBox.GetMin().GetX(); x < spawnerBox.GetMax().GetX(); x += 1.0f)
{
// Use our x distance into the spawnerBox as an arbitrary percentage value that we'll use to calculate
// our other arbitrary values below.
float arbitraryPercentage = AZStd::abs(x / spawnerBox.GetExtents().GetX());
// Create a position that's between min and max Z of the box.
point.m_position = AZ::Vector3(x, y, AZ::Lerp(spawnerBox.GetMin().GetZ(), spawnerBox.GetMax().GetZ(), arbitraryPercentage));
// Create an arbitrary normal value.
point.m_normal = point.m_position.GetNormalized();
// Create an arbitrary surface value.
point.m_masks[AZ_CRC_CE("test_mask")] = arbitraryPercentage;
mockSurfaceDataSystem->m_GetSurfacePoints[AZStd::make_pair(x, y)] = { { point } };
}
}
return mockSurfaceDataSystem;
}
AZStd::unique_ptr<AZ::Entity> GradientSignalBaseFixture::CreateTestEntity(float shapeHalfBounds)
{
// Create the base entity
AZStd::unique_ptr<AZ::Entity> testEntity = CreateEntity();
// Create a mock Shape component that describes the bounds that we're using to map our gradient into world space.
CreateComponent<MockShapeComponent>(testEntity.get());
// Create and keep a reference to a mock shape handler that will respond to shape requests for the mock shape.
auto mockShapeHandler =
CreateMockShape(AZ::Aabb::CreateCenterRadius(AZ::Vector3(shapeHalfBounds), shapeHalfBounds), testEntity->GetId());
m_mockShapeHandlers->push_back(AZStd::move(mockShapeHandler));
// Create a transform that locates our gradient in the center of our desired mock Shape.
auto transform = CreateComponent<AzFramework::TransformComponent>(testEntity.get());
transform->SetLocalTM(AZ::Transform::CreateTranslation(AZ::Vector3(shapeHalfBounds)));
transform->SetWorldTM(AZ::Transform::CreateTranslation(AZ::Vector3(shapeHalfBounds)));
return testEntity;
}
AZStd::unique_ptr<AZ::Entity> GradientSignalBaseFixture::BuildTestConstantGradient(float shapeHalfBounds)
{
// Create a Constant Gradient Component with arbitrary parameters.
auto entity = CreateTestEntity(shapeHalfBounds);
GradientSignal::ConstantGradientConfig config;
config.m_value = 0.75f;
CreateComponent<GradientSignal::ConstantGradientComponent>(entity.get(), config);
ActivateEntity(entity.get());
return entity;
}
AZStd::unique_ptr<AZ::Entity> GradientSignalBaseFixture::BuildTestImageGradient(float shapeHalfBounds)
{
// Create an Image Gradient Component with arbitrary sizes and parameters.
auto entity = CreateTestEntity(shapeHalfBounds);
GradientSignal::ImageGradientConfig config;
const uint32_t imageSize = 4096;
const int32_t imageSeed = 12345;
config.m_imageAsset = ImageAssetMockAssetHandler::CreateImageAsset(imageSize, imageSize, imageSeed);
config.m_tilingX = 1.0f;
config.m_tilingY = 1.0f;
CreateComponent<GradientSignal::ImageGradientComponent>(entity.get(), config);
// Create a Gradient Transform Component with arbitrary parameters.
GradientSignal::GradientTransformConfig gradientTransformConfig;
gradientTransformConfig.m_wrappingType = GradientSignal::WrappingType::None;
CreateComponent<GradientSignal::GradientTransformComponent>(entity.get(), gradientTransformConfig);
ActivateEntity(entity.get());
return entity;
}
AZStd::unique_ptr<AZ::Entity> GradientSignalBaseFixture::BuildTestPerlinGradient(float shapeHalfBounds)
{
// Create a Perlin Gradient Component with arbitrary parameters.
auto entity = CreateTestEntity(shapeHalfBounds);
GradientSignal::PerlinGradientConfig config;
config.m_amplitude = 1.0f;
config.m_frequency = 1.1f;
config.m_octave = 4;
config.m_randomSeed = 12345;
CreateComponent<GradientSignal::PerlinGradientComponent>(entity.get(), config);
// Create a Gradient Transform Component with arbitrary parameters.
GradientSignal::GradientTransformConfig gradientTransformConfig;
gradientTransformConfig.m_wrappingType = GradientSignal::WrappingType::None;
CreateComponent<GradientSignal::GradientTransformComponent>(entity.get(), gradientTransformConfig);
ActivateEntity(entity.get());
return entity;
}
AZStd::unique_ptr<AZ::Entity> GradientSignalBaseFixture::BuildTestRandomGradient(float shapeHalfBounds)
{
// Create a Random Gradient Component with arbitrary parameters.
auto entity = CreateTestEntity(shapeHalfBounds);
GradientSignal::RandomGradientConfig config;
config.m_randomSeed = 12345;
CreateComponent<GradientSignal::RandomGradientComponent>(entity.get(), config);
// Create a Gradient Transform Component with arbitrary parameters.
GradientSignal::GradientTransformConfig gradientTransformConfig;
gradientTransformConfig.m_wrappingType = GradientSignal::WrappingType::None;
CreateComponent<GradientSignal::GradientTransformComponent>(entity.get(), gradientTransformConfig);
ActivateEntity(entity.get());
return entity;
}
AZStd::unique_ptr<AZ::Entity> GradientSignalBaseFixture::BuildTestShapeAreaFalloffGradient(float shapeHalfBounds)
{
// Create a Shape Area Falloff Gradient Component with arbitrary parameters.
auto entity = CreateTestEntity(shapeHalfBounds);
GradientSignal::ShapeAreaFalloffGradientConfig config;
config.m_shapeEntityId = entity->GetId();
config.m_falloffWidth = 16.0f;
config.m_falloffType = GradientSignal::FalloffType::InnerOuter;
CreateComponent<GradientSignal::ShapeAreaFalloffGradientComponent>(entity.get(), config);
ActivateEntity(entity.get());
return entity;
}
AZStd::unique_ptr<AZ::Entity> GradientSignalBaseFixture::BuildTestDitherGradient(
float shapeHalfBounds, const AZ::EntityId& inputGradientId)
{
// Create a Dither Gradient Component with arbitrary parameters.
auto entity = CreateTestEntity(shapeHalfBounds);
GradientSignal::DitherGradientConfig config;
config.m_gradientSampler.m_gradientId = inputGradientId;
config.m_useSystemPointsPerUnit = false;
config.m_pointsPerUnit = 1.0f;
config.m_patternOffset = AZ::Vector3::CreateZero();
config.m_patternType = GradientSignal::DitherGradientConfig::BayerPatternType::PATTERN_SIZE_4x4;
CreateComponent<GradientSignal::DitherGradientComponent>(entity.get(), config);
ActivateEntity(entity.get());
return entity;
}
AZStd::unique_ptr<AZ::Entity> GradientSignalBaseFixture::BuildTestInvertGradient(
float shapeHalfBounds, const AZ::EntityId& inputGradientId)
{
// Create an Invert Gradient Component.
auto entity = CreateTestEntity(shapeHalfBounds);
GradientSignal::InvertGradientConfig config;
config.m_gradientSampler.m_gradientId = inputGradientId;
CreateComponent<GradientSignal::InvertGradientComponent>(entity.get(), config);
ActivateEntity(entity.get());
return entity;
}
AZStd::unique_ptr<AZ::Entity> GradientSignalBaseFixture::BuildTestLevelsGradient(
float shapeHalfBounds, const AZ::EntityId& inputGradientId)
{
// Create a Levels Gradient Component with arbitrary parameters.
auto entity = CreateTestEntity(shapeHalfBounds);
GradientSignal::LevelsGradientConfig config;
config.m_gradientSampler.m_gradientId = inputGradientId;
config.m_inputMin = 0.1f;
config.m_inputMid = 0.3f;
config.m_inputMax = 0.9f;
config.m_outputMin = 0.0f;
config.m_outputMax = 1.0f;
CreateComponent<GradientSignal::LevelsGradientComponent>(entity.get(), config);
ActivateEntity(entity.get());
return entity;
}
AZStd::unique_ptr<AZ::Entity> GradientSignalBaseFixture::BuildTestMixedGradient(
float shapeHalfBounds, const AZ::EntityId& baseGradientId, const AZ::EntityId& mixedGradientId)
{
// Create a Mixed Gradient Component that mixes two input gradients together in arbitrary ways.
auto entity = CreateTestEntity(shapeHalfBounds);
GradientSignal::MixedGradientConfig config;
GradientSignal::MixedGradientLayer layer;
layer.m_enabled = true;
layer.m_operation = GradientSignal::MixedGradientLayer::MixingOperation::Initialize;
layer.m_gradientSampler.m_gradientId = baseGradientId;
layer.m_gradientSampler.m_opacity = 1.0f;
config.m_layers.push_back(layer);
layer.m_operation = GradientSignal::MixedGradientLayer::MixingOperation::Overlay;
layer.m_gradientSampler.m_gradientId = mixedGradientId;
layer.m_gradientSampler.m_opacity = 0.75f;
config.m_layers.push_back(layer);
CreateComponent<GradientSignal::MixedGradientComponent>(entity.get(), config);
ActivateEntity(entity.get());
return entity;
}
AZStd::unique_ptr<AZ::Entity> GradientSignalBaseFixture::BuildTestPosterizeGradient(
float shapeHalfBounds, const AZ::EntityId& inputGradientId)
{
// Create a Posterize Gradient Component with arbitrary parameters.
auto entity = CreateTestEntity(shapeHalfBounds);
GradientSignal::PosterizeGradientConfig config;
config.m_gradientSampler.m_gradientId = inputGradientId;
config.m_mode = GradientSignal::PosterizeGradientConfig::ModeType::Ps;
config.m_bands = 5;
CreateComponent<GradientSignal::PosterizeGradientComponent>(entity.get(), config);
ActivateEntity(entity.get());
return entity;
}
AZStd::unique_ptr<AZ::Entity> GradientSignalBaseFixture::BuildTestReferenceGradient(
float shapeHalfBounds, const AZ::EntityId& inputGradientId)
{
// Create a Reference Gradient Component.
auto entity = CreateTestEntity(shapeHalfBounds);
GradientSignal::ReferenceGradientConfig config;
config.m_gradientSampler.m_gradientId = inputGradientId;
config.m_gradientSampler.m_ownerEntityId = entity->GetId();
CreateComponent<GradientSignal::ReferenceGradientComponent>(entity.get(), config);
ActivateEntity(entity.get());
return entity;
}
AZStd::unique_ptr<AZ::Entity> GradientSignalBaseFixture::BuildTestSmoothStepGradient(
float shapeHalfBounds, const AZ::EntityId& inputGradientId)
{
// Create a Smooth Step Gradient Component with arbitrary parameters.
auto entity = CreateTestEntity(shapeHalfBounds);
GradientSignal::SmoothStepGradientConfig config;
config.m_gradientSampler.m_gradientId = inputGradientId;
config.m_smoothStep.m_falloffMidpoint = 0.75f;
config.m_smoothStep.m_falloffRange = 0.125f;
config.m_smoothStep.m_falloffStrength = 0.25f;
CreateComponent<GradientSignal::SmoothStepGradientComponent>(entity.get(), config);
ActivateEntity(entity.get());
return entity;
}
AZStd::unique_ptr<AZ::Entity> GradientSignalBaseFixture::BuildTestThresholdGradient(
float shapeHalfBounds, const AZ::EntityId& inputGradientId)
{
// Create a Threshold Gradient Component with arbitrary parameters.
auto entity = CreateTestEntity(shapeHalfBounds);
GradientSignal::ThresholdGradientConfig config;
config.m_gradientSampler.m_gradientId = inputGradientId;
config.m_threshold = 0.75f;
CreateComponent<GradientSignal::ThresholdGradientComponent>(entity.get(), config);
ActivateEntity(entity.get());
return entity;
}
AZStd::unique_ptr<AZ::Entity> GradientSignalBaseFixture::BuildTestSurfaceAltitudeGradient(float shapeHalfBounds)
{
// Create a Surface Altitude Gradient Component with arbitrary parameters.
auto entity = CreateTestEntity(shapeHalfBounds);
GradientSignal::SurfaceAltitudeGradientConfig config;
config.m_altitudeMin = -5.0f;
config.m_altitudeMax = 15.0f;
CreateComponent<GradientSignal::SurfaceAltitudeGradientComponent>(entity.get(), config);
ActivateEntity(entity.get());
return entity;
}
AZStd::unique_ptr<AZ::Entity> GradientSignalBaseFixture::BuildTestSurfaceMaskGradient(float shapeHalfBounds)
{
// Create a Surface Mask Gradient Component with arbitrary parameters.
auto entity = CreateTestEntity(shapeHalfBounds);
GradientSignal::SurfaceMaskGradientConfig config;
config.m_surfaceTagList.push_back(AZ_CRC_CE("test_mask"));
CreateComponent<GradientSignal::SurfaceMaskGradientComponent>(entity.get(), config);
ActivateEntity(entity.get());
return entity;
}
AZStd::unique_ptr<AZ::Entity> GradientSignalBaseFixture::BuildTestSurfaceSlopeGradient(float shapeHalfBounds)
{
// Create a Surface Slope Gradient Component with arbitrary parameters.
auto entity = CreateTestEntity(shapeHalfBounds);
GradientSignal::SurfaceSlopeGradientConfig config;
config.m_slopeMin = 5.0f;
config.m_slopeMax = 50.0f;
config.m_rampType = GradientSignal::SurfaceSlopeGradientConfig::RampType::SMOOTH_STEP;
config.m_smoothStep.m_falloffMidpoint = 0.75f;
config.m_smoothStep.m_falloffRange = 0.125f;
config.m_smoothStep.m_falloffStrength = 0.25f;
CreateComponent<GradientSignal::SurfaceSlopeGradientComponent>(entity.get(), config);
ActivateEntity(entity.get());
return entity;
}
void GradientSignalTest::TestFixedDataSampler(const AZStd::vector<float>& expectedOutput, int size, AZ::EntityId gradientEntityId)
{
GradientSignal::GradientSampler gradientSampler;
@@ -67,209 +425,5 @@ namespace UnitTest
}
}
}
#ifdef HAVE_BENCHMARK
void GradientSignalBenchmarkFixture::CreateTestEntity(float shapeHalfBounds)
{
// Create the base entity
m_testEntity = CreateEntity();
// Create a mock Shape component that describes the bounds that we're using to map our gradient into world space.
CreateComponent<MockShapeComponent>(m_testEntity.get());
MockShapeComponentHandler mockShapeHandler(m_testEntity->GetId());
mockShapeHandler.m_GetLocalBounds = AZ::Aabb::CreateCenterRadius(AZ::Vector3(shapeHalfBounds), shapeHalfBounds);
// Create a mock Transform component that locates our gradient in the center of our desired mock Shape.
MockTransformHandler mockTransformHandler;
mockTransformHandler.m_GetLocalTMOutput = AZ::Transform::CreateTranslation(AZ::Vector3(shapeHalfBounds));
mockTransformHandler.m_GetWorldTMOutput = AZ::Transform::CreateTranslation(AZ::Vector3(shapeHalfBounds));
mockTransformHandler.BusConnect(m_testEntity->GetId());
}
void GradientSignalBenchmarkFixture::DestroyTestEntity()
{
m_testEntity.reset();
}
void GradientSignalBenchmarkFixture::CreateTestImageGradient(AZ::Entity* entity)
{
// Create the Image Gradient Component with some default sizes and parameters.
GradientSignal::ImageGradientConfig config;
const uint32_t imageSize = 4096;
const int32_t imageSeed = 12345;
config.m_imageAsset = ImageAssetMockAssetHandler::CreateImageAsset(imageSize, imageSize, imageSeed);
config.m_tilingX = 1.0f;
config.m_tilingY = 1.0f;
CreateComponent<GradientSignal::ImageGradientComponent>(entity, config);
// Create the Gradient Transform Component with some default parameters.
GradientSignal::GradientTransformConfig gradientTransformConfig;
gradientTransformConfig.m_wrappingType = GradientSignal::WrappingType::None;
CreateComponent<GradientSignal::GradientTransformComponent>(entity, gradientTransformConfig);
}
void GradientSignalBenchmarkFixture::CreateTestPerlinGradient(AZ::Entity* entity)
{
// Create the Perlin Gradient Component with some default sizes and parameters.
GradientSignal::PerlinGradientConfig config;
config.m_amplitude = 1.0f;
config.m_frequency = 1.1f;
config.m_octave = 4;
config.m_randomSeed = 12345;
CreateComponent<GradientSignal::PerlinGradientComponent>(entity, config);
// Create the Gradient Transform Component with some default parameters.
GradientSignal::GradientTransformConfig gradientTransformConfig;
gradientTransformConfig.m_wrappingType = GradientSignal::WrappingType::None;
CreateComponent<GradientSignal::GradientTransformComponent>(entity, gradientTransformConfig);
}
void GradientSignalBenchmarkFixture::CreateTestRandomGradient(AZ::Entity* entity)
{
// Create the Random Gradient Component with some default parameters.
GradientSignal::RandomGradientConfig config;
config.m_randomSeed = 12345;
CreateComponent<GradientSignal::RandomGradientComponent>(entity, config);
// Create the Gradient Transform Component with some default parameters.
GradientSignal::GradientTransformConfig gradientTransformConfig;
gradientTransformConfig.m_wrappingType = GradientSignal::WrappingType::None;
CreateComponent<GradientSignal::GradientTransformComponent>(entity, gradientTransformConfig);
}
void GradientSignalBenchmarkFixture::RunSamplerGetValueBenchmark(benchmark::State& state)
{
AZ_PROFILE_FUNCTION(Entity);
// All components are created, so activate the entity
ActivateEntity(m_testEntity.get());
// Create a gradient sampler and run through a series of points to see if they match expectations.
GradientSignal::GradientSampler gradientSampler;
gradientSampler.m_gradientId = m_testEntity->GetId();
// Get the height and width ranges for querying from our benchmark parameters
float height = aznumeric_cast<float>(state.range(0));
float width = aznumeric_cast<float>(state.range(1));
// Call GetValue() for every height and width in our ranges.
for (auto _ : state)
{
for (float y = 0.0f; y < height; y += 1.0f)
{
for (float x = 0.0f; x < width; x += 1.0f)
{
GradientSignal::GradientSampleParams params;
params.m_position = AZ::Vector3(x, y, 0.0f);
float value = gradientSampler.GetValue(params);
benchmark::DoNotOptimize(value);
}
}
}
}
void GradientSignalBenchmarkFixture::RunSamplerGetValuesBenchmark(benchmark::State& state)
{
AZ_PROFILE_FUNCTION(Entity);
// All components are created, so activate the entity
ActivateEntity(m_testEntity.get());
// Create a gradient sampler and run through a series of points to see if they match expectations.
GradientSignal::GradientSampler gradientSampler;
gradientSampler.m_gradientId = m_testEntity->GetId();
// Get the height and width ranges for querying from our benchmark parameters
float height = aznumeric_cast<float>(state.range(0));
float width = aznumeric_cast<float>(state.range(1));
int64_t totalQueryPoints = state.range(0) * state.range(1);
// Call GetValues() for every height and width in our ranges.
for (auto _ : state)
{
// Set up our vector of query positions.
AZStd::vector<AZ::Vector3> positions(totalQueryPoints);
size_t index = 0;
for (float y = 0.0f; y < height; y += 1.0f)
{
for (float x = 0.0f; x < width; x += 1.0f)
{
positions[index++] = AZ::Vector3(x, y, 0.0f);
}
}
// Query and get the results.
AZStd::vector<float> results(totalQueryPoints);
gradientSampler.GetValues(positions, results);
}
}
void GradientSignalBenchmarkFixture::RunEBusGetValueBenchmark(benchmark::State& state)
{
AZ_PROFILE_FUNCTION(Entity);
// All components are created, so activate the entity
ActivateEntity(m_testEntity.get());
GradientSignal::GradientSampleParams params;
// Get the height and width ranges for querying from our benchmark parameters
float height = aznumeric_cast<float>(state.range(0));
float width = aznumeric_cast<float>(state.range(1));
// Call GetValue() for every height and width in our ranges.
for (auto _ : state)
{
for (float y = 0.0f; y < height; y += 1.0f)
{
for (float x = 0.0f; x < width; x += 1.0f)
{
float value = 0.0f;
params.m_position = AZ::Vector3(x, y, 0.0f);
GradientSignal::GradientRequestBus::EventResult(
value, m_testEntity->GetId(), &GradientSignal::GradientRequestBus::Events::GetValue, params);
benchmark::DoNotOptimize(value);
}
}
}
}
void GradientSignalBenchmarkFixture::RunEBusGetValuesBenchmark(benchmark::State& state)
{
AZ_PROFILE_FUNCTION(Entity);
// All components are created, so activate the entity
ActivateEntity(m_testEntity.get());
GradientSignal::GradientSampler gradientSampler;
gradientSampler.m_gradientId = m_testEntity->GetId();
// Get the height and width ranges for querying from our benchmark parameters
float height = aznumeric_cast<float>(state.range(0));
float width = aznumeric_cast<float>(state.range(1));
int64_t totalQueryPoints = state.range(0) * state.range(1);
// Call GetValues() for every height and width in our ranges.
for (auto _ : state)
{
// Set up our vector of query positions.
AZStd::vector<AZ::Vector3> positions(totalQueryPoints);
size_t index = 0;
for (float y = 0.0f; y < height; y += 1.0f)
{
for (float x = 0.0f; x < width; x += 1.0f)
{
positions[index++] = AZ::Vector3(x, y, 0.0f);
}
}
// Query and get the results.
AZStd::vector<float> results(totalQueryPoints);
GradientSignal::GradientRequestBus::Event(
m_testEntity->GetId(), &GradientSignal::GradientRequestBus::Events::GetValues, positions, results);
}
}
#endif
}
@@ -8,6 +8,7 @@
#pragma once
#include <Tests/GradientSignalTestMocks.h>
#include <LmbrCentral/Shape/MockShapes.h>
namespace UnitTest
{
@@ -30,22 +31,56 @@ namespace UnitTest
}
template<typename Component, typename Configuration>
AZ::Component* CreateComponent(AZ::Entity* entity, const Configuration& config)
Component* CreateComponent(AZ::Entity* entity, const Configuration& config)
{
m_app->RegisterComponentDescriptor(Component::CreateDescriptor());
return entity->CreateComponent<Component>(config);
}
template<typename Component>
AZ::Component* CreateComponent(AZ::Entity* entity)
Component* CreateComponent(AZ::Entity* entity)
{
m_app->RegisterComponentDescriptor(Component::CreateDescriptor());
return entity->CreateComponent<Component>();
}
// Create a mock shape that will respond to the shape bus with proper responses for the given input box.
AZStd::unique_ptr<testing::NiceMock<UnitTest::MockShapeComponentRequests>> CreateMockShape(
const AZ::Aabb& spawnerBox, const AZ::EntityId& shapeEntityId);
// Create a mock SurfaceDataSystem that will respond to requests for surface points with mock responses for points inside
// the given input box.
AZStd::unique_ptr<MockSurfaceDataSystem> CreateMockSurfaceDataSystem(const AZ::Aabb& spawnerBox);
// Create an entity with a mock shape and a transform. It won't be activated yet though, because we expect a gradient component
// to also get added to it first before activation.
AZStd::unique_ptr<AZ::Entity> CreateTestEntity(float shapeHalfBounds);
// Create and activate an entity with a gradient component of the requested type, initialized with test data.
AZStd::unique_ptr<AZ::Entity> BuildTestConstantGradient(float shapeHalfBounds);
AZStd::unique_ptr<AZ::Entity> BuildTestImageGradient(float shapeHalfBounds);
AZStd::unique_ptr<AZ::Entity> BuildTestPerlinGradient(float shapeHalfBounds);
AZStd::unique_ptr<AZ::Entity> BuildTestRandomGradient(float shapeHalfBounds);
AZStd::unique_ptr<AZ::Entity> BuildTestShapeAreaFalloffGradient(float shapeHalfBounds);
AZStd::unique_ptr<AZ::Entity> BuildTestDitherGradient(float shapeHalfBounds, const AZ::EntityId& inputGradientId);
AZStd::unique_ptr<AZ::Entity> BuildTestInvertGradient(float shapeHalfBounds, const AZ::EntityId& inputGradientId);
AZStd::unique_ptr<AZ::Entity> BuildTestLevelsGradient(float shapeHalfBounds, const AZ::EntityId& inputGradientId);
AZStd::unique_ptr<AZ::Entity> BuildTestMixedGradient(
float shapeHalfBounds, const AZ::EntityId& baseGradientId, const AZ::EntityId& mixedGradientId);
AZStd::unique_ptr<AZ::Entity> BuildTestPosterizeGradient(float shapeHalfBounds, const AZ::EntityId& inputGradientId);
AZStd::unique_ptr<AZ::Entity> BuildTestReferenceGradient(float shapeHalfBounds, const AZ::EntityId& inputGradientId);
AZStd::unique_ptr<AZ::Entity> BuildTestSmoothStepGradient(float shapeHalfBounds, const AZ::EntityId& inputGradientId);
AZStd::unique_ptr<AZ::Entity> BuildTestThresholdGradient(float shapeHalfBounds, const AZ::EntityId& inputGradientId);
AZStd::unique_ptr<AZ::Entity> BuildTestSurfaceAltitudeGradient(float shapeHalfBounds);
AZStd::unique_ptr<AZ::Entity> BuildTestSurfaceMaskGradient(float shapeHalfBounds);
AZStd::unique_ptr<AZ::Entity> BuildTestSurfaceSlopeGradient(float shapeHalfBounds);
AZStd::unique_ptr<AZ::ComponentApplication> m_app;
AZ::Entity* m_systemEntity = nullptr;
ImageAssetMockAssetHandler* m_mockHandler = nullptr;
AZStd::vector<AZStd::unique_ptr<testing::NiceMock<UnitTest::MockShapeComponentRequests>>>* m_mockShapeHandlers = nullptr;
};
struct GradientSignalTest
@@ -80,33 +115,15 @@ namespace UnitTest
AZ::Debug::TraceMessageBus::Handler::BusConnect();
UnitTest::AllocatorsBenchmarkFixture::SetUp(state);
SetupCoreSystems();
// Create a default test entity with bounds of 256 m x 256 m x 256 m.
const float shapeHalfBounds = 128.0f;
CreateTestEntity(shapeHalfBounds);
}
void internalTearDown(const benchmark::State& state)
{
DestroyTestEntity();
TearDownCoreSystems();
UnitTest::AllocatorsBenchmarkFixture::TearDown(state);
AZ::Debug::TraceMessageBus::Handler::BusDisconnect();
}
void CreateTestEntity(float shapeHalfBounds);
void DestroyTestEntity();
void CreateTestImageGradient(AZ::Entity* entity);
void CreateTestPerlinGradient(AZ::Entity* entity);
void CreateTestRandomGradient(AZ::Entity* entity);
void RunSamplerGetValueBenchmark(benchmark::State& state);
void RunSamplerGetValuesBenchmark(benchmark::State& state);
void RunEBusGetValueBenchmark(benchmark::State& state);
void RunEBusGetValuesBenchmark(benchmark::State& state);
protected:
void SetUp(const benchmark::State& state) override
{
@@ -125,8 +142,6 @@ namespace UnitTest
{
internalTearDown(state);
}
AZStd::unique_ptr<AZ::Entity> m_testEntity;
};
#endif
}
@@ -8,6 +8,7 @@
set(FILES
Tests/GradientSignalBenchmarks.cpp
Tests/GradientSignalGetValuesTests.cpp
Tests/GradientSignalImageTests.cpp
Tests/GradientSignalReferencesTests.cpp
Tests/GradientSignalServicesTests.cpp
@@ -190,7 +190,7 @@ namespace LmbrCentral
{
AZ::Crc32 result = {};
AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references");
AZ_WarningOnce("Shape", !m_isRequestInProgress, "Detected cyclic dependencies with shape entity references");
if (AllowRequest())
{
m_isRequestInProgress = true;
@@ -205,7 +205,7 @@ namespace LmbrCentral
{
AZ::Aabb result = AZ::Aabb::CreateNull();
AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references");
AZ_WarningOnce("Shape", !m_isRequestInProgress, "Detected cyclic dependencies with shape entity references");
if (AllowRequest())
{
m_isRequestInProgress = true;
@@ -221,7 +221,7 @@ namespace LmbrCentral
transform = AZ::Transform::CreateIdentity();
bounds = AZ::Aabb::CreateNull();
AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references");
AZ_WarningOnce("Shape", !m_isRequestInProgress, "Detected cyclic dependencies with shape entity references");
if (AllowRequest())
{
m_isRequestInProgress = true;
@@ -234,7 +234,7 @@ namespace LmbrCentral
{
bool result = false;
AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references");
AZ_WarningOnce("Shape", !m_isRequestInProgress, "Detected cyclic dependencies with shape entity references");
if (AllowRequest())
{
m_isRequestInProgress = true;
@@ -249,7 +249,7 @@ namespace LmbrCentral
{
float result = FLT_MAX;
AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references");
AZ_WarningOnce("Shape", !m_isRequestInProgress, "Detected cyclic dependencies with shape entity references");
if (AllowRequest())
{
m_isRequestInProgress = true;
@@ -264,7 +264,7 @@ namespace LmbrCentral
{
float result = FLT_MAX;
AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references");
AZ_WarningOnce("Shape", !m_isRequestInProgress, "Detected cyclic dependencies with shape entity references");
if (AllowRequest())
{
m_isRequestInProgress = true;
@@ -279,7 +279,7 @@ namespace LmbrCentral
{
AZ::Vector3 result = AZ::Vector3::CreateZero();
AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references");
AZ_WarningOnce("Shape", !m_isRequestInProgress, "Detected cyclic dependencies with shape entity references");
if (AllowRequest())
{
m_isRequestInProgress = true;
@@ -294,7 +294,7 @@ namespace LmbrCentral
{
bool result = false;
AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references");
AZ_WarningOnce("Shape", !m_isRequestInProgress, "Detected cyclic dependencies with shape entity references");
if (AllowRequest())
{
m_isRequestInProgress = true;
@@ -376,60 +376,60 @@ namespace ScriptCanvasEditor::Nodes
int paramIndex = 0;
int outputIndex = 0;
int slotIndex = 0;
auto busId = methodNode->GetBusSlotId();
for (const auto& slot : methodNode->GetSlots())
{
GraphCanvas::TranslationKey slotKey = key;
int& index = (slot.IsData() && slot.IsInput()) ? paramIndex : outputIndex;
int& inputOutputIndex = slot.IsInput() ? paramIndex : outputIndex;
const bool isBusIdSlot =
methodNode->HasBusID() && busId == slot.GetId() && slot.GetDescriptor() == ScriptCanvas::SlotDescriptors::DataIn();
if (slot.IsVisible())
{
AZ::EntityId graphCanvasSlotId = DisplayScriptCanvasSlot(graphCanvasNodeId, slot, index);
AZ::EntityId graphCanvasSlotId = DisplayScriptCanvasSlot(graphCanvasNodeId, slot, slotIndex);
details.m_name = slot.GetName();
details.m_tooltip = slot.GetToolTip();
if (methodNode->HasBusID() && busId == slot.GetId() && slot.GetDescriptor() == ScriptCanvas::SlotDescriptors::DataIn())
if (isBusIdSlot)
{
key = ::Translation::GlobalKeys::EBusSenderIDKey;
GraphCanvas::TranslationRequestBus::BroadcastResult(details, &GraphCanvas::TranslationRequests::GetDetails, key + ".details", details);
GraphCanvas::TranslationRequestBus::BroadcastResult(
details, &GraphCanvas::TranslationRequests::GetDetails, key + ".details", details);
}
else
else if (slot.IsData())
{
if (slot.IsData())
key.clear();
key << context << className << "methods" << updatedMethodName;
if (slot.IsInput())
{
key.clear();
key << context << className << "methods" << updatedMethodName;
if (slot.IsData() && slot.IsInput())
{
key << "params";
}
else
{
key << "results";
}
key << index;
GraphCanvas::TranslationRequestBus::BroadcastResult(details, &GraphCanvas::TranslationRequests::GetDetails, key + ".details", details);
key << "params";
}
if (slot.IsData())
{
index++;
else
{
key << "results";
}
key << inputOutputIndex;
GraphCanvas::TranslationRequestBus::BroadcastResult(
details, &GraphCanvas::TranslationRequests::GetDetails, key + ".details", details);
}
GraphCanvas::SlotRequestBus::Event(graphCanvasSlotId, &GraphCanvas::SlotRequests::SetDetails, details.m_name, details.m_tooltip);
GraphCanvas::SlotRequestBus::Event(
graphCanvasSlotId, &GraphCanvas::SlotRequests::SetDetails, details.m_name, details.m_tooltip);
UpdateSlotDatumLabel(graphCanvasNodeId, slot.GetId(), details.m_name);
}
++index;
++slotIndex;
if (!isBusIdSlot && slot.IsData())
{
++inputOutputIndex;
}
}
// Set the name
@@ -485,9 +485,6 @@ namespace ScriptCanvasEditor::Nodes
AZStd::vector< ScriptCanvas::SlotId > scriptCanvasSlots = busNode->GetNonEventSlotIds();
int paramIndex = 0;
int outputIndex = 0;
for (const auto& slotId : scriptCanvasSlots)
{
ScriptCanvas::Slot* slot = busNode->GetSlot(slotId);
@@ -501,8 +498,6 @@ namespace ScriptCanvasEditor::Nodes
if (slot->IsVisible())
{
int& index = (slot->IsData() && slot->IsInput()) ? paramIndex : outputIndex;
AZ::EntityId gcSlotId = DisplayScriptCanvasSlot(graphCanvasNodeId, (*slot), group);
if (busNode->IsIDRequired() && slot->GetDescriptor() == ScriptCanvas::SlotDescriptors::DataIn())
@@ -516,8 +511,6 @@ namespace ScriptCanvasEditor::Nodes
GraphCanvas::SlotRequestBus::Event(gcSlotId, &GraphCanvas::SlotRequests::SetDetails, details.m_name, details.m_tooltip);
}
++index;
}
}
@@ -615,17 +608,12 @@ namespace ScriptCanvasEditor::Nodes
*graphCanvasUserData = azEventNode->GetEntityId();
}
int paramIndex = 0;
int outputIndex = 0;
for (const ScriptCanvas::Slot& slot: azEventNode->GetSlots())
{
GraphCanvas::SlotGroup group = GraphCanvas::SlotGroups::Invalid;
if (slot.IsVisible())
{
int& index = (slot.IsData() && slot.IsInput()) ? paramIndex : outputIndex;
AZ::EntityId gcSlotId = DisplayScriptCanvasSlot(graphCanvasNodeId, slot, group);
GraphCanvas::TranslationKey key;
@@ -636,8 +624,6 @@ namespace ScriptCanvasEditor::Nodes
GraphCanvas::SlotRequestBus::Event(gcSlotId, &GraphCanvas::SlotRequests::SetName, details.m_name);
GraphCanvas::SlotRequestBus::Event(gcSlotId, &GraphCanvas::SlotRequests::SetTooltip, details.m_tooltip);;
++index;
}
}
@@ -703,9 +689,6 @@ namespace ScriptCanvasEditor::Nodes
AZStd::vector< ScriptCanvas::SlotId > scriptCanvasSlots = busNode->GetNonEventSlotIds();
int paramIndex = 0;
int outputIndex = 0;
for (const auto& slotId : scriptCanvasSlots)
{
ScriptCanvas::Slot* slot = busNode->GetSlot(slotId);
@@ -719,8 +702,6 @@ namespace ScriptCanvasEditor::Nodes
if (slot->IsVisible())
{
int& index = (slot->IsData() && slot->IsInput()) ? paramIndex : outputIndex;
AZ::EntityId gcSlotId = DisplayScriptCanvasSlot(graphCanvasNodeId, (*slot), group);
if (busNode->IsIDRequired() && slot->GetDescriptor() == ScriptCanvas::SlotDescriptors::DataIn())
@@ -731,8 +712,6 @@ namespace ScriptCanvasEditor::Nodes
GraphCanvas::TranslationRequestBus::BroadcastResult(details, &GraphCanvas::TranslationRequests::GetDetails, key, details);
GraphCanvas::SlotRequestBus::Event(gcSlotId, &GraphCanvas::SlotRequests::SetDetails, details.m_name, details.m_tooltip);
}
++index;
}
}
@@ -11,6 +11,9 @@
#include <QAction>
#include <QObject>
#include <QMenu>
#include <QFileDialog>
#include <QStandardPaths>
#include <QMessageBox>
#endif
#include <Source/Translation/TranslationBus.h>
@@ -34,6 +37,26 @@ namespace ScriptCanvasDeveloperEditor
qAction->setShortcut(QAction::tr("Ctrl+Alt+R", "Developer|Reload Text"));
QObject::connect(qAction, &QAction::triggered, [mainWindow]() { ReloadText(mainWindow); });
qAction = mainMenu->addAction(QAction::tr("Dump Translation Database"));
qAction->setAutoRepeat(false);
qAction->setShortcut(QAction::tr("Ctrl+Alt+L", "Developer|Dump Translation Database"));
QObject::connect(
qAction, &QAction::triggered,
[mainWindow]()
{
QString defaultPath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
QString directory = QFileDialog::getExistingDirectory(mainWindow,
QObject::tr("Select output folder for sc_translation.log file"), defaultPath);
if (!directory.isEmpty())
{
const QString path = QDir::toNativeSeparators(directory + "/sc_translation.log");
GraphCanvas::TranslationRequestBus::Broadcast(&GraphCanvas::TranslationRequests::DumpDatabase, path.toUtf8().constData());
QMessageBox::information(
mainWindow, QObject::tr("Finished writing translation database"),
QObject::tr("Translation database written to:<br/><a href=\"file:///%1\">%1</a>").arg(path));
}
});
}
return qAction;
+1 -1
View File
@@ -1,5 +1,5 @@
{
"gem_name": "ScriptCanvasDeveloperGem",
"gem_name": "ScriptCanvasDeveloper",
"display_name": "Script Canvas Developer",
"license": "Apache-2.0 Or MIT",
"license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt",
@@ -160,7 +160,7 @@ namespace Terrain
{
float maxSample = 0.0f;
terrainExists = false;
AZ_WarningOnce("Terrain", !m_isRequestInProgress, "Detected cyclic dependences with terrain height entity references");
AZ_WarningOnce("Terrain", !m_isRequestInProgress, "Detected cyclic dependencies with terrain height entity references");
if (!m_isRequestInProgress)
{
m_isRequestInProgress = true;
@@ -17,6 +17,7 @@
#include <AzCore/Serialization/SerializeContext.h>
#include <AzFramework/Physics/Material.h>
#include <AzFramework/Physics/PhysicsSystem.h>
#include <AzFramework/Terrain/TerrainDataRequestBus.h>
namespace Terrain
@@ -43,11 +44,25 @@ namespace Terrain
AZ::Edit::UIHandlers::ComboBox, &TerrainPhysicsSurfaceMaterialMapping::m_surfaceTag, "Surface Tag",
"Surface type to map to a physics material.")
->DataElement(AZ::Edit::UIHandlers::Default, &TerrainPhysicsSurfaceMaterialMapping::m_materialId, "Material ID", "")
->ElementAttribute(Physics::Attributes::MaterialLibraryAssetId, &TerrainPhysicsSurfaceMaterialMapping::GetMaterialLibraryId)
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->Attribute(AZ::Edit::Attributes::ShowProductAssetFileName, true);
}
}
}
AZ::Data::AssetId TerrainPhysicsSurfaceMaterialMapping::GetMaterialLibraryId()
{
if (const auto* physicsSystem = AZ::Interface<AzPhysics::SystemInterface>::Get())
{
if (const auto* physicsConfiguration = physicsSystem->GetConfiguration())
{
return physicsConfiguration->m_materialLibraryAsset.GetId();
}
}
return {};
}
void TerrainPhysicsColliderConfig::Reflect(AZ::ReflectContext* context)
{
TerrainPhysicsSurfaceMaterialMapping::Reflect(context);
@@ -36,6 +36,9 @@ namespace Terrain
SurfaceData::SurfaceTag m_surfaceTag;
Physics::MaterialId m_materialId;
private:
static AZ::Data::AssetId GetMaterialLibraryId();
};
class TerrainPhysicsColliderConfig
@@ -224,7 +224,7 @@ namespace Vegetation
bool result = true;
AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references");
AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependencies with vegetation entity references");
if (!m_isRequestInProgress)
{
m_isRequestInProgress = true;
@@ -264,7 +264,7 @@ namespace Vegetation
return;
}
AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references");
AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependencies with vegetation entity references");
if (!m_isRequestInProgress)
{
m_isRequestInProgress = true;
@@ -295,7 +295,7 @@ namespace Vegetation
{
AZ_PROFILE_FUNCTION(Entity);
AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references");
AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependencies with vegetation entity references");
if (!m_isRequestInProgress)
{
m_isRequestInProgress = true;
@@ -320,7 +320,7 @@ namespace Vegetation
LmbrCentral::ShapeComponentRequestsBus::EventResult(bounds, GetEntityId(), &LmbrCentral::ShapeComponentRequestsBus::Events::GetEncompassingAabb);
}
AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references");
AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependencies with vegetation entity references");
if (!m_isRequestInProgress)
{
m_isRequestInProgress = true;
@@ -344,7 +344,7 @@ namespace Vegetation
AZ::u32 count = 0;
AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependences with vegetation entity references");
AZ_WarningOnce("Vegetation", !m_isRequestInProgress, "Detected cyclic dependencies with vegetation entity references");
if (!m_isRequestInProgress)
{
m_isRequestInProgress = true;
+1 -1
View File
@@ -25,7 +25,7 @@ ly_associate_package(PACKAGE_NAME DirectXShaderCompilerDxc-1.6.2104-o3de-rev3-ma
ly_associate_package(PACKAGE_NAME SPIRVCross-2021.04.29-rev1-mac TARGETS SPIRVCross PACKAGE_HASH 78c6376ed2fd195b9b1f5fb2b56e5267a32c3aa21fb399e905308de470eb4515)
ly_associate_package(PACKAGE_NAME tiff-4.2.0.15-rev3-mac TARGETS TIFF PACKAGE_HASH c2615ccdadcc0e1d6c5ed61e5965c4d3a82193d206591b79b805c3b3ff35a4bf)
ly_associate_package(PACKAGE_NAME freetype-2.10.4.16-mac TARGETS freetype PACKAGE_HASH f159b346ac3251fb29cb8dd5f805c99b0015ed7fdb3887f656945ca701a61d0d)
ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.7.167-rev6-mac TARGETS AWSNativeSDK PACKAGE_HASH 9b058376dec042ace98e198e902b399739adeb9e9398a6c210171fb530164577)
ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.9.50-rev1-mac TARGETS AWSNativeSDK PACKAGE_HASH 6c27a49376870c606144e4639e15867f9db7e4a1ee5f1a726f152d3bd8459966)
ly_associate_package(PACKAGE_NAME Lua-5.3.5-rev6-mac TARGETS Lua PACKAGE_HASH b9079fd35634774c9269028447562c6b712dbc83b9c64975c095fd423ff04c08)
ly_associate_package(PACKAGE_NAME PhysX-4.1.2.29882248-rev5-mac TARGETS PhysX PACKAGE_HASH 83940b3876115db82cd8ffcb9e902278e75846d6ad94a41e135b155cee1ee186)
ly_associate_package(PACKAGE_NAME mcpp-2.7.2_az.2-rev1-mac TARGETS mcpp PACKAGE_HASH be9558905c9c49179ef3d7d84f0a5472415acdf7fe2d76eb060d9431723ddf2e)
+3
View File
@@ -624,6 +624,9 @@ def get_registered(engine_name: str = None,
this_engines_name = engine_json_data['engine_name']
if this_engines_name == engine_name:
return engine_path
engines_path = json_data.get('engines_path', {})
if engine_name in engines_path:
return pathlib.Path(engines_path[engine_name]).resolve()
elif isinstance(project_name, str):
projects = get_all_projects()