Merge branch 'development' of https://github.com/aws-lumberyard-dev/o3de into mnaumov/FixingEOOrdering_signofffix
Signed-off-by: Mikhail Naumov <mnaumov@amazon.com>monroegm-disable-blank-issue-2
commit
f599a30fae
@ -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 |
@ -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()
|
||||
@ -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);
|
||||
@ -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
|
||||
)
|
||||
@ -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
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue