From e89ec94c380947ee6dbc5c5eb031888dcce59b18 Mon Sep 17 00:00:00 2001 From: jromnoa <80134229+jromnoa@users.noreply.github.com> Date: Thu, 18 Nov 2021 16:59:35 -0800 Subject: [PATCH 1/8] update CMakeLists.txt in preparation for removing the TestSuite_Main_GPU_Optimized file, add compare_screenshot_to_golden_image function, add hydra_AtomGPU_LightComponentScreenshotsMatch.py hydra script Signed-off-by: jromnoa <80134229+jromnoa@users.noreply.github.com> --- .../Gem/PythonTests/Atom/CMakeLists.txt | 14 - .../PythonTests/Atom/TestSuite_Main_GPU.py | 87 ----- .../Atom/TestSuite_Main_GPU_Optimized.py | 47 ++- .../Atom/atom_utils/atom_component_helper.py | 326 +++++++++--------- ..._AtomGPU_LightComponentScreenshotsMatch.py | 0 5 files changed, 213 insertions(+), 261 deletions(-) create mode 100644 AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_LightComponentScreenshotsMatch.py diff --git a/AutomatedTesting/Gem/PythonTests/Atom/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/Atom/CMakeLists.txt index 87a66c880e..26eb96e7ec 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/Atom/CMakeLists.txt @@ -47,18 +47,4 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_BUILD_TESTS_SUPPORTED) COMPONENT Atom ) - ly_add_pytest( - NAME AutomatedTesting::Atom_TestSuite_Main_GPU_Optimized - TEST_SUITE main - TEST_REQUIRES gpu - TEST_SERIAL - TIMEOUT 1200 - PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main_GPU_Optimized.py - RUNTIME_DEPENDENCIES - AssetProcessor - AutomatedTesting.Assets - Editor - COMPONENT - Atom - ) endif() diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU.py index f0e92c7e3e..690f8aeea5 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU.py @@ -5,10 +5,8 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT """ -import datetime import logging import os -import zipfile import pytest @@ -23,96 +21,11 @@ DEFAULT_SUBFOLDER_PATH = 'user/PythonTests/Automated/Screenshots' TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests") -def golden_images_directory(): - """ - Uses this file location to return the valid location for golden image files. - :return: The path to the golden_images directory, but raises an IOError if the golden_images directory is missing. - """ - current_file_directory = os.path.join(os.path.dirname(__file__)) - golden_images_dir = os.path.join(current_file_directory, 'golden_images') - - if not os.path.exists(golden_images_dir): - raise IOError( - f'golden_images" directory was not found at path "{golden_images_dir}"' - f'Please add a "golden_images" directory inside: "{current_file_directory}"' - ) - - return golden_images_dir - - -def create_screenshots_archive(screenshot_path): - """ - Creates a new zip file archive at archive_path containing all files listed within archive_path. - :param screenshot_path: location containing the files to archive, the zip archive file will also be saved here. - :return: None, but creates a new zip file archive inside path containing all of the files inside archive_path. - """ - files_to_archive = [] - - # Search for .png and .ppm files to add to the zip archive file. - for (folder_name, sub_folders, file_names) in os.walk(screenshot_path): - for file_name in file_names: - if file_name.endswith(".png") or file_name.endswith(".ppm"): - file_path = os.path.join(folder_name, file_name) - files_to_archive.append(file_path) - - # Setup variables for naming the zip archive file. - timestamp = datetime.datetime.now().timestamp() - formatted_timestamp = datetime.datetime.utcfromtimestamp(timestamp).strftime("%Y-%m-%d_%H-%M-%S") - screenshots_file = os.path.join(screenshot_path, f'zip_archive_{formatted_timestamp}.zip') - - # Write all of the valid .png and .ppm files to the archive file. - with zipfile.ZipFile(screenshots_file, 'w', compression=zipfile.ZIP_DEFLATED, allowZip64=True) as zip_archive: - for file_path in files_to_archive: - file_name = os.path.basename(file_path) - zip_archive.write(file_path, file_name) - - @pytest.mark.parametrize("project", ["AutomatedTesting"]) @pytest.mark.parametrize("launcher_platform", ["windows_editor"]) @pytest.mark.parametrize("level", ["Base"]) class TestAllComponentsIndepthTests(object): - @pytest.mark.parametrize("screenshot_name", ["AtomBasicLevelSetup.ppm"]) - @pytest.mark.test_case_id("C34603773") - def test_BasicLevelSetup_SetsUpLevel( - self, request, editor, workspace, project, launcher_platform, level, screenshot_name): - """ - Please review the hydra script run by this test for more specific test info. - Tests that a basic rendering level setup can be created (lighting, meshes, materials, etc.). - """ - # Clear existing test screenshots before starting test. - screenshot_directory = os.path.join(workspace.paths.project(), DEFAULT_SUBFOLDER_PATH) - test_screenshots = [os.path.join(screenshot_directory, screenshot_name)] - file_system.delete(test_screenshots, True, True) - - golden_images = [os.path.join(golden_images_directory(), screenshot_name)] - - level_creation_expected_lines = [ - "Viewport is set to the expected size: True", - "Exited game mode" - ] - unexpected_lines = ["Traceback (most recent call last):"] - - hydra.launch_and_validate_results( - request, - TEST_DIRECTORY, - editor, - "hydra_GPUTest_BasicLevelSetup.py", - timeout=180, - expected_lines=level_creation_expected_lines, - unexpected_lines=unexpected_lines, - halt_on_unexpected=True, - cfg_args=[level], - null_renderer=False, - ) - - similarity_threshold = 0.99 - for test_screenshot, golden_image in zip(test_screenshots, golden_images): - screenshot_comparison_result = compare_screenshot_similarity( - test_screenshot, golden_image, similarity_threshold, True, screenshot_directory) - if screenshot_comparison_result != "Screenshots match": - raise Exception(f"Screenshot test failed: {screenshot_comparison_result}") - @pytest.mark.test_case_id("C34525095") def test_LightComponent_ScreenshotMatchesGoldenImage( self, request, editor, workspace, project, launcher_platform, level): diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU_Optimized.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU_Optimized.py index 568768e12e..2cb5828958 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU_Optimized.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU_Optimized.py @@ -11,12 +11,12 @@ import pytest import ly_test_tools.environment.file_system as file_system from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite from ly_test_tools.image.screenshot_compare_qssim import qssim as compare_screenshots -from .atom_utils.atom_component_helper import create_screenshots_archive, golden_images_directory +from .atom_utils.atom_component_helper import ( + create_screenshots_archive, compare_screenshot_to_golden_image, golden_images_directory) DEFAULT_SUBFOLDER_PATH = 'user/PythonTests/Automated/Screenshots' -@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.") @pytest.mark.parametrize("project", ["AutomatedTesting"]) @pytest.mark.parametrize("launcher_platform", ['windows_editor']) class TestAutomation(EditorTestSuite): @@ -36,9 +36,44 @@ class TestAutomation(EditorTestSuite): test_screenshots = [os.path.join(screenshot_directory, self.screenshot_name)] file_system.delete(test_screenshots, True, True) + golden_images = [os.path.join(golden_images_directory(), screenshot_name)] + from Atom.tests import hydra_AtomGPU_BasicLevelSetup as test_module - golden_images = [os.path.join(golden_images_directory(), screenshot_name)] - for test_screenshot, golden_screenshot in zip(test_screenshots, golden_images): - compare_screenshots(test_screenshot, golden_screenshot) - create_screenshots_archive(screenshot_directory) + assert compare_screenshot_to_golden_image(screenshot_directory, test_screenshots, golden_images, 0.99) is True + + @pytest.mark.test_case_id("C34525095") + class AtomGPU_LightComponent_ScreenshotMatchesGoldenImage(EditorSharedTest): + use_null_renderer = False # Default is True + screenshot_names = [ + "AreaLight_1.ppm", + "AreaLight_2.ppm", + "AreaLight_3.ppm", + "AreaLight_4.ppm", + "AreaLight_5.ppm", + "SpotLight_1.ppm", + "SpotLight_2.ppm", + "SpotLight_3.ppm", + "SpotLight_4.ppm", + "SpotLight_5.ppm", + "SpotLight_6.ppm", + ] + test_screenshots = [] # Gets set by setup() + screenshot_directory = "" # Gets set by setup() + + # Clear existing test screenshots before starting test. + def setup(self, workspace): + screenshot_directory = os.path.join(workspace.paths.project(), DEFAULT_SUBFOLDER_PATH) + for screenshot in self.screenshot_names: + screenshot_path = os.path.join(screenshot_directory, screenshot) + self.test_screenshots.append(screenshot_path) + file_system.delete(self.test_screenshots, True, True) + + golden_images = [] + for golden_image in screenshot_names: + golden_image_path = os.path.join(golden_images_directory(), golden_image) + golden_images.append(golden_image_path) + + from Atom.tests import hydra_AtomGPU_LightComponentScreenshotsMatch as test_module + + assert compare_screenshot_to_golden_image(screenshot_directory, test_screenshots, golden_images, 0.99) is True diff --git a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py index 9f37873557..28ae72c2b3 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py @@ -93,161 +93,179 @@ def compare_screenshot_similarity( return result -def create_basic_atom_level(level_name): +def compare_screenshot_to_golden_image( + screenshot_directory, test_screenshots, golden_images, similarity_threshold=0.99): """ - Creates a new level inside the Editor matching level_name & adds the following: - 1. "default_level" entity to hold all other entities. - 2. Adds Grid, Global Skylight (IBL), ground Mesh, Directional Light, Sphere w/ material+mesh, & Camera components. - 3. Each of these components has its settings tweaked slightly to match the ideal scene to test Atom rendering. - :param level_name: name of the level to create and apply this basic setup to. - :return: None + Compares a list of test_screenshots to a list of golden_images and return True if they match within the + similarity threshold set. Otherwise, it will raise ImageComparisonTestFailure with a failure message. + :param screenshot_directory: path to the directory containing screenshots for creating .zip archives. + :param test_screenshots: list of test screenshot path strings. + :param golden_images: list of golden image path strings. + :param similarity_threshold: float threshold tolerance to set when comparing screenshots to golden images. """ - import azlmbr.asset as asset - import azlmbr.bus as bus - import azlmbr.camera as camera - import azlmbr.editor as editor - import azlmbr.entity as entity - import azlmbr.legacy.general as general - import azlmbr.math as math - import azlmbr.object + for test_screenshot, golden_image in zip(test_screenshots, golden_images): + screenshot_comparison_result = compare_screenshot_similarity( + test_screenshot, golden_image, similarity_threshold, True, screenshot_directory) + if screenshot_comparison_result != "Screenshots match": + raise ImageComparisonTestFailure(f"Screenshot test failed: {screenshot_comparison_result}") - import editor_python_test_tools.hydra_editor_utils as hydra - from editor_python_test_tools.editor_test_helper import EditorTestHelper + return True - helper = EditorTestHelper(log_prefix="Atom_EditorTestHelper") - - # Wait for Editor idle loop before executing Python hydra scripts. - general.idle_enable(True) - - # Basic setup for opened level. - helper.open_level(level_name="Base") - general.idle_wait(1.0) - general.update_viewport() - general.idle_wait(0.5) # half a second is more than enough for updating the viewport. - - # Close out problematic windows, FPS meters, and anti-aliasing. - if general.is_helpers_shown(): # Turn off the helper gizmos if visible - general.toggle_helpers() - general.idle_wait(1.0) - if general.is_pane_visible("Error Report"): # Close Error Report windows that block focus. - general.close_pane("Error Report") - if general.is_pane_visible("Error Log"): # Close Error Log windows that block focus. - general.close_pane("Error Log") - general.idle_wait(1.0) - general.run_console("r_displayInfo=0") - general.idle_wait(1.0) - - # Delete all existing entities & create default_level entity - search_filter = azlmbr.entity.SearchFilter() - all_entities = entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter) - editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntities", all_entities) - default_level = hydra.Entity("default_level") - default_position = math.Vector3(0.0, 0.0, 0.0) - default_level.create_entity(default_position, ["Grid"]) - default_level.get_set_test(0, "Controller|Configuration|Secondary Grid Spacing", 1.0) - - # Set the viewport up correctly after adding the parent default_level entity. - screen_width = 1280 - screen_height = 720 - degree_radian_factor = 0.0174533 # Used by "Rotation" property for the Transform component. - general.set_viewport_size(screen_width, screen_height) - general.update_viewport() - helper.wait_for_condition( - function=lambda: helper.isclose(a=general.get_viewport_size().x, b=screen_width, rel_tol=0.1) - and helper.isclose(a=general.get_viewport_size().y, b=screen_height, rel_tol=0.1), - timeout_in_seconds=4.0 - ) - result = helper.isclose(a=general.get_viewport_size().x, b=screen_width, rel_tol=0.1) and helper.isclose( - a=general.get_viewport_size().y, b=screen_height, rel_tol=0.1) - general.log(general.get_viewport_size().x) - general.log(general.get_viewport_size().y) - general.log(general.get_viewport_size().z) - general.log(f"Viewport is set to the expected size: {result}") - general.log("Basic level created") - general.run_console("r_DisplayInfo = 0") - - # Create global_skylight entity and set the properties - global_skylight = hydra.Entity("global_skylight") - global_skylight.create_entity( - entity_position=default_position, - components=["HDRi Skybox", "Global Skylight (IBL)"], - parent_id=default_level.id) - global_skylight_asset_path = os.path.join("LightingPresets", "default_iblskyboxcm.exr.streamingimage") - global_skylight_asset_value = asset.AssetCatalogRequestBus( - bus.Broadcast, "GetAssetIdByPath", global_skylight_asset_path, math.Uuid(), False) - global_skylight.get_set_test(0, "Controller|Configuration|Cubemap Texture", global_skylight_asset_value) - global_skylight.get_set_test(1, "Controller|Configuration|Diffuse Image", global_skylight_asset_value) - global_skylight.get_set_test(1, "Controller|Configuration|Specular Image", global_skylight_asset_value) - - # Create ground_plane entity and set the properties - ground_plane = hydra.Entity("ground_plane") - ground_plane.create_entity( - entity_position=default_position, - components=["Material"], - parent_id=default_level.id) - azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalUniformScale", ground_plane.id, 32.0) - - # Work around to add the correct Atom Mesh component and asset. - mesh_type_id = azlmbr.globals.property.EditorMeshComponentTypeId - ground_plane.components.append( - editor.EditorComponentAPIBus( - bus.Broadcast, "AddComponentsOfType", ground_plane.id, [mesh_type_id] - ).GetValue()[0] - ) - ground_plane_mesh_asset_path = os.path.join("TestData", "Objects", "plane.azmodel") - ground_plane_mesh_asset_value = asset.AssetCatalogRequestBus( - bus.Broadcast, "GetAssetIdByPath", ground_plane_mesh_asset_path, math.Uuid(), False) - ground_plane.get_set_test(1, "Controller|Configuration|Mesh Asset", ground_plane_mesh_asset_value) - - # Add Atom Material component and asset. - ground_plane_material_asset_path = os.path.join("Materials", "Presets", "PBR", "metal_chrome.azmaterial") - ground_plane_material_asset_value = asset.AssetCatalogRequestBus( - bus.Broadcast, "GetAssetIdByPath", ground_plane_material_asset_path, math.Uuid(), False) - ground_plane.get_set_test(0, "Default Material|Material Asset", ground_plane_material_asset_value) - - # Create directional_light entity and set the properties - directional_light = hydra.Entity("directional_light") - directional_light.create_entity( - entity_position=math.Vector3(0.0, 0.0, 10.0), - components=["Directional Light"], - parent_id=default_level.id) - directional_light_rotation = math.Vector3(degree_radian_factor * -90.0, 0.0, 0.0) - azlmbr.components.TransformBus( - azlmbr.bus.Event, "SetLocalRotation", directional_light.id, directional_light_rotation) - - # Create sphere entity and set the properties - sphere_entity = hydra.Entity("sphere") - sphere_entity.create_entity( - entity_position=math.Vector3(0.0, 0.0, 1.0), - components=["Material"], - parent_id=default_level.id) - - # Work around to add the correct Atom Mesh component and asset. - sphere_entity.components.append( - editor.EditorComponentAPIBus( - bus.Broadcast, "AddComponentsOfType", sphere_entity.id, [mesh_type_id] - ).GetValue()[0] - ) - sphere_mesh_asset_path = os.path.join("Models", "sphere.azmodel") - sphere_mesh_asset_value = asset.AssetCatalogRequestBus( - bus.Broadcast, "GetAssetIdByPath", sphere_mesh_asset_path, math.Uuid(), False) - sphere_entity.get_set_test(1, "Controller|Configuration|Mesh Asset", sphere_mesh_asset_value) - - # Add Atom Material component and asset. - sphere_material_asset_path = os.path.join("Materials", "Presets", "PBR", "metal_brass_polished.azmaterial") - sphere_material_asset_value = asset.AssetCatalogRequestBus( - bus.Broadcast, "GetAssetIdByPath", sphere_material_asset_path, math.Uuid(), False) - sphere_entity.get_set_test(0, "Default Material|Material Asset", sphere_material_asset_value) - - # Create camera component and set the properties - camera_entity = hydra.Entity("camera") - camera_entity.create_entity( - entity_position=math.Vector3(5.5, -12.0, 9.0), - components=["Camera"], - parent_id=default_level.id) - rotation = math.Vector3( - degree_radian_factor * -27.0, degree_radian_factor * -12.0, degree_radian_factor * 25.0 - ) - azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", camera_entity.id, rotation) - camera_entity.get_set_test(0, "Controller|Configuration|Field of view", 60.0) - camera.EditorCameraViewRequestBus(azlmbr.bus.Event, "ToggleCameraAsActiveView", camera_entity.id) +# def create_basic_atom_level(level_name): +# """ +# Creates a new level inside the Editor matching level_name & adds the following: +# 1. "default_level" entity to hold all other entities. +# 2. Adds Grid, Global Skylight (IBL), ground Mesh, Directional Light, Sphere w/ material+mesh, & Camera components. +# 3. Each of these components has its settings tweaked slightly to match the ideal scene to test Atom rendering. +# :param level_name: name of the level to create and apply this basic setup to. +# :return: None +# """ +# import azlmbr.asset as asset +# import azlmbr.bus as bus +# import azlmbr.camera as camera +# import azlmbr.editor as editor +# import azlmbr.entity as entity +# import azlmbr.legacy.general as general +# import azlmbr.math as math +# import azlmbr.object +# +# import editor_python_test_tools.hydra_editor_utils as hydra +# from editor_python_test_tools.editor_test_helper import EditorTestHelper +# +# helper = EditorTestHelper(log_prefix="Atom_EditorTestHelper") +# +# # Wait for Editor idle loop before executing Python hydra scripts. +# general.idle_enable(True) +# +# # Basic setup for opened level. +# helper.open_level(level_name="Base") +# general.idle_wait(1.0) +# general.update_viewport() +# general.idle_wait(0.5) # half a second is more than enough for updating the viewport. +# +# # Close out problematic windows, FPS meters, and anti-aliasing. +# if general.is_helpers_shown(): # Turn off the helper gizmos if visible +# general.toggle_helpers() +# general.idle_wait(1.0) +# if general.is_pane_visible("Error Report"): # Close Error Report windows that block focus. +# general.close_pane("Error Report") +# if general.is_pane_visible("Error Log"): # Close Error Log windows that block focus. +# general.close_pane("Error Log") +# general.idle_wait(1.0) +# general.run_console("r_displayInfo=0") +# general.idle_wait(1.0) +# +# # Delete all existing entities & create default_level entity +# search_filter = azlmbr.entity.SearchFilter() +# all_entities = entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter) +# editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntities", all_entities) +# default_level = hydra.Entity("default_level") +# default_position = math.Vector3(0.0, 0.0, 0.0) +# default_level.create_entity(default_position, ["Grid"]) +# default_level.get_set_test(0, "Controller|Configuration|Secondary Grid Spacing", 1.0) +# +# # Set the viewport up correctly after adding the parent default_level entity. +# screen_width = 1280 +# screen_height = 720 +# degree_radian_factor = 0.0174533 # Used by "Rotation" property for the Transform component. +# general.set_viewport_size(screen_width, screen_height) +# general.update_viewport() +# helper.wait_for_condition( +# function=lambda: helper.isclose(a=general.get_viewport_size().x, b=screen_width, rel_tol=0.1) +# and helper.isclose(a=general.get_viewport_size().y, b=screen_height, rel_tol=0.1), +# timeout_in_seconds=4.0 +# ) +# result = helper.isclose(a=general.get_viewport_size().x, b=screen_width, rel_tol=0.1) and helper.isclose( +# a=general.get_viewport_size().y, b=screen_height, rel_tol=0.1) +# general.log(general.get_viewport_size().x) +# general.log(general.get_viewport_size().y) +# general.log(general.get_viewport_size().z) +# general.log(f"Viewport is set to the expected size: {result}") +# general.log("Basic level created") +# general.run_console("r_DisplayInfo = 0") +# +# # Create global_skylight entity and set the properties +# global_skylight = hydra.Entity("global_skylight") +# global_skylight.create_entity( +# entity_position=default_position, +# components=["HDRi Skybox", "Global Skylight (IBL)"], +# parent_id=default_level.id) +# global_skylight_asset_path = os.path.join("LightingPresets", "default_iblskyboxcm.exr.streamingimage") +# global_skylight_asset_value = asset.AssetCatalogRequestBus( +# bus.Broadcast, "GetAssetIdByPath", global_skylight_asset_path, math.Uuid(), False) +# global_skylight.get_set_test(0, "Controller|Configuration|Cubemap Texture", global_skylight_asset_value) +# global_skylight.get_set_test(1, "Controller|Configuration|Diffuse Image", global_skylight_asset_value) +# global_skylight.get_set_test(1, "Controller|Configuration|Specular Image", global_skylight_asset_value) +# +# # Create ground_plane entity and set the properties +# ground_plane = hydra.Entity("ground_plane") +# ground_plane.create_entity( +# entity_position=default_position, +# components=["Material"], +# parent_id=default_level.id) +# azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalUniformScale", ground_plane.id, 32.0) +# +# # Work around to add the correct Atom Mesh component and asset. +# mesh_type_id = azlmbr.globals.property.EditorMeshComponentTypeId +# ground_plane.components.append( +# editor.EditorComponentAPIBus( +# bus.Broadcast, "AddComponentsOfType", ground_plane.id, [mesh_type_id] +# ).GetValue()[0] +# ) +# ground_plane_mesh_asset_path = os.path.join("TestData", "Objects", "plane.azmodel") +# ground_plane_mesh_asset_value = asset.AssetCatalogRequestBus( +# bus.Broadcast, "GetAssetIdByPath", ground_plane_mesh_asset_path, math.Uuid(), False) +# ground_plane.get_set_test(1, "Controller|Configuration|Mesh Asset", ground_plane_mesh_asset_value) +# +# # Add Atom Material component and asset. +# ground_plane_material_asset_path = os.path.join("Materials", "Presets", "PBR", "metal_chrome.azmaterial") +# ground_plane_material_asset_value = asset.AssetCatalogRequestBus( +# bus.Broadcast, "GetAssetIdByPath", ground_plane_material_asset_path, math.Uuid(), False) +# ground_plane.get_set_test(0, "Default Material|Material Asset", ground_plane_material_asset_value) +# +# # Create directional_light entity and set the properties +# directional_light = hydra.Entity("directional_light") +# directional_light.create_entity( +# entity_position=math.Vector3(0.0, 0.0, 10.0), +# components=["Directional Light"], +# parent_id=default_level.id) +# directional_light_rotation = math.Vector3(degree_radian_factor * -90.0, 0.0, 0.0) +# azlmbr.components.TransformBus( +# azlmbr.bus.Event, "SetLocalRotation", directional_light.id, directional_light_rotation) +# +# # Create sphere entity and set the properties +# sphere_entity = hydra.Entity("sphere") +# sphere_entity.create_entity( +# entity_position=math.Vector3(0.0, 0.0, 1.0), +# components=["Material"], +# parent_id=default_level.id) +# +# # Work around to add the correct Atom Mesh component and asset. +# sphere_entity.components.append( +# editor.EditorComponentAPIBus( +# bus.Broadcast, "AddComponentsOfType", sphere_entity.id, [mesh_type_id] +# ).GetValue()[0] +# ) +# sphere_mesh_asset_path = os.path.join("Models", "sphere.azmodel") +# sphere_mesh_asset_value = asset.AssetCatalogRequestBus( +# bus.Broadcast, "GetAssetIdByPath", sphere_mesh_asset_path, math.Uuid(), False) +# sphere_entity.get_set_test(1, "Controller|Configuration|Mesh Asset", sphere_mesh_asset_value) +# +# # Add Atom Material component and asset. +# sphere_material_asset_path = os.path.join("Materials", "Presets", "PBR", "metal_brass_polished.azmaterial") +# sphere_material_asset_value = asset.AssetCatalogRequestBus( +# bus.Broadcast, "GetAssetIdByPath", sphere_material_asset_path, math.Uuid(), False) +# sphere_entity.get_set_test(0, "Default Material|Material Asset", sphere_material_asset_value) +# +# # Create camera component and set the properties +# camera_entity = hydra.Entity("camera") +# camera_entity.create_entity( +# entity_position=math.Vector3(5.5, -12.0, 9.0), +# components=["Camera"], +# parent_id=default_level.id) +# rotation = math.Vector3( +# degree_radian_factor * -27.0, degree_radian_factor * -12.0, degree_radian_factor * 25.0 +# ) +# azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", camera_entity.id, rotation) +# camera_entity.get_set_test(0, "Controller|Configuration|Field of view", 60.0) +# camera.EditorCameraViewRequestBus(azlmbr.bus.Event, "ToggleCameraAsActiveView", camera_entity.id) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_LightComponentScreenshotsMatch.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_LightComponentScreenshotsMatch.py new file mode 100644 index 0000000000..e69de29bb2 From ddd8dc65688732ac4a05540601abe4dd39c49e23 Mon Sep 17 00:00:00 2001 From: jromnoa <80134229+jromnoa@users.noreply.github.com> Date: Wed, 24 Nov 2021 15:49:34 -0800 Subject: [PATCH 2/8] remove the optimized GPU test file and replace the existing GPU test file with the optimized tests, update atom_constants.py for the new Light component properties, add area light test script, still need to add spot light test script to fully finish this task Signed-off-by: jromnoa <80134229+jromnoa@users.noreply.github.com> --- .../PythonTests/Atom/TestSuite_Main_GPU.py | 142 ++++----- .../Atom/TestSuite_Main_GPU_Optimized.py | 81 ----- .../Atom/atom_utils/atom_component_helper.py | 280 ++++++++---------- .../Atom/atom_utils/atom_constants.py | 3 + .../hydra_AtomGPU_AreaLightScreenshotTest.py | 217 ++++++++++++++ .../tests/hydra_AtomGPU_BasicLevelSetup.py | 23 +- ..._AtomGPU_LightComponentScreenshotsMatch.py | 0 .../hydra_AtomGPU_SpotLightScreenshotTest.py | 71 +++++ 8 files changed, 485 insertions(+), 332 deletions(-) delete mode 100644 AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU_Optimized.py create mode 100644 AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_AreaLightScreenshotTest.py delete mode 100644 AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_LightComponentScreenshotsMatch.py create mode 100644 AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU.py index a9b49b8107..14d850245c 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU.py @@ -4,83 +4,82 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT """ - import logging import os import pytest +import editor_python_test_tools.hydra_test_utils as hydra import ly_test_tools.environment.file_system as file_system from ly_test_tools.benchmark.data_aggregator import BenchmarkDataAggregator +from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite +from Atom.atom_utils.atom_component_helper import compare_screenshot_to_golden_image, golden_images_directory -import editor_python_test_tools.hydra_test_utils as hydra -from .atom_utils.atom_component_helper import compare_screenshot_similarity, ImageComparisonTestFailure - -logger = logging.getLogger(__name__) DEFAULT_SUBFOLDER_PATH = 'user/PythonTests/Automated/Screenshots' -TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests") +logger = logging.getLogger(__name__) @pytest.mark.parametrize("project", ["AutomatedTesting"]) -@pytest.mark.parametrize("launcher_platform", ["windows_editor"]) -@pytest.mark.parametrize("level", ["Base"]) -class TestAllComponentsIndepthTests(object): +@pytest.mark.parametrize("launcher_platform", ['windows_editor']) +class TestAutomation(EditorTestSuite): + # Remove -autotest_mode from global_extra_cmdline_args since we need rendering for these tests. + global_extra_cmdline_args = ["-BatchMode"] # Default is ["-BatchMode", "-autotest_mode"] + + enable_prefab_system = False - @pytest.mark.parametrize("screenshot_name", ["AtomBasicLevelSetup.ppm"]) @pytest.mark.test_case_id("C34603773") - def test_BasicLevelSetup_SetsUpLevel( - self, request, editor, workspace, project, launcher_platform, level, screenshot_name): - """ - Please review the hydra script run by this test for more specific test info. - Tests that a basic rendering level setup can be created (lighting, meshes, materials, etc.). - """ + class AtomGPU_BasicLevelSetup_SetsUpLevel(EditorSharedTest): + use_null_renderer = False # Default is True + screenshot_name = "AtomBasicLevelSetup.ppm" + test_screenshots = [] # Gets set by setup() + screenshot_directory = "" # Gets set by setup() + # Clear existing test screenshots before starting test. - screenshot_directory = os.path.join(workspace.paths.project(), DEFAULT_SUBFOLDER_PATH) - test_screenshots = [os.path.join(screenshot_directory, screenshot_name)] - file_system.delete(test_screenshots, True, True) + def setup(self, workspace): + screenshot_directory = os.path.join(workspace.paths.project(), DEFAULT_SUBFOLDER_PATH) + test_screenshots = [os.path.join(screenshot_directory, self.screenshot_name)] + file_system.delete(test_screenshots, True, True) golden_images = [os.path.join(golden_images_directory(), screenshot_name)] - level_creation_expected_lines = [ - "Viewport is set to the expected size: True", - "Exited game mode" - ] - unexpected_lines = ["Traceback (most recent call last):"] + from Atom.tests import hydra_AtomGPU_BasicLevelSetup as test_module - hydra.launch_and_validate_results( - request, - TEST_DIRECTORY, - editor, - "hydra_GPUTest_BasicLevelSetup.py", - timeout=180, - expected_lines=level_creation_expected_lines, - unexpected_lines=unexpected_lines, - halt_on_unexpected=True, - cfg_args=[level], - null_renderer=False, - enable_prefab_system=False, - ) - - similarity_threshold = 0.99 - for test_screenshot, golden_image in zip(test_screenshots, golden_images): - screenshot_comparison_result = compare_screenshot_similarity( - test_screenshot, golden_image, similarity_threshold, True, screenshot_directory) - if screenshot_comparison_result != "Screenshots match": - raise Exception(f"Screenshot test failed: {screenshot_comparison_result}") + assert compare_screenshot_to_golden_image(screenshot_directory, test_screenshots, golden_images, 0.99) is True @pytest.mark.test_case_id("C34525095") - def test_LightComponent_ScreenshotMatchesGoldenImage( - 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 screenshots in a rendered level appear the same as the golden images. - """ + class AtomGPU_LightComponent_AreaLightScreenshotsMatchGoldenImages(EditorSharedTest): + use_null_renderer = False # Default is True screenshot_names = [ "AreaLight_1.ppm", "AreaLight_2.ppm", "AreaLight_3.ppm", "AreaLight_4.ppm", "AreaLight_5.ppm", + ] + test_screenshots = [] # Gets set by setup() + screenshot_directory = "" # Gets set by setup() + + # Clear existing test screenshots before starting test. + def setup(self, workspace): + screenshot_directory = os.path.join(workspace.paths.project(), DEFAULT_SUBFOLDER_PATH) + for screenshot in self.screenshot_names: + screenshot_path = os.path.join(screenshot_directory, screenshot) + self.test_screenshots.append(screenshot_path) + file_system.delete(self.test_screenshots, True, True) + + golden_images = [] + for golden_image in screenshot_names: + golden_image_path = os.path.join(golden_images_directory(), golden_image) + golden_images.append(golden_image_path) + + from Atom.tests import hydra_AtomGPU_AreaLightScreenshotTest as test_module + + assert compare_screenshot_to_golden_image(screenshot_directory, test_screenshots, golden_images, 0.99) is True + + @pytest.mark.test_case_id("C34525110") + class AtomGPU_LightComponent_SpotLightScreenshotsMatchGoldenImages(EditorSharedTest): + use_null_renderer = False # Default is True + screenshot_names = [ "SpotLight_1.ppm", "SpotLight_2.ppm", "SpotLight_3.ppm", @@ -88,40 +87,25 @@ class TestAllComponentsIndepthTests(object): "SpotLight_5.ppm", "SpotLight_6.ppm", ] - screenshot_directory = os.path.join(workspace.paths.project(), DEFAULT_SUBFOLDER_PATH) - test_screenshots = [] - for screenshot in screenshot_names: - screenshot_path = os.path.join(screenshot_directory, screenshot) - test_screenshots.append(screenshot_path) - file_system.delete(test_screenshots, True, True) + test_screenshots = [] # Gets set by setup() + screenshot_directory = "" # Gets set by setup() + + # Clear existing test screenshots before starting test. + def setup(self, workspace): + screenshot_directory = os.path.join(workspace.paths.project(), DEFAULT_SUBFOLDER_PATH) + for screenshot in self.screenshot_names: + screenshot_path = os.path.join(screenshot_directory, screenshot) + self.test_screenshots.append(screenshot_path) + file_system.delete(self.test_screenshots, True, True) golden_images = [] for golden_image in screenshot_names: golden_image_path = os.path.join(golden_images_directory(), golden_image) golden_images.append(golden_image_path) - expected_lines = ["spot_light Controller|Configuration|Shadows|Shadowmap size: SUCCESS"] - unexpected_lines = ["Traceback (most recent call last):"] - hydra.launch_and_validate_results( - request, - TEST_DIRECTORY, - editor, - "hydra_GPUTest_LightComponent.py", - timeout=180, - expected_lines=expected_lines, - unexpected_lines=unexpected_lines, - halt_on_unexpected=True, - cfg_args=[level], - null_renderer=False, - enable_prefab_system=False, - ) + from Atom.tests import hydra_AtomGPU_SpotLightScreenshotTest as test_module - similarity_threshold = 0.99 - for test_screenshot, golden_image in zip(test_screenshots, golden_images): - screenshot_comparison_result = compare_screenshot_similarity( - test_screenshot, golden_image, similarity_threshold, True, screenshot_directory) - if screenshot_comparison_result != "Screenshots match": - raise ImageComparisonTestFailure(f"Screenshot test failed: {screenshot_comparison_result}") + assert compare_screenshot_to_golden_image(screenshot_directory, test_screenshots, golden_images, 0.99) is True @pytest.mark.parametrize('rhi', ['dx12', 'vulkan']) @@ -152,7 +136,7 @@ class TestPerformanceBenchmarkSuite(object): hydra.launch_and_validate_results( request, - TEST_DIRECTORY, + os.path.join(os.path.dirname(__file__), "tests"), editor, "hydra_GPUTest_AtomFeatureIntegrationBenchmark.py", timeout=600, @@ -189,7 +173,7 @@ class TestMaterialEditor(object): hydra.launch_and_validate_results( request, - TEST_DIRECTORY, + os.path.join(os.path.dirname(__file__), "tests"), generic_launcher, editor_script="", run_python="--runpython", diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU_Optimized.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU_Optimized.py deleted file mode 100644 index afd181b849..0000000000 --- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU_Optimized.py +++ /dev/null @@ -1,81 +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 pytest - -import ly_test_tools.environment.file_system as file_system -from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite -from ly_test_tools.image.screenshot_compare_qssim import qssim as compare_screenshots -from .atom_utils.atom_component_helper import ( - create_screenshots_archive, compare_screenshot_to_golden_image, golden_images_directory) - -DEFAULT_SUBFOLDER_PATH = 'user/PythonTests/Automated/Screenshots' - - -@pytest.mark.parametrize("project", ["AutomatedTesting"]) -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) -class TestAutomation(EditorTestSuite): - # Remove -autotest_mode from global_extra_cmdline_args since we need rendering for these tests. - global_extra_cmdline_args = ["-BatchMode"] # Default is ["-BatchMode", "-autotest_mode"] - - enable_prefab_system = False - - @pytest.mark.test_case_id("C34603773") - class AtomGPU_BasicLevelSetup_SetsUpLevel(EditorSharedTest): - use_null_renderer = False # Default is True - screenshot_name = "AtomBasicLevelSetup.ppm" - test_screenshots = [] # Gets set by setup() - screenshot_directory = "" # Gets set by setup() - - # Clear existing test screenshots before starting test. - def setup(self, workspace): - screenshot_directory = os.path.join(workspace.paths.project(), DEFAULT_SUBFOLDER_PATH) - test_screenshots = [os.path.join(screenshot_directory, self.screenshot_name)] - file_system.delete(test_screenshots, True, True) - - golden_images = [os.path.join(golden_images_directory(), screenshot_name)] - - from Atom.tests import hydra_AtomGPU_BasicLevelSetup as test_module - - assert compare_screenshot_to_golden_image(screenshot_directory, test_screenshots, golden_images, 0.99) is True - - @pytest.mark.test_case_id("C34525095") - class AtomGPU_LightComponent_ScreenshotMatchesGoldenImage(EditorSharedTest): - use_null_renderer = False # Default is True - screenshot_names = [ - "AreaLight_1.ppm", - "AreaLight_2.ppm", - "AreaLight_3.ppm", - "AreaLight_4.ppm", - "AreaLight_5.ppm", - "SpotLight_1.ppm", - "SpotLight_2.ppm", - "SpotLight_3.ppm", - "SpotLight_4.ppm", - "SpotLight_5.ppm", - "SpotLight_6.ppm", - ] - test_screenshots = [] # Gets set by setup() - screenshot_directory = "" # Gets set by setup() - - # Clear existing test screenshots before starting test. - def setup(self, workspace): - screenshot_directory = os.path.join(workspace.paths.project(), DEFAULT_SUBFOLDER_PATH) - for screenshot in self.screenshot_names: - screenshot_path = os.path.join(screenshot_directory, screenshot) - self.test_screenshots.append(screenshot_path) - file_system.delete(self.test_screenshots, True, True) - - golden_images = [] - for golden_image in screenshot_names: - golden_image_path = os.path.join(golden_images_directory(), golden_image) - golden_images.append(golden_image_path) - - from Atom.tests import hydra_AtomGPU_LightComponentScreenshotsMatch as test_module - - assert compare_screenshot_to_golden_image(screenshot_directory, test_screenshots, golden_images, 0.99) is True diff --git a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py index 28ae72c2b3..6212ba4314 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py @@ -111,161 +111,125 @@ def compare_screenshot_to_golden_image( return True -# def create_basic_atom_level(level_name): -# """ -# Creates a new level inside the Editor matching level_name & adds the following: -# 1. "default_level" entity to hold all other entities. -# 2. Adds Grid, Global Skylight (IBL), ground Mesh, Directional Light, Sphere w/ material+mesh, & Camera components. -# 3. Each of these components has its settings tweaked slightly to match the ideal scene to test Atom rendering. -# :param level_name: name of the level to create and apply this basic setup to. -# :return: None -# """ -# import azlmbr.asset as asset -# import azlmbr.bus as bus -# import azlmbr.camera as camera -# import azlmbr.editor as editor -# import azlmbr.entity as entity -# import azlmbr.legacy.general as general -# import azlmbr.math as math -# import azlmbr.object -# -# import editor_python_test_tools.hydra_editor_utils as hydra -# from editor_python_test_tools.editor_test_helper import EditorTestHelper -# -# helper = EditorTestHelper(log_prefix="Atom_EditorTestHelper") -# -# # Wait for Editor idle loop before executing Python hydra scripts. -# general.idle_enable(True) -# -# # Basic setup for opened level. -# helper.open_level(level_name="Base") -# general.idle_wait(1.0) -# general.update_viewport() -# general.idle_wait(0.5) # half a second is more than enough for updating the viewport. -# -# # Close out problematic windows, FPS meters, and anti-aliasing. -# if general.is_helpers_shown(): # Turn off the helper gizmos if visible -# general.toggle_helpers() -# general.idle_wait(1.0) -# if general.is_pane_visible("Error Report"): # Close Error Report windows that block focus. -# general.close_pane("Error Report") -# if general.is_pane_visible("Error Log"): # Close Error Log windows that block focus. -# general.close_pane("Error Log") -# general.idle_wait(1.0) -# general.run_console("r_displayInfo=0") -# general.idle_wait(1.0) -# -# # Delete all existing entities & create default_level entity -# search_filter = azlmbr.entity.SearchFilter() -# all_entities = entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter) -# editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntities", all_entities) -# default_level = hydra.Entity("default_level") -# default_position = math.Vector3(0.0, 0.0, 0.0) -# default_level.create_entity(default_position, ["Grid"]) -# default_level.get_set_test(0, "Controller|Configuration|Secondary Grid Spacing", 1.0) -# -# # Set the viewport up correctly after adding the parent default_level entity. -# screen_width = 1280 -# screen_height = 720 -# degree_radian_factor = 0.0174533 # Used by "Rotation" property for the Transform component. -# general.set_viewport_size(screen_width, screen_height) -# general.update_viewport() -# helper.wait_for_condition( -# function=lambda: helper.isclose(a=general.get_viewport_size().x, b=screen_width, rel_tol=0.1) -# and helper.isclose(a=general.get_viewport_size().y, b=screen_height, rel_tol=0.1), -# timeout_in_seconds=4.0 -# ) -# result = helper.isclose(a=general.get_viewport_size().x, b=screen_width, rel_tol=0.1) and helper.isclose( -# a=general.get_viewport_size().y, b=screen_height, rel_tol=0.1) -# general.log(general.get_viewport_size().x) -# general.log(general.get_viewport_size().y) -# general.log(general.get_viewport_size().z) -# general.log(f"Viewport is set to the expected size: {result}") -# general.log("Basic level created") -# general.run_console("r_DisplayInfo = 0") -# -# # Create global_skylight entity and set the properties -# global_skylight = hydra.Entity("global_skylight") -# global_skylight.create_entity( -# entity_position=default_position, -# components=["HDRi Skybox", "Global Skylight (IBL)"], -# parent_id=default_level.id) -# global_skylight_asset_path = os.path.join("LightingPresets", "default_iblskyboxcm.exr.streamingimage") -# global_skylight_asset_value = asset.AssetCatalogRequestBus( -# bus.Broadcast, "GetAssetIdByPath", global_skylight_asset_path, math.Uuid(), False) -# global_skylight.get_set_test(0, "Controller|Configuration|Cubemap Texture", global_skylight_asset_value) -# global_skylight.get_set_test(1, "Controller|Configuration|Diffuse Image", global_skylight_asset_value) -# global_skylight.get_set_test(1, "Controller|Configuration|Specular Image", global_skylight_asset_value) -# -# # Create ground_plane entity and set the properties -# ground_plane = hydra.Entity("ground_plane") -# ground_plane.create_entity( -# entity_position=default_position, -# components=["Material"], -# parent_id=default_level.id) -# azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalUniformScale", ground_plane.id, 32.0) -# -# # Work around to add the correct Atom Mesh component and asset. -# mesh_type_id = azlmbr.globals.property.EditorMeshComponentTypeId -# ground_plane.components.append( -# editor.EditorComponentAPIBus( -# bus.Broadcast, "AddComponentsOfType", ground_plane.id, [mesh_type_id] -# ).GetValue()[0] -# ) -# ground_plane_mesh_asset_path = os.path.join("TestData", "Objects", "plane.azmodel") -# ground_plane_mesh_asset_value = asset.AssetCatalogRequestBus( -# bus.Broadcast, "GetAssetIdByPath", ground_plane_mesh_asset_path, math.Uuid(), False) -# ground_plane.get_set_test(1, "Controller|Configuration|Mesh Asset", ground_plane_mesh_asset_value) -# -# # Add Atom Material component and asset. -# ground_plane_material_asset_path = os.path.join("Materials", "Presets", "PBR", "metal_chrome.azmaterial") -# ground_plane_material_asset_value = asset.AssetCatalogRequestBus( -# bus.Broadcast, "GetAssetIdByPath", ground_plane_material_asset_path, math.Uuid(), False) -# ground_plane.get_set_test(0, "Default Material|Material Asset", ground_plane_material_asset_value) -# -# # Create directional_light entity and set the properties -# directional_light = hydra.Entity("directional_light") -# directional_light.create_entity( -# entity_position=math.Vector3(0.0, 0.0, 10.0), -# components=["Directional Light"], -# parent_id=default_level.id) -# directional_light_rotation = math.Vector3(degree_radian_factor * -90.0, 0.0, 0.0) -# azlmbr.components.TransformBus( -# azlmbr.bus.Event, "SetLocalRotation", directional_light.id, directional_light_rotation) -# -# # Create sphere entity and set the properties -# sphere_entity = hydra.Entity("sphere") -# sphere_entity.create_entity( -# entity_position=math.Vector3(0.0, 0.0, 1.0), -# components=["Material"], -# parent_id=default_level.id) -# -# # Work around to add the correct Atom Mesh component and asset. -# sphere_entity.components.append( -# editor.EditorComponentAPIBus( -# bus.Broadcast, "AddComponentsOfType", sphere_entity.id, [mesh_type_id] -# ).GetValue()[0] -# ) -# sphere_mesh_asset_path = os.path.join("Models", "sphere.azmodel") -# sphere_mesh_asset_value = asset.AssetCatalogRequestBus( -# bus.Broadcast, "GetAssetIdByPath", sphere_mesh_asset_path, math.Uuid(), False) -# sphere_entity.get_set_test(1, "Controller|Configuration|Mesh Asset", sphere_mesh_asset_value) -# -# # Add Atom Material component and asset. -# sphere_material_asset_path = os.path.join("Materials", "Presets", "PBR", "metal_brass_polished.azmaterial") -# sphere_material_asset_value = asset.AssetCatalogRequestBus( -# bus.Broadcast, "GetAssetIdByPath", sphere_material_asset_path, math.Uuid(), False) -# sphere_entity.get_set_test(0, "Default Material|Material Asset", sphere_material_asset_value) -# -# # Create camera component and set the properties -# camera_entity = hydra.Entity("camera") -# camera_entity.create_entity( -# entity_position=math.Vector3(5.5, -12.0, 9.0), -# components=["Camera"], -# parent_id=default_level.id) -# rotation = math.Vector3( -# degree_radian_factor * -27.0, degree_radian_factor * -12.0, degree_radian_factor * 25.0 -# ) -# azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", camera_entity.id, rotation) -# camera_entity.get_set_test(0, "Controller|Configuration|Field of view", 60.0) -# camera.EditorCameraViewRequestBus(azlmbr.bus.Event, "ToggleCameraAsActiveView", camera_entity.id) + +def initial_viewport_setup(screen_width=1280, screen_height=720): + """ + For setting up the initial viewport resolution to expected default values before running a screenshot test. + Defaults to 1280 x 720 resolution (in pixels). + :param screen_width: Width in pixels to set the viewport width size to. + :param screen_height: Height in pixels to set the viewport height size to. + :return: None + """ + import azlmbr.legacy.general as general + + general.set_viewport_size(screen_width, screen_height) + general.update_viewport() + + +def create_basic_atom_rendering_scene(): + """ + Sets up a new scene inside the Editor for testing Atom rendering GPU output. + Setup: Deletes all existing entities before creating the scene. + The created scene includes: + 1. "Default Level" entity that holds all of the other entities. + 2. "Grid" entity: Contains a Grid component. + 3. "Global Skylight (IBL)" entity: Contains HDRI Skybox & Global Skylight (IBL) components. + 4. "Ground Plane" entity: Contains Material & Mesh components. + 5. "Directional Light" entity: Contains Directional Light component. + 6. "Sphere" entity: Contains Material & Mesh components. + 7. "Camera" entity: Contains Camera component. + :return: None + """ + import azlmbr.math as math + import azlmbr.paths + + from editor_python_test_tools.asset_utils import Asset + from editor_python_test_tools.editor_entity_utils import EditorEntity + + from Atom.atom_utils.atom_constants import AtomComponentProperties + + DEGREE_RADIAN_FACTOR = 0.0174533 + + # Setup: Deletes all existing entities before creating the scene. + search_filter = azlmbr.entity.SearchFilter() + all_entities = azlmbr.entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter) + azlmbr.editor.ToolsApplicationRequestBus(azlmbr.bus.Broadcast, "DeleteEntities", all_entities) + + # 1. "Default Level" entity that holds all of the other entities. + default_level_entity_name = "Default Level" + default_level_entity = EditorEntity.create_editor_entity_at(math.Vector3(0.0, 0.0, 0.0), default_level_entity_name) + + # 2. "Grid" entity: Contains a Grid component. + grid_entity = EditorEntity.create_editor_entity(AtomComponentProperties.grid(), default_level_entity.id) + grid_component = grid_entity.add_component(AtomComponentProperties.grid()) + secondary_grid_spacing_value = 1.0 + grid_component.set_component_property_value( + AtomComponentProperties.grid('Secondary Grid Spacing'), secondary_grid_spacing_value) + + # 3. "Global Skylight (IBL)" entity: Contains HDRI Skybox & Global Skylight (IBL) components. + global_skylight_entity = EditorEntity.create_editor_entity( + AtomComponentProperties.global_skylight(), default_level_entity.id) + hdri_skybox_component = global_skylight_entity.add_component(AtomComponentProperties.hdri_skybox()) + global_skylight_component = global_skylight_entity.add_component(AtomComponentProperties.global_skylight()) + global_skylight_image_asset_path = os.path.join("LightingPresets", "default_iblskyboxcm.exr.streamingimage") + global_skylight_image_asset = Asset.find_asset_by_path(global_skylight_image_asset_path, False) + hdri_skybox_component.set_component_property_value( + AtomComponentProperties.hdri_skybox('Cubemap Texture'), global_skylight_image_asset.id) + global_skylight_diffuse_image_asset_path = os.path.join( + "LightingPresets", "default_iblskyboxcm_ibldiffuse.exr.streamingimage") + global_skylight_diffuse_image_asset = Asset.find_asset_by_path(global_skylight_diffuse_image_asset_path, False) + global_skylight_component.set_component_property_value( + AtomComponentProperties.global_skylight('Diffuse Image'), global_skylight_diffuse_image_asset.id) + global_skylight_specular_image_asset_path = os.path.join( + "LightingPresets", "default_iblskyboxcm_iblspecular.exr.streamingimage") + global_skylight_specular_image_asset = Asset.find_asset_by_path( + global_skylight_specular_image_asset_path, False) + global_skylight_component.set_component_property_value( + AtomComponentProperties.global_skylight('Specular Image'), global_skylight_specular_image_asset.id) + + # 4. "Ground Plane" entity: Contains Material & Mesh components. + ground_plane_name = "Ground Plane" + ground_plane_entity = EditorEntity.create_editor_entity(ground_plane_name, default_level_entity.id) + ground_plane_material_component = ground_plane_entity.add_component(AtomComponentProperties.material()) + ground_plane_entity.set_local_uniform_scale(32.0) + ground_plane_mesh_component = ground_plane_entity.add_component(AtomComponentProperties.mesh()) + ground_plane_mesh_asset_path = os.path.join("TestData", "Objects", "plane.azmodel") + ground_plane_mesh_asset = Asset.find_asset_by_path(ground_plane_mesh_asset_path, False) + ground_plane_mesh_component.set_component_property_value( + AtomComponentProperties.mesh('Mesh Asset'), ground_plane_mesh_asset.id) + ground_plane_material_asset_path = os.path.join("Materials", "Presets", "PBR", "metal_chrome.azmaterial") + ground_plane_material_asset = Asset.find_asset_by_path(ground_plane_material_asset_path, False) + ground_plane_material_component.set_component_property_value( + AtomComponentProperties.material('Material Asset'), ground_plane_material_asset.id) + + # 5. "Directional Light" entity: Contains Directional Light component. + directional_light_entity = EditorEntity.create_editor_entity_at( + math.Vector3(0.0, 0.0, 10.0), AtomComponentProperties.directional_light(), default_level_entity.id) + directional_light_entity.add_component(AtomComponentProperties.directional_light()) + directional_light_entity_rotation = math.Vector3(DEGREE_RADIAN_FACTOR * -90.0, 0.0, 0.0) + directional_light_entity.set_local_rotation(directional_light_entity_rotation) + + # 6. "Sphere" entity: Contains Material & Mesh components. + sphere_entity = EditorEntity.create_editor_entity_at( + math.Vector3(0.0, 0.0, 1.0), "Sphere", default_level_entity.id) + sphere_mesh_component = sphere_entity.add_component(AtomComponentProperties.mesh()) + sphere_mesh_asset_path = os.path.join("Models", "sphere.azmodel") + sphere_mesh_asset = Asset.find_asset_by_path(sphere_mesh_asset_path, False) + sphere_mesh_component.set_component_property_value( + AtomComponentProperties.mesh('Mesh Asset'), sphere_mesh_asset.id) + sphere_material_component = sphere_entity.add_component(AtomComponentProperties.material()) + sphere_material_asset_path = os.path.join("Materials", "Presets", "PBR", "metal_brass_polished.azmaterial") + sphere_material_asset = Asset.find_asset_by_path(sphere_material_asset_path, False) + sphere_material_component.set_component_property_value( + AtomComponentProperties.material('Material Asset'), sphere_material_asset.id) + + # 7. "Camera" entity: Contains Camera component. + camera_entity = EditorEntity.create_editor_entity_at( + math.Vector3(5.5, -12.0, 9.0), AtomComponentProperties.camera(), default_level_entity.id) + camera_component = camera_entity.add_component(AtomComponentProperties.camera()) + camera_entity_rotation = math.Vector3( + DEGREE_RADIAN_FACTOR * -27.0, DEGREE_RADIAN_FACTOR * -12.0, DEGREE_RADIAN_FACTOR * 25.0) + camera_entity.set_local_rotation(camera_entity_rotation) + camera_fov_value = 60.0 + camera_component.set_component_property_value(AtomComponentProperties.camera('Field of view'), camera_fov_value) + azlmbr.camera.EditorCameraViewRequestBus(azlmbr.bus.Event, "ToggleCameraAsActiveView", camera_entity.id) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py index ef9e90802b..2655a79fde 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py @@ -255,6 +255,9 @@ class AtomComponentProperties: """ properties = { 'name': 'Light', + 'Attenuation Radius Mode': 'Controller|Configuration|Attenuation radius|Mode', + 'Color': 'Controller|Configuration|Color', + 'Intensity': 'Controller|Configuration|Intensity', 'Light type': 'Controller|Configuration|Light type', } return properties[property] diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_AreaLightScreenshotTest.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_AreaLightScreenshotTest.py new file mode 100644 index 0000000000..d9a24c13ec --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_AreaLightScreenshotTest.py @@ -0,0 +1,217 @@ +""" +Copyright (c) Contributors to the Open 3D Engine Project. +For complete copyright and license terms please see the LICENSE at the root of this distribution. + +SPDX-License-Identifier: Apache-2.0 OR MIT +""" + + +class Tests: + area_light_entity_created = ( + "Area Light entity successfully created", + "Area Light entity failed to be created") + area_light_entity_deleted = ( + "Area Light entity was deleted", + "Area Light entity was not deleted") + enter_game_mode = ( + "Entered game mode", + "Failed to enter game mode") + exit_game_mode = ( + "Exited game mode", + "Couldn't exit game mode") + light_component_added = ( + "Light component was added", + "Light component wasn't added") + light_component_attenuation_radius_property_set = ( + "Light component Attenuation Radius Property was set", + "Light component Attenuation Radius Property was not set") + light_component_color_property_set = ( + "Light component Color property was set", + "Light component Color property was not set") + light_component_intensity_property_set = ( + "Light component Intensity property was set", + "Light component Intensity property was not set") + light_component_light_type_property_set = ( + "Light type property was set", + "Light type property was not set") + + +def AtomGPU_LightComponent_AreaLightScreenshotsMatchGoldenImages(): + """ + Summary: + Light component test using the Capsule, Spot (disk), and Point (sphere) Light type property options. + Sets each scene up and then takes a screenshot of each scene for test comparison. + + Test setup: + - Wait for Editor idle loop. + - Open the "Base" level. + - Close error windows and display helpers then update the viewport size. + - Runs the create_basic_atom_rendering_scene() function to setup the test scene. + + Expected Behavior: + The test scripts sets up the scenes correctly and takes accurate screenshots. + + Test Steps: + 1. Create Area Light entity with no components. + 2. Add a Light component to the Area Light entity. + 3. Set the Light type property to Capsule for the Light component. + 4. Set the Light component's Color property to 255, 0, 0. + 5. Enter game mode and take a screenshot then exit game mode. + 6. Set the Intensity property of the Light component to 0.0. + 7. Set the Attenuation Radius Mode property of the Light component to 1 (automatic). + 8. Enter game mode and take a screenshot then exit game mode. + 9. Set the Intensity property of the Light component to 1000.0 + 10. Enter game mode and take a screenshot then exit game mode. + 11. Set the Light type property to Spot (disk) for the Light component & rotate DEGREE_RADIAN_FACTOR * 90 degrees. + 12. Enter game mode and take a screenshot then exit game mode. + 13. Set the Light type property to Point (sphere) instead of Spot (disk) for the Light component. + 14. Enter game mode and take a screenshot then exit game mode. + 15. Delete the Area Light entity. + 16. Look for errors. + + :return: None + """ + + import azlmbr.legacy.general as general + import azlmbr.paths + + from editor_python_test_tools.editor_entity_utils import EditorEntity + from editor_python_test_tools.utils import Report, Tracer, TestHelper + + from Atom.atom_utils.atom_constants import AtomComponentProperties, LIGHT_TYPES + from Atom.atom_utils.atom_component_helper import initial_viewport_setup, create_basic_atom_rendering_scene + from Atom.atom_utils.screenshot_utils import ScreenshotHelper + + DEGREE_RADIAN_FACTOR = 0.0174533 + + with Tracer() as error_tracer: + # Test setup begins. + # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. + TestHelper.init_idle() + TestHelper.open_level("", "Base") + + # Setup: Close error windows and display helpers then update the viewport size. + TestHelper.close_error_windows() + TestHelper.close_display_helpers() + initial_viewport_setup() + general.update_viewport() + + # Setup: Runs the create_basic_atom_rendering_scene() function to setup the test scene. + create_basic_atom_rendering_scene() + + # Test steps begin. + # 1. Create Area Light entity with no components. + area_light_entity_name = "Area Light" + area_light_entity = EditorEntity.create_editor_entity_at( + azlmbr.math.Vector3(0.0, 0.0, 0.0), area_light_entity_name) + Report.critical_result(Tests.area_light_entity_created, area_light_entity.exists()) + + # 2. Add a Light component to the Area Light entity. + light_component = area_light_entity.add_component(AtomComponentProperties.light()) + Report.critical_result( + Tests.light_component_added, area_light_entity.has_component(AtomComponentProperties.light())) + + # 3. Set the Light type property to Capsule for the Light component. + light_component.set_component_property_value( + AtomComponentProperties.light('Light type'), LIGHT_TYPES['capsule']) + Report.result( + Tests.light_component_light_type_property_set, + light_component.get_component_property_value( + AtomComponentProperties.light('Light type')) == LIGHT_TYPES['capsule']) + + # 4. Set the Light component's Color property to 255, 0, 0. + light_component_color_value = azlmbr.math.Color(255.0, 0.0, 0.0, 0.0) + light_component.set_component_property_value( + AtomComponentProperties.light('Color'), light_component_color_value) + Report.result( + Tests.light_component_color_property_set, + light_component.get_component_property_value( + AtomComponentProperties.light('Color')) == light_component_color_value) + + # 5. Enter game mode and take a screenshot then exit game mode. + TestHelper.enter_game_mode(Tests.enter_game_mode) + TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0) + ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking("AreaLight_1.ppm") + TestHelper.exit_game_mode(Tests.exit_game_mode) + TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0) + + # 6. Set the Intensity property of the Light component to 0.0. + light_component.set_component_property_value(AtomComponentProperties.light('Intensity'), 0.0) + Report.result( + Tests.light_component_intensity_property_set, + light_component.get_component_property_value(AtomComponentProperties.light('Intensity')) == 0.0) + + # 7. Set the Attenuation Radius Mode property of the Light component to 1 (automatic). + light_component.set_component_property_value(AtomComponentProperties.light('Attenuation Radius Mode'), 1) + Report.result( + Tests.light_component_attenuation_radius_property_set, + light_component.get_component_property_value(AtomComponentProperties.light('Attenuation Radius Mode')) == 1) + + # 8. Enter game mode and take a screenshot then exit game mode. + TestHelper.enter_game_mode(Tests.enter_game_mode) + TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0) + ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking("AreaLight_2.ppm") + TestHelper.exit_game_mode(Tests.exit_game_mode) + TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0) + + # 9. Set the Intensity property of the Light component to 1000.0 + light_component.set_component_property_value(AtomComponentProperties.light('Intensity'), 1000.0) + Report.result( + Tests.light_component_intensity_property_set, + light_component.get_component_property_value(AtomComponentProperties.light('Intensity')) == 1000.0) + + # 10. Enter game mode and take a screenshot then exit game mode. + TestHelper.enter_game_mode(Tests.enter_game_mode) + TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0) + ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking("AreaLight_3.ppm") + TestHelper.exit_game_mode(Tests.exit_game_mode) + TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0) + + # 11. Set the Light type property to Spot (disk) for the Light component & + # rotate DEGREE_RADIAN_FACTOR * 90 degrees. + light_component.set_component_property_value( + AtomComponentProperties.light('Light type'), LIGHT_TYPES['spot_disk']) + area_light_rotation = azlmbr.math.Vector3(DEGREE_RADIAN_FACTOR * 90.0, 0.0, 0.0) + azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", area_light_entity.id, area_light_rotation) + Report.result( + Tests.light_component_light_type_property_set, + light_component.get_component_property_value( + AtomComponentProperties.light('Light type')) == LIGHT_TYPES['spot_disk']) + + # 12. Enter game mode and take a screenshot then exit game mode. + TestHelper.enter_game_mode(Tests.enter_game_mode) + TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0) + ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking("AreaLight_4.ppm") + TestHelper.exit_game_mode(Tests.exit_game_mode) + TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0) + + # 13. Set the Light type property to Point (sphere) instead of Spot (disk) for the Light component. + light_component.set_component_property_value( + AtomComponentProperties.light('Light type'), LIGHT_TYPES['sphere']) + Report.result( + Tests.light_component_light_type_property_set, + light_component.get_component_property_value( + AtomComponentProperties.light('Light type')) == LIGHT_TYPES['sphere']) + + # 14. Enter game mode and take a screenshot then exit game mode. + TestHelper.enter_game_mode(Tests.enter_game_mode) + TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0) + ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking("AreaLight_4.ppm") + TestHelper.exit_game_mode(Tests.exit_game_mode) + TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0) + + # 15. Delete the Area Light entity. + area_light_entity.delete() + Report.result(Tests.area_light_entity_deleted, not area_light_entity.exists()) + + # 16. Look for errors. + TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0) + for error_info in error_tracer.errors: + Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}") + for assert_info in error_tracer.asserts: + Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}") + + +if __name__ == "__main__": + from editor_python_test_tools.utils import Report + Report.start_test(AtomGPU_LightComponent_AreaLightScreenshotsMatchGoldenImages) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_BasicLevelSetup.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_BasicLevelSetup.py index 127b3e5b5f..b15e5b2131 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_BasicLevelSetup.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_BasicLevelSetup.py @@ -80,6 +80,7 @@ def AtomGPU_BasicLevelSetup_SetsUpLevel(): Test setup: - Wait for Editor idle loop. - Open the "Base" level. + - Deletes all existing entities before creating the scene. Expected Behavior: The scene can be setup for a basic level. @@ -115,7 +116,6 @@ def AtomGPU_BasicLevelSetup_SetsUpLevel(): """ import os - from math import isclose import azlmbr.legacy.general as general import azlmbr.math as math @@ -126,21 +126,11 @@ def AtomGPU_BasicLevelSetup_SetsUpLevel(): from editor_python_test_tools.utils import Report, Tracer, TestHelper from Atom.atom_utils.atom_constants import AtomComponentProperties + from Atom.atom_utils.atom_component_helper import initial_viewport_setup from Atom.atom_utils.screenshot_utils import ScreenshotHelper - SCREENSHOT_NAME = "AtomBasicLevelSetup" - SCREEN_WIDTH = 1280 - SCREEN_HEIGHT = 720 DEGREE_RADIAN_FACTOR = 0.0174533 - - def initial_viewport_setup(screen_width, screen_height): - general.set_viewport_size(screen_width, screen_height) - general.update_viewport() - TestHelper.wait_for_condition( - function=lambda: isclose(a=general.get_viewport_size().x, b=SCREEN_WIDTH, rel_tol=0.1) - and isclose(a=general.get_viewport_size().y, b=SCREEN_HEIGHT, rel_tol=0.1), - timeout_in_seconds=4.0 - ) + SCREENSHOT_NAME = "AtomBasicLevelSetup" with Tracer() as error_tracer: # Test setup begins. @@ -148,11 +138,16 @@ def AtomGPU_BasicLevelSetup_SetsUpLevel(): TestHelper.init_idle() TestHelper.open_level("", "Base") + # Setup: Deletes all existing entities before creating the scene. + search_filter = azlmbr.entity.SearchFilter() + all_entities = azlmbr.entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter) + azlmbr.editor.ToolsApplicationRequestBus(azlmbr.bus.Broadcast, "DeleteEntities", all_entities) + # Test steps begin. # 1. Close error windows and display helpers then update the viewport size. TestHelper.close_error_windows() TestHelper.close_display_helpers() - initial_viewport_setup(SCREEN_WIDTH, SCREEN_HEIGHT) + initial_viewport_setup() general.update_viewport() # 2. Create Default Level Entity. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_LightComponentScreenshotsMatch.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_LightComponentScreenshotsMatch.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py new file mode 100644 index 0000000000..e7ac32b339 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py @@ -0,0 +1,71 @@ +""" +Copyright (c) Contributors to the Open 3D Engine Project. +For complete copyright and license terms please see the LICENSE at the root of this distribution. + +SPDX-License-Identifier: Apache-2.0 OR MIT +""" + + +class Tests: + tbd = ( + "tbd", + "tbd") + + +def AtomGPU_LightComponent_SpotLightScreenshotsMatchGoldenImages(): + """ + Summary: + Light component test using the Spot (disk) Light type property option and modifying the shadows and colors. + Sets each scene up and then takes a screenshot of each scene for test comparison. + + Test setup: + - Wait for Editor idle loop. + - Open the "Base" level. + - Close error windows and display helpers then update the viewport size. + - Runs the create_basic_atom_rendering_scene() function to setup the test scene. + + Expected Behavior: + The test scripts sets up the scenes correctly and takes accurate screenshots. + + Test Steps: + 1. Add Directional Light component to the existing Directional Light entity. + 2. + :return: None + """ + + import azlmbr.legacy.general as general + import azlmbr.paths + + from editor_python_test_tools.utils import Report, Tracer, TestHelper + + from Atom.atom_utils.atom_component_helper import initial_viewport_setup, create_basic_atom_rendering_scene + + with Tracer() as error_tracer: + # Test setup begins. + # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. + TestHelper.init_idle() + TestHelper.open_level("", "Base") + + # Setup: Close error windows and display helpers then update the viewport size. + TestHelper.close_error_windows() + TestHelper.close_display_helpers() + initial_viewport_setup() + general.update_viewport() + + # Setup: Runs the create_basic_atom_rendering_scene() function to setup the test scene. + create_basic_atom_rendering_scene() + + # Test steps begin. + # 1. + + # ???. Look for errors. + TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0) + for error_info in error_tracer.errors: + Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}") + for assert_info in error_tracer.asserts: + Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}") + + +if __name__ == "__main__": + from editor_python_test_tools.utils import Report + Report.start_test(AtomGPU_LightComponent_SpotLightScreenshotsMatchGoldenImages) From cc76ee58a7d4863cd239aced499fc7de3731147d Mon Sep 17 00:00:00 2001 From: jromnoa <80134229+jromnoa@users.noreply.github.com> Date: Wed, 1 Dec 2021 18:46:58 -0800 Subject: [PATCH 3/8] update light component constant, fixed the return value for find_editor_entity(), removed old GPU test scripts, added new GPU test scripts Signed-off-by: jromnoa <80134229+jromnoa@users.noreply.github.com> --- .../Atom/atom_utils/atom_constants.py | 5 + .../hydra_AtomGPU_SpotLightScreenshotTest.py | 217 ++++++++++++++- .../tests/hydra_GPUTest_BasicLevelSetup.py | 200 -------------- .../tests/hydra_GPUTest_LightComponent.py | 261 ------------------ .../editor_entity_utils.py | 24 +- 5 files changed, 226 insertions(+), 481 deletions(-) delete mode 100644 AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_BasicLevelSetup.py delete mode 100644 AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_LightComponent.py diff --git a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py index 2655a79fde..559f4aebee 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py @@ -257,8 +257,13 @@ class AtomComponentProperties: 'name': 'Light', 'Attenuation Radius Mode': 'Controller|Configuration|Attenuation radius|Mode', 'Color': 'Controller|Configuration|Color', + 'Enable shadow': 'Controller|Configuration|Shadows|Enable shadow', + 'Enable shutters': 'Controller|Configuration|Shutters|Enable shutters', + 'Inner angle': 'Controller|Configuration|Shutters|Inner angle', 'Intensity': 'Controller|Configuration|Intensity', 'Light type': 'Controller|Configuration|Light type', + 'Outer angle': 'Controller|Configuration|Shutters|Outer angle', + 'Shadowmap size': 'Controller|Configuration|Shadows|Shadowmap size', } return properties[property] diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py index e7ac32b339..9b1c88a4fc 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py @@ -7,9 +7,54 @@ SPDX-License-Identifier: Apache-2.0 OR MIT class Tests: - tbd = ( - "tbd", - "tbd") + directional_light_component_disabled = ( + "Disabled Directional Light component", + "Couldn't disable Directional Light component") + enter_game_mode = ( + "Entered game mode", + "Failed to enter game mode") + exit_game_mode = ( + "Exited game mode", + "Couldn't exit game mode") + global_skylight_component_disabled = ( + "Disabled Global Skylight (IBL) component", + "Couldn't disable Global Skylight (IBL) component") + hdri_skybox_component_disabled = ( + "Disabled HDRi Skybox component", + "Couldn't disable HDRi Skybox component") + light_component_added = ( + "Light component added", + "Couldn't add Light component") + light_component_color_property_set = ( + "Color property was set", + "Color property was not set") + light_component_enable_shadow_property_set = ( + "Enable shadow property was set", + "Enable shadow property was not set") + light_component_enable_shutters_property_set = ( + "Enable shutters property was set", + "Enable shutters property was not set") + light_component_inner_angle_property_set = ( + "Inner angle property was set", + "Inner angle property was not set") + light_component_intensity_property_set = ( + "Intensity property was set", + "Intensity property was not set") + light_component_light_type_property_set = ( + "Light type property was set", + "Light type property was not set") + light_component_outer_angle_property_set = ( + "Outer angle property was set", + "Outer angle property was not set") + light_component_shadowmap_size_property_set = ( + "Shadowmap size was set", + "Shadowmap size was not set") + material_component_material_asset_property_set = ( + "Material Asset property was set", + "Material Asset property was not set") + spot_light_entity_created = ( + "Spot Light entity created", + "Couldn't create Spot Light entity") def AtomGPU_LightComponent_SpotLightScreenshotsMatchGoldenImages(): @@ -28,17 +73,26 @@ def AtomGPU_LightComponent_SpotLightScreenshotsMatchGoldenImages(): The test scripts sets up the scenes correctly and takes accurate screenshots. Test Steps: - 1. Add Directional Light component to the existing Directional Light entity. - 2. + 1. Find the Directional Light entity then disable its Directional Light component. + 2. Disable Global Skylight (IBL) and HDRi Skybox components on the Global Skylight entity. + + :return: None """ + import os import azlmbr.legacy.general as general import azlmbr.paths + from editor_python_test_tools.asset_utils import Asset + from editor_python_test_tools.editor_entity_utils import EditorEntity from editor_python_test_tools.utils import Report, Tracer, TestHelper + from Atom.atom_utils.atom_constants import AtomComponentProperties, LIGHT_TYPES from Atom.atom_utils.atom_component_helper import initial_viewport_setup, create_basic_atom_rendering_scene + from Atom.atom_utils.screenshot_utils import ScreenshotHelper + + DEGREE_RADIAN_FACTOR = 0.0174533 with Tracer() as error_tracer: # Test setup begins. @@ -56,14 +110,153 @@ def AtomGPU_LightComponent_SpotLightScreenshotsMatchGoldenImages(): create_basic_atom_rendering_scene() # Test steps begin. - # 1. + # 1. Find the Directional Light entity then disable its Directional Light component. + directional_light_name = AtomComponentProperties.directional_light() + directional_light_entity = EditorEntity.find_editor_entity(directional_light_name) + directional_light_component = directional_light_entity.get_components_of_type([directional_light_name])[0] + directional_light_component.disable_component() + Report.critical_result(Tests.directional_light_component_disabled, not directional_light_component.is_enabled()) - # ???. Look for errors. - TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0) - for error_info in error_tracer.errors: - Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}") - for assert_info in error_tracer.asserts: - Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}") + # 2. Disable Global Skylight (IBL) component on the Global Skylight (IBL) entity. + global_skylight_name = AtomComponentProperties.global_skylight() + global_skylight_entity = EditorEntity.find_editor_entity(global_skylight_name) + global_skylight_component = global_skylight_entity.get_components_of_type([global_skylight_name])[0] + global_skylight_component.disable_component() + Report.critical_result(Tests.global_skylight_component_disabled, not global_skylight_component.is_enabled()) + + # 3. Disable HDRi Skybox component on the Global Skylight (IBL) entity + hdri_skybox_name = AtomComponentProperties.hdri_skybox() + hdri_skybox_component = global_skylight_entity.get_components_of_type([hdri_skybox_name])[0] + hdri_skybox_component.disable_component() + Report.critical_result(Tests.hdri_skybox_component_disabled, not hdri_skybox_component.is_enabled()) + + # 4. Create a Spot Light entity and rotate it. + spot_light_name = "Spot Light" + spot_light_entity = EditorEntity.create_editor_entity_at( + azlmbr.math.Vector3(0.7, -2.0, 1.0), spot_light_name) + rotation = azlmbr.math.Vector3(DEGREE_RADIAN_FACTOR * 300.0, 0.0, 0.0) + spot_light_entity.set_local_rotation(rotation) + Report.critical_result(Tests.spot_light_entity_created, spot_light_entity.exists()) + + # 5. Attach a Light component to the Spot Light entity. + light_name = AtomComponentProperties.light() + light_component = spot_light_entity.add_component(light_name) + Report.critical_result(Tests.light_component_added, light_component.is_enabled()) + + # 6. Set the Light component Light Type to Spot (disk). + light_component.set_component_property_value( + AtomComponentProperties.light('Light type'), LIGHT_TYPES['spot_disk']) + Report.result( + Tests.light_component_light_type_property_set, + light_component.get_component_property_value( + AtomComponentProperties.light('Light type')) == LIGHT_TYPES['spot_disk']) + + # 7. Enter game mode and take a screenshot then exit game mode. + TestHelper.enter_game_mode(Tests.enter_game_mode) + TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0) + ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking("SpotLight_1.ppm") + TestHelper.exit_game_mode(Tests.exit_game_mode) + TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0) + + # 8. Change the default material asset for the Ground Plane entity. + ground_plane_name = "Ground Plane" + ground_plane_entity = EditorEntity.find_editor_entity(ground_plane_name) + ground_plane_material_component_name = AtomComponentProperties.material() + ground_plane_material_component = ground_plane_entity.get_components_of_type( + [ground_plane_material_component_name])[0] + ground_plane_material_asset_path = os.path.join( + "Materials", "Presets", "Macbeth", "22_neutral_5-0_0-70d.azmaterial") + ground_plane_material_asset = Asset.find_asset_by_path(ground_plane_material_asset_path, False) + ground_plane_material_component.set_component_property_value( + AtomComponentProperties.material('Material Asset'), ground_plane_material_asset.id) + Report.result( + Tests.material_component_material_asset_property_set, + light_component.get_component_property_value(AtomComponentProperties.material('Material Asset'))) + + # 9. Enter game mode and take a screenshot then exit game mode. + TestHelper.enter_game_mode(Tests.enter_game_mode) + TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0) + ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking("SpotLight_2.ppm") + TestHelper.exit_game_mode(Tests.exit_game_mode) + TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0) + + # 10. Increase the Intensity value of the Light component. + light_component.set_component_property_value(AtomComponentProperties.light('Intensity'), 800.0) + Report.result( + Tests.light_component_intensity_property_set, + light_component.get_component_property_value( + AtomComponentProperties.light('Intensity')) == 800.0) + + # 11. Enter game mode and take a screenshot then exit game mode. + TestHelper.enter_game_mode(Tests.enter_game_mode) + TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0) + ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking("SpotLight_3.ppm") + TestHelper.exit_game_mode(Tests.exit_game_mode) + TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0) + + # 12. Change the Light component Color property value. + color_value = azlmbr.math.Color(47.0 / 255.0, 75.0 / 255.0, 37.0 / 255.0, 255.0 / 255.0) + light_component.set_component_property_value(AtomComponentProperties.light('Color'), color_value) + Report.result( + Tests.light_component_color_property_set, + light_component.get_component_property_value(AtomComponentProperties.light('Color')) == color_value) + + # 13. Enter game mode and take a screenshot then exit game mode. + TestHelper.enter_game_mode(Tests.enter_game_mode) + TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0) + ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking("SpotLight_4.ppm") + TestHelper.exit_game_mode(Tests.exit_game_mode) + TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0) + + # 14. Change the Light component Enable shutters, Inner angle, and Outer angle property values. + enable_shutters = True + inner_angle = 60.0 + outer_angle = 75.0 + light_component.set_component_property_value(AtomComponentProperties.light('Enable shutters'), enable_shutters) + light_component.set_component_property_value(AtomComponentProperties.light('Inner angle'), inner_angle) + light_component.set_component_property_value(AtomComponentProperties.light('Outer angle'), outer_angle) + Report.result( + Tests.light_component_enable_shutters_property_set, + light_component.get_component_property_value( + AtomComponentProperties.light('Enable shutters')) == enable_shutters) + Report.result( + Tests.light_component_inner_angle_property_set, + light_component.get_component_property_value(AtomComponentProperties.light('Inner angle')) == inner_angle) + Report.result( + Tests.light_component_outer_angle_property_set, + light_component.get_component_property_value(AtomComponentProperties.light('Outer angle')) == outer_angle) + + # 15. Enter game mode and take a screenshot then exit game mode. + TestHelper.enter_game_mode(Tests.enter_game_mode) + TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0) + ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking("SpotLight_5.ppm") + TestHelper.exit_game_mode(Tests.exit_game_mode) + TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0) + + # 16. Change the Light component Enable shadow and Shadowmap size property values then move Spot Light entity. + light_component.set_component_property_value(AtomComponentProperties.light('Enable shadow'), True) + light_component.set_component_property_value(AtomComponentProperties.light('Shadowmap size'), 256.0) + spot_light_entity.set_world_rotation(azlmbr.math.Vector3(0.7, -2.0, 1.9)) + Report.result( + Tests.light_component_enable_shadow_property_set, + light_component.get_component_property_value(AtomComponentProperties.light('Enable shadow')) is True) + Report.result( + Tests.light_component_shadowmap_size_property_set, + light_component.get_component_property_value(AtomComponentProperties.light('Shadowmap size')) == 256.0) + + # 17. Enter game mode and take a screenshot then exit game mode. + TestHelper.enter_game_mode(Tests.enter_game_mode) + TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0) + ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking("SpotLight_6.ppm") + TestHelper.exit_game_mode(Tests.exit_game_mode) + TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0) + + # 18. Look for errors. + TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0) + for error_info in error_tracer.errors: + Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}") + for assert_info in error_tracer.asserts: + Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}") if __name__ == "__main__": diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_BasicLevelSetup.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_BasicLevelSetup.py deleted file mode 100644 index 1641b529ae..0000000000 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_BasicLevelSetup.py +++ /dev/null @@ -1,200 +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 editor_python_test_tools.hydra_editor_utils as hydra -from editor_python_test_tools.editor_test_helper import EditorTestHelper -from Atom.atom_utils.screenshot_utils import ScreenshotHelper - -SCREEN_WIDTH = 1280 -SCREEN_HEIGHT = 720 -DEGREE_RADIAN_FACTOR = 0.0174533 - -helper = EditorTestHelper(log_prefix="Test_Atom_BasicLevelSetup") - - -def run(): - """ - 1. View -> Layouts -> Restore Default Layout, sets the viewport to ratio 16:9 @ 1280 x 720 - 2. Runs console command r_DisplayInfo = 0 - 3. Deletes all entities currently present in the level. - 4. Creates a "default_level" entity to hold all other entities, setting the translate values to x:0, y:0, z:0 - 5. Adds a Grid component to the "default_level" & updates its Grid Spacing to 1.0m - 6. Adds a "global_skylight" entity to "default_level", attaching an HDRi Skybox w/ a Cubemap Texture. - 7. Adds a Global Skylight (IBL) component w/ diffuse image and specular image to "global_skylight" entity. - 8. Adds a "ground_plane" entity to "default_level", attaching a Mesh component & Material component. - 9. Adds a "directional_light" entity to "default_level" & adds a Directional Light component. - 10. Adds a "sphere" entity to "default_level" & adds a Mesh component with a Material component to it. - 11. Adds a "camera" entity to "default_level" & adds a Camera component with 80 degree FOV and Transform values: - Translate - x:5.5m, y:-12.0m, z:9.0m - Rotate - x:-27.0, y:-12.0, z:25.0 - 12. Finally enters game mode, takes a screenshot, & exits game mode. - :return: None - """ - import azlmbr.asset as asset - import azlmbr.bus as bus - import azlmbr.camera as camera - import azlmbr.entity as entity - import azlmbr.legacy.general as general - import azlmbr.math as math - import azlmbr.paths - import azlmbr.editor as editor - - def initial_viewport_setup(screen_width, screen_height): - general.set_viewport_size(screen_width, screen_height) - general.update_viewport() - helper.wait_for_condition( - function=lambda: helper.isclose(a=general.get_viewport_size().x, b=SCREEN_WIDTH, rel_tol=0.1) - and helper.isclose(a=general.get_viewport_size().y, b=SCREEN_HEIGHT, rel_tol=0.1), - timeout_in_seconds=4.0 - ) - result = helper.isclose(a=general.get_viewport_size().x, b=SCREEN_WIDTH, rel_tol=0.1) and helper.isclose( - a=general.get_viewport_size().y, b=SCREEN_HEIGHT, rel_tol=0.1) - general.log(general.get_viewport_size().x) - general.log(general.get_viewport_size().y) - general.log(general.get_viewport_size().z) - general.log(f"Viewport is set to the expected size: {result}") - general.run_console("r_DisplayInfo = 0") - - def after_level_load(): - """Function to call after creating/opening a level to ensure it loads.""" - # Give everything a second to initialize. - general.idle_enable(True) - general.idle_wait(1.0) - general.update_viewport() - general.idle_wait(0.5) # half a second is more than enough for updating the viewport. - - # Close out problematic windows, FPS meters, and anti-aliasing. - if general.is_helpers_shown(): # Turn off the helper gizmos if visible - general.toggle_helpers() - general.idle_wait(1.0) - if general.is_pane_visible("Error Report"): # Close Error Report windows that block focus. - general.close_pane("Error Report") - if general.is_pane_visible("Error Log"): # Close Error Log windows that block focus. - general.close_pane("Error Log") - general.idle_wait(1.0) - general.run_console("r_displayInfo=0") - general.idle_wait(1.0) - - # Wait for Editor idle loop before executing Python hydra scripts. - general.idle_enable(True) - - # Basic setup for opened level. - helper.open_level(level_name="Base") - after_level_load() - initial_viewport_setup(SCREEN_WIDTH, SCREEN_HEIGHT) - - # Create default_level entity - search_filter = azlmbr.entity.SearchFilter() - all_entities = entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter) - editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntities", all_entities) - - default_level = hydra.Entity("default_level") - position = math.Vector3(0.0, 0.0, 0.0) - default_level.create_entity(position, ["Grid"]) - default_level.get_set_test(0, "Controller|Configuration|Secondary Grid Spacing", 1.0) - - # Create global_skylight entity and set the properties - global_skylight = hydra.Entity("global_skylight") - global_skylight.create_entity( - entity_position=math.Vector3(0.0, 0.0, 0.0), - components=["HDRi Skybox", "Global Skylight (IBL)"], - parent_id=default_level.id - ) - global_skylight_image_asset_path = os.path.join("LightingPresets", "default_iblskyboxcm.exr.streamingimage") - global_skylight_image_asset = asset.AssetCatalogRequestBus( - bus.Broadcast, "GetAssetIdByPath", global_skylight_image_asset_path, math.Uuid(), False) - global_skylight.get_set_test(0, "Controller|Configuration|Cubemap Texture", global_skylight_image_asset) - hydra.get_set_test(global_skylight, 1, "Controller|Configuration|Diffuse Image", global_skylight_image_asset) - hydra.get_set_test(global_skylight, 1, "Controller|Configuration|Specular Image", global_skylight_image_asset) - - # Create ground_plane entity and set the properties - ground_plane = hydra.Entity("ground_plane") - ground_plane.create_entity( - entity_position=math.Vector3(0.0, 0.0, 0.0), - components=["Material"], - parent_id=default_level.id - ) - azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalUniformScale", ground_plane.id, 32.0) - - # Work around to add the correct Atom Mesh component and asset. - mesh_type_id = azlmbr.globals.property.EditorMeshComponentTypeId - ground_plane.components.append( - editor.EditorComponentAPIBus( - bus.Broadcast, "AddComponentsOfType", ground_plane.id, [mesh_type_id] - ).GetValue()[0] - ) - ground_plane_mesh_asset_path = os.path.join("TestData", "Objects", "plane.azmodel") - ground_plane_mesh_asset = asset.AssetCatalogRequestBus( - bus.Broadcast, "GetAssetIdByPath", ground_plane_mesh_asset_path, math.Uuid(), False) - hydra.get_set_test(ground_plane, 1, "Controller|Configuration|Mesh Asset", ground_plane_mesh_asset) - - # Add Atom Material component and asset. - ground_plane_material_asset_path = os.path.join("Materials", "Presets", "PBR", "metal_chrome.azmaterial") - ground_plane_material_asset = asset.AssetCatalogRequestBus( - bus.Broadcast, "GetAssetIdByPath", ground_plane_material_asset_path, math.Uuid(), False) - ground_plane.get_set_test(0, "Default Material|Material Asset", ground_plane_material_asset) - - # Create directional_light entity and set the properties - directional_light = hydra.Entity("directional_light") - directional_light.create_entity( - entity_position=math.Vector3(0.0, 0.0, 10.0), - components=["Directional Light"], - parent_id=default_level.id - ) - rotation = math.Vector3(DEGREE_RADIAN_FACTOR * -90.0, 0.0, 0.0) - azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", directional_light.id, rotation) - - # Create sphere entity and set the properties - sphere = hydra.Entity("sphere") - sphere.create_entity( - entity_position=math.Vector3(0.0, 0.0, 1.0), - components=["Material"], - parent_id=default_level.id - ) - - # Work around to add the correct Atom Mesh component and asset. - sphere.components.append( - editor.EditorComponentAPIBus( - bus.Broadcast, "AddComponentsOfType", sphere.id, [mesh_type_id] - ).GetValue()[0] - ) - sphere_mesh_asset_path = os.path.join("Models", "sphere.azmodel") - sphere_mesh_asset = asset.AssetCatalogRequestBus( - bus.Broadcast, "GetAssetIdByPath", sphere_mesh_asset_path, math.Uuid(), False) - hydra.get_set_test(sphere, 1, "Controller|Configuration|Mesh Asset", sphere_mesh_asset) - - # Add Atom Material component and asset. - sphere_material_asset_path = os.path.join("Materials", "Presets", "PBR", "metal_brass_polished.azmaterial") - sphere_material_asset = asset.AssetCatalogRequestBus( - bus.Broadcast, "GetAssetIdByPath", sphere_material_asset_path, math.Uuid(), False) - sphere.get_set_test(0, "Default Material|Material Asset", sphere_material_asset) - - # Create camera component and set the properties - camera_entity = hydra.Entity("camera") - position = math.Vector3(5.5, -12.0, 9.0) - camera_entity.create_entity(components=["Camera"], entity_position=position, parent_id=default_level.id) - rotation = math.Vector3( - DEGREE_RADIAN_FACTOR * -27.0, DEGREE_RADIAN_FACTOR * -12.0, DEGREE_RADIAN_FACTOR * 25.0 - ) - azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", camera_entity.id, rotation) - camera_entity.get_set_test(0, "Controller|Configuration|Field of view", 60.0) - camera.EditorCameraViewRequestBus(azlmbr.bus.Event, "ToggleCameraAsActiveView", camera_entity.id) - - # Enter game mode, take screenshot, & exit game mode. - general.idle_wait(0.5) - general.enter_game_mode() - general.idle_wait(1.0) - helper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=2.0) - ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking(f"{'AtomBasicLevelSetup'}.ppm") - general.exit_game_mode() - helper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=2.0) - - -if __name__ == "__main__": - run() diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_LightComponent.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_LightComponent.py deleted file mode 100644 index f69ceb2120..0000000000 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_LightComponent.py +++ /dev/null @@ -1,261 +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.asset as asset -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 import atom_component_helper, atom_constants, screenshot_utils -from editor_python_test_tools.editor_test_helper import EditorTestHelper - -helper = EditorTestHelper(log_prefix="Atom_EditorTestHelper") - -LEVEL_NAME = "Base" -LIGHT_COMPONENT = "Light" -LIGHT_TYPE_PROPERTY = 'Controller|Configuration|Light type' -DEGREE_RADIAN_FACTOR = 0.0174533 - - -def run(): - """ - Sets up the tests by making sure the required level is created & setup correctly. - It then executes 2 test cases - see each associated test function's docstring for more info. - - Finally prints the string "Light component tests 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 - """ - atom_component_helper.create_basic_atom_level(level_name=LEVEL_NAME) - - # Run tests. - area_light_test() - spot_light_test() - general.log("Light component tests completed.") - - -def area_light_test(): - """ - Basic test for the "Light" component attached to an "area_light" entity. - - Test Case - Light Component: Capsule, Spot (disk), and Point (sphere): - 1. Creates "area_light" entity w/ a Light component that has a Capsule Light type w/ the color set to 255, 0, 0 - 2. Enters game mode to take a screenshot for comparison, then exits game mode. - 3. Sets the Light component Intensity Mode to Lumens (default). - 4. Ensures the Light component Mode is Automatic (default). - 5. Sets the Intensity value of the Light component to 0.0 - 6. Enters game mode again, takes another screenshot for comparison, then exits game mode. - 7. Updates the Intensity value of the Light component to 1000.0 - 8. Enters game mode again, takes another screenshot for comparison, then exits game mode. - 9. Swaps the Capsule light type option to Spot (disk) light type on the Light component - 10. Updates "area_light" entity Transform rotate value to x: 90.0, y:0.0, z:0.0 - 11. Enters game mode again, takes another screenshot for comparison, then exits game mode. - 12. Swaps the Spot (disk) light type for the Point (sphere) light type in the Light component. - 13. Enters game mode again, takes another screenshot for comparison, then exits game mode. - 14. Deletes the Light component from the "area_light" entity and verifies its successful. - """ - # Create an "area_light" entity with "Light" component using Light type of "Capsule" - area_light_entity_name = "area_light" - area_light = hydra.Entity(area_light_entity_name) - area_light.create_entity(math.Vector3(-1.0, -2.0, 3.0), [LIGHT_COMPONENT]) - general.log( - f"{area_light_entity_name}_test: Component added to the entity: " - f"{hydra.has_components(area_light.id, [LIGHT_COMPONENT])}") - light_component_id_pair = hydra.attach_component_to_entity(area_light.id, LIGHT_COMPONENT) - - # Select the "Capsule" light type option. - azlmbr.editor.EditorComponentAPIBus( - azlmbr.bus.Broadcast, - 'SetComponentProperty', - light_component_id_pair, - LIGHT_TYPE_PROPERTY, - atom_constants.LIGHT_TYPES['capsule'] - ) - - # Update color and take screenshot in game mode - color = math.Color(255.0, 0.0, 0.0, 0.0) - area_light.get_set_test(0, "Controller|Configuration|Color", color) - general.idle_wait(1.0) - screenshot_utils.take_screenshot_game_mode("AreaLight_1", area_light_entity_name) - - # Update intensity value to 0.0 and take screenshot in game mode - area_light.get_set_test(0, "Controller|Configuration|Attenuation Radius|Mode", 1) - area_light.get_set_test(0, "Controller|Configuration|Intensity", 0.0) - general.idle_wait(1.0) - screenshot_utils.take_screenshot_game_mode("AreaLight_2", area_light_entity_name) - - # Update intensity value to 1000.0 and take screenshot in game mode - area_light.get_set_test(0, "Controller|Configuration|Intensity", 1000.0) - general.idle_wait(1.0) - screenshot_utils.take_screenshot_game_mode("AreaLight_3", area_light_entity_name) - - # Swap the "Capsule" light type option to "Spot (disk)" light type - azlmbr.editor.EditorComponentAPIBus( - azlmbr.bus.Broadcast, - 'SetComponentProperty', - light_component_id_pair, - LIGHT_TYPE_PROPERTY, - atom_constants.LIGHT_TYPES['spot_disk'] - ) - area_light_rotation = math.Vector3(DEGREE_RADIAN_FACTOR * 90.0, 0.0, 0.0) - azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", area_light.id, area_light_rotation) - general.idle_wait(1.0) - screenshot_utils.take_screenshot_game_mode("AreaLight_4", area_light_entity_name) - - # Swap the "Spot (disk)" light type to the "Point (sphere)" light type and take screenshot. - azlmbr.editor.EditorComponentAPIBus( - azlmbr.bus.Broadcast, - 'SetComponentProperty', - light_component_id_pair, - LIGHT_TYPE_PROPERTY, - atom_constants.LIGHT_TYPES['sphere'] - ) - general.idle_wait(1.0) - screenshot_utils.take_screenshot_game_mode("AreaLight_5", area_light_entity_name) - - editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntityById", area_light.id) - - -def spot_light_test(): - """ - Basic test for the Light component attached to a "spot_light" entity. - - Test Case - Light Component: Spot (disk) with shadows & colors: - 1. Creates "spot_light" entity w/ a Light component attached to it. - 2. Selects the "directional_light" entity already present in the level and disables it. - 3. Selects the "global_skylight" entity already present in the level and disables the HDRi Skybox component, - as well as the Global Skylight (IBL) component. - 4. Enters game mode to take a screenshot for comparison, then exits game mode. - 5. Selects the "ground_plane" entity and changes updates the material to a new material. - 6. Enters game mode to take a screenshot for comparison, then exits game mode. - 7. Selects the "spot_light" entity and increases the Light component Intensity to 800 lm - 8. Enters game mode to take a screenshot for comparison, then exits game mode. - 9. Selects the "spot_light" entity and sets the Light component Color to 47, 75, 37 - 10. Enters game mode to take a screenshot for comparison, then exits game mode. - 11. Selects the "spot_light" entity and modifies the Shutter controls to the following values: - - Enable shutters: True - - Inner Angle: 60.0 - - Outer Angle: 75.0 - 12. Enters game mode to take a screenshot for comparison, then exits game mode. - 13. Selects the "spot_light" entity and modifies the Shadow controls to the following values: - - Enable Shadow: True - - ShadowmapSize: 256 - 14. Modifies the world translate position of the "spot_light" entity to 0.7, -2.0, 1.9 (for casting shadows better) - 15. Enters game mode to take a screenshot for comparison, then exits game mode. - """ - # Disable "Directional Light" component for the "directional_light" entity - # "directional_light" entity is created by the create_basic_atom_level() function by default. - directional_light_entity_id = hydra.find_entity_by_name("directional_light") - directional_light = hydra.Entity(name='directional_light', id=directional_light_entity_id) - directional_light_component_type = azlmbr.editor.EditorComponentAPIBus( - azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Directional Light"], 0)[0] - directional_light_component = azlmbr.editor.EditorComponentAPIBus( - azlmbr.bus.Broadcast, 'GetComponentOfType', directional_light.id, directional_light_component_type - ).GetValue() - editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [directional_light_component]) - general.idle_wait(0.5) - - # Disable "Global Skylight (IBL)" and "HDRi Skybox" components for the "global_skylight" entity - global_skylight_entity_id = hydra.find_entity_by_name("global_skylight") - global_skylight = hydra.Entity(name='global_skylight', id=global_skylight_entity_id) - global_skylight_component_type = azlmbr.editor.EditorComponentAPIBus( - azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Global Skylight (IBL)"], 0)[0] - global_skylight_component = azlmbr.editor.EditorComponentAPIBus( - azlmbr.bus.Broadcast, 'GetComponentOfType', global_skylight.id, global_skylight_component_type - ).GetValue() - editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [global_skylight_component]) - hdri_skybox_component_type = azlmbr.editor.EditorComponentAPIBus( - azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["HDRi Skybox"], 0)[0] - hdri_skybox_component = azlmbr.editor.EditorComponentAPIBus( - azlmbr.bus.Broadcast, 'GetComponentOfType', global_skylight.id, hdri_skybox_component_type - ).GetValue() - editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [hdri_skybox_component]) - general.idle_wait(0.5) - - # Create a "spot_light" entity with "Light" component using Light Type of "Spot (disk)" - spot_light_entity_name = "spot_light" - spot_light = hydra.Entity(spot_light_entity_name) - spot_light.create_entity(math.Vector3(0.7, -2.0, 1.0), [LIGHT_COMPONENT]) - general.log( - f"{spot_light_entity_name}_test: Component added to the entity: " - f"{hydra.has_components(spot_light.id, [LIGHT_COMPONENT])}") - rotation = math.Vector3(DEGREE_RADIAN_FACTOR * 300.0, 0.0, 0.0) - azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", spot_light.id, rotation) - light_component_type = hydra.attach_component_to_entity(spot_light.id, LIGHT_COMPONENT) - editor.EditorComponentAPIBus( - azlmbr.bus.Broadcast, - 'SetComponentProperty', - light_component_type, - LIGHT_TYPE_PROPERTY, - atom_constants.LIGHT_TYPES['spot_disk'] - ) - - general.idle_wait(1.0) - screenshot_utils.take_screenshot_game_mode("SpotLight_1", spot_light_entity_name) - - # Change default material of ground plane entity and take screenshot - ground_plane_entity_id = hydra.find_entity_by_name("ground_plane") - ground_plane = hydra.Entity(name='ground_plane', id=ground_plane_entity_id) - ground_plane_asset_path = os.path.join("Materials", "Presets", "MacBeth", "22_neutral_5-0_0-70d.azmaterial") - ground_plane_asset_value = asset.AssetCatalogRequestBus( - bus.Broadcast, "GetAssetIdByPath", ground_plane_asset_path, math.Uuid(), False) - material_property_path = "Default Material|Material Asset" - material_component_type = azlmbr.editor.EditorComponentAPIBus( - azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Material"], 0)[0] - material_component = azlmbr.editor.EditorComponentAPIBus( - azlmbr.bus.Broadcast, 'GetComponentOfType', ground_plane.id, material_component_type).GetValue() - editor.EditorComponentAPIBus( - azlmbr.bus.Broadcast, - 'SetComponentProperty', - material_component, - material_property_path, - ground_plane_asset_value - ) - general.idle_wait(1.0) - screenshot_utils.take_screenshot_game_mode("SpotLight_2", spot_light_entity_name) - - # Increase intensity value of the Spot light and take screenshot in game mode - spot_light.get_set_test(0, "Controller|Configuration|Intensity", 800.0) - general.idle_wait(1.0) - screenshot_utils.take_screenshot_game_mode("SpotLight_3", spot_light_entity_name) - - # Update the Spot light color and take screenshot in game mode - color_value = math.Color(47.0 / 255.0, 75.0 / 255.0, 37.0 / 255.0, 255.0 / 255.0) - spot_light.get_set_test(0, "Controller|Configuration|Color", color_value) - general.idle_wait(1.0) - screenshot_utils.take_screenshot_game_mode("SpotLight_4", spot_light_entity_name) - - # Update the Shutter controls of the Light component and take screenshot - spot_light.get_set_test(0, "Controller|Configuration|Shutters|Enable shutters", True) - spot_light.get_set_test(0, "Controller|Configuration|Shutters|Inner angle", 60.0) - spot_light.get_set_test(0, "Controller|Configuration|Shutters|Outer angle", 75.0) - general.idle_wait(1.0) - screenshot_utils.take_screenshot_game_mode("SpotLight_5", spot_light_entity_name) - - # Update the Shadow controls, move the spot_light entity world translate position and take screenshot - spot_light.get_set_test(0, "Controller|Configuration|Shadows|Enable shadow", True) - spot_light.get_set_test(0, "Controller|Configuration|Shadows|Shadowmap size", 256.0) - azlmbr.components.TransformBus( - azlmbr.bus.Event, "SetWorldTranslation", spot_light.id, math.Vector3(0.7, -2.0, 1.9)) - general.idle_wait(1.0) - screenshot_utils.take_screenshot_game_mode("SpotLight_6", spot_light_entity_name) - - -if __name__ == "__main__": - run() diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py index 59e454479c..5b0ab0067c 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py @@ -25,7 +25,7 @@ class EditorComponent: """ EditorComponent class used to set and get the component property value using path EditorComponent object is returned from either of - EditorEntity.add_component() or Entity.add_components() or EditorEntity.get_component_objects() + EditorEntity.add_component() or Entity.add_components() or EditorEntity.get_components_of_type() which also assigns self.id and self.type_id to the EditorComponent object. """ @@ -94,6 +94,13 @@ class EditorComponent: """ return editor.EditorComponentAPIBus(bus.Broadcast, "IsComponentEnabled", self.id) + def disable_component(self): + """ + Used to disable the component using its id value. + :return: None + """ + editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [self.id]) + @staticmethod def get_type_ids(component_names: list) -> list: """ @@ -107,7 +114,6 @@ class EditorComponent: return type_ids - def convert_to_azvector3(xyz) -> azlmbr.math.Vector3: """ Converts a vector3-like element into a azlmbr.math.Vector3 @@ -120,6 +126,7 @@ def convert_to_azvector3(xyz) -> azlmbr.math.Vector3: else: raise ValueError("vector must be a 3 element list/tuple or azlmbr.math.Vector3") + class EditorEntity: """ Entity class is used to create and interact with Editor Entities. @@ -136,10 +143,11 @@ class EditorEntity: # Creation functions @classmethod - def find_editor_entity(cls, entity_name: str, must_be_unique : bool = False) -> EditorEntity: + def find_editor_entity(cls, entity_name: str, must_be_unique: bool = False) -> EditorEntity: """ Given Entity name, outputs entity object :param entity_name: Name of entity to find + :param must_be_unique: bool that asserts the entity_name specified is unique when set to True :return: EditorEntity class object """ entities = cls.find_editor_entities([entity_name]) @@ -147,14 +155,14 @@ class EditorEntity: if must_be_unique: assert len(entities) == 1, f"Failure: Multiple entities with name: '{entity_name}' when expected only one" - entity = cls(entities[0]) + entity = entities[0] return entity @classmethod - def find_editor_entities(cls, entity_names: List[str]) -> EditorEntity: + def find_editor_entities(cls, entity_names: List[str]) -> List[EditorEntity]: """ Given Entities names, returns a list of EditorEntity - :param entity_name: Name of entity to find + :param entity_names: List of entity names to find :return: List[EditorEntity] class object """ searchFilter = azlmbr.entity.SearchFilter() @@ -438,7 +446,7 @@ class EditorEntity: def set_local_rotation(self, new_rotation) -> None: """ Sets the set the local rotation(relative to the parent) of the current entity. - :param vector3_rotation: The math.Vector3 value to use for rotation on the entity (uses radians). + :param new_rotation: The math.Vector3 value to use for rotation on the entity (uses radians). :return: None """ new_rotation = convert_to_azvector3(new_rotation) @@ -454,7 +462,7 @@ class EditorEntity: def set_local_translation(self, new_translation) -> None: """ Sets the local translation(relative to the parent) of the current entity. - :param vector3_translation: The math.Vector3 value to use for translation on the entity. + :param new_translation: The math.Vector3 value to use for translation on the entity. :return: None """ new_translation = convert_to_azvector3(new_translation) From d158d36ce41a20fa5dc5c5563046cbed6ec6381f Mon Sep 17 00:00:00 2001 From: jromnoa <80134229+jromnoa@users.noreply.github.com> Date: Thu, 2 Dec 2021 13:14:48 -0800 Subject: [PATCH 4/8] add the test steps to the docstring for the AtomGPU_LightComponent_SpotLightScreenshotsMatchGoldenImages() function Signed-off-by: jromnoa <80134229+jromnoa@users.noreply.github.com> --- .../hydra_AtomGPU_SpotLightScreenshotTest.py | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py index 9b1c88a4fc..e1cbbbc613 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py @@ -74,8 +74,23 @@ def AtomGPU_LightComponent_SpotLightScreenshotsMatchGoldenImages(): Test Steps: 1. Find the Directional Light entity then disable its Directional Light component. - 2. Disable Global Skylight (IBL) and HDRi Skybox components on the Global Skylight entity. - + 2. Disable Global Skylight (IBL) component on the Global Skylight (IBL) entity. + 3. Disable HDRi Skybox component on the Global Skylight (IBL) entity. + 4. Create a Spot Light entity and rotate it. + 5. Attach a Light component to the Spot Light entity. + 6. Set the Light component Light Type to Spot (disk). + 7. Enter game mode and take a screenshot then exit game mode. + 8. Change the default material asset for the Ground Plane entity. + 9. Enter game mode and take a screenshot then exit game mode. + 10. Increase the Intensity value of the Light component. + 11. Enter game mode and take a screenshot then exit game mode. + 12. Change the Light component Color property value. + 13. Enter game mode and take a screenshot then exit game mode. + 14. Change the Light component Enable shutters, Inner angle, and Outer angle property values. + 15. Enter game mode and take a screenshot then exit game mode. + 16. Change the Light component Enable shadow and Shadowmap size property values then move Spot Light entity. + 17. Enter game mode and take a screenshot then exit game mode. + 18. Look for errors. :return: None """ @@ -124,7 +139,7 @@ def AtomGPU_LightComponent_SpotLightScreenshotsMatchGoldenImages(): global_skylight_component.disable_component() Report.critical_result(Tests.global_skylight_component_disabled, not global_skylight_component.is_enabled()) - # 3. Disable HDRi Skybox component on the Global Skylight (IBL) entity + # 3. Disable HDRi Skybox component on the Global Skylight (IBL) entity. hdri_skybox_name = AtomComponentProperties.hdri_skybox() hdri_skybox_component = global_skylight_entity.get_components_of_type([hdri_skybox_name])[0] hdri_skybox_component.disable_component() From 97cd722ac16c18253f12517b7199cb7bd35ef1a6 Mon Sep 17 00:00:00 2001 From: jromnoa <80134229+jromnoa@users.noreply.github.com> Date: Thu, 2 Dec 2021 14:42:37 -0800 Subject: [PATCH 5/8] remove shadowmap size calls to fix test, clean up some property value assignments for component tests Signed-off-by: jromnoa <80134229+jromnoa@users.noreply.github.com> --- .../PythonTests/Atom/atom_utils/atom_constants.py | 1 - .../tests/hydra_AtomGPU_SpotLightScreenshotTest.py | 14 ++++---------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py index 559f4aebee..59a07cf7bc 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py @@ -263,7 +263,6 @@ class AtomComponentProperties: 'Intensity': 'Controller|Configuration|Intensity', 'Light type': 'Controller|Configuration|Light type', 'Outer angle': 'Controller|Configuration|Shutters|Outer angle', - 'Shadowmap size': 'Controller|Configuration|Shadows|Shadowmap size', } return properties[property] diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py index e1cbbbc613..dd2470e8b2 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py @@ -46,9 +46,6 @@ class Tests: light_component_outer_angle_property_set = ( "Outer angle property was set", "Outer angle property was not set") - light_component_shadowmap_size_property_set = ( - "Shadowmap size was set", - "Shadowmap size was not set") material_component_material_asset_property_set = ( "Material Asset property was set", "Material Asset property was not set") @@ -186,7 +183,8 @@ def AtomGPU_LightComponent_SpotLightScreenshotsMatchGoldenImages(): AtomComponentProperties.material('Material Asset'), ground_plane_material_asset.id) Report.result( Tests.material_component_material_asset_property_set, - light_component.get_component_property_value(AtomComponentProperties.material('Material Asset'))) + ground_plane_material_component.get_component_property_value( + AtomComponentProperties.material('Material Asset')) == ground_plane_material_asset.id) # 9. Enter game mode and take a screenshot then exit game mode. TestHelper.enter_game_mode(Tests.enter_game_mode) @@ -248,16 +246,12 @@ def AtomGPU_LightComponent_SpotLightScreenshotsMatchGoldenImages(): TestHelper.exit_game_mode(Tests.exit_game_mode) TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0) - # 16. Change the Light component Enable shadow and Shadowmap size property values then move Spot Light entity. + # 16. Change the Light component Enable shadow and slightly move Spot Light entity. light_component.set_component_property_value(AtomComponentProperties.light('Enable shadow'), True) - light_component.set_component_property_value(AtomComponentProperties.light('Shadowmap size'), 256.0) - spot_light_entity.set_world_rotation(azlmbr.math.Vector3(0.7, -2.0, 1.9)) Report.result( Tests.light_component_enable_shadow_property_set, light_component.get_component_property_value(AtomComponentProperties.light('Enable shadow')) is True) - Report.result( - Tests.light_component_shadowmap_size_property_set, - light_component.get_component_property_value(AtomComponentProperties.light('Shadowmap size')) == 256.0) + spot_light_entity.set_world_rotation(azlmbr.math.Vector3(0.7, -2.0, 1.9)) # 17. Enter game mode and take a screenshot then exit game mode. TestHelper.enter_game_mode(Tests.enter_game_mode) From ad3148ece52405e481e6d1f5cc572915625d59c2 Mon Sep 17 00:00:00 2001 From: jromnoa <80134229+jromnoa@users.noreply.github.com> Date: Mon, 6 Dec 2021 16:05:55 -0800 Subject: [PATCH 6/8] add new enter_exit_game_mode_take_screenshot() shared function Signed-off-by: jromnoa <80134229+jromnoa@users.noreply.github.com> --- .../Atom/atom_utils/atom_component_helper.py | 22 ++++++++++ .../hydra_AtomGPU_AreaLightScreenshotTest.py | 34 ++++------------ .../hydra_AtomGPU_SpotLightScreenshotTest.py | 40 ++++--------------- .../editor_python_test_tools/utils.py | 6 +-- 4 files changed, 39 insertions(+), 63 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py index 6212ba4314..5fdd4c810d 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py @@ -126,6 +126,28 @@ def initial_viewport_setup(screen_width=1280, screen_height=720): general.update_viewport() +def enter_exit_game_mode_take_screenshot(screenshot_name, enter_game_tuple, exit_game_tuple, timeout_in_seconds=4): + """ + Enters game mode, takes a screenshot named screenshot_name (must include file extension), and exits game mode. + :param screenshot_name: string representing the name of the screenshot file, including file extension. + :param enter_game_tuple: tuple where the 1st string is success & 2nd string is failure for entering the game. + :param exit_game_tuple: tuple where the 1st string is success & 2nd string is failure for exiting the game. + :param timeout_in_seconds: int or float seconds to wait for entering/exiting game mode. + :return: None + """ + import azlmbr.legacy.general as general + + from editor_python_test_tools.utils import TestHelper + + from Atom.atom_utils.screenshot_utils import ScreenshotHelper + + TestHelper.enter_game_mode(enter_game_tuple) + TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=timeout_in_seconds) + ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking(screenshot_name) + TestHelper.exit_game_mode(exit_game_tuple) + TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=timeout_in_seconds) + + def create_basic_atom_rendering_scene(): """ Sets up a new scene inside the Editor for testing Atom rendering GPU output. diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_AreaLightScreenshotTest.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_AreaLightScreenshotTest.py index d9a24c13ec..03f842f9b4 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_AreaLightScreenshotTest.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_AreaLightScreenshotTest.py @@ -79,8 +79,8 @@ def AtomGPU_LightComponent_AreaLightScreenshotsMatchGoldenImages(): from editor_python_test_tools.utils import Report, Tracer, TestHelper from Atom.atom_utils.atom_constants import AtomComponentProperties, LIGHT_TYPES - from Atom.atom_utils.atom_component_helper import initial_viewport_setup, create_basic_atom_rendering_scene - from Atom.atom_utils.screenshot_utils import ScreenshotHelper + from Atom.atom_utils.atom_component_helper import ( + initial_viewport_setup, create_basic_atom_rendering_scene, enter_exit_game_mode_take_screenshot) DEGREE_RADIAN_FACTOR = 0.0174533 @@ -129,11 +129,7 @@ def AtomGPU_LightComponent_AreaLightScreenshotsMatchGoldenImages(): AtomComponentProperties.light('Color')) == light_component_color_value) # 5. Enter game mode and take a screenshot then exit game mode. - TestHelper.enter_game_mode(Tests.enter_game_mode) - TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0) - ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking("AreaLight_1.ppm") - TestHelper.exit_game_mode(Tests.exit_game_mode) - TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0) + enter_exit_game_mode_take_screenshot("AreaLight_1.ppm", Tests.enter_game_mode, Tests.exit_game_mode) # 6. Set the Intensity property of the Light component to 0.0. light_component.set_component_property_value(AtomComponentProperties.light('Intensity'), 0.0) @@ -148,11 +144,7 @@ def AtomGPU_LightComponent_AreaLightScreenshotsMatchGoldenImages(): light_component.get_component_property_value(AtomComponentProperties.light('Attenuation Radius Mode')) == 1) # 8. Enter game mode and take a screenshot then exit game mode. - TestHelper.enter_game_mode(Tests.enter_game_mode) - TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0) - ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking("AreaLight_2.ppm") - TestHelper.exit_game_mode(Tests.exit_game_mode) - TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0) + enter_exit_game_mode_take_screenshot("AreaLight_2.ppm", Tests.enter_game_mode, Tests.exit_game_mode) # 9. Set the Intensity property of the Light component to 1000.0 light_component.set_component_property_value(AtomComponentProperties.light('Intensity'), 1000.0) @@ -161,11 +153,7 @@ def AtomGPU_LightComponent_AreaLightScreenshotsMatchGoldenImages(): light_component.get_component_property_value(AtomComponentProperties.light('Intensity')) == 1000.0) # 10. Enter game mode and take a screenshot then exit game mode. - TestHelper.enter_game_mode(Tests.enter_game_mode) - TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0) - ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking("AreaLight_3.ppm") - TestHelper.exit_game_mode(Tests.exit_game_mode) - TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0) + enter_exit_game_mode_take_screenshot("AreaLight_3.ppm", Tests.enter_game_mode, Tests.exit_game_mode) # 11. Set the Light type property to Spot (disk) for the Light component & # rotate DEGREE_RADIAN_FACTOR * 90 degrees. @@ -179,11 +167,7 @@ def AtomGPU_LightComponent_AreaLightScreenshotsMatchGoldenImages(): AtomComponentProperties.light('Light type')) == LIGHT_TYPES['spot_disk']) # 12. Enter game mode and take a screenshot then exit game mode. - TestHelper.enter_game_mode(Tests.enter_game_mode) - TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0) - ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking("AreaLight_4.ppm") - TestHelper.exit_game_mode(Tests.exit_game_mode) - TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0) + enter_exit_game_mode_take_screenshot("AreaLight_4.ppm", Tests.enter_game_mode, Tests.exit_game_mode) # 13. Set the Light type property to Point (sphere) instead of Spot (disk) for the Light component. light_component.set_component_property_value( @@ -194,11 +178,7 @@ def AtomGPU_LightComponent_AreaLightScreenshotsMatchGoldenImages(): AtomComponentProperties.light('Light type')) == LIGHT_TYPES['sphere']) # 14. Enter game mode and take a screenshot then exit game mode. - TestHelper.enter_game_mode(Tests.enter_game_mode) - TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0) - ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking("AreaLight_4.ppm") - TestHelper.exit_game_mode(Tests.exit_game_mode) - TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0) + enter_exit_game_mode_take_screenshot("AreaLight_5.ppm", Tests.enter_game_mode, Tests.exit_game_mode) # 15. Delete the Area Light entity. area_light_entity.delete() diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py index dd2470e8b2..0c099dc04d 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py @@ -101,8 +101,8 @@ def AtomGPU_LightComponent_SpotLightScreenshotsMatchGoldenImages(): from editor_python_test_tools.utils import Report, Tracer, TestHelper from Atom.atom_utils.atom_constants import AtomComponentProperties, LIGHT_TYPES - from Atom.atom_utils.atom_component_helper import initial_viewport_setup, create_basic_atom_rendering_scene - from Atom.atom_utils.screenshot_utils import ScreenshotHelper + from Atom.atom_utils.atom_component_helper import ( + initial_viewport_setup, create_basic_atom_rendering_scene, enter_exit_game_mode_take_screenshot) DEGREE_RADIAN_FACTOR = 0.0174533 @@ -164,11 +164,7 @@ def AtomGPU_LightComponent_SpotLightScreenshotsMatchGoldenImages(): AtomComponentProperties.light('Light type')) == LIGHT_TYPES['spot_disk']) # 7. Enter game mode and take a screenshot then exit game mode. - TestHelper.enter_game_mode(Tests.enter_game_mode) - TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0) - ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking("SpotLight_1.ppm") - TestHelper.exit_game_mode(Tests.exit_game_mode) - TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0) + enter_exit_game_mode_take_screenshot("SpotLight_1.ppm", Tests.enter_game_mode, Tests.exit_game_mode) # 8. Change the default material asset for the Ground Plane entity. ground_plane_name = "Ground Plane" @@ -187,11 +183,7 @@ def AtomGPU_LightComponent_SpotLightScreenshotsMatchGoldenImages(): AtomComponentProperties.material('Material Asset')) == ground_plane_material_asset.id) # 9. Enter game mode and take a screenshot then exit game mode. - TestHelper.enter_game_mode(Tests.enter_game_mode) - TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0) - ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking("SpotLight_2.ppm") - TestHelper.exit_game_mode(Tests.exit_game_mode) - TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0) + enter_exit_game_mode_take_screenshot("SpotLight_2.ppm", Tests.enter_game_mode, Tests.exit_game_mode) # 10. Increase the Intensity value of the Light component. light_component.set_component_property_value(AtomComponentProperties.light('Intensity'), 800.0) @@ -201,11 +193,7 @@ def AtomGPU_LightComponent_SpotLightScreenshotsMatchGoldenImages(): AtomComponentProperties.light('Intensity')) == 800.0) # 11. Enter game mode and take a screenshot then exit game mode. - TestHelper.enter_game_mode(Tests.enter_game_mode) - TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0) - ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking("SpotLight_3.ppm") - TestHelper.exit_game_mode(Tests.exit_game_mode) - TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0) + enter_exit_game_mode_take_screenshot("SpotLight_3.ppm", Tests.enter_game_mode, Tests.exit_game_mode) # 12. Change the Light component Color property value. color_value = azlmbr.math.Color(47.0 / 255.0, 75.0 / 255.0, 37.0 / 255.0, 255.0 / 255.0) @@ -215,11 +203,7 @@ def AtomGPU_LightComponent_SpotLightScreenshotsMatchGoldenImages(): light_component.get_component_property_value(AtomComponentProperties.light('Color')) == color_value) # 13. Enter game mode and take a screenshot then exit game mode. - TestHelper.enter_game_mode(Tests.enter_game_mode) - TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0) - ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking("SpotLight_4.ppm") - TestHelper.exit_game_mode(Tests.exit_game_mode) - TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0) + enter_exit_game_mode_take_screenshot("SpotLight_4.ppm", Tests.enter_game_mode, Tests.exit_game_mode) # 14. Change the Light component Enable shutters, Inner angle, and Outer angle property values. enable_shutters = True @@ -240,11 +224,7 @@ def AtomGPU_LightComponent_SpotLightScreenshotsMatchGoldenImages(): light_component.get_component_property_value(AtomComponentProperties.light('Outer angle')) == outer_angle) # 15. Enter game mode and take a screenshot then exit game mode. - TestHelper.enter_game_mode(Tests.enter_game_mode) - TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0) - ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking("SpotLight_5.ppm") - TestHelper.exit_game_mode(Tests.exit_game_mode) - TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0) + enter_exit_game_mode_take_screenshot("SpotLight_5.ppm", Tests.enter_game_mode, Tests.exit_game_mode) # 16. Change the Light component Enable shadow and slightly move Spot Light entity. light_component.set_component_property_value(AtomComponentProperties.light('Enable shadow'), True) @@ -254,11 +234,7 @@ def AtomGPU_LightComponent_SpotLightScreenshotsMatchGoldenImages(): spot_light_entity.set_world_rotation(azlmbr.math.Vector3(0.7, -2.0, 1.9)) # 17. Enter game mode and take a screenshot then exit game mode. - TestHelper.enter_game_mode(Tests.enter_game_mode) - TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0) - ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking("SpotLight_6.ppm") - TestHelper.exit_game_mode(Tests.exit_game_mode) - TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0) + enter_exit_game_mode_take_screenshot("SpotLight_6.ppm", Tests.enter_game_mode, Tests.exit_game_mode) # 18. Look for errors. TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0) diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/utils.py index 481d73274f..7231af4a12 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/utils.py @@ -56,8 +56,7 @@ class TestHelper: general.idle_wait_frames(200) @staticmethod - def enter_game_mode(msgtuple_success_fail : Tuple[str, str]): - # type: (tuple) -> None + def enter_game_mode(msgtuple_success_fail: Tuple[str, str]) -> None: """ :param msgtuple_success_fail: The tuple with the expected/unexpected messages for entering game mode. @@ -70,8 +69,7 @@ class TestHelper: Report.critical_result(msgtuple_success_fail, general.is_in_game_mode()) @staticmethod - def multiplayer_enter_game_mode(msgtuple_success_fail : Tuple[str, str], sv_default_player_spawn_asset : str): - # type: (tuple) -> None + def multiplayer_enter_game_mode(msgtuple_success_fail: Tuple[str, str], sv_default_player_spawn_asset: str) -> None: """ :param msgtuple_success_fail: The tuple with the expected/unexpected messages for entering game mode. :param sv_default_player_spawn_asset: The path to the network player prefab that will be automatically spawned upon entering gamemode. The engine default is "prefabs/player.network.spawnable" From 9d6dc1ac637eb50ad2cd9868fd91720be2de2f48 Mon Sep 17 00:00:00 2001 From: jromnoa <80134229+jromnoa@users.noreply.github.com> Date: Mon, 6 Dec 2021 16:38:42 -0800 Subject: [PATCH 7/8] add ATTENUATION_RADIUS_MODE constant with its 2 available options of automatic or explicit Signed-off-by: jromnoa <80134229+jromnoa@users.noreply.github.com> --- .../PythonTests/Atom/atom_utils/atom_constants.py | 13 +++++++++++++ .../tests/hydra_AtomGPU_AreaLightScreenshotTest.py | 8 +++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py index 59a07cf7bc..400349c5ee 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py @@ -18,6 +18,12 @@ LIGHT_TYPES = { 'simple_spot': 7, } +# Attenuation Radius Mode options for the Light component. +ATTENUATION_RADIUS_MODE = { + 'automatic': 1, + 'explicit': 0, +} + class AtomComponentProperties: """ @@ -249,7 +255,14 @@ class AtomComponentProperties: def light(property: str = 'name') -> str: """ Light component properties. + - 'Attenuation Radius Mode' controls whether the attenuation radius is calculated automatically or explicitly. + - 'Color' the RGB value to set for the color of the light. + - 'Enable shadow' toggle for enabling shadows for the light. + - 'Enable shutters' toggle for enabling shutters for the light. + - 'Inner angle' inner angle value for the shutters (in degrees) + - 'Intensity' the intensity of the light in the set photometric unit (float with no ceiling). - 'Light type' from atom_constants.py LIGHT_TYPES + - 'Outer angle' outer angle value for the shutters (in degrees) :param property: From the last element of the property tree path. Default 'name' for component name string. :return: Full property path OR component name if no property specified. """ diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_AreaLightScreenshotTest.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_AreaLightScreenshotTest.py index 03f842f9b4..a56c72e46c 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_AreaLightScreenshotTest.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_AreaLightScreenshotTest.py @@ -78,7 +78,7 @@ def AtomGPU_LightComponent_AreaLightScreenshotsMatchGoldenImages(): from editor_python_test_tools.editor_entity_utils import EditorEntity from editor_python_test_tools.utils import Report, Tracer, TestHelper - from Atom.atom_utils.atom_constants import AtomComponentProperties, LIGHT_TYPES + from Atom.atom_utils.atom_constants import AtomComponentProperties, ATTENUATION_RADIUS_MODE, LIGHT_TYPES from Atom.atom_utils.atom_component_helper import ( initial_viewport_setup, create_basic_atom_rendering_scene, enter_exit_game_mode_take_screenshot) @@ -138,10 +138,12 @@ def AtomGPU_LightComponent_AreaLightScreenshotsMatchGoldenImages(): light_component.get_component_property_value(AtomComponentProperties.light('Intensity')) == 0.0) # 7. Set the Attenuation Radius Mode property of the Light component to 1 (automatic). - light_component.set_component_property_value(AtomComponentProperties.light('Attenuation Radius Mode'), 1) + light_component.set_component_property_value( + AtomComponentProperties.light('Attenuation Radius Mode'), ATTENUATION_RADIUS_MODE['automatic']) Report.result( Tests.light_component_attenuation_radius_property_set, - light_component.get_component_property_value(AtomComponentProperties.light('Attenuation Radius Mode')) == 1) + light_component.get_component_property_value( + AtomComponentProperties.light('Attenuation Radius Mode')) == ATTENUATION_RADIUS_MODE['automatic']) # 8. Enter game mode and take a screenshot then exit game mode. enter_exit_game_mode_take_screenshot("AreaLight_2.ppm", Tests.enter_game_mode, Tests.exit_game_mode) From 523691497d505a586519700fe495caa85f528631 Mon Sep 17 00:00:00 2001 From: jromnoa <80134229+jromnoa@users.noreply.github.com> Date: Mon, 6 Dec 2021 16:43:07 -0800 Subject: [PATCH 8/8] call AtomComponentProperties.light(), AtomComponentProperties.directional_light(), etc. as is for its component name, rather than make a component name variable Signed-off-by: jromnoa <80134229+jromnoa@users.noreply.github.com> --- .../hydra_AtomGPU_SpotLightScreenshotTest.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py index 0c099dc04d..fbfb6e3468 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py @@ -123,22 +123,22 @@ def AtomGPU_LightComponent_SpotLightScreenshotsMatchGoldenImages(): # Test steps begin. # 1. Find the Directional Light entity then disable its Directional Light component. - directional_light_name = AtomComponentProperties.directional_light() - directional_light_entity = EditorEntity.find_editor_entity(directional_light_name) - directional_light_component = directional_light_entity.get_components_of_type([directional_light_name])[0] + directional_light_entity = EditorEntity.find_editor_entity(AtomComponentProperties.directional_light()) + directional_light_component = directional_light_entity.get_components_of_type( + [AtomComponentProperties.directional_light()])[0] directional_light_component.disable_component() Report.critical_result(Tests.directional_light_component_disabled, not directional_light_component.is_enabled()) # 2. Disable Global Skylight (IBL) component on the Global Skylight (IBL) entity. - global_skylight_name = AtomComponentProperties.global_skylight() - global_skylight_entity = EditorEntity.find_editor_entity(global_skylight_name) - global_skylight_component = global_skylight_entity.get_components_of_type([global_skylight_name])[0] + global_skylight_entity = EditorEntity.find_editor_entity(AtomComponentProperties.global_skylight()) + global_skylight_component = global_skylight_entity.get_components_of_type( + [AtomComponentProperties.global_skylight()])[0] global_skylight_component.disable_component() Report.critical_result(Tests.global_skylight_component_disabled, not global_skylight_component.is_enabled()) # 3. Disable HDRi Skybox component on the Global Skylight (IBL) entity. - hdri_skybox_name = AtomComponentProperties.hdri_skybox() - hdri_skybox_component = global_skylight_entity.get_components_of_type([hdri_skybox_name])[0] + hdri_skybox_component = global_skylight_entity.get_components_of_type( + [AtomComponentProperties.hdri_skybox()])[0] hdri_skybox_component.disable_component() Report.critical_result(Tests.hdri_skybox_component_disabled, not hdri_skybox_component.is_enabled()) @@ -151,8 +151,7 @@ def AtomGPU_LightComponent_SpotLightScreenshotsMatchGoldenImages(): Report.critical_result(Tests.spot_light_entity_created, spot_light_entity.exists()) # 5. Attach a Light component to the Spot Light entity. - light_name = AtomComponentProperties.light() - light_component = spot_light_entity.add_component(light_name) + light_component = spot_light_entity.add_component(AtomComponentProperties.light()) Report.critical_result(Tests.light_component_added, light_component.is_enabled()) # 6. Set the Light component Light Type to Spot (disk).