Initial check-in of in-memory prefab creation helpers for Dynamic Vegetation tests

Signed-off-by: jckand-amzn <jckand@amazon.com>
This commit is contained in:
jckand-amzn
2021-11-12 15:47:18 -06:00
parent 669ac8bb61
commit 11c219701e
4 changed files with 169 additions and 2 deletions
@@ -132,6 +132,7 @@ class EditorEntity:
def __init__(self, id: azlmbr.entity.EntityId):
self.id: azlmbr.entity.EntityId = id
self.components: List[EditorComponent] = []
# Creation functions
@classmethod
@@ -258,6 +259,7 @@ class EditorEntity:
:return: Component object of newly added component.
"""
component = self.add_components([component_name])[0]
self.components.append(component)
return component
def add_components(self, component_names: list) -> List[EditorComponent]:
@@ -279,7 +281,7 @@ class EditorEntity:
), f"Failure: Could not add component: '{new_comp.get_component_name()}' to entity: '{self.get_name()}'"
new_comp.id = add_component_outcome.GetValue()[0]
components.append(new_comp)
self.components.append(new_comp)
return components
def get_components_of_type(self, component_names: list) -> List[EditorComponent]:
@@ -0,0 +1,90 @@
"""
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 DynVegUtils_TempPrefabCreationWorks():
"""
Summary:
An existing level is opened. Each Prefab setup to be spawned by Dynamic Vegetation tests is created in memory and
validated against existing components/mesh assignments. A spawner is then created with the temporary prefabs to ensure
proper functionality with Dynamic Vegetation components.
Expected Behavior:
Temporary prefabs contain the expected components/assets. Instances plant as expected in the assigned area.
Test Steps:
1) Open an existing level
2) Create each of the necessary temporary prefabs, and validate the component/mesh setups
3) Create a Vegetation Layer Spawner setup using the temporary prefabs as Prefab Instance Spawner types
4) Create a surface to plant on and validate instance counts
5) Verify expected instance counts
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
import os
import azlmbr.editor as editor
import azlmbr.legacy.general as general
import azlmbr.bus as bus
import azlmbr.math as math
import editor_python_test_tools.hydra_editor_utils as hydra
from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg
from editor_python_test_tools.utils import Report, Tracer
from editor_python_test_tools.utils import TestHelper as helper
from editor_python_test_tools.prefab_utils import Prefab, PrefabInstance, get_prefab_file_path
with Tracer() as error_tracer:
# Create dictionary for prefab filenames and paths to create using helper function
mesh_prefabs = {
"PinkFlower": os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel"),
"PurpleFlower": os.path.join("assets", "objects", "foliage", "grass_flower_purple.azmodel"),
"1m_Cube": os.path.join("objects", "_primitives", "_box_1x1.azmodel"),
"CedarTree": os.path.join("assets", "objects", "foliage", "cedar.azmodel"),
"Bush": os.path.join("assets", "objects", "foliage", "bush_privet_01.azmodel"),
}
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Prefab", "Base")
# 2) Create a Dynamic Vegetation surface in preparation of prefab creation
center_point = math.Vector3(0.0, 0.0, 0.0)
dynveg.create_surface_entity("Planting Surface", center_point, 128.0, 128.0, 1.0)
# 3) Create each of the Mesh asset prefabs and validate that the prefab created successfully
for prefab_filename, asset_path in mesh_prefabs.items():
prefab_created = (
f"Temporary {prefab_filename} prefab created successfully",
f"Failed to create temporary {prefab_filename} prefab"
)
prefab = dynveg.create_temp_mesh_prefab(asset_path, prefab_filename)
Report.result(prefab_created, helper.wait_for_condition(lambda: PrefabInstance.is_valid(prefab[1]), 3.0))
# 4) Assign the temp prefab to the prefab instance spawner, and validate the instance count
#for prefab_filename in mesh_prefabs:
spawner_entity = dynveg.create_prefab_spawner("PrefabSpawner", center_point, 16.0, 16.0, 16.0,
get_prefab_file_path("Sphere"))
# 5) Report errors/asserts
helper.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}")
general.idle_wait(20.0)
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(DynVegUtils_TempPrefabCreationWorks)
@@ -0,0 +1,22 @@
"""
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 EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
@pytest.mark.SUITE_main
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(EditorTestSuite):
global_extra_cmdline_args = []
class test_DynVegUtils_TempPrefabCreationWorks(EditorSharedTest):
from .EditorScripts import DynVegUtils_TempPrefabCreationWorks as test_module
@@ -19,6 +19,25 @@ import azlmbr.paths
sys.path.append(os.path.join(azlmbr.paths.projectroot, 'Gem', 'PythonTests'))
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.editor_entity_utils import EditorEntity, EditorComponent
from editor_python_test_tools.prefab_utils import Prefab
def create_temp_mesh_prefab(mesh_asset_path, prefab_filename):
# Create initial entity
root = EditorEntity.create_editor_entity(name=prefab_filename)
assert root.exists(), "Failed to create entity"
# Add mesh component
mesh_component = root.add_component("Mesh")
assert root.has_component("Mesh") and mesh_component.is_enabled(), "Failed to add/activate Mesh component"
# Assign the specified mesh asset
mesh_asset = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", mesh_asset_path, math.Uuid(), False)
mesh_component.set_component_property_value("Controller|Configuration|Mesh Asset", mesh_asset)
assert mesh_component.get_component_property_value("Controller|Configuration|Mesh Asset"), \
"Failed to set Mesh asset"
# Create and return the temporary/in-memory prefab
temp_prefab = Prefab.create_prefab([root], prefab_filename)
return temp_prefab
def create_surface_entity(name, center_point, box_size_x, box_size_y, box_size_z):
@@ -52,6 +71,40 @@ def create_mesh_surface_entity_with_slopes(name, center_point, uniform_scale):
return surface_entity
def create_prefab_spawner(name, center_point, box_size_x, box_size_y, box_size_z, prefab_asset_path):
# Create a vegetation area entity to use as our test vegetation spawner
spawner_entity = EditorEntity.create_editor_entity_at(center_point, name=name)
spawner_entity.add_components(["Vegetation Layer Spawner", "Box Shape", "Vegetation Asset List"])
if spawner_entity.id.IsValid():
print(f"'{spawner_entity.get_name()}' created")
spawner_entity.components[1].set_component_property_value("Box Shape|Box Configuration|Dimensions",
math.Vector3(box_size_x, box_size_y, box_size_z))
# Set the vegetation area to a Prefab spawner with a specific prefab asset selected
prefab_spawner = vegetation.PrefabInstanceSpawner()
prefab_spawner.SetPrefabAssetPath(prefab_asset_path)
descriptor = spawner_entity.components[2].get_component_property_value("Configuration|Embedded Assets|[0]")
descriptor.spawner = prefab_spawner
spawner_entity.components[2].set_component_property_value("Configuration|Embedded Assets|[0]", descriptor)
return spawner_entity
def create_empty_spawner(name, center_point, box_size_x, box_size_y, box_size_z):
# Create a vegetation area entity to use as our test vegetation spawner
spawner_entity = EditorEntity.create_editor_entity_at(center_point, name=name)
spawner_entity.add_components(["Vegetation Layer Spawner", "Box Shape", "Vegetation Asset List"])
if spawner_entity.id.IsValid():
print(f"'{spawner_entity.get_name()}' created")
spawner_entity.components[1].set_component_property_value("Box Shape|Box Configuration|Dimensions",
math.Vector3(box_size_x, box_size_y, box_size_z))
# Set the vegetation area to an empty spawner
empty_spawner = vegetation.EmptyInstanceSpawner()
descriptor = spawner_entity.components[2].get_component_property_value("Configuration|Embedded Assets|[0]")
descriptor.spawner = empty_spawner
spawner_entity.components[2].set_component_property_value("Configuration|Embedded Assets|[0]", descriptor)
return spawner_entity
def create_vegetation_area(name, center_point, box_size_x, box_size_y, box_size_z, dynamic_slice_asset_path):
# Create a vegetation area entity to use as our test vegetation spawner
spawner_entity = hydra.Entity(name)
@@ -67,7 +120,7 @@ def create_vegetation_area(name, center_point, box_size_x, box_size_y, box_size_
# Set the vegetation area to a Dynamic Slice spawner with a specific slice asset selected
dynamic_slice_spawner = vegetation.DynamicSliceInstanceSpawner()
dynamic_slice_spawner.SetSliceAssetPath(dynamic_slice_asset_path)
descriptor = hydra.get_component_property_value(spawner_entity.components[2], 'Configuration|Embedded Assets|[0]')
descriptor = vegetation.Descriptor()
descriptor.spawner = dynamic_slice_spawner
spawner_entity.get_set_test(2, "Configuration|Embedded Assets|[0]", descriptor)
return spawner_entity