""" 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 """ def DuplicateEntity_WithNestedEntitiesAndNestedPrefabs(): """ Test description: - Creates a root entity. - Creates linear nested entities with the root entity as a parent. - Creates linear nested prefabs with the root entity as a parent. - Duplicates the entire hierarchy, and validates. - Validates Undo/Redo operations on the duplication. """ from pathlib import Path import azlmbr.bus as bus import azlmbr.legacy.general as general import azlmbr.prefab as prefab from editor_python_test_tools.editor_entity_utils import EditorEntity from editor_python_test_tools.wait_utils import PrefabWaiter from consts.physics import PHYSX_PRIMITIVE_COLLIDER as PHYSX_PRIMITIVE_COLLIDER_NAME import Prefab.tests.PrefabTestUtils as prefab_test_utils NESTED_ENTITIES_NAME_PREFIX = 'NestedEntity_' NESTED_PREFABS_FILE_NAME_PREFIX = Path(__file__).stem + '_' + 'nested_prefabs_' NESTED_PREFABS_NAME_PREFIX = 'NestedPrefabs_Prefab_' NESTED_PREFABS_TEST_ENTITY_NAME = 'TestEntity' PARENT_CREATION_POSITION = azlmbr.math.Vector3(0.0, 0.0, 0.0) CHILDREN_CREATION_POSITION = azlmbr.math.Vector3(100.0, 100.0, 100.0) NUM_NESTED_ENTITIES_LEVELS = 3 NUM_NESTED_PREFABS_LEVELS = 3 def validate_duplicated_hierarchy(): root_entities = EditorEntity.find_editor_entities(["Parent"]) assert len(root_entities) == 2, "Failed to find expected duplicated entity hierarchy root" for root_entity in root_entities: expected_children_names = [f"{NESTED_PREFABS_NAME_PREFIX}0", f"{NESTED_ENTITIES_NAME_PREFIX}0"] child_entities = root_entity.get_children() for child in child_entities: assert child.get_name() in expected_children_names, "Failed to find expected children of root entity" # Validate the duplicated child nested entity hierarchy if child.get_name() == f"{NESTED_ENTITIES_NAME_PREFIX}0": prefab_test_utils.validate_linear_nested_entities(child, NUM_NESTED_ENTITIES_LEVELS, CHILDREN_CREATION_POSITION) # Validate the duplicated child nested prefab hierarchy elif child.get_name() == f"{NESTED_PREFABS_NAME_PREFIX}0": first_child_prefab = child.get_children()[0] assert first_child_prefab.get_name() == f"{NESTED_PREFABS_NAME_PREFIX}1", \ f"Found unexpected child after duplication. Expected {NESTED_PREFABS_NAME_PREFIX}1, " \ f"found {first_child_prefab.get_name()}." second_child_prefab = first_child_prefab.get_children()[0] assert second_child_prefab.get_name() == f"{NESTED_PREFABS_NAME_PREFIX}2", \ f"Found unexpected child after duplication. Expected {NESTED_PREFABS_NAME_PREFIX}2, " \ f"found {second_child_prefab.get_name()}." prefab_test_utils.open_base_tests_level() # Creates a new entity to serve as the parent for the nested entity and nested prefab hierarchies parent_entity = EditorEntity.create_editor_entity_at(PARENT_CREATION_POSITION, "Parent") # Creates new nested entities as children of the parent entity # Asserts if creation didn't succeed nested_entities_root = prefab_test_utils.create_linear_nested_entities( NESTED_ENTITIES_NAME_PREFIX, NUM_NESTED_ENTITIES_LEVELS, CHILDREN_CREATION_POSITION, parent_id=parent_entity.id) prefab_test_utils.validate_linear_nested_entities(nested_entities_root, NUM_NESTED_ENTITIES_LEVELS, CHILDREN_CREATION_POSITION) # Creates new nested prefabs at the root level # Asserts if creation didn't succeed nested_prefab_root = EditorEntity.create_editor_entity_at(CHILDREN_CREATION_POSITION, name=NESTED_PREFABS_TEST_ENTITY_NAME, parent_id=parent_entity.id) assert nested_prefab_root.id.IsValid(), "Couldn't create TestEntity" nested_prefab_root.add_component(PHYSX_PRIMITIVE_COLLIDER_NAME) assert nested_prefab_root.has_component(PHYSX_PRIMITIVE_COLLIDER_NAME), f"Failed to add a {PHYSX_PRIMITIVE_COLLIDER_NAME}" nested_prefabs, nested_prefab_instances = prefab_test_utils.create_linear_nested_prefabs( [nested_prefab_root], NESTED_PREFABS_FILE_NAME_PREFIX, NESTED_PREFABS_NAME_PREFIX, NUM_NESTED_PREFABS_LEVELS) prefab_test_utils.validate_linear_nested_prefab_instances_hierarchy(nested_prefab_instances) # Duplicates the entity hierarchy and validates duplicate_outcome = prefab.PrefabPublicRequestBus(bus.Broadcast, 'DuplicateEntitiesInInstance', [parent_entity.id]) assert duplicate_outcome.IsSuccess(), \ f"Failed to duplicate nested entity hierarchy with root entity {parent_entity.get_name()}" PrefabWaiter.wait_for_propagation() validate_duplicated_hierarchy() # Test undo/redo on entity hierarchy duplication general.undo() PrefabWaiter.wait_for_propagation() root_entities = EditorEntity.find_editor_entities(["Parent"]) assert len(root_entities) == 1, "Undo Failed: Found unexpected duplicated entity hierarchy root after Undo" prefab_test_utils.validate_linear_nested_entities(nested_entities_root, NUM_NESTED_ENTITIES_LEVELS, CHILDREN_CREATION_POSITION) prefab_test_utils.validate_linear_nested_prefab_instances_hierarchy(nested_prefab_instances) general.redo() PrefabWaiter.wait_for_propagation() validate_duplicated_hierarchy() if __name__ == "__main__": from editor_python_test_tools.utils import Report Report.start_test(DuplicateEntity_WithNestedEntitiesAndNestedPrefabs)