Merge branch 'development' of https://github.com/aws-lumberyard-dev/o3de into mnaumov/FixingEOOrdering_signofffix
Signed-off-by: Mikhail Naumov <mnaumov@amazon.com>
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
|
||||
<path d="M3.145,8.433c0-1.47,1.196-2.666,2.666-2.666h9.544c-0.158-0.819-0.88-1.443-1.744-1.443H3.487
|
||||
c-0.978,0-1.778,0.8-1.778,1.778v5.356c0,0.861,0.62,1.582,1.436,1.743V8.433z" fill="#FFFFFF"/>
|
||||
<g>
|
||||
<path d="M6.833,11.654c0-1.47,1.196-2.666,2.666-2.666h9.069c-0.158-0.819-0.88-1.443-1.744-1.443H6.7
|
||||
c-0.978,0-1.778,0.8-1.778,1.778v5.356c0,0.978,0.8,1.778,1.778,1.778h0.133V11.654z" fill="#FFFFFF"/>
|
||||
</g>
|
||||
<path d="M20.513,10.765H10.388c-0.978,0-1.778,0.8-1.778,1.777v5.356c0,0.978,0.8,1.778,1.778,1.778h10.125
|
||||
c0.978,0,1.778-0.8,1.778-1.778v-5.356C22.29,11.565,21.49,10.765,20.513,10.765z M19.332,15.967h-7.763
|
||||
c-0.264,0-0.478-0.355-0.478-0.793c0-0.438,0.214-0.793,0.478-0.793h7.763c0.264,0,0.478,0.355,0.478,0.793
|
||||
C19.81,15.612,19.597,15.967,19.332,15.967z" fill="#FFFFFF"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -9,87 +9,20 @@ 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
|
||||
from Atom.atom_utils.atom_constants import LIGHT_TYPES
|
||||
|
||||
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'])
|
||||
@pytest.mark.parametrize("level", ["auto_test"])
|
||||
class TestAtomEditorComponentsMain(object):
|
||||
"""Holds tests for Atom components."""
|
||||
|
||||
@pytest.mark.test_case_id("C34525095")
|
||||
def test_AtomEditorComponents_LightComponent(
|
||||
self, request, editor, workspace, project, launcher_platform, level):
|
||||
"""
|
||||
Please review the hydra script run by this test for more specific test info.
|
||||
Tests that the Light component has the expected property options available to it.
|
||||
"""
|
||||
cfg_args = [level]
|
||||
|
||||
expected_lines = [
|
||||
"light_entity Entity successfully created",
|
||||
"Entity has a Light component",
|
||||
"light_entity_test: Component added to the entity: True",
|
||||
f"light_entity_test: Property value is {LIGHT_TYPES['sphere']} which matches {LIGHT_TYPES['sphere']}",
|
||||
"Controller|Configuration|Shadows|Enable shadow set to True",
|
||||
"light_entity Controller|Configuration|Shadows|Shadowmap size: SUCCESS",
|
||||
"Controller|Configuration|Shadows|Shadow filter method set to 1", # PCF
|
||||
"Controller|Configuration|Shadows|Filtering sample count set to 4",
|
||||
"Controller|Configuration|Shadows|Filtering sample count set to 64",
|
||||
"Controller|Configuration|Shadows|Shadow filter method set to 2", # ESM
|
||||
"Controller|Configuration|Shadows|ESM exponent set to 50.0",
|
||||
"Controller|Configuration|Shadows|ESM exponent set to 5000.0",
|
||||
"Controller|Configuration|Shadows|Shadow filter method set to 3", # ESM+PCF
|
||||
f"light_entity_test: Property value is {LIGHT_TYPES['spot_disk']} which matches {LIGHT_TYPES['spot_disk']}",
|
||||
f"light_entity_test: Property value is {LIGHT_TYPES['capsule']} which matches {LIGHT_TYPES['capsule']}",
|
||||
f"light_entity_test: Property value is {LIGHT_TYPES['quad']} which matches {LIGHT_TYPES['quad']}",
|
||||
"light_entity Controller|Configuration|Fast approximation: SUCCESS",
|
||||
"light_entity Controller|Configuration|Both directions: SUCCESS",
|
||||
f"light_entity_test: Property value is {LIGHT_TYPES['polygon']} which matches {LIGHT_TYPES['polygon']}",
|
||||
f"light_entity_test: Property value is {LIGHT_TYPES['simple_point']} "
|
||||
f"which matches {LIGHT_TYPES['simple_point']}",
|
||||
"Controller|Configuration|Attenuation radius|Mode set to 0",
|
||||
"Controller|Configuration|Attenuation radius|Radius set to 100.0",
|
||||
f"light_entity_test: Property value is {LIGHT_TYPES['simple_spot']} "
|
||||
f"which matches {LIGHT_TYPES['simple_spot']}",
|
||||
"Controller|Configuration|Shutters|Outer angle set to 45.0",
|
||||
"Controller|Configuration|Shutters|Outer angle set to 90.0",
|
||||
"light_entity_test: Component added to the entity: True",
|
||||
"Light component test (non-GPU) completed.",
|
||||
]
|
||||
|
||||
unexpected_lines = ["Traceback (most recent call last):"]
|
||||
|
||||
hydra.launch_and_validate_results(
|
||||
request,
|
||||
TEST_DIRECTORY,
|
||||
editor,
|
||||
"hydra_AtomEditorComponents_LightComponent.py",
|
||||
timeout=120,
|
||||
expected_lines=expected_lines,
|
||||
unexpected_lines=unexpected_lines,
|
||||
halt_on_unexpected=True,
|
||||
null_renderer=True,
|
||||
cfg_args=cfg_args,
|
||||
enable_prefab_system=False,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
class TestAutomation(EditorTestSuite):
|
||||
|
||||
enable_prefab_system = False
|
||||
|
||||
#this test is intermittently timing out without ever having executed. sandboxing while we investigate cause.
|
||||
# this test is intermittently timing out without ever having executed. sandboxing while we investigate cause.
|
||||
@pytest.mark.test_case_id("C36525660")
|
||||
class AtomEditorComponents_DisplayMapperAdded(EditorSharedTest):
|
||||
from Atom.tests import hydra_AtomEditorComponents_DisplayMapperAdded as test_module
|
||||
|
||||
-213
@@ -1,213 +0,0 @@
|
||||
"""
|
||||
Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.projectroot, "Gem", "PythonTests"))
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from Atom.atom_utils.atom_constants import LIGHT_TYPES
|
||||
|
||||
LIGHT_TYPE_PROPERTY = 'Controller|Configuration|Light type'
|
||||
SPHERE_AND_SPOT_DISK_LIGHT_PROPERTIES = [
|
||||
("Controller|Configuration|Shadows|Enable shadow", True),
|
||||
("Controller|Configuration|Shadows|Shadowmap size", 0), # 256
|
||||
("Controller|Configuration|Shadows|Shadowmap size", 1), # 512
|
||||
("Controller|Configuration|Shadows|Shadowmap size", 2), # 1024
|
||||
("Controller|Configuration|Shadows|Shadowmap size", 3), # 2048
|
||||
("Controller|Configuration|Shadows|Shadow filter method", 1), # PCF
|
||||
("Controller|Configuration|Shadows|Filtering sample count", 4.0),
|
||||
("Controller|Configuration|Shadows|Filtering sample count", 64.0),
|
||||
("Controller|Configuration|Shadows|Shadow filter method", 2), # ECM
|
||||
("Controller|Configuration|Shadows|ESM exponent", 50),
|
||||
("Controller|Configuration|Shadows|ESM exponent", 5000),
|
||||
("Controller|Configuration|Shadows|Shadow filter method", 3), # ESM+PCF
|
||||
]
|
||||
QUAD_LIGHT_PROPERTIES = [
|
||||
("Controller|Configuration|Both directions", True),
|
||||
("Controller|Configuration|Fast approximation", True),
|
||||
]
|
||||
SIMPLE_POINT_LIGHT_PROPERTIES = [
|
||||
("Controller|Configuration|Attenuation radius|Mode", 0),
|
||||
("Controller|Configuration|Attenuation radius|Radius", 100.0),
|
||||
]
|
||||
SIMPLE_SPOT_LIGHT_PROPERTIES = [
|
||||
("Controller|Configuration|Shutters|Inner angle", 45.0),
|
||||
("Controller|Configuration|Shutters|Outer angle", 90.0),
|
||||
]
|
||||
|
||||
|
||||
def verify_required_component_property_value(entity_name, component, property_path, expected_property_value):
|
||||
"""
|
||||
Compares the property value of component against the expected_property_value.
|
||||
:param entity_name: name of the entity to use (for test verification purposes).
|
||||
:param component: component to check on a given entity for its current property value.
|
||||
:param property_path: the path to the property inside the component.
|
||||
:param expected_property_value: The value expected from the value inside property_path.
|
||||
:return: None, but prints to general.log() which the test uses to verify against.
|
||||
"""
|
||||
property_value = editor.EditorComponentAPIBus(
|
||||
bus.Broadcast, "GetComponentProperty", component, property_path).GetValue()
|
||||
general.log(f"{entity_name}_test: Property value is {property_value} "
|
||||
f"which matches {expected_property_value}")
|
||||
|
||||
|
||||
def run():
|
||||
"""
|
||||
Test Case - Light Component
|
||||
1. Creates a "light_entity" Entity and attaches a "Light" component to it.
|
||||
2. Updates the Light component to each light type option from the LIGHT_TYPES constant.
|
||||
3. The test will check the Editor log to ensure each light type was selected.
|
||||
4. Prints the string "Light component test (non-GPU) completed" after completion.
|
||||
|
||||
Tests will fail immediately if any of these log lines are found:
|
||||
1. Trace::Assert
|
||||
2. Trace::Error
|
||||
3. Traceback (most recent call last):
|
||||
|
||||
:return: None
|
||||
"""
|
||||
# Create a "light_entity" entity with "Light" component.
|
||||
light_entity_name = "light_entity"
|
||||
light_component = "Light"
|
||||
light_entity = hydra.Entity(light_entity_name)
|
||||
light_entity.create_entity(math.Vector3(-1.0, -2.0, 3.0), [light_component])
|
||||
general.log(
|
||||
f"{light_entity_name}_test: Component added to the entity: "
|
||||
f"{hydra.has_components(light_entity.id, [light_component])}")
|
||||
|
||||
# Populate the light_component_id_pair value so that it can be used to select all Light component options.
|
||||
light_component_id_pair = None
|
||||
component_type_id_list = azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', [light_component], 0)
|
||||
if len(component_type_id_list) < 1:
|
||||
general.log(f"ERROR: A component class with name {light_component} doesn't exist")
|
||||
light_component_id_pair = None
|
||||
elif len(component_type_id_list) > 1:
|
||||
general.log(f"ERROR: Found more than one component classes with same name: {light_component}")
|
||||
light_component_id_pair = None
|
||||
entity_component_id_pair = azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast, 'GetComponentOfType', light_entity.id, component_type_id_list[0])
|
||||
if entity_component_id_pair.IsSuccess():
|
||||
light_component_id_pair = entity_component_id_pair.GetValue()
|
||||
|
||||
# Test each Light component option can be selected and it's properties updated.
|
||||
# Point (sphere) light type checks.
|
||||
light_type_property_test(
|
||||
light_type=LIGHT_TYPES['sphere'],
|
||||
light_properties=SPHERE_AND_SPOT_DISK_LIGHT_PROPERTIES,
|
||||
light_component_id_pair=light_component_id_pair,
|
||||
light_entity_name=light_entity_name,
|
||||
light_entity=light_entity
|
||||
)
|
||||
|
||||
# Spot (disk) light type checks.
|
||||
light_type_property_test(
|
||||
light_type=LIGHT_TYPES['spot_disk'],
|
||||
light_properties=SPHERE_AND_SPOT_DISK_LIGHT_PROPERTIES,
|
||||
light_component_id_pair=light_component_id_pair,
|
||||
light_entity_name=light_entity_name,
|
||||
light_entity=light_entity
|
||||
)
|
||||
|
||||
# Capsule light type checks.
|
||||
azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast,
|
||||
'SetComponentProperty',
|
||||
light_component_id_pair,
|
||||
LIGHT_TYPE_PROPERTY,
|
||||
LIGHT_TYPES['capsule']
|
||||
)
|
||||
verify_required_component_property_value(
|
||||
entity_name=light_entity_name,
|
||||
component=light_entity.components[0],
|
||||
property_path=LIGHT_TYPE_PROPERTY,
|
||||
expected_property_value=LIGHT_TYPES['capsule']
|
||||
)
|
||||
|
||||
# Quad light type checks.
|
||||
light_type_property_test(
|
||||
light_type=LIGHT_TYPES['quad'],
|
||||
light_properties=QUAD_LIGHT_PROPERTIES,
|
||||
light_component_id_pair=light_component_id_pair,
|
||||
light_entity_name=light_entity_name,
|
||||
light_entity=light_entity
|
||||
)
|
||||
|
||||
# Polygon light type checks.
|
||||
azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast,
|
||||
'SetComponentProperty',
|
||||
light_component_id_pair,
|
||||
LIGHT_TYPE_PROPERTY,
|
||||
LIGHT_TYPES['polygon']
|
||||
)
|
||||
verify_required_component_property_value(
|
||||
entity_name=light_entity_name,
|
||||
component=light_entity.components[0],
|
||||
property_path=LIGHT_TYPE_PROPERTY,
|
||||
expected_property_value=LIGHT_TYPES['polygon']
|
||||
)
|
||||
|
||||
# Point (simple punctual) light type checks.
|
||||
light_type_property_test(
|
||||
light_type=LIGHT_TYPES['simple_point'],
|
||||
light_properties=SIMPLE_POINT_LIGHT_PROPERTIES,
|
||||
light_component_id_pair=light_component_id_pair,
|
||||
light_entity_name=light_entity_name,
|
||||
light_entity=light_entity
|
||||
)
|
||||
|
||||
# Spot (simple punctual) light type checks.
|
||||
light_type_property_test(
|
||||
light_type=LIGHT_TYPES['simple_spot'],
|
||||
light_properties=SIMPLE_SPOT_LIGHT_PROPERTIES,
|
||||
light_component_id_pair=light_component_id_pair,
|
||||
light_entity_name=light_entity_name,
|
||||
light_entity=light_entity
|
||||
)
|
||||
|
||||
general.log("Light component test (non-GPU) completed.")
|
||||
|
||||
|
||||
def light_type_property_test(light_type, light_properties, light_component_id_pair, light_entity_name, light_entity):
|
||||
"""
|
||||
Updates the current light type and modifies its properties, then verifies they are accurate to what was set.
|
||||
:param light_type: The type of light to update, must match a value in LIGHT_TYPES
|
||||
:param light_properties: List of tuples detailing properties to modify with update values.
|
||||
:param light_component_id_pair: Entity + component ID pair for updating the light component on a given entity.
|
||||
:param light_entity_name: the name of the Entity holding the light component.
|
||||
:param light_entity: the Entity object containing the light component.
|
||||
:return: None
|
||||
"""
|
||||
azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast,
|
||||
'SetComponentProperty',
|
||||
light_component_id_pair,
|
||||
LIGHT_TYPE_PROPERTY,
|
||||
light_type
|
||||
)
|
||||
verify_required_component_property_value(
|
||||
entity_name=light_entity_name,
|
||||
component=light_entity.components[0],
|
||||
property_path=LIGHT_TYPE_PROPERTY,
|
||||
expected_property_value=light_type
|
||||
)
|
||||
|
||||
for light_property in light_properties:
|
||||
light_entity.get_set_test(0, light_property[0], light_property[1])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
+7
-6
@@ -68,7 +68,7 @@ def ShapeIntersectionFilter_FilterStageToggle():
|
||||
# Create a new entity as a child of the vegetation area entity with Box Shape
|
||||
box = hydra.Entity("box")
|
||||
box.create_entity(position, ["Box Shape"])
|
||||
box.get_set_test(0, "Box Shape|Box Configuration|Dimensions", math.Vector3(8.0, 8.0, 1.0))
|
||||
box.get_set_test(0, "Box Shape|Box Configuration|Dimensions", math.Vector3(5.0, 5.0, 1.0))
|
||||
|
||||
# Create a new entity as a child of the vegetation area entity with Cylinder Shape.
|
||||
cylinder = hydra.Entity("cylinder")
|
||||
@@ -80,10 +80,10 @@ def ShapeIntersectionFilter_FilterStageToggle():
|
||||
|
||||
# On the Shape Intersection Filter component, click the crosshair button, and add child entities one by one
|
||||
vegetation.get_set_test(3, "Configuration|Shape Entity Id", box.id)
|
||||
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 8.0, 100), 2.0)
|
||||
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 49), 2.0)
|
||||
Report.result(Tests.instance_count_in_box_shape, result)
|
||||
vegetation.get_set_test(3, "Configuration|Shape Entity Id", cylinder.id)
|
||||
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 100), 2.0)
|
||||
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 121), 2.0)
|
||||
Report.result(Tests.instance_count_in_cylinder_shape, result)
|
||||
|
||||
# Create a new entity as a child of the area entity with Random Noise Gradient, Gradient Transform Modifier,
|
||||
@@ -98,12 +98,13 @@ def ShapeIntersectionFilter_FilterStageToggle():
|
||||
# Pin the Random Noise entity to the Gradient Entity Id field of the Position Modifier's Gradient X
|
||||
vegetation.get_set_test(4, "Configuration|Position X|Gradient|Gradient Entity Id", random_noise.id)
|
||||
|
||||
# Toggle between PreProcess and PostProcess
|
||||
# Toggle between PreProcess and PostProcess and validate instances. Validate in a 0.3m wider radius due to position
|
||||
# offsets
|
||||
vegetation.get_set_test(3, "Configuration|Filter Stage", 1)
|
||||
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 117), 2.0)
|
||||
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.3, 121), 2.0)
|
||||
Report.result(Tests.preprocess_instance_count, result)
|
||||
vegetation.get_set_test(3, "Configuration|Filter Stage", 2)
|
||||
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 122), 2.0)
|
||||
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.3, 122), 2.0)
|
||||
Report.result(Tests.postprocess_instance_count, result)
|
||||
|
||||
|
||||
|
||||
@@ -131,7 +131,6 @@ class TestAutomation_PrefabNotEnabled(EditorTestSuite):
|
||||
class test_ShapeIntersectionFilter_InstancesPlantInAssignedShape(EditorParallelTest):
|
||||
from .EditorScripts import ShapeIntersectionFilter_InstancesPlantInAssignedShape as test_module
|
||||
|
||||
@pytest.mark.skip("https://github.com/o3de/o3de/issues/6973")
|
||||
class test_ShapeIntersectionFilter_FilterStageToggle(EditorParallelTest):
|
||||
from .EditorScripts import ShapeIntersectionFilter_FilterStageToggle as test_module
|
||||
|
||||
|
||||
@@ -191,6 +191,7 @@ void AssetImporterManager::OnBrowseDestinationFilePath(QLineEdit* destinationLin
|
||||
fileDialog.setViewMode(QFileDialog::List);
|
||||
fileDialog.setWindowModality(Qt::WindowModality::ApplicationModal);
|
||||
fileDialog.setWindowTitle(tr("Select import destination"));
|
||||
fileDialog.setFileMode(QFileDialog::Directory);
|
||||
|
||||
QSettings settings;
|
||||
QString currentDestination = settings.value(AssetImporterManagerPrivate::g_selectDestinationFilesPath).toString();
|
||||
|
||||
@@ -32,6 +32,15 @@ AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
|
||||
AZ_CVAR_EXTERNED(bool, ed_useNewAssetBrowserTableView);
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace AssetBrowser
|
||||
{
|
||||
static constexpr const char* CollapseAllIcon = "Assets/Editor/Icons/AssetBrowser/Collapse_All.svg";
|
||||
static constexpr const char* MenuIcon = ":/Menu/menu.svg";
|
||||
} // namespace AssetBrowser
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
class ListenerForShowAssetEditorEvent
|
||||
: public QObject
|
||||
, private AzToolsFramework::EditorEvents::Bus::Handler
|
||||
@@ -87,10 +96,21 @@ AzAssetBrowserWindow::AzAssetBrowserWindow(QWidget* parent)
|
||||
|
||||
m_assetBrowserModel->SetFilterModel(m_filterModel.data());
|
||||
|
||||
m_ui->m_collapseAllButton->setAutoRaise(true); // hover highlight
|
||||
m_ui->m_collapseAllButton->setIcon(QIcon(AzAssetBrowser::CollapseAllIcon));
|
||||
|
||||
connect(
|
||||
m_ui->m_collapseAllButton, &QToolButton::clicked, this,
|
||||
[this]()
|
||||
{
|
||||
m_ui->m_assetBrowserTreeViewWidget->collapseAll();
|
||||
});
|
||||
|
||||
if (ed_useNewAssetBrowserTableView)
|
||||
{
|
||||
m_ui->m_toggleDisplayViewBtn->setVisible(true);
|
||||
m_ui->m_toggleDisplayViewBtn->setIcon(QIcon(":/Menu/menu.svg"));
|
||||
m_ui->m_toggleDisplayViewBtn->setAutoRaise(true);
|
||||
m_ui->m_toggleDisplayViewBtn->setIcon(QIcon(AzAssetBrowser::MenuIcon));
|
||||
|
||||
m_tableModel->setFilterRole(Qt::DisplayRole);
|
||||
m_tableModel->setSourceModel(m_filterModel.data());
|
||||
|
||||
@@ -72,6 +72,22 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="m_collapseAllButton">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::ClickFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string extracomment="Collapse All"/>
|
||||
</property>
|
||||
<property name="toolTipDuration">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
@@ -143,15 +159,6 @@
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderShowSortIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
||||
@@ -408,7 +408,7 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
|
||||
// check if engine path is registered
|
||||
auto allEngines = m_manifest.attr("get_engines")();
|
||||
auto allEngines = m_manifest.attr("get_manifest_engines")();
|
||||
if (pybind11::isinstance<pybind11::list>(allEngines))
|
||||
{
|
||||
const AZ::IO::FixedMaxPath enginePathFixed(Py_To_String(enginePath));
|
||||
@@ -891,7 +891,7 @@ namespace O3DE::ProjectManager
|
||||
|
||||
bool result = ExecuteWithLock([&] {
|
||||
// external projects
|
||||
for (auto path : m_manifest.attr("get_projects")())
|
||||
for (auto path : m_manifest.attr("get_manifest_projects")())
|
||||
{
|
||||
projects.push_back(ProjectInfoFromPath(path));
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Code",
|
||||
"summary": "",
|
||||
"summary": "Image processing for Atom",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Code",
|
||||
"summary": "",
|
||||
"summary": "Atom Bootstrap",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Code",
|
||||
"summary": "",
|
||||
"summary": "Debug Camera component for Atom",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Code",
|
||||
"summary": "",
|
||||
"summary": "Common features for Atom",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Code",
|
||||
"summary": "",
|
||||
"summary": "DX12 RHI for Atom",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Code",
|
||||
"summary": "",
|
||||
"summary": "Metal RHI for Atom",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Code",
|
||||
"summary": "",
|
||||
"summary": "Atom Null RHI",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Code",
|
||||
"summary": "",
|
||||
"summary": "Vulcan RHI for Atom",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Code",
|
||||
"summary": "",
|
||||
"summary": "RHI for Atom",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Code",
|
||||
"summary": "",
|
||||
"summary": "RPI for Atom",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Code",
|
||||
"summary": "",
|
||||
"summary": "Tools Framework for Atom",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Code",
|
||||
"summary": "",
|
||||
"summary": "Atom Bridge",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Code",
|
||||
"summary": "",
|
||||
"summary": "Font Rendering for Atom",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Tool",
|
||||
"summary": "",
|
||||
"summary": "ImGui tools for Atom",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Code",
|
||||
"summary": "",
|
||||
"summary": "Viewport display icons for Atom",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Code",
|
||||
"summary": "",
|
||||
"summary": "Viewport Display Information for Atom",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Code",
|
||||
"summary": "",
|
||||
"summary": "Common features for Atom",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Code",
|
||||
"summary": "",
|
||||
"summary": "EmotionFX for Atom",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Code",
|
||||
"summary": "",
|
||||
"summary": "ImGui support for Atom",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
|
||||
@@ -104,7 +104,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
|
||||
NAME FastNoise.Editor.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
|
||||
NAMESPACE Gem
|
||||
FILES_CMAKE
|
||||
fastnoise_tests_files.cmake
|
||||
fastnoise_editor_tests_files.cmake
|
||||
COMPILE_DEFINITIONS
|
||||
PUBLIC
|
||||
FASTNOISE_EDITOR
|
||||
@@ -120,23 +120,31 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
|
||||
ly_add_googletest(
|
||||
NAME Gem::FastNoise.Editor.Tests
|
||||
)
|
||||
else()
|
||||
ly_add_target(
|
||||
NAME FastNoise.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
|
||||
NAMESPACE Gem
|
||||
FILES_CMAKE
|
||||
fastnoise_tests_files.cmake
|
||||
INCLUDE_DIRECTORIES
|
||||
PRIVATE
|
||||
Tests
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
AZ::AzTest
|
||||
Gem::FastNoise.Static
|
||||
Gem::LmbrCentral
|
||||
)
|
||||
ly_add_googletest(
|
||||
NAME Gem::FastNoise.Tests
|
||||
)
|
||||
endif()
|
||||
|
||||
ly_add_target(
|
||||
NAME FastNoise.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
|
||||
NAMESPACE Gem
|
||||
FILES_CMAKE
|
||||
fastnoise_tests_files.cmake
|
||||
INCLUDE_DIRECTORIES
|
||||
PRIVATE
|
||||
Tests
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
AZ::AzTest
|
||||
Gem::FastNoise.Static
|
||||
Gem::GradientSignal
|
||||
Gem::GradientSignal.Tests.Static
|
||||
Gem::LmbrCentral
|
||||
)
|
||||
ly_add_googletest(
|
||||
NAME Gem::FastNoise.Tests
|
||||
)
|
||||
|
||||
ly_add_googlebenchmark(
|
||||
NAME Gem::FastNoise.Benchmarks
|
||||
TARGET Gem::FastNoise.Tests
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
@@ -54,6 +54,21 @@ namespace FastNoiseGem
|
||||
return AZ::Edit::PropertyVisibility::Hide;
|
||||
}
|
||||
|
||||
bool FastNoiseGradientConfig::operator==(const FastNoiseGradientConfig& rhs) const
|
||||
{
|
||||
return (m_cellularDistanceFunction == rhs.m_cellularDistanceFunction)
|
||||
&& (m_cellularJitter == rhs.m_cellularJitter)
|
||||
&& (m_cellularReturnType == rhs.m_cellularReturnType)
|
||||
&& (m_fractalType == rhs.m_fractalType)
|
||||
&& (m_frequency == rhs.m_frequency)
|
||||
&& (m_gain == rhs.m_gain)
|
||||
&& (m_interp == rhs.m_interp)
|
||||
&& (m_lacunarity == rhs.m_lacunarity)
|
||||
&& (m_noiseType == rhs.m_noiseType)
|
||||
&& (m_octaves == rhs.m_octaves)
|
||||
&& (m_seed == rhs.m_seed);
|
||||
}
|
||||
|
||||
void FastNoiseGradientConfig::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
@@ -306,7 +321,7 @@ namespace FastNoiseGem
|
||||
|
||||
float FastNoiseGradientComponent::GetValue(const GradientSignal::GradientSampleParams& sampleParams) const
|
||||
{
|
||||
AZ::Vector3 uvw = sampleParams.m_position;
|
||||
AZ::Vector3 uvw;
|
||||
bool wasPointRejected = false;
|
||||
|
||||
{
|
||||
@@ -314,13 +329,34 @@ namespace FastNoiseGem
|
||||
m_gradientTransform.TransformPositionToUVW(sampleParams.m_position, uvw, wasPointRejected);
|
||||
}
|
||||
|
||||
if (!wasPointRejected)
|
||||
// Generator returns a range between [-1, 1], map that to [0, 1]
|
||||
return wasPointRejected ?
|
||||
0.0f :
|
||||
AZ::GetClamp((m_generator.GetNoise(uvw.GetX(), uvw.GetY(), uvw.GetZ()) + 1.0f) / 2.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
void FastNoiseGradientComponent::GetValues(AZStd::span<const AZ::Vector3> positions, AZStd::span<float> outValues) const
|
||||
{
|
||||
if (positions.size() != outValues.size())
|
||||
{
|
||||
// Generator returns a range between [-1, 1], map that to [0, 1]
|
||||
return AZ::GetClamp((m_generator.GetNoise(uvw.GetX(), uvw.GetY(), uvw.GetZ()) + 1.0f) / 2.0f, 0.0f, 1.0f);
|
||||
AZ_Assert(false, "input and output lists are different sizes (%zu vs %zu).", positions.size(), outValues.size());
|
||||
return;
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
AZStd::shared_lock<decltype(m_transformMutex)> lock(m_transformMutex);
|
||||
AZ::Vector3 uvw;
|
||||
|
||||
for (size_t index = 0; index < positions.size(); index++)
|
||||
{
|
||||
bool wasPointRejected = false;
|
||||
|
||||
m_gradientTransform.TransformPositionToUVW(positions[index], uvw, wasPointRejected);
|
||||
|
||||
// Generator returns a range between [-1, 1], map that to [0, 1]
|
||||
outValues[index] = wasPointRejected ?
|
||||
0.0f :
|
||||
AZ::GetClamp((m_generator.GetNoise(uvw.GetX(), uvw.GetY(), uvw.GetZ()) + 1.0f) / 2.0f, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TValueType, TValueType FastNoiseGradientConfig::*TConfigMember, void (FastNoise::*TMethod)(TValueType)>
|
||||
|
||||
@@ -47,6 +47,8 @@ namespace FastNoiseGem
|
||||
AZ::u32 GetFrequencyParameterVisbility() const;
|
||||
AZ::u32 GetInterpParameterVisibility() const;
|
||||
|
||||
bool operator==(const FastNoiseGradientConfig& rhs) const;
|
||||
|
||||
int m_seed = 1;
|
||||
float m_frequency = 1.f;
|
||||
FastNoise::Interp m_interp = FastNoise::Interp::Quintic;
|
||||
@@ -90,6 +92,7 @@ namespace FastNoiseGem
|
||||
|
||||
// GradientRequestBus overrides...
|
||||
float GetValue(const GradientSignal::GradientSampleParams& sampleParams) const override;
|
||||
void GetValues(AZStd::span<const AZ::Vector3> positions, AZStd::span<float> outValues) const override;
|
||||
|
||||
protected:
|
||||
FastNoiseGradientConfig m_configuration;
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_BENCHMARK
|
||||
|
||||
#include <AzTest/AzTest.h>
|
||||
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <FastNoiseGradientComponent.h>
|
||||
#include <FastNoiseTest.h>
|
||||
#include <GradientSignalTestHelpers.h>
|
||||
#include <GradientSignal/Components/GradientTransformComponent.h>
|
||||
#include <GradientSignal/Ebuses/GradientRequestBus.h>
|
||||
#include <GradientSignal/Ebuses/GradientTransformModifierRequestBus.h>
|
||||
#include <GradientSignal/GradientSampler.h>
|
||||
#include <LmbrCentral/Shape/BoxShapeComponentBus.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
class FastNoiseGetValues
|
||||
: public ::benchmark::Fixture
|
||||
{
|
||||
public:
|
||||
void RunGetValueOrGetValuesBenchmark(benchmark::State& state, FastNoise::NoiseType noiseType)
|
||||
{
|
||||
AZ::Entity* noiseEntity = aznew AZ::Entity("noise_entity");
|
||||
ASSERT_TRUE(noiseEntity != nullptr);
|
||||
noiseEntity->CreateComponent<AzFramework::TransformComponent>();
|
||||
noiseEntity->CreateComponent(LmbrCentral::BoxShapeComponentTypeId);
|
||||
noiseEntity->CreateComponent<GradientSignal::GradientTransformComponent>();
|
||||
|
||||
// Set up a FastNoise component with the requested noise type
|
||||
FastNoiseGem::FastNoiseGradientConfig cfg;
|
||||
cfg.m_frequency = 0.01f;
|
||||
cfg.m_noiseType = noiseType;
|
||||
noiseEntity->CreateComponent<FastNoiseGem::FastNoiseGradientComponent>(cfg);
|
||||
|
||||
noiseEntity->Init();
|
||||
noiseEntity->Activate();
|
||||
|
||||
UnitTest::GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, noiseEntity->GetId());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_Value)(benchmark::State& state)
|
||||
{
|
||||
RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::Value);
|
||||
}
|
||||
|
||||
BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_ValueFractal)(benchmark::State& state)
|
||||
{
|
||||
RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::ValueFractal);
|
||||
}
|
||||
|
||||
BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_Perlin)(benchmark::State& state)
|
||||
{
|
||||
RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::Perlin);
|
||||
}
|
||||
|
||||
BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_PerlinFractal)(benchmark::State& state)
|
||||
{
|
||||
RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::PerlinFractal);
|
||||
}
|
||||
|
||||
BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_Simplex)(benchmark::State& state)
|
||||
{
|
||||
RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::Simplex);
|
||||
}
|
||||
|
||||
BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_SimplexFractal)(benchmark::State& state)
|
||||
{
|
||||
RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::SimplexFractal);
|
||||
}
|
||||
|
||||
BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_Cellular)(benchmark::State& state)
|
||||
{
|
||||
RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::Cellular);
|
||||
}
|
||||
|
||||
BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_WhiteNoise)(benchmark::State& state)
|
||||
{
|
||||
RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::WhiteNoise);
|
||||
}
|
||||
|
||||
BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_Cubic)(benchmark::State& state)
|
||||
{
|
||||
RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::Cubic);
|
||||
}
|
||||
|
||||
BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_CubicFractal)(benchmark::State& state)
|
||||
{
|
||||
RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::CubicFractal);
|
||||
}
|
||||
|
||||
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_Value);
|
||||
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_ValueFractal);
|
||||
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_Perlin);
|
||||
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_PerlinFractal);
|
||||
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_Simplex);
|
||||
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_SimplexFractal);
|
||||
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_Cellular);
|
||||
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_WhiteNoise);
|
||||
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_Cubic);
|
||||
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_CubicFractal);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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 <AzTest/AzTest.h>
|
||||
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <EditorFastNoiseGradientComponent.h>
|
||||
#include <FastNoiseTest.h>
|
||||
|
||||
|
||||
class FastNoiseEditorTestApp : public ::testing::Test
|
||||
{
|
||||
};
|
||||
|
||||
TEST_F(FastNoiseEditorTestApp, FastNoise_EditorCreateGameEntity)
|
||||
{
|
||||
AZStd::unique_ptr<AZ::Entity> noiseEntity(aznew AZ::Entity("editor_noise_entity"));
|
||||
ASSERT_TRUE(noiseEntity != nullptr);
|
||||
|
||||
FastNoiseGem::EditorFastNoiseGradientComponent editor;
|
||||
auto* editorBase = static_cast<AzToolsFramework::Components::EditorComponentBase*>(&editor);
|
||||
editorBase->BuildGameEntity(noiseEntity.get());
|
||||
|
||||
// the new game entity's FastNoise component should look like the default one
|
||||
FastNoiseGem::FastNoiseGradientConfig defaultConfig;
|
||||
FastNoiseGem::FastNoiseGradientConfig gameComponentConfig;
|
||||
|
||||
FastNoiseGem::FastNoiseGradientComponent* noiseComp = noiseEntity->FindComponent<FastNoiseGem::FastNoiseGradientComponent>();
|
||||
ASSERT_TRUE(noiseComp != nullptr);
|
||||
|
||||
// Change a value in the gameComponentConfig just to verify that it got overwritten instead of simply matching the default.
|
||||
gameComponentConfig.m_seed++;
|
||||
noiseComp->WriteOutConfig(&gameComponentConfig);
|
||||
ASSERT_EQ(defaultConfig, gameComponentConfig);
|
||||
}
|
||||
|
||||
// This uses custom test / benchmark hooks so that we can load LmbrCentral and GradientSignal Gems.
|
||||
AZ_UNIT_TEST_HOOK(new UnitTest::FastNoiseTestEnvironment, UnitTest::FastNoiseBenchmarkEnvironment);
|
||||
@@ -10,199 +10,61 @@
|
||||
|
||||
#include <AzCore/Component/ComponentApplication.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Math/Random.h>
|
||||
#include <AzCore/Memory/Memory.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AzCore/Script/ScriptContext.h>
|
||||
#include <AzCore/std/chrono/clocks.h>
|
||||
#include <FastNoiseSystemComponent.h>
|
||||
#include <AzFramework/Components/TransformComponent.h>
|
||||
#include <FastNoiseGradientComponent.h>
|
||||
#include <FastNoiseModule.h>
|
||||
#include <FastNoiseTest.h>
|
||||
#include <GradientSignalTestHelpers.h>
|
||||
#include <GradientSignal/Components/GradientTransformComponent.h>
|
||||
#include <GradientSignal/Ebuses/GradientRequestBus.h>
|
||||
#include <GradientSignal/Ebuses/GradientTransformModifierRequestBus.h>
|
||||
#include <GradientSignal/Ebuses/GradientTransformRequestBus.h>
|
||||
#include <GradientSignal/GradientSampler.h>
|
||||
#include <LmbrCentral/Shape/BoxShapeComponentBus.h>
|
||||
|
||||
class MockGradientTransformComponent
|
||||
: public AZ::Component
|
||||
, private GradientSignal::GradientTransformRequestBus::Handler
|
||||
, private GradientSignal::GradientTransformModifierRequestBus::Handler
|
||||
class FastNoiseTest : public ::testing::Test
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(MockGradientTransformComponent, "{464CF47B-7E10-4E1B-BD06-79BD2AC91399}");
|
||||
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services)
|
||||
{
|
||||
services.push_back(AZ_CRC("GradientTransformService", 0x8c8c5ecc));
|
||||
}
|
||||
static void Reflect([[maybe_unused]] AZ::ReflectContext* context) {}
|
||||
|
||||
MockGradientTransformComponent() = default;
|
||||
~MockGradientTransformComponent() = default;
|
||||
|
||||
// AZ::Component interface
|
||||
void Activate() override {}
|
||||
void Deactivate() override {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//// GradientTransformRequestBus
|
||||
const GradientSignal::GradientTransform& GetGradientTransform() const override
|
||||
{
|
||||
return m_gradientTransform;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// GradientTransformModifierRequestBus
|
||||
bool GetAllowReference() const override { return false; }
|
||||
void SetAllowReference([[maybe_unused]] bool value) override {}
|
||||
|
||||
AZ::EntityId GetShapeReference() const override { return AZ::EntityId(); }
|
||||
void SetShapeReference([[maybe_unused]] AZ::EntityId shapeReference) override {}
|
||||
|
||||
bool GetOverrideBounds() const override { return false; }
|
||||
void SetOverrideBounds([[maybe_unused]] bool value) override {}
|
||||
|
||||
AZ::Vector3 GetBounds() const override { return AZ::Vector3(); }
|
||||
void SetBounds([[maybe_unused]] AZ::Vector3 bounds) override {}
|
||||
|
||||
GradientSignal::TransformType GetTransformType() const override { return static_cast<GradientSignal::TransformType>(0); }
|
||||
void SetTransformType([[maybe_unused]] GradientSignal::TransformType type) override {}
|
||||
|
||||
bool GetOverrideTranslate() const override { return false; }
|
||||
void SetOverrideTranslate([[maybe_unused]] bool value) override {}
|
||||
|
||||
AZ::Vector3 GetTranslate() const override { return AZ::Vector3(); }
|
||||
void SetTranslate([[maybe_unused]] AZ::Vector3 translate) override {}
|
||||
|
||||
bool GetOverrideRotate() const override { return false; }
|
||||
void SetOverrideRotate([[maybe_unused]] bool value) override {}
|
||||
|
||||
AZ::Vector3 GetRotate() const override { return AZ::Vector3(); }
|
||||
void SetRotate([[maybe_unused]] AZ::Vector3 rotate) override {}
|
||||
|
||||
bool GetOverrideScale() const override { return false; }
|
||||
void SetOverrideScale([[maybe_unused]] bool value) override {}
|
||||
|
||||
AZ::Vector3 GetScale() const override { return AZ::Vector3(); }
|
||||
void SetScale([[maybe_unused]] AZ::Vector3 scale) override {}
|
||||
|
||||
float GetFrequencyZoom() const override { return false; }
|
||||
void SetFrequencyZoom([[maybe_unused]] float frequencyZoom) override {}
|
||||
|
||||
GradientSignal::WrappingType GetWrappingType() const override { return static_cast<GradientSignal::WrappingType>(0); }
|
||||
void SetWrappingType([[maybe_unused]] GradientSignal::WrappingType type) override {}
|
||||
|
||||
bool GetIs3D() const override { return false; }
|
||||
void SetIs3D([[maybe_unused]] bool value) override {}
|
||||
|
||||
bool GetAdvancedMode() const override { return false; }
|
||||
void SetAdvancedMode([[maybe_unused]] bool value) override {}
|
||||
|
||||
GradientSignal::GradientTransform m_gradientTransform;
|
||||
};
|
||||
|
||||
TEST(FastNoiseTest, ComponentsWithComponentApplication)
|
||||
{
|
||||
AZ::ComponentApplication::Descriptor appDesc;
|
||||
appDesc.m_memoryBlocksByteSize = 10 * 1024 * 1024;
|
||||
appDesc.m_recordingMode = AZ::Debug::AllocationRecords::RECORD_FULL;
|
||||
appDesc.m_stackRecordLevels = 20;
|
||||
|
||||
AZ::ComponentApplication app;
|
||||
AZ::Entity* systemEntity = app.Create(appDesc);
|
||||
ASSERT_TRUE(systemEntity != nullptr);
|
||||
app.RegisterComponentDescriptor(FastNoiseGem::FastNoiseSystemComponent::CreateDescriptor());
|
||||
systemEntity->CreateComponent<FastNoiseGem::FastNoiseSystemComponent>();
|
||||
|
||||
systemEntity->Init();
|
||||
systemEntity->Activate();
|
||||
|
||||
AZ::Entity* noiseEntity = aznew AZ::Entity("fastnoise_entity");
|
||||
noiseEntity->CreateComponent<FastNoiseGem::FastNoiseGradientComponent>();
|
||||
app.AddEntity(noiseEntity);
|
||||
|
||||
app.Destroy();
|
||||
ASSERT_TRUE(true);
|
||||
}
|
||||
|
||||
class FastNoiseTestApp
|
||||
: public ::testing::Test
|
||||
{
|
||||
public:
|
||||
FastNoiseTestApp()
|
||||
: m_application()
|
||||
, m_systemEntity(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
AZ::ComponentApplication::Descriptor appDesc;
|
||||
appDesc.m_memoryBlocksByteSize = 10 * 1024 * 1024;
|
||||
appDesc.m_recordingMode = AZ::Debug::AllocationRecords::RECORD_FULL;
|
||||
appDesc.m_stackRecordLevels = 20;
|
||||
|
||||
AZ::ComponentApplication::StartupParameters appStartup;
|
||||
appStartup.m_createStaticModulesCallback =
|
||||
[](AZStd::vector<AZ::Module*>& modules)
|
||||
{
|
||||
modules.emplace_back(new FastNoiseGem::FastNoiseModule);
|
||||
};
|
||||
|
||||
m_systemEntity = m_application.Create(appDesc, appStartup);
|
||||
m_application.RegisterComponentDescriptor(MockGradientTransformComponent::CreateDescriptor());
|
||||
m_systemEntity->Init();
|
||||
m_systemEntity->Activate();
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
m_application.Destroy();
|
||||
}
|
||||
|
||||
AZ::ComponentApplication m_application;
|
||||
AZ::Entity* m_systemEntity;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// testing class to inspect protected data members in the FastNoiseGradientComponent
|
||||
struct FastNoiseGradientComponentTester : public FastNoiseGem::FastNoiseGradientComponent
|
||||
{
|
||||
const FastNoiseGem::FastNoiseGradientConfig& GetConfig() const { return m_configuration; }
|
||||
|
||||
void AssertTrue(const FastNoiseGem::FastNoiseGradientConfig& cfg)
|
||||
{
|
||||
ASSERT_TRUE(m_configuration.m_cellularDistanceFunction == cfg.m_cellularDistanceFunction);
|
||||
ASSERT_TRUE(m_configuration.m_cellularJitter == cfg.m_cellularJitter);
|
||||
ASSERT_TRUE(m_configuration.m_cellularReturnType == cfg.m_cellularReturnType);
|
||||
ASSERT_TRUE(m_configuration.m_fractalType == cfg.m_fractalType);
|
||||
ASSERT_TRUE(m_configuration.m_frequency == cfg.m_frequency);
|
||||
ASSERT_TRUE(m_configuration.m_gain == cfg.m_gain);
|
||||
ASSERT_TRUE(m_configuration.m_interp == cfg.m_interp);
|
||||
ASSERT_TRUE(m_configuration.m_lacunarity == cfg.m_lacunarity);
|
||||
ASSERT_TRUE(m_configuration.m_noiseType == cfg.m_noiseType);
|
||||
ASSERT_TRUE(m_configuration.m_octaves == cfg.m_octaves);
|
||||
ASSERT_TRUE(m_configuration.m_seed == cfg.m_seed);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(FastNoiseTestApp, FastNoise_Component)
|
||||
TEST_F(FastNoiseTest, FastNoise_ComponentCreatesSuccessfully)
|
||||
{
|
||||
AZ::Entity* noiseEntity = aznew AZ::Entity("noise_entity");
|
||||
ASSERT_TRUE(noiseEntity != nullptr);
|
||||
noiseEntity->CreateComponent<FastNoiseGem::FastNoiseGradientComponent>();
|
||||
m_application.AddEntity(noiseEntity);
|
||||
|
||||
FastNoiseGem::FastNoiseGradientComponent* noiseComp = noiseEntity->FindComponent<FastNoiseGem::FastNoiseGradientComponent>();
|
||||
ASSERT_TRUE(noiseComp != nullptr);
|
||||
}
|
||||
|
||||
TEST_F(FastNoiseTestApp, FastNoise_ComponentEbus)
|
||||
TEST_F(FastNoiseTest, FastNoise_ComponentMatchesConfiguration)
|
||||
{
|
||||
AZ::Entity* noiseEntity = aznew AZ::Entity("noise_entity");
|
||||
ASSERT_TRUE(noiseEntity != nullptr);
|
||||
|
||||
FastNoiseGem::FastNoiseGradientConfig cfg;
|
||||
FastNoiseGem::FastNoiseGradientConfig componentConfig;
|
||||
|
||||
noiseEntity->CreateComponent<AzFramework::TransformComponent>();
|
||||
noiseEntity->CreateComponent(LmbrCentral::BoxShapeComponentTypeId);
|
||||
noiseEntity->CreateComponent<GradientSignal::GradientTransformComponent>();
|
||||
noiseEntity->CreateComponent<FastNoiseGem::FastNoiseGradientComponent>(cfg);
|
||||
|
||||
FastNoiseGem::FastNoiseGradientComponent* noiseComp = noiseEntity->FindComponent<FastNoiseGem::FastNoiseGradientComponent>();
|
||||
ASSERT_TRUE(noiseComp != nullptr);
|
||||
noiseComp->WriteOutConfig(&componentConfig);
|
||||
ASSERT_EQ(cfg, componentConfig);
|
||||
}
|
||||
|
||||
TEST_F(FastNoiseTest, FastNoise_ComponentEbusWorksSuccessfully)
|
||||
{
|
||||
AZ::Entity* noiseEntity = aznew AZ::Entity("noise_entity");
|
||||
ASSERT_TRUE(noiseEntity != nullptr);
|
||||
noiseEntity->CreateComponent<AzFramework::TransformComponent>();
|
||||
noiseEntity->CreateComponent(LmbrCentral::BoxShapeComponentTypeId);
|
||||
noiseEntity->CreateComponent<GradientSignal::GradientTransformComponent>();
|
||||
noiseEntity->CreateComponent<FastNoiseGem::FastNoiseGradientComponent>();
|
||||
noiseEntity->CreateComponent<MockGradientTransformComponent>();
|
||||
|
||||
noiseEntity->Init();
|
||||
noiseEntity->Activate();
|
||||
@@ -210,51 +72,39 @@ TEST_F(FastNoiseTestApp, FastNoise_ComponentEbus)
|
||||
GradientSignal::GradientSampleParams params;
|
||||
float sample = -1.0f;
|
||||
|
||||
GradientSignal::GradientRequestBus::EventResult(sample, noiseEntity->GetId(), &GradientSignal::GradientRequestBus::Events::GetValue, params);
|
||||
GradientSignal::GradientRequestBus::EventResult(sample, noiseEntity->GetId(),
|
||||
&GradientSignal::GradientRequestBus::Events::GetValue, params);
|
||||
ASSERT_TRUE(sample >= 0.0f);
|
||||
ASSERT_TRUE(sample <= 1.0f);
|
||||
}
|
||||
|
||||
TEST_F(FastNoiseTestApp, FastNoise_ComponentMatchesConfiguration)
|
||||
TEST_F(FastNoiseTest, FastNoise_VerifyGetValueAndGetValuesMatch)
|
||||
{
|
||||
const float shapeHalfBounds = 128.0f;
|
||||
|
||||
AZ::Entity* noiseEntity = aznew AZ::Entity("noise_entity");
|
||||
ASSERT_TRUE(noiseEntity != nullptr);
|
||||
noiseEntity->CreateComponent<AzFramework::TransformComponent>();
|
||||
noiseEntity->CreateComponent<GradientSignal::GradientTransformComponent>();
|
||||
|
||||
AZ::SimpleLcgRandom rand(AZStd::GetTimeNowMicroSecond());
|
||||
// Create a Box Shape to map our gradient into
|
||||
LmbrCentral::BoxShapeConfig boxConfig(AZ::Vector3(shapeHalfBounds * 2.0f));
|
||||
auto boxComponent = noiseEntity->CreateComponent(LmbrCentral::BoxShapeComponentTypeId);
|
||||
boxComponent->SetConfiguration(boxConfig);
|
||||
|
||||
// Create a Fast Noise component with an adjusted frequency. (The defaults of Perlin noise with frequency=1.0 would cause us
|
||||
// to always get back the same noise value)
|
||||
FastNoiseGem::FastNoiseGradientConfig cfg;
|
||||
|
||||
cfg.m_frequency = 0.01f;
|
||||
noiseEntity->CreateComponent<FastNoiseGem::FastNoiseGradientComponent>(cfg);
|
||||
noiseEntity->CreateComponent<MockGradientTransformComponent>();
|
||||
|
||||
m_application.AddEntity(noiseEntity);
|
||||
noiseEntity->Init();
|
||||
noiseEntity->Activate();
|
||||
|
||||
FastNoiseGem::FastNoiseGradientComponent* noiseComp = noiseEntity->FindComponent<FastNoiseGem::FastNoiseGradientComponent>();
|
||||
ASSERT_TRUE(noiseComp != nullptr);
|
||||
reinterpret_cast<FastNoiseGradientComponentTester*>(noiseComp)->AssertTrue(cfg);
|
||||
// Create a gradient sampler and run through a series of points to see if they match expectations.
|
||||
UnitTest::GradientSignalTestHelpers::CompareGetValueAndGetValues(noiseEntity->GetId(), shapeHalfBounds);
|
||||
}
|
||||
|
||||
#if FASTNOISE_EDITOR
|
||||
#include <EditorFastNoiseGradientComponent.h>
|
||||
|
||||
TEST_F(FastNoiseTestApp, FastNoise_EditorCreateGameEntity)
|
||||
{
|
||||
AZStd::unique_ptr<AZ::Entity> noiseEntity(aznew AZ::Entity("editor_noise_entity"));
|
||||
ASSERT_TRUE(noiseEntity != nullptr);
|
||||
|
||||
FastNoiseGem::EditorFastNoiseGradientComponent editor;
|
||||
auto* editorBase = static_cast<AzToolsFramework::Components::EditorComponentBase*>(&editor);
|
||||
editorBase->BuildGameEntity(noiseEntity.get());
|
||||
|
||||
// the new game entity's ocean component should look like the default one
|
||||
FastNoiseGem::FastNoiseGradientConfig cfg;
|
||||
|
||||
FastNoiseGem::FastNoiseGradientComponent* noiseComp = noiseEntity->FindComponent<FastNoiseGem::FastNoiseGradientComponent>();
|
||||
ASSERT_TRUE(noiseComp != nullptr);
|
||||
reinterpret_cast<FastNoiseGradientComponentTester*>(noiseComp)->AssertTrue(cfg);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV);
|
||||
// This uses custom test / benchmark hooks so that we can load LmbrCentral and GradientSignal Gems.
|
||||
AZ_UNIT_TEST_HOOK(new UnitTest::FastNoiseTestEnvironment, UnitTest::FastNoiseBenchmarkEnvironment);
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzFramework/Components/TransformComponent.h>
|
||||
#include <AzTest/GemTestEnvironment.h>
|
||||
#include <FastNoiseGradientComponent.h>
|
||||
#include <FastNoiseSystemComponent.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
// The FastNoise unit tests need to use the GemTestEnvironment to load the GradientSignal and LmbrCentral Gems so that
|
||||
// GradientTransform components can be used in the unit tests and benchmarks.
|
||||
class FastNoiseTestEnvironment
|
||||
: public AZ::Test::GemTestEnvironment
|
||||
{
|
||||
public:
|
||||
void AddGemsAndComponents() override
|
||||
{
|
||||
AddDynamicModulePaths({ "GradientSignal" });
|
||||
AddDynamicModulePaths({ "LmbrCentral" });
|
||||
|
||||
AddComponentDescriptors({
|
||||
AzFramework::TransformComponent::CreateDescriptor(),
|
||||
FastNoiseGem::FastNoiseSystemComponent::CreateDescriptor(),
|
||||
FastNoiseGem::FastNoiseGradientComponent::CreateDescriptor()
|
||||
});
|
||||
|
||||
AddRequiredComponents({ FastNoiseGem::FastNoiseSystemComponent::TYPEINFO_Uuid() });
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef HAVE_BENCHMARK
|
||||
//! The Benchmark environment is used for one time setup and tear down of shared resources
|
||||
class FastNoiseBenchmarkEnvironment
|
||||
: public AZ::Test::BenchmarkEnvironmentBase
|
||||
, public FastNoiseTestEnvironment
|
||||
|
||||
{
|
||||
protected:
|
||||
void SetUpBenchmark() override
|
||||
{
|
||||
SetupEnvironment();
|
||||
}
|
||||
|
||||
void TearDownBenchmark() override
|
||||
{
|
||||
TeardownEnvironment();
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#
|
||||
# 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
|
||||
#
|
||||
#
|
||||
|
||||
set(FILES
|
||||
Tests/FastNoiseEditorTest.cpp
|
||||
Source/FastNoiseModule.h
|
||||
Source/FastNoiseModule.cpp
|
||||
)
|
||||
@@ -7,6 +7,7 @@
|
||||
#
|
||||
|
||||
set(FILES
|
||||
Tests/FastNoiseBenchmarks.cpp
|
||||
Tests/FastNoiseTest.cpp
|
||||
Source/FastNoiseModule.h
|
||||
Source/FastNoiseModule.cpp
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#ifdef HAVE_BENCHMARK
|
||||
|
||||
#include <Tests/GradientSignalTestFixtures.h>
|
||||
#include <Tests/GradientSignalTestHelpers.h>
|
||||
|
||||
#include <AzTest/AzTest.h>
|
||||
#include <AzCore/Memory/PoolAllocator.h>
|
||||
@@ -21,220 +22,42 @@ namespace UnitTest
|
||||
class GradientGetValues : public GradientSignalBenchmarkFixture
|
||||
{
|
||||
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,
|
||||
};
|
||||
|
||||
// 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);
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Base Gradients
|
||||
|
||||
BENCHMARK_DEFINE_F(GradientGetValues, BM_ConstantGradient)(benchmark::State& state)
|
||||
{
|
||||
auto entity = BuildTestConstantGradient(TestShapeHalfBounds);
|
||||
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
}
|
||||
|
||||
BENCHMARK_DEFINE_F(GradientGetValues, BM_ImageGradient)(benchmark::State& state)
|
||||
{
|
||||
auto entity = BuildTestImageGradient(TestShapeHalfBounds);
|
||||
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
}
|
||||
|
||||
|
||||
BENCHMARK_DEFINE_F(GradientGetValues, BM_PerlinGradient)(benchmark::State& state)
|
||||
{
|
||||
auto entity = BuildTestPerlinGradient(TestShapeHalfBounds);
|
||||
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
}
|
||||
|
||||
BENCHMARK_DEFINE_F(GradientGetValues, BM_RandomGradient)(benchmark::State& state)
|
||||
{
|
||||
auto entity = BuildTestRandomGradient(TestShapeHalfBounds);
|
||||
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
}
|
||||
|
||||
BENCHMARK_DEFINE_F(GradientGetValues, BM_ShapeAreaFalloffGradient)(benchmark::State& state)
|
||||
{
|
||||
auto entity = BuildTestShapeAreaFalloffGradient(TestShapeHalfBounds);
|
||||
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
}
|
||||
|
||||
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_ConstantGradient);
|
||||
@@ -250,21 +73,21 @@ namespace UnitTest
|
||||
{
|
||||
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
|
||||
auto entity = BuildTestDitherGradient(TestShapeHalfBounds, baseEntity->GetId());
|
||||
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
}
|
||||
|
||||
BENCHMARK_DEFINE_F(GradientGetValues, BM_InvertGradient)(benchmark::State& state)
|
||||
{
|
||||
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
|
||||
auto entity = BuildTestDitherGradient(TestShapeHalfBounds, baseEntity->GetId());
|
||||
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
}
|
||||
|
||||
BENCHMARK_DEFINE_F(GradientGetValues, BM_LevelsGradient)(benchmark::State& state)
|
||||
{
|
||||
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
|
||||
auto entity = BuildTestLevelsGradient(TestShapeHalfBounds, baseEntity->GetId());
|
||||
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
}
|
||||
|
||||
BENCHMARK_DEFINE_F(GradientGetValues, BM_MixedGradient)(benchmark::State& state)
|
||||
@@ -272,35 +95,35 @@ namespace UnitTest
|
||||
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
|
||||
auto mixedEntity = BuildTestConstantGradient(TestShapeHalfBounds);
|
||||
auto entity = BuildTestMixedGradient(TestShapeHalfBounds, baseEntity->GetId(), mixedEntity->GetId());
|
||||
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
}
|
||||
|
||||
BENCHMARK_DEFINE_F(GradientGetValues, BM_PosterizeGradient)(benchmark::State& state)
|
||||
{
|
||||
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
|
||||
auto entity = BuildTestPosterizeGradient(TestShapeHalfBounds, baseEntity->GetId());
|
||||
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
}
|
||||
|
||||
BENCHMARK_DEFINE_F(GradientGetValues, BM_ReferenceGradient)(benchmark::State& state)
|
||||
{
|
||||
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
|
||||
auto entity = BuildTestReferenceGradient(TestShapeHalfBounds, baseEntity->GetId());
|
||||
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
}
|
||||
|
||||
BENCHMARK_DEFINE_F(GradientGetValues, BM_SmoothStepGradient)(benchmark::State& state)
|
||||
{
|
||||
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
|
||||
auto entity = BuildTestSmoothStepGradient(TestShapeHalfBounds, baseEntity->GetId());
|
||||
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
GradientSignalTestHelpers::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());
|
||||
GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
}
|
||||
|
||||
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_DitherGradient);
|
||||
@@ -321,7 +144,7 @@ namespace UnitTest
|
||||
CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds)));
|
||||
|
||||
auto entity = BuildTestSurfaceAltitudeGradient(TestShapeHalfBounds);
|
||||
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
}
|
||||
|
||||
BENCHMARK_DEFINE_F(GradientGetValues, BM_SurfaceMaskGradient)(benchmark::State& state)
|
||||
@@ -330,7 +153,7 @@ namespace UnitTest
|
||||
CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds)));
|
||||
|
||||
auto entity = BuildTestSurfaceMaskGradient(TestShapeHalfBounds);
|
||||
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
}
|
||||
|
||||
BENCHMARK_DEFINE_F(GradientGetValues, BM_SurfaceSlopeGradient)(benchmark::State& state)
|
||||
@@ -339,7 +162,7 @@ namespace UnitTest
|
||||
CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds)));
|
||||
|
||||
auto entity = BuildTestSurfaceSlopeGradient(TestShapeHalfBounds);
|
||||
RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
|
||||
}
|
||||
|
||||
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_SurfaceAltitudeGradient);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
|
||||
#include <Tests/GradientSignalTestFixtures.h>
|
||||
#include <Tests/GradientSignalTestHelpers.h>
|
||||
#include <AzTest/AzTest.h>
|
||||
|
||||
namespace UnitTest
|
||||
@@ -18,79 +19,36 @@ namespace UnitTest
|
||||
// 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_NEAR instead of EXPECT_NEAR 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_NEAR(value, results[positionIndex], 0.000001f);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(GradientSignalGetValuesTestsFixture, ImageGradientComponent_VerifyGetValueAndGetValuesMatch)
|
||||
{
|
||||
auto entity = BuildTestImageGradient(TestShapeHalfBounds);
|
||||
CompareGetValueAndGetValues(entity->GetId());
|
||||
GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
|
||||
}
|
||||
|
||||
TEST_F(GradientSignalGetValuesTestsFixture, PerlinGradientComponent_VerifyGetValueAndGetValuesMatch)
|
||||
{
|
||||
auto entity = BuildTestPerlinGradient(TestShapeHalfBounds);
|
||||
CompareGetValueAndGetValues(entity->GetId());
|
||||
GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
|
||||
}
|
||||
|
||||
TEST_F(GradientSignalGetValuesTestsFixture, RandomGradientComponent_VerifyGetValueAndGetValuesMatch)
|
||||
{
|
||||
auto entity = BuildTestRandomGradient(TestShapeHalfBounds);
|
||||
CompareGetValueAndGetValues(entity->GetId());
|
||||
GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
|
||||
}
|
||||
|
||||
TEST_F(GradientSignalGetValuesTestsFixture, ConstantGradientComponent_VerifyGetValueAndGetValuesMatch)
|
||||
{
|
||||
auto entity = BuildTestConstantGradient(TestShapeHalfBounds);
|
||||
CompareGetValueAndGetValues(entity->GetId());
|
||||
GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
|
||||
}
|
||||
|
||||
TEST_F(GradientSignalGetValuesTestsFixture, ShapeAreaFalloffGradientComponent_VerifyGetValueAndGetValuesMatch)
|
||||
{
|
||||
auto entity = BuildTestShapeAreaFalloffGradient(TestShapeHalfBounds);
|
||||
CompareGetValueAndGetValues(entity->GetId());
|
||||
GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
|
||||
}
|
||||
|
||||
TEST_F(GradientSignalGetValuesTestsFixture, DitherGradientComponent_VerifyGetValueAndGetValuesMatch)
|
||||
@@ -98,21 +56,21 @@ namespace UnitTest
|
||||
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
|
||||
|
||||
auto entity = BuildTestDitherGradient(TestShapeHalfBounds, baseEntity->GetId());
|
||||
CompareGetValueAndGetValues(entity->GetId());
|
||||
GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
|
||||
}
|
||||
|
||||
TEST_F(GradientSignalGetValuesTestsFixture, InvertGradientComponent_VerifyGetValueAndGetValuesMatch)
|
||||
{
|
||||
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
|
||||
auto entity = BuildTestInvertGradient(TestShapeHalfBounds, baseEntity->GetId());
|
||||
CompareGetValueAndGetValues(entity->GetId());
|
||||
GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
|
||||
}
|
||||
|
||||
TEST_F(GradientSignalGetValuesTestsFixture, LevelsGradientComponent_VerifyGetValueAndGetValuesMatch)
|
||||
{
|
||||
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
|
||||
auto entity = BuildTestLevelsGradient(TestShapeHalfBounds, baseEntity->GetId());
|
||||
CompareGetValueAndGetValues(entity->GetId());
|
||||
GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
|
||||
}
|
||||
|
||||
TEST_F(GradientSignalGetValuesTestsFixture, MixedGradientComponent_VerifyGetValueAndGetValuesMatch)
|
||||
@@ -120,35 +78,35 @@ namespace UnitTest
|
||||
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
|
||||
auto mixedEntity = BuildTestConstantGradient(TestShapeHalfBounds);
|
||||
auto entity = BuildTestMixedGradient(TestShapeHalfBounds, baseEntity->GetId(), mixedEntity->GetId());
|
||||
CompareGetValueAndGetValues(entity->GetId());
|
||||
GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
|
||||
}
|
||||
|
||||
TEST_F(GradientSignalGetValuesTestsFixture, PosterizeGradientComponent_VerifyGetValueAndGetValuesMatch)
|
||||
{
|
||||
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
|
||||
auto entity = BuildTestPosterizeGradient(TestShapeHalfBounds, baseEntity->GetId());
|
||||
CompareGetValueAndGetValues(entity->GetId());
|
||||
GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
|
||||
}
|
||||
|
||||
TEST_F(GradientSignalGetValuesTestsFixture, ReferenceGradientComponent_VerifyGetValueAndGetValuesMatch)
|
||||
{
|
||||
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
|
||||
auto entity = BuildTestReferenceGradient(TestShapeHalfBounds, baseEntity->GetId());
|
||||
CompareGetValueAndGetValues(entity->GetId());
|
||||
GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
|
||||
}
|
||||
|
||||
TEST_F(GradientSignalGetValuesTestsFixture, SmoothStepGradientComponent_VerifyGetValueAndGetValuesMatch)
|
||||
{
|
||||
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
|
||||
auto entity = BuildTestSmoothStepGradient(TestShapeHalfBounds, baseEntity->GetId());
|
||||
CompareGetValueAndGetValues(entity->GetId());
|
||||
GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
|
||||
}
|
||||
|
||||
TEST_F(GradientSignalGetValuesTestsFixture, ThresholdGradientComponent_VerifyGetValueAndGetValuesMatch)
|
||||
{
|
||||
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
|
||||
auto entity = BuildTestThresholdGradient(TestShapeHalfBounds, baseEntity->GetId());
|
||||
CompareGetValueAndGetValues(entity->GetId());
|
||||
GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
|
||||
}
|
||||
|
||||
TEST_F(GradientSignalGetValuesTestsFixture, SurfaceAltitudeGradientComponent_VerifyGetValueAndGetValuesMatch)
|
||||
@@ -157,7 +115,7 @@ namespace UnitTest
|
||||
CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds)));
|
||||
|
||||
auto entity = BuildTestSurfaceAltitudeGradient(TestShapeHalfBounds);
|
||||
CompareGetValueAndGetValues(entity->GetId());
|
||||
GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
|
||||
}
|
||||
|
||||
TEST_F(GradientSignalGetValuesTestsFixture, SurfaceMaskGradientComponent_VerifyGetValueAndGetValuesMatch)
|
||||
@@ -166,7 +124,7 @@ namespace UnitTest
|
||||
CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds)));
|
||||
|
||||
auto entity = BuildTestSurfaceMaskGradient(TestShapeHalfBounds);
|
||||
CompareGetValueAndGetValues(entity->GetId());
|
||||
GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
|
||||
}
|
||||
|
||||
TEST_F(GradientSignalGetValuesTestsFixture, SurfaceSlopeGradientComponent_VerifyGetValueAndGetValuesMatch)
|
||||
@@ -175,7 +133,7 @@ namespace UnitTest
|
||||
CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds)));
|
||||
|
||||
auto entity = BuildTestSurfaceSlopeGradient(TestShapeHalfBounds);
|
||||
CompareGetValueAndGetValues(entity->GetId());
|
||||
GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* 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/GradientSignalTestHelpers.h>
|
||||
#include <AzCore/Math/Aabb.h>
|
||||
#include <GradientSignal/GradientSampler.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
void GradientSignalTestHelpers::CompareGetValueAndGetValues(AZ::EntityId gradientEntityId, float shapeHalfBounds)
|
||||
{
|
||||
// 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(-shapeHalfBounds), AZ::Vector3(shapeHalfBounds));
|
||||
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_NEAR instead of EXPECT_NEAR 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_NEAR(value, results[positionIndex], 0.000001f);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_BENCHMARK
|
||||
|
||||
void GradientSignalTestHelpers::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 GradientSignalTestHelpers::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 GradientSignalTestHelpers::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 GradientSignalTestHelpers::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 GradientSignalTestHelpers::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 GradientSignalTestHelpers::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.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzTest/AzTest.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
class GradientSignalTestHelpers
|
||||
{
|
||||
public:
|
||||
static void CompareGetValueAndGetValues(AZ::EntityId gradientEntityId, float shapeHalfBounds);
|
||||
|
||||
#ifdef HAVE_BENCHMARK
|
||||
// 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,
|
||||
};
|
||||
|
||||
static void FillQueryPositions(AZStd::vector<AZ::Vector3>& positions, float height, float width);
|
||||
|
||||
static void RunEBusGetValueBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange);
|
||||
static void RunEBusGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange);
|
||||
static void RunSamplerGetValueBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange);
|
||||
static void RunSamplerGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange);
|
||||
static void RunGetValueOrGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId);
|
||||
|
||||
// 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.
|
||||
#ifndef GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F
|
||||
#define GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(Fixture, Func) \
|
||||
BENCHMARK_REGISTER_F(Fixture, Func) \
|
||||
->Args({ GradientSignalTestHelpers::GetValuePermutation::EBUS_GET_VALUE, 1024 }) \
|
||||
->Args({ GradientSignalTestHelpers::GetValuePermutation::EBUS_GET_VALUE, 2048 }) \
|
||||
->Args({ GradientSignalTestHelpers::GetValuePermutation::EBUS_GET_VALUE, 4096 }) \
|
||||
->ArgNames({ "EbusGetValue", "size" }) \
|
||||
->Unit(::benchmark::kMillisecond); \
|
||||
BENCHMARK_REGISTER_F(Fixture, Func) \
|
||||
->Args({ GradientSignalTestHelpers::GetValuePermutation::EBUS_GET_VALUES, 1024 }) \
|
||||
->Args({ GradientSignalTestHelpers::GetValuePermutation::EBUS_GET_VALUES, 2048 }) \
|
||||
->Args({ GradientSignalTestHelpers::GetValuePermutation::EBUS_GET_VALUES, 4096 }) \
|
||||
->ArgNames({ "EbusGetValues", "size" }) \
|
||||
->Unit(::benchmark::kMillisecond); \
|
||||
BENCHMARK_REGISTER_F(Fixture, Func) \
|
||||
->Args({ GradientSignalTestHelpers::GetValuePermutation::SAMPLER_GET_VALUE, 1024 }) \
|
||||
->Args({ GradientSignalTestHelpers::GetValuePermutation::SAMPLER_GET_VALUE, 2048 }) \
|
||||
->Args({ GradientSignalTestHelpers::GetValuePermutation::SAMPLER_GET_VALUE, 4096 }) \
|
||||
->ArgNames({ "SamplerGetValue", "size" }) \
|
||||
->Unit(::benchmark::kMillisecond); \
|
||||
BENCHMARK_REGISTER_F(Fixture, Func) \
|
||||
->Args({ GradientSignalTestHelpers::GetValuePermutation::SAMPLER_GET_VALUES, 1024 }) \
|
||||
->Args({ GradientSignalTestHelpers::GetValuePermutation::SAMPLER_GET_VALUES, 2048 }) \
|
||||
->Args({ GradientSignalTestHelpers::GetValuePermutation::SAMPLER_GET_VALUES, 4096 }) \
|
||||
->ArgNames({ "SamplerGetValues", "size" }) \
|
||||
->Unit(::benchmark::kMillisecond);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@@ -7,6 +7,8 @@
|
||||
#
|
||||
|
||||
set(FILES
|
||||
Tests/GradientSignalTestHelpers.cpp
|
||||
Tests/GradientSignalTestHelpers.h
|
||||
Tests/GradientSignalTestFixtures.cpp
|
||||
Tests/GradientSignalTestFixtures.h
|
||||
Tests/GradientSignalTestMocks.cpp
|
||||
|
||||
Reference in New Issue
Block a user