diff --git a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py index 339108090f..0f13dd6b20 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py @@ -87,12 +87,18 @@ class AtomComponentProperties: def decal(property: str = 'name') -> str: """ Decal component properties. + - 'Attenuation Angle' controls how much the angle between geometry and decal impacts opacity. 0-1 Radians + - 'Opacity' where one is opaque and zero is transparent + - 'Sort Key' 0-255 stacking z-sort like key to define which decal is on top of another - 'Material' the material Asset.id of the decal. :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. """ properties = { 'name': 'Decal', + 'Attenuation Angle': 'Controller|Configuration|Attenuation Angle', + 'Opacity': 'Controller|Configuration|Opacity', + 'Sort Key': 'Controller|Configuration|Sort Key', 'Material': 'Controller|Configuration|Material', } return properties[property] diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DecalAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DecalAdded.py index eb5e24e3a6..238a2e31cb 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DecalAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DecalAdded.py @@ -8,49 +8,61 @@ SPDX-License-Identifier: Apache-2.0 OR MIT class Tests: camera_creation = ( "Camera Entity successfully created", - "Camera Entity failed to be created") + "P0: Camera Entity failed to be created") camera_component_added = ( "Camera component was added to entity", - "Camera component failed to be added to entity") + "P0: Camera component failed to be added to entity") camera_component_check = ( "Entity has a Camera component", - "Entity failed to find Camera component") + "P0: Entity failed to find Camera component") creation_undo = ( "UNDO Entity creation success", - "UNDO Entity creation failed") + "P0: UNDO Entity creation failed") creation_redo = ( "REDO Entity creation success", - "REDO Entity creation failed") + "P0: REDO Entity creation failed") decal_creation = ( "Decal Entity successfully created", - "Decal Entity failed to be created") + "P0: Decal Entity failed to be created") decal_component = ( "Entity has a Decal component", - "Entity failed to find Decal component") + "P0: Entity failed to find Decal component") + decal_component_removed = ( + "Decal component removed", + "P0: Decal component failed to be removed") material_property_set = ( "Material property set on Decal component", - "Couldn't set Material property on Decal component") + "P0: Couldn't set Material property on Decal component") + attenuation_property_set = ( + "Attenuation Angle property set on Decal component", + "P1: Couldn't set Attenuation Angle property on Decal component") + opacity_property_set = ( + "Opacity property set on Decal component", + "P1: Coudn't set Opacity property on Decal component") + sort_key_property_set = ( + "Sort Key property set on Decal component", + "P1: Couldn't set Sort Key property on Decal component") enter_game_mode = ( "Entered game mode", - "Failed to enter game mode") + "P0: Failed to enter game mode") exit_game_mode = ( "Exited game mode", - "Couldn't exit game mode") + "P0: Couldn't exit game mode") is_visible = ( "Entity is visible", - "Entity was not visible") + "P0: Entity was not visible") is_hidden = ( "Entity is hidden", - "Entity was not hidden") + "P0: Entity was not hidden") entity_deleted = ( "Entity deleted", - "Entity was not deleted") + "P0: Entity was not deleted") deletion_undo = ( "UNDO deletion success", - "UNDO deletion failed") + "P0: UNDO deletion failed") deletion_redo = ( "REDO deletion success", - "REDO deletion failed") + "P0: REDO deletion failed") def AtomEditorComponents_Decal_AddedToEntity(): @@ -71,14 +83,18 @@ def AtomEditorComponents_Decal_AddedToEntity(): 2) Add Decal component to Decal entity. 3) UNDO the entity creation and component addition. 4) REDO the entity creation and component addition. - 5) Enter/Exit game mode. - 6) Test IsHidden. - 7) Test IsVisible. - 8) Set Material property on Decal component. - 9) Delete Decal entity. - 10) UNDO deletion. - 11) REDO deletion. - 12) Look for errors and asserts. + 5) Set Material property on Decal component. + 6) Set Attenuation Angle property on Decal component. + 7) Set Opacity property on Decal component + 8) Set Sort Key property on Decal Component + 9) Remove Decal component then UNDO the remove + 10) Enter/Exit game mode. + 11) Test IsHidden. + 12) Test IsVisible. + 13) Delete Decal entity. + 14) UNDO deletion. + 15) REDO deletion. + 16) Look for errors and asserts. :return: None """ @@ -130,42 +146,69 @@ def AtomEditorComponents_Decal_AddedToEntity(): general.idle_wait_frames(1) Report.result(Tests.creation_redo, decal_entity.exists()) - # 5. Enter/Exit game mode. + # 5. Set Material property on Decal component. + decal_material_asset_path = os.path.join("materials", "basic_grey.azmaterial") + decal_material_asset = Asset.find_asset_by_path(decal_material_asset_path, False) + decal_component.set_component_property_value(AtomComponentProperties.decal('Material'), decal_material_asset.id) + get_material_property = decal_component.get_component_property_value(AtomComponentProperties.decal('Material')) + Report.result(Tests.material_property_set, get_material_property == decal_material_asset.id) + + # 6. Set Attenuation Angle property on Decal component + decal_component.set_component_property_value(AtomComponentProperties.decal('Attenuation Angle'), value=0.75) + get_attenuation_property = decal_component.get_component_property_value( + AtomComponentProperties.decal('Attenuation Angle')) + Report.result(Tests.attenuation_property_set, get_attenuation_property == 0.75) + + # 7. Set Opacity property on Decal component + decal_component.set_component_property_value(AtomComponentProperties.decal('Opacity'), value=0.5) + get_opacity_property = decal_component.get_component_property_value(AtomComponentProperties.decal('Opacity')) + Report.result(Tests.opacity_property_set, get_opacity_property == 0.5) + + # 8. Set Sort Key property on Decal component + decal_component.set_component_property_value(AtomComponentProperties.decal('Sort Key'), value=255.0) + get_sort_key_property = decal_component.get_component_property_value(AtomComponentProperties.decal('Sort Key')) + Report.result(Tests.sort_key_property_set, get_sort_key_property == 255.0) + decal_component.set_component_property_value(AtomComponentProperties.decal('Sort Key'), value=0) + get_sort_key_property = decal_component.get_component_property_value(AtomComponentProperties.decal('Sort Key')) + Report.result(Tests.sort_key_property_set, get_sort_key_property == 0) + + # 9. Remove Decal component then UNDO the remove + decal_component.remove() + general.idle_wait_frames(1) + Report.result(Tests.decal_component_removed, not decal_entity.has_component(AtomComponentProperties.decal())) + general.undo() + general.idle_wait_frames(1) + Report.result(Tests.decal_component, decal_entity.has_component(AtomComponentProperties.decal())) + + # 10. Enter/Exit game mode. TestHelper.enter_game_mode(Tests.enter_game_mode) general.idle_wait_frames(1) TestHelper.exit_game_mode(Tests.exit_game_mode) - # 6. Test IsHidden. + # 11. Test IsHidden. decal_entity.set_visibility_state(False) Report.result(Tests.is_hidden, decal_entity.is_hidden() is True) - # 7. Test IsVisible. + # 12. Test IsVisible. decal_entity.set_visibility_state(True) general.idle_wait_frames(1) Report.result(Tests.is_visible, decal_entity.is_visible() is True) - # 8. Set Material property on Decal component. - decal_material_asset_path = os.path.join("materials", "basic_grey.azmaterial") - decal_material_asset = Asset.find_asset_by_path(decal_material_asset_path, False) - decal_component.set_component_property_value(AtomComponentProperties.decal('Material'), decal_material_asset.id) - get_material_property = decal_component.get_component_property_value(AtomComponentProperties.decal('Material')) - Report.result(Tests.material_property_set, get_material_property == decal_material_asset.id) - - # 9. Delete Decal entity. + # 13. Delete Decal entity. decal_entity.delete() Report.result(Tests.entity_deleted, not decal_entity.exists()) - # 10. UNDO deletion. + # 14. UNDO deletion. general.undo() general.idle_wait_frames(1) Report.result(Tests.deletion_undo, decal_entity.exists()) - # 11. REDO deletion. + # 15. REDO deletion. general.redo() general.idle_wait_frames(1) Report.result(Tests.deletion_redo, not decal_entity.exists()) - # 12. Look for errors and asserts. + # 16. Look for errors and asserts. TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0) for error_info in error_tracer.errors: Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}") 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 d8d4a77a65..7803d8caa6 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 @@ -34,6 +34,7 @@ class EditorComponent: 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. self.type_id is the UUID for the component type as provided by an ebus call. + self.id is an azlmbr.entity.EntityComponentIdPair which contains both entity and component id's """ def __init__(self, type_id: uuid): @@ -270,6 +271,13 @@ class EditorComponent: warnings.warn("disable_component is deprecated, use set_enabled(False) instead.", DeprecationWarning) editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [self.id]) + def remove(self): + """ + Removes the component from its associated entity. Essentially a delete since only UNDO can return it. + :return: None + """ + editor.EditorComponentAPIBus(bus.Broadcast, "RemoveComponents", [self.id]) + @staticmethod def get_type_ids(component_names: list, entity_type: EditorEntityType = EditorEntityType.GAME) -> list: """ diff --git a/AutomatedTesting/Materials/decal/airship_symbol_decal.material b/AutomatedTesting/Materials/decal/airship_symbol_decal.material new file mode 100644 index 0000000000..40060aafeb --- /dev/null +++ b/AutomatedTesting/Materials/decal/airship_symbol_decal.material @@ -0,0 +1,36 @@ +{ + "materialType": "Materials/Types/StandardPBR.materialtype", + "materialTypeVersion": 4, + "properties": { + "baseColor": { + "textureMap": "Materials/decal/airship_symbol_decal.tif" + }, + "general": { + "doubleSided": true + }, + "metallic": { + "useTexture": false + }, + "normal": { + "useTexture": false + }, + "opacity": { + "alphaSource": "Split", + "factor": 0.6899999976158142, + "mode": "Cutout", + "textureMap": "Materials/decal/airship_symbol_decal.tif" + }, + "roughness": { + "useTexture": false + }, + "specularF0": { + "useTexture": false + }, + "uv": { + "center": [ + 0.0, + 1.0 + ] + } + } +} \ No newline at end of file diff --git a/AutomatedTesting/Materials/decal/airship_symbol_decal.tif b/AutomatedTesting/Materials/decal/airship_symbol_decal.tif new file mode 100644 index 0000000000..9b571a14fa --- /dev/null +++ b/AutomatedTesting/Materials/decal/airship_symbol_decal.tif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2252ba28e19432d99e58fa03b672f855e1f520805eda71764e076fe349e1915a +size 4205906 diff --git a/AutomatedTesting/Materials/decal/scorch_01_decal.material b/AutomatedTesting/Materials/decal/scorch_01_decal.material new file mode 100644 index 0000000000..3f700d483a --- /dev/null +++ b/AutomatedTesting/Materials/decal/scorch_01_decal.material @@ -0,0 +1,35 @@ +{ + "materialType": "Materials/Types/StandardPBR.materialtype", + "materialTypeVersion": 4, + "properties": { + "baseColor": { + "textureMap": "Materials/decal/scorch_01_decal.tif" + }, + "general": { + "doubleSided": true + }, + "metallic": { + "useTexture": false + }, + "normal": { + "useTexture": false + }, + "opacity": { + "factor": 1.0, + "mode": "Blended", + "textureMap": "Materials/decal/scorch_01_decal.tif" + }, + "roughness": { + "useTexture": false + }, + "specularF0": { + "useTexture": false + }, + "uv": { + "center": [ + 0.0, + 1.0 + ] + } + } +} \ No newline at end of file diff --git a/AutomatedTesting/Materials/decal/scorch_01_decal.tif b/AutomatedTesting/Materials/decal/scorch_01_decal.tif new file mode 100644 index 0000000000..935388bd93 --- /dev/null +++ b/AutomatedTesting/Materials/decal/scorch_01_decal.tif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:889072da11d2034a0d37ec6ae81b551a61b62d6d602965b0b919a999c56d67e2 +size 16793812