| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357 |
- """
- 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:
- creation_undo = (
- "UNDO Entity creation success",
- "P0: UNDO Entity creation failed")
- creation_redo = (
- "REDO Entity creation success",
- "P0: REDO Entity creation failed")
- material_creation = (
- "Material Entity successfully created",
- "P0: Material Entity failed to be created")
- material_component = (
- "Entity has a Material component",
- "P0: Entity failed to find Material component")
- material_disabled = (
- "Material component disabled",
- "P0: Material component was not disabled.")
- actor_component = (
- "Entity has an Actor component",
- "P0: Entity did not have an Actor component")
- actor_undo = (
- "Entity Actor component gone",
- "P0: Entity Actor component add failed to undo")
- mesh_component = (
- "Entity has a Mesh component",
- "P0: Entity did not have a Mesh component")
- material_enabled = (
- "Material component enabled",
- "P0: Material component was not enabled.")
- enter_game_mode = (
- "Entered game mode",
- "P0: Failed to enter game mode")
- exit_game_mode = (
- "Exited game mode",
- "P0: Couldn't exit game mode")
- is_visible = (
- "Entity is visible",
- "P0: Entity was not visible")
- is_hidden = (
- "Entity is hidden",
- "P0: Entity was not hidden")
- entity_deleted = (
- "Entity deleted",
- "P0: Entity was not deleted")
- deletion_undo = (
- "UNDO deletion success",
- "P0: UNDO deletion failed")
- deletion_redo = (
- "REDO deletion success",
- "P0: REDO deletion failed")
- model_asset = (
- "Model Asset set",
- "P1: Model Asset not set")
- default_material = (
- "Default Material set to metal_gold.azmaterial",
- "P1: Default Material was not set as expected")
- model_material_count = (
- "Model Material count is 5 as expected",
- "P1: Model Material count did not reach 5 within timeout")
- model_material_label = (
- "Model Material zero index is labeled lambert0",
- "P1: Model Material index zero does not have the expected label")
- model_material_asset_path = (
- "Asset path of the Material Model index zero is as expected",
- "P1: Material Model index zero Asset path is not as expected")
- enable_lod_materials = (
- "Enable LOD Materials property set to True",
- "P1: Enable LOD Materials property was not set correctly ")
- lod_material_count = (
- "LOD Material count is 5 as expected",
- "P1: LOD Material count did not reach 5 within timeout")
- lod_material_label = (
- "LOD Material zero index is labeled lambert0",
- "P1: LOD Material index zero does not have the expected label")
- lod_material_asset_path = (
- "Asset path of LOD Material index zero first item is as expected",
- "P1: Asset path of LOD Material index zero first item is not as expected")
- lod_material_set = (
- "LOD material zero is set to metal_gold.azmaterial id",
- "P1: LOD material zero was not property set as expected")
- controler_materials_is_empty_container = (
- "Controller|Materials is a container property and is empty",
- "P1: Controller|Materials is not a container or is not empty as expected")
- clear_default_material = (
- "Default Material cleared with MaterialComponentRequestBus",
- "P1: Default Material FAILED to clear with MaterialComponentRequestBus. does not contain empty AssetId.")
- def AtomEditorComponents_Material_AddedToEntity():
- """
- Summary:
- Tests the Material component can be added to an entity and has the expected functionality.
- Test setup:
- - Wait for Editor idle loop.
- - Open the "Base" level.
- Expected Behavior:
- The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
- Creation and deletion undo/redo should also work.
- Test Steps:
- 1) Create a Material entity with no components.
- 2) Add a Material component to Material entity.
- 3) UNDO the entity creation and component addition.
- 4) REDO the entity creation and component addition.
- 5) Verify Material component not enabled.
- 6) Add Actor component since it is required by the Material component.
- 7) Verify Material component is enabled.
- 8) Remove Actor component
- 9) Verify Material component not enabled.
- 10) Add Mesh component since it is required by the Material component.
- 11) Verify Material component is enabled.
- 12) Set a model asset to Mesh component
- 13) Wait for Model Materials to indicate count 5 terminate early if container fails to reflect correct count
- 14) Get the slot zero material from the container property Model Materials (materials defined in the fbx)
- 15) Enable the use of LOD materials
- 16) Wait for LOD Materials to indicate count 5 terminate early if container fails to reflect correct count
- 17) Get the slot zero list from LOD Material
- 18) Override the slot zero LOD Material asset using EditorMaterialComponentSlot method SetAssetId
- 19) Clear the LOD Material override and confirm the active asset is the default value
- 20) Set the Default Material asset to an override using set component property by path
- 21) Clear the assignment of a default material using MaterialComponentRequestBus and confirm null asset
- 22) Set the Default Material asset using MaterialComponentRequestBus
- 23) Enter/Exit game mode.
- 24) Test IsHidden.
- 25) Test IsVisible.
- 26) Delete Material entity.
- 27) UNDO deletion.
- 28) REDO deletion.
- 29) Look for errors or asserts.
- :return: None
- """
- import os
- import azlmbr.legacy.general as general
- import azlmbr.bus as bus
- import azlmbr.render as render
- 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
- 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("Graphics", "base_empty")
- # Test steps begin.
- # 1. Create a Material entity with no components.
- material_entity = EditorEntity.create_editor_entity(AtomComponentProperties.material())
- Report.critical_result(Tests.material_creation, material_entity.exists())
- # 2. Add a Material component to Material entity.
- material_component = material_entity.add_component(AtomComponentProperties.material())
- Report.critical_result(
- Tests.material_component,
- material_entity.has_component(AtomComponentProperties.material()))
- # 3. UNDO the entity creation and component addition.
- # -> UNDO component addition.
- general.undo()
- # -> UNDO naming entity.
- general.undo()
- # -> UNDO selecting entity.
- general.undo()
- # -> UNDO entity creation.
- general.undo()
- general.idle_wait_frames(1)
- Report.result(Tests.creation_undo, not material_entity.exists())
- # 4. REDO the entity creation and component addition.
- # -> REDO entity creation.
- general.redo()
- # -> REDO selecting entity.
- general.redo()
- # -> REDO naming entity.
- general.redo()
- # -> REDO component addition.
- general.redo()
- general.idle_wait_frames(1)
- Report.result(Tests.creation_redo, material_entity.exists())
- # 5. Verify Material component not enabled.
- Report.result(Tests.material_disabled, not material_component.is_enabled())
- # 6. Add Actor component since it is required by the Material component.
- actor_component = material_entity.add_component(AtomComponentProperties.actor())
- Report.result(Tests.actor_component, material_entity.has_component(AtomComponentProperties.actor()))
- # 7. Verify Material component is enabled.
- Report.result(Tests.material_enabled, material_component.is_enabled())
- # 8. Remove actor component.
- actor_component.remove()
- general.idle_wait_frames(1)
- Report.result(Tests.actor_undo, not material_entity.has_component(AtomComponentProperties.actor()))
- # 9. Verify Material component not enabled.
- Report.result(Tests.material_disabled, not material_component.is_enabled())
- # 10. Add Mesh component since it is required by the Material component.
- mesh_component = material_entity.add_component(AtomComponentProperties.mesh())
- Report.result(Tests.mesh_component, material_entity.has_component(AtomComponentProperties.mesh()))
- # 11. Verify Material component is enabled.
- Report.result(Tests.material_enabled, material_component.is_enabled())
- # 12. Set a model asset to Mesh component
- # Set a simple model to ensure that the more complex model will load cleanly
- model_path = os.path.join('objects', 'cube.fbx.azmodel')
- model = Asset.find_asset_by_path(model_path)
- mesh_component.set_component_property_value(AtomComponentProperties.mesh('Model Asset'), model.id)
- general.idle_wait_frames(1)
- # Update model asset to a model with 5 LOD materials
- model_path = os.path.join('testdata', 'objects', 'modelhotreload', 'sphere_5lods.fbx.azmodel')
- model = Asset.find_asset_by_path(model_path)
- mesh_component.set_component_property_value(AtomComponentProperties.mesh('Model Asset'), model.id)
- general.idle_wait_frames(1)
- Report.result(
- Tests.model_asset,
- mesh_component.get_component_property_value(AtomComponentProperties.mesh('Model Asset')) == model.id)
- # 13. Wait for Model Materials to indicate count 5 terminate early if container fails to reflect correct count
- Report.critical_result(Tests.model_material_count, TestHelper.wait_for_condition(
- lambda: (material_component.get_container_count(
- AtomComponentProperties.material('Model Materials')) == 5), timeout_in_seconds=5))
- # 14. Get the slot zero material from the container property Model Materials (materials defined in the fbx)
- item = material_component.get_container_item(AtomComponentProperties.material('Model Materials'), key=0)
- # item is an EditorMaterialComponentSlot which defines a number of method interfaces found in
- # .\o3de\Gems\AtomLyIntegration\CommonFeatures\Code\Source\Material\EditorMaterialComponentSlot.cpp
- label = item.GetLabel()
- Report.result(Tests.model_material_label, label == 'lambert0')
- # Asset path for lambert0 is 'objects/sphere_5lods_lambert0_11781189446760285338.fbx.azmaterial'; numbers may vary
- default_asset = Asset(item.GetDefaultAssetId())
- default_asset_path = default_asset.get_path()
- Report.result(
- Tests.model_material_asset_path,
- default_asset_path.startswith('testdata/objects/modelhotreload/sphere_5lods_lambert0_'))
- # 15. Enable the use of LOD materials
- material_component.set_component_property_value(AtomComponentProperties.material('Enable LOD Materials'), True)
- Report.result(
- Tests.enable_lod_materials,
- material_component.get_component_property_value(
- AtomComponentProperties.material('Enable LOD Materials')) is True)
- # 16. Wait for LOD Materials to indicate count 5 terminate early if container fails to reflect correct count
- Report.critical_result(Tests.lod_material_count, TestHelper.wait_for_condition(
- lambda: (material_component.get_container_count(
- AtomComponentProperties.material('LOD Materials')) == 5), timeout_in_seconds=5))
- # 17. Get the slot zero list from LOD Material
- item = material_component.get_container_item(
- AtomComponentProperties.material('LOD Materials'), key=0) # list of EditorMaterialComponentSlot
- active_asset = Asset(item[0].GetActiveAssetId())
- active_asset_path = active_asset.get_path()
- Report.result(
- Tests.lod_material_asset_path,
- active_asset_path.startswith('testdata/objects/modelhotreload/sphere_5lods_lambert0_'))
- # Setup a material for overrides in further testing
- material_path = os.path.join('materials', 'presets', 'pbr', 'metal_gold.azmaterial')
- metal_gold = Asset.find_asset_by_path(material_path)
- # 18. Override the slot zero LOD Material asset using EditorMaterialComponentSlot method SetAssetId
- item[0].SetAssetId(metal_gold.id)
- # check override with EditorMaterialComponentSlot method GetActiveAssetId
- Report.result(Tests.lod_material_set, item[0].GetActiveAssetId() == metal_gold.id)
- # FindMaterialAsignementId expects slot index and slot label (index for default material is -1, slot 0 is 0)
- assignment_id = render.MaterialComponentRequestBus(
- bus.Event, "FindMaterialAssignmentId", material_entity.id, 0, 'lambert0')
- # check override with ebus call
- Report.result(Tests.lod_material_set,
- render.MaterialComponentRequestBus(
- bus.Event, "GetMaterialAssetId", material_entity.id, assignment_id) == metal_gold.id)
- # 19. Clear the LOD Material override and confirm the active asset is the default value
- item[0].Clear()
- general.idle_wait_frames(1)
- active_asset = Asset(item[0].GetActiveAssetId())
- active_asset_path = active_asset.get_path()
- Report.result(
- Tests.lod_material_asset_path,
- active_asset_path.startswith('testdata/objects/modelhotreload/sphere_5lods_lambert0_'))
- # 20. Set the Default Material asset to an override using set component property by path
- material_component.set_component_property_value(
- AtomComponentProperties.material('Material Asset'), metal_gold.id)
- Report.result(
- Tests.default_material,
- material_component.get_component_property_value(
- AtomComponentProperties.material('Material Asset')) == metal_gold.id)
- # 21. Clear the assignment of a default material using MaterialComponentRequestBus and confirm null asset
- render.MaterialComponentRequestBus(bus.Event, "ClearMaterialAssetIdOnDefaultSlot", material_entity.id)
- default_material_asset_id = render.MaterialComponentRequestBus(
- bus.Event, "GetMaterialAssetIdOnDefaultSlot", material_entity.id)
- Report.result(Tests.clear_default_material, default_material_asset_id == azlmbr.asset.AssetId())
- # 22. Set the Default Material asset using MaterialComponentRequestBus
- render.MaterialComponentRequestBus(
- bus.Event, "SetMaterialAssetIdOnDefaultSlot", material_entity.id, metal_gold.id)
- default_material_asset_id = render.MaterialComponentRequestBus(
- bus.Event, "GetMaterialAssetIdOnDefaultSlot", material_entity.id)
- Report.result(Tests.default_material, default_material_asset_id == metal_gold.id)
- # 23. 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)
- # 24. Test IsHidden.
- material_entity.set_visibility_state(False)
- Report.result(Tests.is_hidden, material_entity.is_hidden() is True)
- # 25. Test IsVisible.
- material_entity.set_visibility_state(True)
- general.idle_wait_frames(1)
- Report.result(Tests.is_visible, material_entity.is_visible() is True)
- # 26. Delete Material entity.
- material_entity.delete()
- Report.result(Tests.entity_deleted, not material_entity.exists())
- # 27. UNDO deletion.
- general.undo()
- general.idle_wait_frames(1)
- Report.result(Tests.deletion_undo, material_entity.exists())
- # 28. REDO deletion.
- general.redo()
- general.idle_wait_frames(1)
- Report.result(Tests.deletion_redo, not material_entity.exists())
- # 29. Look for errors or 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}")
- 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(AtomEditorComponents_Material_AddedToEntity)
|