Merge branch 'development' of https://github.com/aws-lumberyard/o3de into Neil_o3de_local

This commit is contained in:
Neil Widmaier
2022-01-24 13:56:34 -08:00
1340 changed files with 19353 additions and 13265 deletions
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<path d="M3.145,8.433c0-1.47,1.196-2.666,2.666-2.666h9.544c-0.158-0.819-0.88-1.443-1.744-1.443H3.487
c-0.978,0-1.778,0.8-1.778,1.778v5.356c0,0.861,0.62,1.582,1.436,1.743V8.433z" fill="#FFFFFF"/>
<g>
<path d="M6.833,11.654c0-1.47,1.196-2.666,2.666-2.666h9.069c-0.158-0.819-0.88-1.443-1.744-1.443H6.7
c-0.978,0-1.778,0.8-1.778,1.778v5.356c0,0.978,0.8,1.778,1.778,1.778h0.133V11.654z" fill="#FFFFFF"/>
</g>
<path d="M20.513,10.765H10.388c-0.978,0-1.778,0.8-1.778,1.777v5.356c0,0.978,0.8,1.778,1.778,1.778h10.125
c0.978,0,1.778-0.8,1.778-1.778v-5.356C22.29,11.565,21.49,10.765,20.513,10.765z M19.332,15.967h-7.763
c-0.264,0-0.478-0.355-0.478-0.793c0-0.438,0.214-0.793,0.478-0.793h7.763c0.264,0,0.478,0.355,0.478,0.793
C19.81,15.612,19.597,15.967,19.332,15.967z" fill="#FFFFFF"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7f94f2634eacb4d7bee20dacc45edef96e4d268f1adb7960b8aa8f3b6e2906ed
size 6867609
+129
View File
@@ -0,0 +1,129 @@
{
"ContainerEntity": {
"Id": "ContainerEntity",
"Name": "Bush",
"Components": {
"Component_[1140272189295067758]": {
"$type": "EditorInspectorComponent",
"Id": 1140272189295067758
},
"Component_[13437832196484687256]": {
"$type": "EditorOnlyEntityComponent",
"Id": 13437832196484687256
},
"Component_[1553903646452669645]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 1553903646452669645
},
"Component_[15914009348632444632]": {
"$type": "EditorEntitySortComponent",
"Id": 15914009348632444632,
"Child Entity Order": [
"Entity_[7511491868318]"
]
},
"Component_[18046340308818780248]": {
"$type": "EditorPrefabComponent",
"Id": 18046340308818780248
},
"Component_[1948833233489872938]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 1948833233489872938,
"Parent Entity": ""
},
"Component_[2903632350157981339]": {
"$type": "SelectionComponent",
"Id": 2903632350157981339
},
"Component_[48827510535192710]": {
"$type": "EditorPendingCompositionComponent",
"Id": 48827510535192710
},
"Component_[5609536793322429681]": {
"$type": "EditorLockComponent",
"Id": 5609536793322429681
},
"Component_[5859168386298620990]": {
"$type": "EditorEntityIconComponent",
"Id": 5859168386298620990
},
"Component_[6604616929271524505]": {
"$type": "EditorVisibilityComponent",
"Id": 6604616929271524505
}
}
},
"Entities": {
"Entity_[7511491868318]": {
"Id": "Entity_[7511491868318]",
"Name": "Bush",
"Components": {
"Component_[10227459330338484901]": {
"$type": "EditorInspectorComponent",
"Id": 10227459330338484901,
"ComponentOrderEntryArray": [
{
"ComponentId": 4998941225335869157
},
{
"ComponentId": 9922994635792843826,
"SortIndex": 1
}
]
},
"Component_[10972351222359420947]": {
"$type": "EditorOnlyEntityComponent",
"Id": 10972351222359420947
},
"Component_[12101122374155214392]": {
"$type": "EditorPendingCompositionComponent",
"Id": 12101122374155214392
},
"Component_[1535264614652988260]": {
"$type": "SelectionComponent",
"Id": 1535264614652988260
},
"Component_[16367811417907891218]": {
"$type": "EditorVisibilityComponent",
"Id": 16367811417907891218
},
"Component_[17044216787716682880]": {
"$type": "EditorEntitySortComponent",
"Id": 17044216787716682880
},
"Component_[2129822594969629430]": {
"$type": "EditorEntityIconComponent",
"Id": 2129822594969629430
},
"Component_[2838015156782745450]": {
"$type": "EditorLockComponent",
"Id": 2838015156782745450
},
"Component_[4998941225335869157]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 4998941225335869157,
"Parent Entity": "ContainerEntity"
},
"Component_[8773358049076362578]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 8773358049076362578
},
"Component_[9922994635792843826]": {
"$type": "AZ::Render::EditorMeshComponent",
"Id": 9922994635792843826,
"Controller": {
"Configuration": {
"ModelAsset": {
"assetId": {
"guid": "{1201406D-FB20-5B5F-B9B5-6A6E8DE00A14}",
"subId": 276506120
},
"assetHint": "assets/objects/foliage/bush_privet_01.azmodel"
}
}
}
}
}
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,129 @@
{
"ContainerEntity": {
"Id": "ContainerEntity",
"Name": "PurpleFlower",
"Components": {
"Component_[10519928302743666073]": {
"$type": "EditorPrefabComponent",
"Id": 10519928302743666073
},
"Component_[13894087802180240181]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 13894087802180240181,
"Parent Entity": ""
},
"Component_[15788541052719571801]": {
"$type": "EditorEntityIconComponent",
"Id": 15788541052719571801
},
"Component_[15842981265136092481]": {
"$type": "SelectionComponent",
"Id": 15842981265136092481
},
"Component_[16360384897559021149]": {
"$type": "EditorInspectorComponent",
"Id": 16360384897559021149
},
"Component_[16713545675046303279]": {
"$type": "EditorVisibilityComponent",
"Id": 16713545675046303279
},
"Component_[1806734194268113785]": {
"$type": "EditorPendingCompositionComponent",
"Id": 1806734194268113785
},
"Component_[5392020700593853313]": {
"$type": "EditorEntitySortComponent",
"Id": 5392020700593853313,
"Child Entity Order": [
"Entity_[14335611090324]"
]
},
"Component_[5995854518752659458]": {
"$type": "EditorLockComponent",
"Id": 5995854518752659458
},
"Component_[6963022284400845376]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 6963022284400845376
},
"Component_[8055275578170091546]": {
"$type": "EditorOnlyEntityComponent",
"Id": 8055275578170091546
}
}
},
"Entities": {
"Entity_[14335611090324]": {
"Id": "Entity_[14335611090324]",
"Name": "PurpleFlower",
"Components": {
"Component_[10887353073528055802]": {
"$type": "EditorPendingCompositionComponent",
"Id": 10887353073528055802
},
"Component_[12641127425852859189]": {
"$type": "AZ::Render::EditorMeshComponent",
"Id": 12641127425852859189,
"Controller": {
"Configuration": {
"ModelAsset": {
"assetId": {
"guid": "{D493A670-6D82-5AE9-A2C8-A2EB02684F71}",
"subId": 284799939
},
"assetHint": "assets/objects/foliage/grass_flower_purple.azmodel"
}
}
}
},
"Component_[14406733303466080015]": {
"$type": "EditorInspectorComponent",
"Id": 14406733303466080015,
"ComponentOrderEntryArray": [
{
"ComponentId": 9231452352781000222
},
{
"ComponentId": 12641127425852859189,
"SortIndex": 1
}
]
},
"Component_[1452384341905923012]": {
"$type": "EditorLockComponent",
"Id": 1452384341905923012
},
"Component_[2215454016415585892]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 2215454016415585892
},
"Component_[4104108067383423623]": {
"$type": "EditorVisibilityComponent",
"Id": 4104108067383423623
},
"Component_[4197335450471807917]": {
"$type": "SelectionComponent",
"Id": 4197335450471807917
},
"Component_[6877680739064997650]": {
"$type": "EditorOnlyEntityComponent",
"Id": 6877680739064997650
},
"Component_[7372550507186490390]": {
"$type": "EditorEntityIconComponent",
"Id": 7372550507186490390
},
"Component_[7673532337364366244]": {
"$type": "EditorEntitySortComponent",
"Id": 7673532337364366244
},
"Component_[9231452352781000222]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 9231452352781000222,
"Parent Entity": "ContainerEntity"
}
}
}
}
}
@@ -2,11 +2,11 @@
<Class name="DescriptorListAsset" type="{60961B36-E3CA-4877-B197-1462C1363F6E}">
<Class name="AZStd::vector" field="Descriptors" type="{FC36C5E0-6152-5B06-AF30-3FC494B85FAB}">
<Class name="Descriptor" field="element" version="8" type="{A5A5E7F7-FC36-4BD1-8A93-21362574B9DA}">
<Class name="AZ::Uuid" field="SpawnerType" value="{BBA5CC1E-B4CA-4792-89F7-93711E98FBD1}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
<Class name="AZ::Uuid" field="SpawnerType" value="{74BEEDB5-81CF-409F-B375-0D93D81EF2E3}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
<Class name="AZStd::shared_ptr" field="InstanceSpawner" type="{7C7046DE-F8B1-529D-AD8C-829C6C0E2FCD}">
<Class name="DynamicSliceInstanceSpawner" field="element" type="{BBA5CC1E-B4CA-4792-89F7-93711E98FBD1}">
<Class name="PrefabInstanceSpawner" field="element" type="{74BEEDB5-81CF-409F-B375-0D93D81EF2E3}">
<Class name="InstanceSpawner" field="BaseClass1" type="{01AD0758-B04A-4B43-BC2B-BDCD77F4EF6A}"/>
<Class name="Asset" field="SliceAsset" value="id={EBFE34EB-D0A8-5E51-8234-3BE38082B28C}:2,type={78802ABF-9595-463A-8D2B-D022F906F9B1},hint={slices/pinkflower.dynamicslice}" version="1" type="{77A19D40-8731-4D3C-9041-1B43047366A4}"/>
<Class name="Asset" field="SpawnableAsset" value="id={80C0CF4E-9A5E-544B-B89E-BC980175A259}:e6f903d2,type={855E3021-D305-4845-B284-20C3F7FDF16B},hint={Assets/Prefabs/PinkFlower.prefab},loadBehavior=1" version="2" type="{77A19D40-8731-4D3C-9041-1B43047366A4}"/>
</Class>
</Class>
<Class name="float" field="Weight" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
@@ -12,12 +12,6 @@
################################################################################
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
# Only enable AWS automated tests on Windows
set(SUPPORTED_PLATFORMS "Windows" "Linux")
if (NOT "${PAL_PLATFORM_NAME}" IN_LIST SUPPORTED_PLATFORMS)
return()
endif()
ly_add_pytest(
NAME AutomatedTesting::AWSTests
TEST_SUITE awsi
@@ -3,7 +3,7 @@
## Prerequisites
1. Build the O3DE Editor and AutomatedTesting.GameLauncher in Profile.
2. Install the latest version of NodeJs.
3. AWS CLI is installed and configured following [Configuration and Credential File Settings](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html).
3. AWS CLI is installed and AWS crendentials are configured via [environment variables](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html) or [default profile](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html).
4. [AWS Cloud Development Kit (CDK)](https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html#getting_started_install) is installed.
## Deploy CDK Applications
@@ -68,6 +68,10 @@ class AwsCredentials:
if (len(self._credentials.sections()) == 0) and (not self._credentials_file_exists):
os.remove(self._credentials_path)
return
credentials_file_dir = os.path.dirname(self._credentials_path)
if not os.path.isdir(credentials_file_dir):
os.makedirs(credentials_file_dir)
with open(self._credentials_path, 'w+') as credential_file:
self._credentials.write(credential_file)
@@ -16,7 +16,7 @@ logging.getLogger('nose').setLevel(logging.WARNING)
class AwsUtils:
def __init__(self, arn: str, session_name: str, region_name: str):
local_session = boto3.Session(profile_name='default')
local_session = boto3.Session()
local_sts_client = local_session.client('sts')
self._local_account_id = local_sts_client.get_caller_identity()["Account"]
logger.info(f'Local Account Id: {self._local_account_id}')
@@ -6,11 +6,13 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import os
import platform
# ARN of the IAM role to assume for retrieving temporary AWS credentials
ASSUME_ROLE_ARN = os.environ.get('ASSUME_ROLE_ARN', 'arn:aws:iam::645075835648:role/o3de-automation-tests')
# Name of the AWS project deployed by the CDK applications
AWS_PROJECT_NAME = os.environ.get('O3DE_AWS_PROJECT_NAME', 'AWSAUTO')
AWS_PROJECT_NAME = os.environ.get('O3DE_AWS_PROJECT_NAME').upper() if os.environ.get('O3DE_AWS_PROJECT_NAME') else \
(os.environ.get('BRANCH_NAME', '') + '-' + os.environ.get('PIPELINE_NAME', '') + '-' + platform.system()).upper()
# Region for the existing CloudFormation stacks used by the automation tests
AWS_REGION = os.environ.get('O3DE_AWS_DEPLOY_REGION', 'us-east-1')
# Name of the default resource mapping config file used by the automation tests
@@ -21,7 +21,7 @@ TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests")
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
class TestAutomation(EditorTestSuite):
enable_prefab_system = False
enable_prefab_system = True
@pytest.mark.test_case_id("C36525657")
class AtomEditorComponents_BloomAdded(EditorSharedTest):
@@ -120,6 +120,14 @@ class TestAutomation(EditorTestSuite):
class AtomEditorComponents_SSAOAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_SSAOAdded as test_module
@pytest.mark.test_case_id("C36529666")
class AtomEditorComponentsLevel_DiffuseGlobalIlluminationAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponentsLevel_DiffuseGlobalIlluminationAdded as test_module
@pytest.mark.test_case_id("C36525660")
class AtomEditorComponentsLevel_DisplayMapperAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponentsLevel_DisplayMapperAdded as test_module
class ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges(EditorSharedTest):
from Atom.tests import hydra_ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges as test_module
@@ -173,9 +181,11 @@ class TestMaterialEditorBasicTests(object):
"Document saved as copy is saved with changes: True",
"Document saved as child is saved with changes: True",
"Save All worked as expected: True",
"P1: Asset Browser visibility working as expected: True",
"P1: Inspector visibility working as expected: True",
]
unexpected_lines = [
"Traceback (most recent call last):"
# Including any lines in unexpected_lines will cause the test to run for the duration of the timeout
]
hydra.launch_and_validate_results(
@@ -9,97 +9,20 @@ import os
import pytest
import ly_test_tools.environment.file_system as file_system
import editor_python_test_tools.hydra_test_utils as hydra
from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite
from Atom.atom_utils.atom_constants import LIGHT_TYPES
logger = logging.getLogger(__name__)
TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests")
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("level", ["auto_test"])
class TestAtomEditorComponentsMain(object):
"""Holds tests for Atom components."""
@pytest.mark.test_case_id("C34525095")
def test_AtomEditorComponents_LightComponent(
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 has the expected property options available to it.
"""
cfg_args = [level]
expected_lines = [
"light_entity Entity successfully created",
"Entity has a Light component",
"light_entity_test: Component added to the entity: True",
f"light_entity_test: Property value is {LIGHT_TYPES['sphere']} which matches {LIGHT_TYPES['sphere']}",
"Controller|Configuration|Shadows|Enable shadow set to True",
"light_entity Controller|Configuration|Shadows|Shadowmap size: SUCCESS",
"Controller|Configuration|Shadows|Shadow filter method set to 1", # PCF
"Controller|Configuration|Shadows|Filtering sample count set to 4",
"Controller|Configuration|Shadows|Filtering sample count set to 64",
"Controller|Configuration|Shadows|Shadow filter method set to 2", # ESM
"Controller|Configuration|Shadows|ESM exponent set to 50.0",
"Controller|Configuration|Shadows|ESM exponent set to 5000.0",
"Controller|Configuration|Shadows|Shadow filter method set to 3", # ESM+PCF
f"light_entity_test: Property value is {LIGHT_TYPES['spot_disk']} which matches {LIGHT_TYPES['spot_disk']}",
f"light_entity_test: Property value is {LIGHT_TYPES['capsule']} which matches {LIGHT_TYPES['capsule']}",
f"light_entity_test: Property value is {LIGHT_TYPES['quad']} which matches {LIGHT_TYPES['quad']}",
"light_entity Controller|Configuration|Fast approximation: SUCCESS",
"light_entity Controller|Configuration|Both directions: SUCCESS",
f"light_entity_test: Property value is {LIGHT_TYPES['polygon']} which matches {LIGHT_TYPES['polygon']}",
f"light_entity_test: Property value is {LIGHT_TYPES['simple_point']} "
f"which matches {LIGHT_TYPES['simple_point']}",
"Controller|Configuration|Attenuation radius|Mode set to 0",
"Controller|Configuration|Attenuation radius|Radius set to 100.0",
f"light_entity_test: Property value is {LIGHT_TYPES['simple_spot']} "
f"which matches {LIGHT_TYPES['simple_spot']}",
"Controller|Configuration|Shutters|Outer angle set to 45.0",
"Controller|Configuration|Shutters|Outer angle set to 90.0",
"light_entity_test: Component added to the entity: True",
"Light component test (non-GPU) completed.",
]
unexpected_lines = ["Traceback (most recent call last):"]
hydra.launch_and_validate_results(
request,
TEST_DIRECTORY,
editor,
"hydra_AtomEditorComponents_LightComponent.py",
timeout=120,
expected_lines=expected_lines,
unexpected_lines=unexpected_lines,
halt_on_unexpected=True,
null_renderer=True,
cfg_args=cfg_args,
enable_prefab_system=False,
)
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
class TestAutomation(EditorTestSuite):
enable_prefab_system = False
#this test is intermittently timing out without ever having executed. sandboxing while we investigate cause.
# this test is intermittently timing out without ever having executed. sandboxing while we investigate cause.
@pytest.mark.test_case_id("C36525660")
class AtomEditorComponents_DisplayMapperAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_DisplayMapperAdded as test_module
# this test causes editor to crash when using slices. once automation transitions to prefabs it should pass
@pytest.mark.test_case_id("C36529666")
class AtomEditorComponentsLevel_DiffuseGlobalIlluminationAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponentsLevel_DiffuseGlobalIlluminationAdded as test_module
# this test causes editor to crash when using slices. once automation transitions to prefabs it should pass
@pytest.mark.test_case_id("C36525660")
class AtomEditorComponentsLevel_DisplayMapperAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponentsLevel_DisplayMapperAdded as test_module
@@ -125,11 +125,11 @@ def is_pane_visible(pane_name):
"""
:return: bool
"""
return atomtools.AtomToolsWindowRequestBus(bus.Broadcast, "IsDockWidgetVisible", pane_name)
return atomtools.AtomToolsMainWindowRequestBus(bus.Broadcast, "IsDockWidgetVisible", pane_name)
def set_pane_visibility(pane_name, value):
atomtools.AtomToolsWindowRequestBus(bus.Broadcast, "SetDockWidgetVisible", pane_name, value)
atomtools.AtomToolsMainWindowRequestBus(bus.Broadcast, "SetDockWidgetVisible", pane_name, value)
def select_lighting_config(config_name):
@@ -60,7 +60,7 @@ def AtomEditorComponentsLevel_DiffuseGlobalIllumination_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Add Diffuse Global Illumination level component to the level entity.
@@ -86,10 +86,10 @@ def AtomEditorComponentsLevel_DiffuseGlobalIllumination_AddedToEntity():
# 4. Set Quality Level property to Low
diffuse_global_illumination_component.set_component_property_value(
AtomComponentProperties.diffuse_global_illumination('Quality Level', GLOBAL_ILLUMINATION_QUALITY['Low']))
AtomComponentProperties.diffuse_global_illumination('Quality Level'), GLOBAL_ILLUMINATION_QUALITY['Low'])
quality = diffuse_global_illumination_component.get_component_property_value(
AtomComponentProperties.diffuse_global_illumination('Quality Level'))
Report.result(diffuse_global_illumination_quality, quality == GLOBAL_ILLUMINATION_QUALITY['Low'])
Report.result(Tests.diffuse_global_illumination_quality, quality == GLOBAL_ILLUMINATION_QUALITY['Low'])
# 5. Enter/Exit game mode.
TestHelper.enter_game_mode(Tests.enter_game_mode)
@@ -67,7 +67,7 @@ def AtomEditorComponentsLevel_DisplayMapper_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Add Display Mapper level component to the level entity.
@@ -102,7 +102,7 @@ def AtomEditorComponentsLevel_DisplayMapper_AddedToEntity():
display_mapper_component.set_component_property_value(
AtomComponentProperties.display_mapper('Enable LDR color grading LUT'), True)
Report.result(
Test.enable_ldr_color_grading_lut,
Tests.enable_ldr_color_grading_lut,
display_mapper_component.get_component_property_value(
AtomComponentProperties.display_mapper('Enable LDR color grading LUT')) is True)
@@ -97,7 +97,7 @@ def AtomEditorComponents_Bloom_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create an Bloom entity with no components.
@@ -170,10 +170,12 @@ def AtomEditorComponents_Bloom_AddedToEntity():
# 13. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, bloom_entity.exists())
# 14. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not bloom_entity.exists())
# 15. Look for errors and asserts.
@@ -95,7 +95,7 @@ def AtomEditorComponents_Decal_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create a Decal entity with no components.
@@ -162,6 +162,7 @@ def AtomEditorComponents_Decal_AddedToEntity():
# 11. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not decal_entity.exists())
# 12. Look for errors and asserts.
@@ -97,7 +97,7 @@ def AtomEditorComponents_DeferredFog_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create an Deferred Fog entity with no components.
@@ -174,10 +174,12 @@ def AtomEditorComponents_DeferredFog_AddedToEntity():
# 13. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, deferred_fog_entity.exists())
# 14. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not deferred_fog_entity.exists())
# 15. Look for errors and asserts.
@@ -107,7 +107,7 @@ def AtomEditorComponents_DepthOfField_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create a DepthOfField entity with no components.
@@ -189,10 +189,12 @@ def AtomEditorComponents_DepthOfField_AddedToEntity():
# 15. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, depth_of_field_entity.exists())
# 16. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not depth_of_field_entity.exists())
# 17. Look for errors and asserts.
@@ -90,7 +90,7 @@ def AtomEditorComponents_DiffuseProbeGrid_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create a Diffuse Probe Grid entity with no components.
@@ -168,10 +168,12 @@ def AtomEditorComponents_DiffuseProbeGrid_AddedToEntity():
# 12. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, diffuse_probe_grid_entity.exists())
# 13. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not diffuse_probe_grid_entity.exists())
# 14. Look for errors or asserts.
@@ -95,7 +95,7 @@ def AtomEditorComponents_DirectionalLight_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create a Directional Light entity with no components.
@@ -168,10 +168,12 @@ def AtomEditorComponents_DirectionalLight_AddedToEntity():
# 12. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, directional_light_entity.exists())
# 13. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not directional_light_entity.exists())
# 14. Look for errors and asserts.
@@ -91,7 +91,7 @@ def AtomEditorComponents_DisplayMapper_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create a Display Mapper entity with no components.
@@ -166,10 +166,12 @@ def AtomEditorComponents_DisplayMapper_AddedToEntity():
# 11. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, display_mapper_entity.exists())
# 12. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not display_mapper_entity.exists())
# 13. Look for errors and asserts.
@@ -81,7 +81,7 @@ def AtomEditorComponents_EntityReference_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create an Entity Reference entity with no components.
@@ -139,10 +139,12 @@ def AtomEditorComponents_EntityReference_AddedToEntity():
# 9. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, entity_reference_entity.exists())
# 10. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not entity_reference_entity.exists())
# 11. Look for errors and asserts.
@@ -101,7 +101,7 @@ def AtomEditorComponents_ExposureControl_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Creation of Exposure Control entity with no components.
@@ -169,10 +169,12 @@ def AtomEditorComponents_ExposureControl_AddedToEntity():
# 12. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, exposure_control_entity.exists())
# 13. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not exposure_control_entity.exists())
# 14. Look for errors and asserts.
@@ -99,7 +99,7 @@ def AtomEditorComponents_GlobalSkylightIBL_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create a Global Skylight (IBL) entity with no components.
@@ -176,10 +176,12 @@ def AtomEditorComponents_GlobalSkylightIBL_AddedToEntity():
# 11. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, global_skylight_entity.exists())
# 12. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not global_skylight_entity.exists())
# 13. Look for errors and asserts.
@@ -82,7 +82,7 @@ def AtomEditorComponents_Grid_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create a Grid entity with no components.
@@ -139,10 +139,12 @@ def AtomEditorComponents_Grid_AddedToEntity():
# 9. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, grid_entity.exists())
# 10. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not grid_entity.exists())
# 11. Look for errors or asserts.
@@ -96,7 +96,7 @@ def AtomEditorComponents_HDRColorGrading_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create an HDR Color Grading entity with no components.
@@ -173,10 +173,12 @@ def AtomEditorComponents_HDRColorGrading_AddedToEntity():
# 13. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, hdr_color_grading_entity.exists())
# 14. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not hdr_color_grading_entity.exists())
# 15. Look for errors and asserts.
@@ -87,7 +87,7 @@ def AtomEditorComponents_HDRiSkybox_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create an HDRi Skybox with no components.
@@ -158,10 +158,12 @@ def AtomEditorComponents_HDRiSkybox_AddedToEntity():
# 10. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, hdri_skybox_entity.exists())
# 11. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not hdri_skybox_entity.exists())
# 12. Look for errors or asserts.
@@ -89,7 +89,7 @@ def AtomEditorComponents_Light_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create a Light entity with no components.
@@ -144,10 +144,12 @@ def AtomEditorComponents_Light_AddedToEntity():
# 9. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, light_entity.exists())
# 10. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not light_entity.exists())
# 11. Look for errors asserts.
@@ -1,213 +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.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.atom_constants import LIGHT_TYPES
LIGHT_TYPE_PROPERTY = 'Controller|Configuration|Light type'
SPHERE_AND_SPOT_DISK_LIGHT_PROPERTIES = [
("Controller|Configuration|Shadows|Enable shadow", True),
("Controller|Configuration|Shadows|Shadowmap size", 0), # 256
("Controller|Configuration|Shadows|Shadowmap size", 1), # 512
("Controller|Configuration|Shadows|Shadowmap size", 2), # 1024
("Controller|Configuration|Shadows|Shadowmap size", 3), # 2048
("Controller|Configuration|Shadows|Shadow filter method", 1), # PCF
("Controller|Configuration|Shadows|Filtering sample count", 4.0),
("Controller|Configuration|Shadows|Filtering sample count", 64.0),
("Controller|Configuration|Shadows|Shadow filter method", 2), # ECM
("Controller|Configuration|Shadows|ESM exponent", 50),
("Controller|Configuration|Shadows|ESM exponent", 5000),
("Controller|Configuration|Shadows|Shadow filter method", 3), # ESM+PCF
]
QUAD_LIGHT_PROPERTIES = [
("Controller|Configuration|Both directions", True),
("Controller|Configuration|Fast approximation", True),
]
SIMPLE_POINT_LIGHT_PROPERTIES = [
("Controller|Configuration|Attenuation radius|Mode", 0),
("Controller|Configuration|Attenuation radius|Radius", 100.0),
]
SIMPLE_SPOT_LIGHT_PROPERTIES = [
("Controller|Configuration|Shutters|Inner angle", 45.0),
("Controller|Configuration|Shutters|Outer angle", 90.0),
]
def verify_required_component_property_value(entity_name, component, property_path, expected_property_value):
"""
Compares the property value of component against the expected_property_value.
:param entity_name: name of the entity to use (for test verification purposes).
:param component: component to check on a given entity for its current property value.
:param property_path: the path to the property inside the component.
:param expected_property_value: The value expected from the value inside property_path.
:return: None, but prints to general.log() which the test uses to verify against.
"""
property_value = editor.EditorComponentAPIBus(
bus.Broadcast, "GetComponentProperty", component, property_path).GetValue()
general.log(f"{entity_name}_test: Property value is {property_value} "
f"which matches {expected_property_value}")
def run():
"""
Test Case - Light Component
1. Creates a "light_entity" Entity and attaches a "Light" component to it.
2. Updates the Light component to each light type option from the LIGHT_TYPES constant.
3. The test will check the Editor log to ensure each light type was selected.
4. Prints the string "Light component test (non-GPU) 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
"""
# Create a "light_entity" entity with "Light" component.
light_entity_name = "light_entity"
light_component = "Light"
light_entity = hydra.Entity(light_entity_name)
light_entity.create_entity(math.Vector3(-1.0, -2.0, 3.0), [light_component])
general.log(
f"{light_entity_name}_test: Component added to the entity: "
f"{hydra.has_components(light_entity.id, [light_component])}")
# Populate the light_component_id_pair value so that it can be used to select all Light component options.
light_component_id_pair = None
component_type_id_list = azlmbr.editor.EditorComponentAPIBus(
azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', [light_component], 0)
if len(component_type_id_list) < 1:
general.log(f"ERROR: A component class with name {light_component} doesn't exist")
light_component_id_pair = None
elif len(component_type_id_list) > 1:
general.log(f"ERROR: Found more than one component classes with same name: {light_component}")
light_component_id_pair = None
entity_component_id_pair = azlmbr.editor.EditorComponentAPIBus(
azlmbr.bus.Broadcast, 'GetComponentOfType', light_entity.id, component_type_id_list[0])
if entity_component_id_pair.IsSuccess():
light_component_id_pair = entity_component_id_pair.GetValue()
# Test each Light component option can be selected and it's properties updated.
# Point (sphere) light type checks.
light_type_property_test(
light_type=LIGHT_TYPES['sphere'],
light_properties=SPHERE_AND_SPOT_DISK_LIGHT_PROPERTIES,
light_component_id_pair=light_component_id_pair,
light_entity_name=light_entity_name,
light_entity=light_entity
)
# Spot (disk) light type checks.
light_type_property_test(
light_type=LIGHT_TYPES['spot_disk'],
light_properties=SPHERE_AND_SPOT_DISK_LIGHT_PROPERTIES,
light_component_id_pair=light_component_id_pair,
light_entity_name=light_entity_name,
light_entity=light_entity
)
# Capsule light type checks.
azlmbr.editor.EditorComponentAPIBus(
azlmbr.bus.Broadcast,
'SetComponentProperty',
light_component_id_pair,
LIGHT_TYPE_PROPERTY,
LIGHT_TYPES['capsule']
)
verify_required_component_property_value(
entity_name=light_entity_name,
component=light_entity.components[0],
property_path=LIGHT_TYPE_PROPERTY,
expected_property_value=LIGHT_TYPES['capsule']
)
# Quad light type checks.
light_type_property_test(
light_type=LIGHT_TYPES['quad'],
light_properties=QUAD_LIGHT_PROPERTIES,
light_component_id_pair=light_component_id_pair,
light_entity_name=light_entity_name,
light_entity=light_entity
)
# Polygon light type checks.
azlmbr.editor.EditorComponentAPIBus(
azlmbr.bus.Broadcast,
'SetComponentProperty',
light_component_id_pair,
LIGHT_TYPE_PROPERTY,
LIGHT_TYPES['polygon']
)
verify_required_component_property_value(
entity_name=light_entity_name,
component=light_entity.components[0],
property_path=LIGHT_TYPE_PROPERTY,
expected_property_value=LIGHT_TYPES['polygon']
)
# Point (simple punctual) light type checks.
light_type_property_test(
light_type=LIGHT_TYPES['simple_point'],
light_properties=SIMPLE_POINT_LIGHT_PROPERTIES,
light_component_id_pair=light_component_id_pair,
light_entity_name=light_entity_name,
light_entity=light_entity
)
# Spot (simple punctual) light type checks.
light_type_property_test(
light_type=LIGHT_TYPES['simple_spot'],
light_properties=SIMPLE_SPOT_LIGHT_PROPERTIES,
light_component_id_pair=light_component_id_pair,
light_entity_name=light_entity_name,
light_entity=light_entity
)
general.log("Light component test (non-GPU) completed.")
def light_type_property_test(light_type, light_properties, light_component_id_pair, light_entity_name, light_entity):
"""
Updates the current light type and modifies its properties, then verifies they are accurate to what was set.
:param light_type: The type of light to update, must match a value in LIGHT_TYPES
:param light_properties: List of tuples detailing properties to modify with update values.
:param light_component_id_pair: Entity + component ID pair for updating the light component on a given entity.
:param light_entity_name: the name of the Entity holding the light component.
:param light_entity: the Entity object containing the light component.
:return: None
"""
azlmbr.editor.EditorComponentAPIBus(
azlmbr.bus.Broadcast,
'SetComponentProperty',
light_component_id_pair,
LIGHT_TYPE_PROPERTY,
light_type
)
verify_required_component_property_value(
entity_name=light_entity_name,
component=light_entity.components[0],
property_path=LIGHT_TYPE_PROPERTY,
expected_property_value=light_type
)
for light_property in light_properties:
light_entity.get_set_test(0, light_property[0], light_property[1])
if __name__ == "__main__":
run()
@@ -104,7 +104,7 @@ def AtomEditorComponents_LookModification_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create an Look Modification entity with no components.
@@ -192,10 +192,12 @@ def AtomEditorComponents_LookModification_AddedToEntity():
# 14. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, look_modification_entity.exists())
# 15. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not look_modification_entity.exists())
# 16. Look for errors and asserts.
@@ -102,7 +102,7 @@ def AtomEditorComponents_Material_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create a Material entity with no components.
@@ -184,10 +184,12 @@ def AtomEditorComponents_Material_AddedToEntity():
# 16. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, material_entity.exists())
# 17. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not material_entity.exists())
# 18. Look for errors or asserts.
@@ -87,7 +87,7 @@ def AtomEditorComponents_Mesh_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create a Mesh entity with no components.
@@ -151,10 +151,12 @@ def AtomEditorComponents_Mesh_AddedToEntity():
# 10. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, mesh_entity.exists())
# 11. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not mesh_entity.exists())
# 12. Look for errors or asserts.
@@ -80,7 +80,7 @@ def AtomEditorComponents_OcclusionCullingPlane_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create a occlusion culling plane entity with no components.
@@ -140,10 +140,12 @@ def AtomEditorComponents_OcclusionCullingPlane_AddedToEntity():
# 9. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, occlusion_culling_plane_entity.exists())
# 10. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not occlusion_culling_plane_entity.exists())
# 11. Look for errors or asserts.
@@ -89,7 +89,7 @@ def AtomEditorComponents_PhysicalSky_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create a Physical Sky entity with no components.
@@ -146,10 +146,12 @@ def AtomEditorComponents_PhysicalSky_AddedToEntity():
# 9. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, physical_sky_entity.exists())
# 10. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not physical_sky_entity.exists())
# 11. Look for errors and asserts.
@@ -92,7 +92,7 @@ def AtomEditorComponents_PostFXGradientWeightModifier_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create a PostFX Gradient Weight Modifier entity with no components.
@@ -162,10 +162,12 @@ def AtomEditorComponents_PostFXGradientWeightModifier_AddedToEntity():
# 12. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, postfx_gradient_weight_entity.exists())
# 13. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not postfx_gradient_weight_entity.exists())
# 14. Look for errors or asserts.
@@ -80,7 +80,7 @@ def AtomEditorComponents_postfx_layer_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create a PostFX Layer entity with no components.
@@ -137,10 +137,12 @@ def AtomEditorComponents_postfx_layer_AddedToEntity():
# 9. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, postfx_layer_entity.exists())
# 10. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not postfx_layer_entity.exists())
# 11. Look for errors or asserts.
@@ -92,7 +92,7 @@ def AtomEditorComponents_PostFXRadiusWeightModifier_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create a Post FX Radius Weight Modifier entity with no components.
@@ -161,10 +161,12 @@ def AtomEditorComponents_PostFXRadiusWeightModifier_AddedToEntity():
# 12. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, postfx_radius_weight_entity.exists())
# 13. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not postfx_radius_weight_entity.exists())
# 14. Look for errors and asserts.
@@ -98,7 +98,7 @@ def AtomEditorComponents_postfx_shape_weight_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create a PostFx Shape Weight Modifier entity with no components.
@@ -188,10 +188,12 @@ def AtomEditorComponents_postfx_shape_weight_AddedToEntity():
# 15. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, postfx_shape_weight_entity.exists())
# 16. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not postfx_shape_weight_entity.exists())
# 17. Look for errors or asserts.
@@ -97,7 +97,7 @@ def AtomEditorComponents_ReflectionProbe_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create a Reflection Probe entity with no components.
@@ -183,10 +183,12 @@ def AtomEditorComponents_ReflectionProbe_AddedToEntity():
# 13. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, reflection_probe_entity.exists())
# 14. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not reflection_probe_entity.exists())
# 15. Look for errors or asserts.
@@ -94,7 +94,7 @@ def AtomEditorComponents_SSAO_AddedToEntity():
# 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")
TestHelper.open_level("Graphics", "base_empty")
# Test steps begin.
# 1. Create a SSAO entity with no components.
@@ -163,10 +163,12 @@ def AtomEditorComponents_SSAO_AddedToEntity():
# 12. UNDO deletion.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_undo, ssao_entity.exists())
# 13. REDO deletion.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.deletion_redo, not ssao_entity.exists())
# 14. Look for errors and asserts.
@@ -36,6 +36,19 @@ MATERIAL_TYPE_PATH = os.path.join(
CACHE_FILE_EXTENSION = ".azmaterial"
def verify_pane_visibility(pane_name: str):
"""
print log lines indicating Material Editor pane visibility function
:param pane_name: Name of the pane to be tested
"""
initial_value = material_editor.is_pane_visible(pane_name)
material_editor.set_pane_visibility(pane_name, not initial_value)
result = (material_editor.is_pane_visible(pane_name) is not initial_value)
material_editor.set_pane_visibility(pane_name, initial_value)
result = result and (initial_value is material_editor.is_pane_visible(pane_name))
print(f"P1: {pane_name} visibility working as expected: {result}")
def run():
"""
Summary:
@@ -49,9 +62,12 @@ def run():
7. Saving as a New Material
8. Saving as a Child Material
9. Saving all Open Materials
10. Verify Asset Browser pane visibility
11. Verify Material Inspector pane visibility
Expected Result:
All the above functions work as expected in Material Editor.
Pane visibility functions as expected
:return: None
"""
@@ -186,6 +202,14 @@ def run():
material_editor.set_property(document2_id, property2_name, initial_color)
material_editor.save_all()
material_editor.close_all_documents()
# 10) Verify Asset Browser pane visibility
verify_pane_visibility("Asset Browser")
# 11) Verify Material Inspector pane visibility
verify_pane_visibility("Inspector")
# Confirm documents closed and exit Material Editor
material_editor.wait_for_condition(lambda:
(not material_editor.is_open(document1_id)) and
(not material_editor.is_open(document2_id)) and
@@ -5,9 +5,9 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import collections.abc
from typing import List
from math import isclose
import collections.abc
import azlmbr.bus as bus
import azlmbr.editor as editor
@@ -14,7 +14,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
NAME AutomatedTesting::DynamicVegetationTests_Main_Optimized
TEST_SERIAL
TEST_SUITE main
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Main_Optimized.py
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Main.py
RUNTIME_DEPENDENCIES
AZ::AssetProcessor
Legacy::Editor
@@ -27,7 +27,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
NAME AutomatedTesting::DynamicVegetationTests_Periodic_Optimized
TEST_SERIAL
TEST_SUITE periodic
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Periodic_Optimized.py
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Periodic.py
RUNTIME_DEPENDENCIES
AZ::AssetProcessor
Legacy::Editor
@@ -58,7 +58,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
NAME AutomatedTesting::GradientSignalTests_Periodic_Optimized
TEST_SERIAL
TEST_SUITE periodic
PATH ${CMAKE_CURRENT_LIST_DIR}/gradient_signal/TestSuite_Periodic_Optimized.py
PATH ${CMAKE_CURRENT_LIST_DIR}/gradient_signal/TestSuite_Periodic.py
RUNTIME_DEPENDENCIES
AZ::AssetProcessor
Legacy::Editor
@@ -51,22 +51,18 @@ def AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude():
import os
import azlmbr.asset as asset
import azlmbr.editor as editor
import azlmbr.legacy.general as general
import azlmbr.bus as bus
import azlmbr.math as math
import azlmbr.prefab as prefab
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.prefab_utils import Prefab
from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("", "Base")
hydra.open_base_level()
# Set view of planting area for visual debugging
general.set_current_view_position(512.0, 500.0, 38.0)
@@ -76,9 +72,9 @@ def AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude():
center_point = math.Vector3(512.0, 512.0, 32.0)
flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
flower_prefab = dynveg.create_temp_mesh_prefab(flower_asset_path, "PinkFlower")[0]
flower_prefab = dynveg.create_temp_mesh_prefab(flower_asset_path, "AltFilter_PinkFlower")[0]
spawner_entity = dynveg.create_prefab_vegetation_area("Instance Spawner", center_point, 32.0, 32.0, 32.0, flower_prefab)
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", center_point, 32.0, 32.0, 32.0, flower_prefab)
# Add a Vegetation Altitude Filter
spawner_entity.add_component("Vegetation Altitude Filter")
@@ -32,9 +32,7 @@ def AltitudeFilter_FilterStageToggle():
import os
import azlmbr.legacy.general as general
import azlmbr.bus as bus
import azlmbr.math as math
import azlmbr.prefab as prefab
import editor_python_test_tools.hydra_editor_utils as hydra
from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg
@@ -45,17 +43,16 @@ def AltitudeFilter_FilterStageToggle():
POSTPROCESS_INSTANCE_COUNT = 34
# Open an existing simple level
helper.init_idle()
helper.open_level("", "Base")
hydra.open_base_level()
general.set_current_view_position(512.0, 480.0, 38.0)
# Create basic vegetation entity
position = math.Vector3(512.0, 512.0, 32.0)
flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
flower_prefab = dynveg.create_temp_mesh_prefab(flower_asset_path, "PinkFlower")[0]
flower_prefab = dynveg.create_temp_mesh_prefab(flower_asset_path, "AltFilter_PinkFlower2")[0]
vegetation = dynveg.create_prefab_vegetation_area("vegetation", position, 16.0, 16.0, 16.0, flower_prefab)
vegetation = dynveg.create_temp_prefab_vegetation_area("vegetation", position, 16.0, 16.0, 16.0, flower_prefab)
# Add a Vegetation Altitude Filter to the vegetation area entity
vegetation.add_component("Vegetation Altitude Filter")
@@ -56,8 +56,7 @@ def AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude():
from editor_python_test_tools.utils import TestHelper as helper
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("", "Base")
hydra.open_base_level()
# Set view of planting area for visual debugging
general.set_current_view_position(512.0, 500.0, 38.0)
@@ -67,9 +66,9 @@ def AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude():
center_point = math.Vector3(512.0, 512.0, 32.0)
flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
flower_prefab = dynveg.create_temp_mesh_prefab(flower_asset_path, "PinkFlower")[0]
flower_prefab = dynveg.create_temp_mesh_prefab(flower_asset_path, "AltFilter_PinkFlower3")[0]
spawner_entity = dynveg.create_prefab_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 16.0, flower_prefab)
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 16.0, flower_prefab)
# Add a Vegetation Altitude Filter
spawner_entity.add_component("Vegetation Altitude Filter")
@@ -56,19 +56,21 @@ def AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea():
"""
import os
from pathlib import Path
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.legacy.general as general
import azlmbr.math as math
import azlmbr.vegetation as vegetation
import azlmbr.prefab as prefab
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
from editor_python_test_tools.utils import TestHelper as helper
def create_asset_list_entity(name, center, dynamic_slice_asset_path):
def create_asset_list_entity(name, center, target_prefab):
asset_list_entity = hydra.Entity(name)
asset_list_entity.create_entity(
center,
@@ -77,18 +79,34 @@ def AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea():
if asset_list_entity.id.IsValid():
print(f"'{asset_list_entity.name}' created")
# Set the Asset List to a Dynamic Slice spawner with a specific slice asset selected
dynamic_slice_spawner = vegetation.DynamicSliceInstanceSpawner()
dynamic_slice_spawner.SetSliceAssetPath(dynamic_slice_asset_path)
if target_prefab:
# Get the in-memory spawnable asset id if exists
spawnable_name = Path(target_prefab.file_path).stem
spawnable_asset_id = prefab.PrefabPublicRequestBus(bus.Broadcast, 'GetInMemorySpawnableAssetId',
spawnable_name)
# Create the in-memory spawnable asset from given prefab if the spawnable does not exist
if not spawnable_asset_id.is_valid():
create_spawnable_result = prefab.PrefabPublicRequestBus(bus.Broadcast, 'CreateInMemorySpawnableAsset',
target_prefab.file_path,
spawnable_name)
assert create_spawnable_result.IsSuccess(), \
f"Prefab operation 'CreateInMemorySpawnableAssets' failed. Error: {create_spawnable_result.GetError()}"
spawnable_asset_id = create_spawnable_result.GetValue()
else:
spawnable_asset_id = None
# Set the vegetation area to a prefab instance spawner with a specific prefab asset selected
descriptor = hydra.get_component_property_value(asset_list_entity.components[0],
"Configuration|Embedded Assets|[0]")
descriptor.spawner = dynamic_slice_spawner
'Configuration|Embedded Assets|[0]')
prefab_spawner = vegetation.PrefabInstanceSpawner()
prefab_spawner.SetPrefabAssetId(spawnable_asset_id)
descriptor.spawner = prefab_spawner
asset_list_entity.get_set_test(0, "Configuration|Embedded Assets|[0]", descriptor)
return asset_list_entity
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# Set view of planting area for visual debugging
general.set_current_view_position(512.0, 500.0, 38.0)
@@ -96,11 +114,13 @@ def AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea():
# 2) Create 3 entities with Vegetation Asset List components set to spawn different descriptors
center_point = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
asset_path2 = os.path.join("Slices", "PurpleFlower.dynamicslice")
asset_list_entity = create_asset_list_entity("Asset List 1", center_point, asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "AssetList_PinkFlower")[0]
purple_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
purple_flower_prefab = dynveg.create_temp_mesh_prefab(purple_flower_asset_path, "AssetList_PurpleFlower")[0]
asset_list_entity = create_asset_list_entity("Asset List 1", center_point, pink_flower_prefab)
asset_list_entity2 = create_asset_list_entity("Asset List 2", center_point, None)
asset_list_entity3 = create_asset_list_entity("Asset List 3", center_point, asset_path2)
asset_list_entity3 = create_asset_list_entity("Asset List 3", center_point, purple_flower_prefab)
# 3) Create a planting surface and add a Vegetation System Settings level component with instances set to spawn
# on center instead of corner
@@ -56,8 +56,7 @@ def AssetWeightSelector_InstancesExpressBasedOnWeight():
from editor_python_test_tools.utils import TestHelper as helper
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# Set view of planting area for visual debugging
general.set_current_view_position(512.0, 500.0, 38.0)
@@ -66,14 +65,15 @@ def AssetWeightSelector_InstancesExpressBasedOnWeight():
# 2) Create a new instance spawner entity with multiple Dynamic Slice Instance Spawner descriptors, one set to a
# valid slice entity, and one set to None
spawner_center_point = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0,
asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "AssetWeight_PinkFlower")[0]
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0,
pink_flower_prefab)
desc_asset = hydra.get_component_property_value(spawner_entity.components[2],
"Configuration|Embedded Assets")[0]
desc_list = [desc_asset, desc_asset]
spawner_entity.get_set_test(2, "Configuration|Embedded Assets", desc_list)
spawner_entity.get_set_test(2, "Configuration|Embedded Assets|[1]|Instance|Slice Asset", None)
spawner_entity.get_set_test(2, "Configuration|Embedded Assets|[1]|Instance|Prefab Asset", None)
# Add an Asset Weight Selector component to the spawner entity
spawner_entity.add_component("Vegetation Asset Weight Selector")
@@ -64,16 +64,15 @@ def DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius():
instance_query_point_c = math.Vector3(515.0, 512.5, 32.0)
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
general.set_current_view_position(512.0, 480.0, 38.0)
# 2) Create a new entity with required vegetation area components
spawner_center_point = math.Vector3(520.0, 520.0, 32.0)
asset_path = os.path.join("Slices", "1m_cube.dynamicslice")
spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0,
asset_path)
cube_asset_path = os.path.join("testdata", "multi-mat_fbx", "multi-mat_1m_cube.azmodel")
cube_prefab = dynveg.create_temp_mesh_prefab(cube_asset_path, "DistanceBetween_1m_cube2")[0]
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0,
cube_prefab)
# 3) Create a surface to plant on
surface_center_point = math.Vector3(512.0, 512.0, 32.0)
@@ -62,16 +62,15 @@ def DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius():
instance_query_point_c = math.Vector3(515.0, 512.5, 32.0)
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
general.set_current_view_position(512.0, 480.0, 38.0)
# 2) Create a new entity with required vegetation area components
spawner_center_point = math.Vector3(520.0, 520.0, 32.0)
asset_path = os.path.join("Slices", "1m_cube.dynamicslice")
spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0,
asset_path)
cube_asset_path = os.path.join("testdata", "multi-mat_fbx", "multi-mat_1m_cube.azmodel")
cube_prefab = dynveg.create_temp_mesh_prefab(cube_asset_path, "DistanceBetween_1m_cube")[0]
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point,
16.0, 16.0, 16.0, cube_prefab)
# 3) Create a surface to plant on
surface_center_point = math.Vector3(512.0, 512.0, 32.0)
@@ -39,11 +39,11 @@ def DynVegUtils_TempPrefabCreationWorks():
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"),
"UtilsTest_PinkFlower": os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel"),
"UtilsTest_PurpleFlower": os.path.join("assets", "objects", "foliage", "grass_flower_purple.azmodel"),
"UtilsTest_1m_Cube": os.path.join("objects", "_primitives", "_box_1x1.azmodel"),
"UtilsTest_CedarTree": os.path.join("assets", "objects", "foliage", "cedar.azmodel"),
"UtilsTest_Bush": os.path.join("assets", "objects", "foliage", "bush_privet_01.azmodel"),
}
# 1) Open an existing simple level
@@ -71,8 +71,7 @@ def DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks():
from editor_python_test_tools.utils import TestHelper as helper
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
general.set_current_view_position(512.0, 480.0, 38.0)
# Grab the UUID that we need for creating an Dynamic Slice Instance Spawner
@@ -57,8 +57,7 @@ def EmptyInstanceSpawner_EmptySpawnerWorks():
from editor_python_test_tools.utils import TestHelper as helper
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
general.set_current_view_position(512.0, 480.0, 38.0)
# Grab the UUID that we need for creating an Empty Spawner
@@ -60,8 +60,7 @@ def InstanceSpawnerPriority_LayerAndSubPriority():
from editor_python_test_tools.utils import TestHelper as helper
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# Set view of planting area for visual debugging
general.set_current_view_position(512.0, 500.0, 38.0)
@@ -69,9 +68,10 @@ def InstanceSpawnerPriority_LayerAndSubPriority():
# 2) Create overlapping areas: 1 instance spawner area, and 1 blocker area
spawner_center_point = math.Vector3(508.0, 508.0, 32.0)
asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 1.0,
asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "Priority_PinkFlower")[0]
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 1.0,
pink_flower_prefab)
blocker_center_point = math.Vector3(516.0, 516.0, 32.0)
blocker_entity = dynveg.create_blocker_area("Instance Blocker", blocker_center_point, 16.0, 16.0, 1.0)
@@ -85,18 +85,14 @@ def LayerBlender_E2E_Editor():
# 2) Create 2 vegetation areas with different meshes
purple_position = math.Vector3(504.0, 512.0, 32.0)
purple_asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
spawner_entity_1 = dynveg.create_dynamic_slice_vegetation_area("Purple Spawner",
purple_position,
16.0, 16.0, 1.0,
purple_asset_path)
purple_flower_prefab_path = os.path.join("assets", "prefabs", "PurpleFlower.spawnable")
spawner_entity_1 = dynveg.create_prefab_vegetation_area("Purple Spawner", purple_position, 16.0, 16.0, 1.0,
purple_flower_prefab_path)
pink_position = math.Vector3(520.0, 512.0, 32.0)
pink_asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
spawner_entity_2 = dynveg.create_dynamic_slice_vegetation_area("Pink Spawner",
pink_position,
16.0, 16.0, 1.0,
pink_asset_path)
pink_flower_prefab_path = os.path.join("assets", "prefabs", "PinkFlower.spawnable")
spawner_entity_2 = dynveg.create_prefab_vegetation_area("Pink Spawner", pink_position, 16.0, 16.0, 1.0,
pink_flower_prefab_path)
base_position = math.Vector3(512.0, 512.0, 32.0)
dynveg.create_surface_entity("Surface Entity",
@@ -135,11 +131,11 @@ def LayerBlender_E2E_Editor():
pink_count = 0
purple_count = 0
for instance in instances:
purple_asset_path = purple_asset_path.replace("\\", "/").lower()
pink_asset_path = pink_asset_path.replace("\\", "/").lower()
if instance.descriptor.spawner.GetSliceAssetPath() == pink_asset_path:
purple_flower_prefab_path = purple_flower_prefab_path.replace("\\", "/").lower()
pink_flower_prefab_path = pink_flower_prefab_path.replace("\\", "/").lower()
if instance.descriptor.spawner.GetPrefabAssetPath() == pink_flower_prefab_path:
pink_count += 1
elif instance.descriptor.spawner.GetSliceAssetPath() == purple_asset_path:
elif instance.descriptor.spawner.GetPrefabAssetPath() == purple_flower_prefab_path:
purple_count += 1
Report.result(Tests.instances_blended, pink_count == purple_count and (pink_count + purple_count == num_expected))
@@ -152,11 +148,10 @@ def LayerBlender_E2E_Editor():
components.TransformBus(bus.Event, "MoveEntity", search_entity_ids[0], cam_position)
azlmbr.components.TransformBus(bus.Event, "SetLocalRotation", search_entity_ids[0], cam_rot_degrees_vector)
# 6) Save and export to engine
# 6) Save the created level
general.save_level()
general.export_to_engine()
pak_path = os.path.join(paths.products, "levels", lvl_name, "level.pak")
success = helper.wait_for_condition(lambda: os.path.exists(pak_path), 10.0)
level_prefab_path = os.path.join(paths.products, "levels", lvl_name, f"{lvl_name}.spawnable")
success = helper.wait_for_condition(lambda: os.path.exists(level_prefab_path), 5.0)
Report.result(Tests.saved_and_exported, success)
@@ -17,7 +17,6 @@ class Tests:
)
def LayerBlocker_InstancesBlockedInConfiguredArea():
"""
Summary:
@@ -58,8 +57,7 @@ def LayerBlocker_InstancesBlockedInConfiguredArea():
from editor_python_test_tools.utils import TestHelper as helper
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# Set view of planting area for visual debugging
general.set_current_view_position(512.0, 500.0, 38.0)
@@ -67,9 +65,10 @@ def LayerBlocker_InstancesBlockedInConfiguredArea():
# 2) Create a new instance spawner entity
spawner_center_point = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0,
asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "Blocker_PinkFlower")[0]
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point,
16.0, 16.0, 16.0, pink_flower_prefab)
# 3) Create surface for planting on
dynveg.create_surface_entity("Surface Entity", spawner_center_point, 32.0, 32.0, 1.0)
@@ -42,16 +42,17 @@ def LayerSpawner_FilterStageToggle():
POSTPROCESS_INSTANCE_COUNT = 19
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
general.set_current_view_position(500.49, 498.69, 46.66)
general.set_current_view_rotation(-42.05, 0.00, -36.33)
# Create a vegetation area with all needed components
position = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
vegetation_entity = dynveg.create_dynamic_slice_vegetation_area("vegetation", position, 16.0, 16.0, 16.0, asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SpawnerFilter_PinkFlower")[0]
vegetation_entity = dynveg.create_temp_prefab_vegetation_area("vegetation", position, 16.0, 16.0, 16.0,
pink_flower_prefab)
vegetation_entity.add_component("Vegetation Altitude Filter")
vegetation_entity.add_component("Vegetation Position Modifier")
@@ -42,19 +42,16 @@ def LayerSpawner_InheritBehaviorFlag():
SURFACE_TAG = "test_tag"
def set_dynamic_slice_asset(entity_obj, component_index, dynamic_slice_asset_path):
dynamic_slice_spawner = vegetation.DynamicSliceInstanceSpawner()
dynamic_slice_spawner.SetSliceAssetPath(dynamic_slice_asset_path)
descriptor = hydra.get_component_property_value(
entity_obj.components[component_index], "Configuration|Embedded Assets|[0]"
)
descriptor.spawner = dynamic_slice_spawner
def set_prefab_asset(entity_obj, component_index, spawnable_prefab):
descriptor = hydra.get_component_property_value(entity_obj.components[component_index],
"Configuration|Embedded Assets|[0]")
prefab_spawner = vegetation.PrefabInstanceSpawner()
prefab_spawner.SetPrefabAssetId(spawnable_prefab)
descriptor.spawner = prefab_spawner
entity_obj.get_set_test(2, "Configuration|Embedded Assets|[0]", descriptor)
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
general.set_current_view_position(512.0, 480.0, 38.0)
# Create Emitter entity and add the required components
@@ -80,7 +77,9 @@ def LayerSpawner_InheritBehaviorFlag():
veg_1.create_entity(
position, ["Vegetation Layer Spawner", "Shape Reference", "Vegetation Asset List"]
)
set_dynamic_slice_asset(veg_1, 2, os.path.join("Slices", "PinkFlower.dynamicslice"))
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SpawnerInheritBehavior_PinkFlower")[0]
set_prefab_asset(veg_1, 2, pink_flower_prefab)
veg_1.get_set_test(1, "Configuration|Shape Entity Id", blender_entity.id)
# Create second vegetation area and assign a valid asset
@@ -88,7 +87,9 @@ def LayerSpawner_InheritBehaviorFlag():
veg_2.create_entity(
position, ["Vegetation Layer Spawner", "Shape Reference", "Vegetation Asset List"]
)
set_dynamic_slice_asset(veg_2, 2, os.path.join("Slices", "PurpleFlower.dynamicslice"))
purple_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
purple_flower_prefab = dynveg.create_temp_mesh_prefab(purple_flower_asset_path, "temp_PurpleFlower")[0]
set_prefab_asset(veg_2, 2, purple_flower_prefab)
veg_2.get_set_test(1, "Configuration|Shape Entity Id", blender_entity.id)
# Assign the vegetation areas to the Blender entity
@@ -56,16 +56,14 @@ def LayerSpawner_InstancesPlantInAllSupportedShapes():
Report.result(success, result)
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# 2) Create basic vegetation area entity and set the properties
entity_position = math.Vector3(125.0, 136.0, 32.0)
asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
vegetation = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner",
entity_position,
10.0, 10.0, 10.0,
asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SpawnerShapePlant_PinkFlower")[0]
vegetation = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 10.0, 10.0, 10.0,
pink_flower_prefab)
vegetation.remove_component("Box Shape")
vegetation.add_component("Shape Reference")
@@ -43,13 +43,13 @@ def LayerSpawner_InstancesRefreshUsingCorrectViewportCamera():
import azlmbr.legacy.general as general
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
from editor_python_test_tools.utils import TestHelper as helper
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# Set up a test environment to validate that switching viewports correctly changes which camera
# the vegetation system uses.
@@ -100,11 +100,12 @@ def LayerSpawner_InstancesRefreshUsingCorrectViewportCamera():
surface_height)
# Create the two vegetation areas
test_slice_asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
first_veg_entity = dynveg.create_dynamic_slice_vegetation_area("Veg Area 1", first_entity_center_point, box_size, box_size,
box_size, test_slice_asset_path)
second_veg_entity = dynveg.create_dynamic_slice_vegetation_area("Veg Area 2", second_entity_center_point, box_size, box_size,
box_size, test_slice_asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SpawnerViewportRefresh_PinkFlower")[0]
first_veg_entity = dynveg.create_temp_prefab_vegetation_area("Veg Area 1", first_entity_center_point, box_size, box_size,
box_size, pink_flower_prefab)
second_veg_entity = dynveg.create_temp_prefab_vegetation_area("Veg Area 2", second_entity_center_point, box_size, box_size,
box_size, pink_flower_prefab)
# When the first viewport is active, the first area should be full of instances, and the second should be empty
general.set_active_viewport(0)
@@ -50,19 +50,17 @@ def MeshBlocker_InstancesBlockedByMesh():
from editor_python_test_tools.utils import TestHelper as helper
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
general.set_current_view_position(500.49, 498.69, 46.66)
general.set_current_view_rotation(-42.05, 0.00, -36.33)
# Create entity with components "Vegetation Layer Spawner", "Vegetation Asset List", "Box Shape"
entity_position = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner",
entity_position,
10.0, 10.0, 10.0,
asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "MeshBlocker_PinkFlower")[0]
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 10.0, 10.0, 10.0,
pink_flower_prefab)
# Create surface entity to plant on
dynveg.create_surface_entity("Surface Entity", entity_position, 10.0, 10.0, 1.0)
@@ -53,19 +53,17 @@ def MeshBlocker_InstancesBlockedByMeshHeightTuning():
from editor_python_test_tools.utils import TestHelper as helper
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
general.set_current_view_position(500.49, 498.69, 46.66)
general.set_current_view_rotation(-42.05, 0.00, -36.33)
# 2) Create entity with components "Vegetation Layer Spawner", "Vegetation Asset List", "Box Shape"
entity_position = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner",
entity_position,
10.0, 10.0, 10.0,
asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "MeshBlocker_PinkFlower2")[0]
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 10.0, 10.0, 10.0,
pink_flower_prefab)
# 3) Create surface entity to plant on
dynveg.create_surface_entity("Surface Entity", entity_position, 10.0, 10.0, 1.0)
@@ -58,8 +58,7 @@ def MeshSurfaceTagEmitter_DependentOnMeshComponent():
return editor.EditorComponentAPIBus(bus.Broadcast, "IsComponentEnabled", EntityComponentIdPair)
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# 2) Create a new entity with component "Mesh Surface Tag Emitter"
entity_position = math.Vector3(125.0, 136.0, 32.0)
@@ -47,8 +47,7 @@ def MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully():
from editor_python_test_tools.utils import TestHelper as helper
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# 2) Create a new entity with components "Mesh Surface Tag Emitter", "Mesh"
entity_position = math.Vector3(125.0, 136.0, 32.0)
@@ -55,8 +55,7 @@ def PhysXColliderSurfaceTagEmitter_E2E_Editor():
return behavior_context_test_success
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# Verify all of the BehaviorContext API:
behavior_context = (
@@ -90,8 +89,10 @@ def PhysXColliderSurfaceTagEmitter_E2E_Editor():
dynveg.create_surface_entity("Baseline Surface", entity_center_point, 32.0, 32.0, 1.0)
# Create a new entity with required vegetation area components
asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Veg Area", entity_center_point, 32.0, 32.0, 32.0, asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "PhysXCollider_PinkFlower")[0]
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_center_point, test_box_size,
test_box_size, test_box_size, pink_flower_prefab)
# Add a Vegetation Surface Mask Filter component to the spawner entity and set it to include the "test" tag
spawner_entity.add_component("Vegetation Surface Mask Filter")
@@ -64,8 +64,7 @@ def PositionModifier_AutoSnapToSurfaceWorks():
'Configuration|Position Z|Range Min', 'Configuration|Position Z|Range Max']
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# Set view of planting area for visual debugging
general.set_current_view_position(512.0, 500.0, 38.0)
@@ -73,9 +72,10 @@ def PositionModifier_AutoSnapToSurfaceWorks():
# 2) Create a new entity with required vegetation area components and a Position Modifier
spawner_center_point = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0,
asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "PosMod_PinkFlower")[0]
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0,
16.0, pink_flower_prefab)
# Add a Vegetation Position Modifier and set offset values to 0
spawner_entity.add_component("Vegetation Position Modifier")
@@ -102,16 +102,17 @@ def PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets():
return offset_success and offset_success2
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# Set view of planting area for visual debugging
general.set_current_view_position(16.0, -5.0, 32.0)
# 2) Create a new entity with required vegetation area components
spawner_center_point = math.Vector3(16.0, 16.0, 32.0)
asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 1.0, 1.0, 1.0, asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "PosMod_PinkFlower2")[0]
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point, 1.0, 1.0,
1.0, pink_flower_prefab)
# Add a Vegetation Position Modifier and set offset values to 0
spawner_entity.add_component("Vegetation Position Modifier")
@@ -63,12 +63,14 @@ def DynamicSliceInstanceSpawner_Embedded_E2E():
import azlmbr.entity as entity
import azlmbr.math as math
import azlmbr.paths as paths
import azlmbr.vegetation as vegetation
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
from editor_python_test_tools.utils import TestHelper as helper
# 1) Create a new, temporary level
lvl_name = "tmp_level"
helper.init_idle()
@@ -79,13 +81,14 @@ def DynamicSliceInstanceSpawner_Embedded_E2E():
# 2) Create a new entity with required vegetation area components and Script Canvas component for launcher test
center_point = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 1.0, asset_path)
pink_flower_prefab_path = os.path.join("assets", "prefabs", "PinkFlower.spawnable")
spawner_entity = dynveg.create_prefab_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 1.0,
pink_flower_prefab_path)
spawner_entity.add_component("Script Canvas")
instance_counter_path = os.path.join("scriptcanvas", "instance_counter.scriptcanvas")
instance_counter_script = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", instance_counter_path,
math.Uuid(), False)
spawner_entity.get_set_test(3, "Script Canvas Asset|Script Canvas Asset", instance_counter_script)
spawner_entity.get_set_test(3, "Properties", instance_counter_script)
Report.result(Tests.spawner_entity_created, spawner_entity.id.IsValid() and hydra.has_components(spawner_entity.id,
["Script Canvas"]))
@@ -106,11 +109,10 @@ def DynamicSliceInstanceSpawner_Embedded_E2E():
search_entity_ids = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
components.TransformBus(bus.Event, "MoveEntity", search_entity_ids[0], cam_position)
# 6) Save and export to engine
# 6) Save the created level
general.save_level()
general.export_to_engine()
pak_path = os.path.join(paths.products, "levels", lvl_name, "level.pak")
success = helper.wait_for_condition(lambda: os.path.exists(pak_path), 10.0)
level_prefab_path = os.path.join(paths.products, "levels", lvl_name, f"{lvl_name}.spawnable")
success = helper.wait_for_condition(lambda: os.path.exists(level_prefab_path), 5.0)
Report.result(Tests.saved_and_exported, success)
@@ -128,11 +128,10 @@ def DynamicSliceInstanceSpawner_External_E2E():
search_entity_ids = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
components.TransformBus(bus.Event, "MoveEntity", search_entity_ids[0], cam_position)
# 6) Save and export to engine
# 6) Save the created level
general.save_level()
general.export_to_engine()
pak_path = os.path.join(paths.products, "levels", lvl_name, "level.pak")
success = helper.wait_for_condition(lambda: os.path.exists(pak_path), 10.0)
level_prefab_path = os.path.join(paths.products, "levels", lvl_name, f"{lvl_name}.spawnable")
success = helper.wait_for_condition(lambda: os.path.exists(level_prefab_path), 5.0)
Report.result(Tests.saved_and_exported, success)
@@ -81,14 +81,15 @@ def RotationModifierOverrides_InstancesRotateWithinRange():
return result
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
general.set_current_view_position(512.0, 480.0, 38.0)
# 2) Create vegetation entity and add components
entity_position = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Spawner Entity", entity_position, 16.0, 16.0, 16.0, asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "RotMod_PinkFlower2")[0]
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 16.0, 16.0, 16.0,
pink_flower_prefab)
spawner_entity.add_component("Vegetation Rotation Modifier")
# Our default vegetation settings places 20 instances per 16 meters, so we expect 20 * 20 total instances.
num_expected = 20 * 20
@@ -120,13 +120,14 @@ def RotationModifier_InstancesRotateWithinRange():
# Main Script
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
general.set_current_view_position(512.0, 480.0, 38.0)
# 2) Set up vegetation entities
asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Spawner Entity", LEVEL_CENTER, 2.0, 2.0, 2.0, asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "RotMod_PinkFlower")[0]
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", LEVEL_CENTER, 2.0, 2.0, 2.0,
pink_flower_prefab)
additional_components = [
"Vegetation Rotation Modifier"
@@ -91,16 +91,17 @@ def ScaleModifierOverrides_InstancesProperlyScale():
return False
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
general.set_current_view_position(500.49, 498.69, 46.66)
general.set_current_view_rotation(-42.05, 0.00, -36.33)
# 2) Create a new entity with components "Vegetation Layer Spawner", "Vegetation Asset List", "Box Shape"
entity_position = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Spawner Entity", entity_position, 16.0, 16.0, 10.0, asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "ScaleMod_PinkFlower2")[0]
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 16.0, 16.0, 16.0,
pink_flower_prefab)
# Create a surface to plant on and add a Vegetation Debugger Level component to allow refreshes
dynveg.create_surface_entity("Surface Entity", entity_position, 20.0, 20.0, 1.0)
@@ -84,8 +84,7 @@ def ScaleModifier_InstancesProperlyScale():
return False
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
general.set_current_view_position(500.49, 498.69, 46.66)
general.set_current_view_rotation(-42.05, 0.00, -36.33)
@@ -93,9 +92,10 @@ def ScaleModifier_InstancesProperlyScale():
# 2) Create a new entity with components Vegetation Layer Spawner, Vegetation Asset List, Box Shape and
# Vegetation Scale Modifier
entity_position = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Spawner Entity", entity_position, 16.0, 16.0, 16.0,
asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "ScaleMod_PinkFlower")[0]
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 16.0, 16.0, 16.0,
pink_flower_prefab)
spawner_entity.add_component("Vegetation Scale Modifier")
# Create a surface to plant on and add a Vegetation Debugger Level component to allow refreshes
@@ -49,15 +49,16 @@ def ShapeIntersectionFilter_FilterStageToggle():
from editor_python_test_tools.utils import TestHelper as helper
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
general.set_current_view_position(512.0, 480.0, 38.0)
# Create basic vegetation entity
position = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
vegetation = dynveg.create_dynamic_slice_vegetation_area("vegetation", position, 16.0, 16.0, 16.0, asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "ShapeIntersection_PinkFlower")[0]
vegetation = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", position, 16.0, 16.0, 16.0,
pink_flower_prefab)
# Create Surface for instances to plant on
dynveg.create_surface_entity("Surface_Entity_Parent", position, 16.0, 16.0, 1.0)
@@ -68,7 +69,7 @@ def ShapeIntersectionFilter_FilterStageToggle():
# Create a new entity as a child of the vegetation area entity with Box Shape
box = hydra.Entity("box")
box.create_entity(position, ["Box Shape"])
box.get_set_test(0, "Box Shape|Box Configuration|Dimensions", math.Vector3(8.0, 8.0, 1.0))
box.get_set_test(0, "Box Shape|Box Configuration|Dimensions", math.Vector3(5.0, 5.0, 1.0))
# Create a new entity as a child of the vegetation area entity with Cylinder Shape.
cylinder = hydra.Entity("cylinder")
@@ -80,10 +81,10 @@ def ShapeIntersectionFilter_FilterStageToggle():
# On the Shape Intersection Filter component, click the crosshair button, and add child entities one by one
vegetation.get_set_test(3, "Configuration|Shape Entity Id", box.id)
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 8.0, 100), 2.0)
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 49), 2.0)
Report.result(Tests.instance_count_in_box_shape, result)
vegetation.get_set_test(3, "Configuration|Shape Entity Id", cylinder.id)
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 100), 2.0)
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 121), 2.0)
Report.result(Tests.instance_count_in_cylinder_shape, result)
# Create a new entity as a child of the area entity with Random Noise Gradient, Gradient Transform Modifier,
@@ -98,12 +99,13 @@ def ShapeIntersectionFilter_FilterStageToggle():
# Pin the Random Noise entity to the Gradient Entity Id field of the Position Modifier's Gradient X
vegetation.get_set_test(4, "Configuration|Position X|Gradient|Gradient Entity Id", random_noise.id)
# Toggle between PreProcess and PostProcess
# Toggle between PreProcess and PostProcess and validate instances. Validate in a 0.3m wider radius due to position
# offsets
vegetation.get_set_test(3, "Configuration|Filter Stage", 1)
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 117), 2.0)
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.3, 121), 2.0)
Report.result(Tests.preprocess_instance_count, result)
vegetation.get_set_test(3, "Configuration|Filter Stage", 2)
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 122), 2.0)
result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.3, 122), 2.0)
Report.result(Tests.postprocess_instance_count, result)
@@ -60,8 +60,7 @@ def ShapeIntersectionFilter_InstancesPlantInAssignedShape():
from editor_python_test_tools.utils import TestHelper as helper
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# Set view of planting area for visual debugging
general.set_current_view_position(512.0, 500.0, 38.0)
@@ -69,9 +68,10 @@ def ShapeIntersectionFilter_InstancesPlantInAssignedShape():
# 2) Create a new entity with required vegetation area components and Vegetation Shape Intersection Filter
center_point = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 1.0,
asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "ShapeIntersection_PinkFlower2")[0]
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 1.0,
pink_flower_prefab)
spawner_entity.add_component("Vegetation Shape Intersection Filter")
# Create a planting surface
@@ -58,15 +58,16 @@ def SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment():
return False
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
general.set_current_view_position(512.0, 480.0, 38.0)
# Create a spawner entity setup with all needed components
center_point = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 32.0, asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SlopeAlign_PinkFlower2")[0]
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 32.0,
pink_flower_prefab)
# Create a sloped mesh surface for the instances to plant on
center_point = math.Vector3(502.0, 512.0, 24.0)
@@ -59,15 +59,16 @@ def SlopeAlignmentModifier_InstanceSurfaceAlignment():
return False
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
general.set_current_view_position(512.0, 480.0, 38.0)
# Create a spawner entity setup with all needed components
center_point = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 32.0, asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SlopeAlign_PinkFlower")[0]
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", center_point, 16.0, 16.0, 32.0,
pink_flower_prefab)
# Create a sloped mesh surface for the instances to plant on
center_point = math.Vector3(502.0, 512.0, 24.0)
@@ -63,16 +63,17 @@ def SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlopes():
from editor_python_test_tools.utils import TestHelper as helper
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# Set view of planting area for visual debugging
general.set_current_view_position(512.0, 475.0, 38.0)
# 2) Create a new entity with required vegetation area components
center_point = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", center_point, 32.0, 32.0, 32.0, asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "Slope_PinkFlower")[0]
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", center_point, 32.0, 32.0, 32.0,
pink_flower_prefab)
# Add a Vegetation Slope Filter
spawner_entity.add_component("Vegetation Slope Filter")
@@ -7,21 +7,21 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
class Tests:
spawner_slice_created = (
"Spawner slice created successfully",
"Failed to create Spawner slice"
spawner_prefab_created = (
"Spawner prefab created successfully",
"Failed to create Spawner prefab"
)
instance_count_unhidden = (
"Initial instance counts are as expected",
"Found an unexpected number of initial instances"
)
instance_count_hidden = (
"Instance counts upon hiding the Spawner slice are as expected",
"Unexpectedly found instances with the Spawner slice hidden"
"Instance counts upon hiding the Spawner prefab are as expected",
"Unexpectedly found instances with the Spawner prefab hidden"
)
blender_slice_created = (
"Blender slice created successfully",
"Failed to create Blender slice"
blender_prefab_created = (
"Blender prefab created successfully",
"Failed to create Blender prefab"
)
@@ -43,81 +43,76 @@ def SpawnerSlices_SliceCreationAndVisibilityToggleWorks():
import azlmbr.math as math
import azlmbr.legacy.general as general
import azlmbr.slice as slice
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.asset as asset
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.editor_entity_utils import EditorEntity
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
def path_is_valid_asset(asset_path):
asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", asset_path, math.Uuid(), False)
return asset_id.invoke("IsValid")
from editor_python_test_tools.prefab_utils import Prefab
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
general.set_current_view_position(512.0, 480.0, 38.0)
# 2) C2627900 Verifies if a slice containing the Vegetation Layer Spawner component can be created.
# 2) Verifies if a prefab containing the Vegetation Layer Spawner component can be created.
# 2.1) Create basic vegetation entity
position = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
veg_1 = dynveg.create_dynamic_slice_vegetation_area("vegetation_1", position, 16.0, 16.0, 16.0, asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SpawnerPrefab_PinkFlower")[0]
veg_1 = dynveg.create_temp_prefab_vegetation_area("vegetation_1", position, 16.0, 16.0, 16.0,
pink_flower_prefab)
# 2.2) Create slice from the entity
slice_path = os.path.join("slices", "TestSlice_1.slice")
slice.SliceRequestBus(bus.Broadcast, "CreateNewSlice", veg_1.id, slice_path)
# 2.2) Create prefab from the entity
spawner_prefab_filename = "TestPrefab_1"
spawner_prefab, spawner_prefab_instance = Prefab.create_prefab([veg_1], spawner_prefab_filename)
# 2.3) Verify if the slice has been created successfully
spawner_slice_success = helper.wait_for_condition(lambda: path_is_valid_asset(slice_path), 10.0)
Report.result(Tests.spawner_slice_created, spawner_slice_success)
# Verify if prefab is created
Report.result(Tests.spawner_prefab_created, spawner_prefab.is_prefab_loaded(spawner_prefab_filename))
# 3) C2627904: Hiding a slice containing the component clears any visuals from the Viewport
# 3) Hiding a prefab containing the component clears any visuals from the Viewport
# 3.1) Create Surface for instances to plant on
dynveg.create_surface_entity("Surface_Entity", position, 16.0, 16.0, 1.0)
# 3.2) Initially verify instance count before hiding slice
# 3.2) Initially verify instance count before hiding prefab
initial_count_success = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 16.0, 400), 5.0)
Report.result(Tests.instance_count_unhidden, initial_count_success)
# 3.3) Hide the slice and verify instance count
editor.EditorEntityAPIBus(bus.Event, "SetVisibilityState", veg_1.id, False)
# 3.3) Hide the prefab and verify instance count
editor.EditorEntityAPIBus(bus.Event, "SetVisibilityState", spawner_prefab_instance.container_entity.id, False)
hidden_instance_count = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 16.0, 0), 5.0)
Report.result(Tests.instance_count_hidden, hidden_instance_count)
# 3.4) Unhide the slice
editor.EditorEntityAPIBus(bus.Event, "SetVisibilityState", veg_1.id, True)
editor.EditorEntityAPIBus(bus.Event, "SetVisibilityState", spawner_prefab_instance.container_entity.id, True)
# 4) C2627905 A slice containing the Vegetation Layer Blender component can be created.
# 4) A slice containing the Vegetation Layer Blender component can be created.
# 4.1) Create another vegetation entity to add to blender component
veg_2 = dynveg.create_dynamic_slice_vegetation_area("vegetation_2", position, 1.0, 1.0, 1.0, "")
veg_2 = dynveg.create_empty_vegetation_area("vegetation_2", position, 1.0, 1.0, 1.0)
# 4.2) Create entity with Vegetation Layer Blender
components_to_add = ["Box Shape", "Vegetation Layer Blender"]
blender_entity = hydra.Entity("blender_entity")
blender_entity.create_entity(position, components_to_add)
blender_entity = EditorEntity.create_editor_entity("blender_entity")
blender_entity.add_components(components_to_add)
# 4.3) Pin both the vegetation areas to the blender entity
pte = hydra.get_property_tree(blender_entity.components[1])
pte = blender_entity.components[1].get_property_tree()
path = "Configuration|Vegetation Areas"
pte.update_container_item(path, 0, veg_1.id)
pte.add_container_item(path, 1, veg_2.id)
# 4.4) Drag the simple vegetation areas under the Vegetation Layer Blender entity to create an entity hierarchy.
veg_1.set_test_parent_entity(blender_entity)
veg_2.set_test_parent_entity(blender_entity)
veg_2.set_parent_entity(blender_entity.id)
# 4.5) Create slice from blender entity
slice_path = os.path.join("slices", "TestSlice_2.slice")
slice.SliceRequestBus(bus.Broadcast, "CreateNewSlice", blender_entity.id, slice_path)
# 4.5) Create prefab from blender entity
blender_prefab_filename = "TestPrefab_2"
blender_prefab, blender_prefab_instance = Prefab.create_prefab([veg_2], blender_prefab_filename)
# 4.6) Verify if the slice has been created successfully
blender_slice_success = helper.wait_for_condition(lambda: path_is_valid_asset(slice_path), 5.0)
Report.result(Tests.blender_slice_created, blender_slice_success)
# 4.6) Verify if the prefab has been created successfully
Report.result(Tests.blender_prefab_created, blender_prefab.is_prefab_loaded(blender_prefab_filename))
if __name__ == "__main__":
@@ -34,13 +34,12 @@ def SurfaceDataRefreshes_RemainsStable():
import azlmbr.legacy.general as general
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
from editor_python_test_tools.utils import TestHelper as helper
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
world_center = math.Vector3(512.0, 512.0, 32.0)
@@ -67,8 +67,7 @@ def SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected():
surface_data.SurfaceTag("test_tag3")]
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# Set view of planting area for visual debugging
general.set_current_view_position(512.0, 500.0, 38.0)
@@ -76,9 +75,10 @@ def SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected():
# 2) Create a new instance spawner entity with multiple Dynamic Slice Instance Spawner descriptors
spawner_center_point = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0, 16.0,
asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SurfaceMaskOverrides_PinkFlower")[0]
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", spawner_center_point, 16.0, 16.0,
16.0, pink_flower_prefab)
asset_list_component = spawner_entity.components[2]
desc_asset = hydra.get_component_property_value(asset_list_component,
"Configuration|Embedded Assets")[0]
@@ -39,12 +39,12 @@ def SurfaceMaskFilter_BasicSurfaceTagCreation():
"""
import azlmbr.surface_data as surface_data
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
tag1 = surface_data.SurfaceTag()
tag2 = surface_data.SurfaceTag()
@@ -91,18 +91,16 @@ def SurfaceMaskFilter_ExclusionList():
Report.info(f"Failed to add Generated surface tag of {surface_tag}")
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
general.set_current_view_position(512.0, 480.0, 38.0)
# 2) Create entity with components "Vegetation Layer Spawner", "Vegetation Asset List", "Box Shape"
entity_position = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner",
entity_position,
10.0, 10.0, 10.0,
asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SurfaceMaskTagExclusion_PinkFlower")[0]
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 10.0, 10.0, 10.0,
pink_flower_prefab)
# 3) Add a Vegetation Surface Mask Filter component to the entity.
spawner_entity.add_component("Vegetation Surface Mask Filter")
@@ -92,18 +92,16 @@ def SurfaceMaskFilter_InclusionList():
Report.info(f"Failed to add Generated surface tag of {surface_tag}")
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
general.set_current_view_position(512.0, 480.0, 38.0)
# 2) Create entity with components "Vegetation Layer Spawner", "Vegetation Asset List", "Box Shape"
entity_position = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Instance Spawner",
entity_position,
10.0, 10.0, 10.0,
asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SurfaceMaskTagInclusion_PinkFlower")[0]
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", entity_position, 10.0, 10.0, 10.0,
pink_flower_prefab)
# 3) Add a Vegetation Surface Mask Filter component to the entity.
spawner_entity.add_component("Vegetation Surface Mask Filter")
@@ -47,15 +47,16 @@ def SystemSettings_SectorPointDensity():
INSTANCE_COUNT_AFTER_DENSITY_CHANGE = 100
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
general.set_current_view_position(512.0, 480.0, 38.0)
# Create basic vegetation entity
position = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
dynveg.create_dynamic_slice_vegetation_area("vegetation", position, 16.0, 16.0, 1.0, asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SectorPoint_PinkFlower")[0]
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", position, 16.0, 16.0, 1.0,
pink_flower_prefab)
dynveg.create_surface_entity("Surface_Entity", position, 16.0, 16.0, 1.0)
# Count the number of vegetation instances in the vegetation area
@@ -43,15 +43,16 @@ def SystemSettings_SectorSize():
VEGETATION_INSTANCE_COUNT = 400
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
general.set_current_view_position(512.0, 480.0, 38.0)
# Create basic vegetation entity
position = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PinkFlower.dynamicslice")
vegetation = dynveg.create_dynamic_slice_vegetation_area("vegetation", position, 16.0, 16.0, 1.0, asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "SectorSize_PinkFlower")[0]
vegetation = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", position, 16.0, 16.0, 1.0,
pink_flower_prefab)
dynveg.create_surface_entity("Surface_Entity", position, 16.0, 16.0, 1.0)
# Add the Vegetation Debugger component to the Level Inspector
@@ -43,18 +43,20 @@ def VegetationInstances_DespawnWhenOutOfRange():
import azlmbr.legacy.general as general
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
from editor_python_test_tools.utils import TestHelper as helper
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# Create vegetation layer spawner
world_center = math.Vector3(512.0, 512.0, 32.0)
asset_path = os.path.join("Slices", "PurpleFlower.dynamicslice")
spawner_entity = dynveg.create_dynamic_slice_vegetation_area("Spawner Instance", world_center, 16.0, 16.0, 16.0, asset_path)
pink_flower_asset_path = os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel")
pink_flower_prefab = dynveg.create_temp_mesh_prefab(pink_flower_asset_path, "RangeDespawn_PinkFlower")[0]
spawner_entity = dynveg.create_temp_prefab_vegetation_area("Instance Spawner", world_center, 16.0, 16.0, 16.0,
pink_flower_prefab)
# Create a surface to spawn on
dynveg.create_surface_entity("Spawner Entity", world_center, 16.0, 16.0, 1.0)
@@ -7,21 +7,171 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
import os
import pytest
import sys
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../automatedtesting_shared')
from base import TestAutomationBase
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(TestAutomationBase):
class TestAutomation(EditorTestSuite):
def test_DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks(self, request, workspace, editor, launcher_platform):
# Helpers for test asset cleanup
def cleanup_test_level(self, workspace):
file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")],
True, True)
class test_AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude(EditorSharedTest):
from .EditorScripts import AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude as test_module
class test_AltitudeFilter_FilterStageToggle(EditorSharedTest):
from .EditorScripts import AltitudeFilter_FilterStageToggle as test_module
class test_AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude(EditorSharedTest):
from .EditorScripts import AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude as test_module
class test_AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea(EditorSharedTest):
from .EditorScripts import AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea as test_module
class test_AssetWeightSelector_InstancesExpressBasedOnWeight(EditorSharedTest):
from .EditorScripts import AssetWeightSelector_InstancesExpressBasedOnWeight as test_module
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/4155")
class test_DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius(EditorSharedTest):
from .EditorScripts import DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius as test_module
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/4155")
class test_DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius(EditorSharedTest):
from .EditorScripts import DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius as test_module
class test_DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks(EditorSharedTest):
from .EditorScripts import DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_EmptyInstanceSpawner_EmptySpawnerWorks(self, request, workspace, editor, launcher_platform):
class test_EmptyInstanceSpawner_EmptySpawnerWorks(EditorSharedTest):
from .EditorScripts import EmptyInstanceSpawner_EmptySpawnerWorks as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
class test_InstanceSpawnerPriority_LayerAndSubPriority_HigherValuesPlantOverLower(EditorSharedTest):
from .EditorScripts import InstanceSpawnerPriority_LayerAndSubPriority as test_module
class test_LayerBlender_E2E_Editor(EditorSingleTest):
from .EditorScripts import LayerBlender_E2E_Editor as test_module
# Custom setup/teardown to remove test level created during test
def setup(self, request, workspace, editor, editor_test_results, launcher_platform):
TestAutomation.cleanup_test_level(self, workspace)
def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
TestAutomation.cleanup_test_level(self, workspace)
class test_LayerBlocker_InstancesBlockedInConfiguredArea(EditorSharedTest):
from .EditorScripts import LayerBlocker_InstancesBlockedInConfiguredArea as test_module
class test_LayerSpawner_FilterStageToggle(EditorSharedTest):
from .EditorScripts import LayerSpawner_FilterStageToggle as test_module
class test_LayerSpawner_InheritBehaviorFlag(EditorSharedTest):
from .EditorScripts import LayerSpawner_InheritBehaviorFlag as test_module
class test_LayerSpawner_InstancesPlantInAllSupportedShapes(EditorSharedTest):
from .EditorScripts import LayerSpawner_InstancesPlantInAllSupportedShapes as test_module
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/6549")
class test_LayerSpawner_InstancesRefreshUsingCorrectViewportCamera(EditorSharedTest):
from .EditorScripts import LayerSpawner_InstancesRefreshUsingCorrectViewportCamera as test_module
class test_MeshBlocker_InstancesBlockedByMesh(EditorSharedTest):
from .EditorScripts import MeshBlocker_InstancesBlockedByMesh as test_module
class test_MeshBlocker_InstancesBlockedByMeshHeightTuning(EditorSharedTest):
from .EditorScripts import MeshBlocker_InstancesBlockedByMeshHeightTuning as test_module
class test_MeshSurfaceTagEmitter_DependentOnMeshComponent(EditorSharedTest):
from .EditorScripts import MeshSurfaceTagEmitter_DependentOnMeshComponent as test_module
class test_MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(EditorSharedTest):
from .EditorScripts import MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully as test_module
class test_PhysXColliderSurfaceTagEmitter_E2E_Editor(EditorSharedTest):
from .EditorScripts import PhysXColliderSurfaceTagEmitter_E2E_Editor as test_module
class test_PositionModifier_AutoSnapToSurfaceWorks(EditorSharedTest):
from .EditorScripts import PositionModifier_AutoSnapToSurfaceWorks as test_module
class test_PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets(EditorSharedTest):
from .EditorScripts import \
PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets as test_module
class test_PrefabInstanceSpawner_Embedded_E2E_Editor(EditorSingleTest):
from .EditorScripts import PrefabInstanceSpawner_Embedded_E2E as test_module
# Custom setup/teardown to remove test level created during test
def setup(self, request, workspace, editor, editor_test_results, launcher_platform):
TestAutomation.cleanup_test_level(self, workspace)
def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
TestAutomation.cleanup_test_level(self, workspace)
class test_PrefabInstanceSpawner_External_E2E_Editor(EditorSingleTest):
from .EditorScripts import PrefabInstanceSpawner_External_E2E as test_module
# Custom setup/teardown to remove test level created during test
def setup(self, request, workspace, editor, editor_test_results, launcher_platform):
TestAutomation.cleanup_test_level(self, workspace)
def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
TestAutomation.cleanup_test_level(self, workspace)
class test_RotationModifier_InstancesRotateWithinRange(EditorSharedTest):
from .EditorScripts import RotationModifier_InstancesRotateWithinRange as test_module
class test_RotationModifierOverrides_InstancesRotateWithinRange(EditorSharedTest):
from .EditorScripts import RotationModifierOverrides_InstancesRotateWithinRange as test_module
class test_ScaleModifier_InstancesProperlyScale(EditorSharedTest):
from .EditorScripts import ScaleModifier_InstancesProperlyScale as test_module
class test_ScaleModifierOverrides_InstancesProperlyScale(EditorSharedTest):
from .EditorScripts import ScaleModifierOverrides_InstancesProperlyScale as test_module
class test_ShapeIntersectionFilter_FilterStageToggle(EditorSharedTest):
from .EditorScripts import ShapeIntersectionFilter_FilterStageToggle as test_module
class test_ShapeIntersectionFilter_InstancesPlantInAssignedShape(EditorSharedTest):
from .EditorScripts import ShapeIntersectionFilter_InstancesPlantInAssignedShape as test_module
class test_SlopeAlignmentModifier_InstanceSurfaceAlignment(EditorSharedTest):
from .EditorScripts import SlopeAlignmentModifier_InstanceSurfaceAlignment as test_module
class test_SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment(EditorSharedTest):
from .EditorScripts import SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment as test_module
class test_SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlopes(EditorSharedTest):
from .EditorScripts import SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlope as test_module
class test_SpawnerPrefabs_PrefabCreationAndVisibilityToggleWorks(EditorSharedTest):
from .EditorScripts import SpawnerPrefabs_PrefabCreationAndVisibilityToggleWorks as test_module
class test_SurfaceDataRefreshes_RemainsStable(EditorSharedTest):
from .EditorScripts import SurfaceDataRefreshes_RemainsStable as test_module
class test_SurfaceMaskFilter_BasicSurfaceTagCreation(EditorSharedTest):
from .EditorScripts import SurfaceMaskFilter_BasicSurfaceTagCreation as test_module
class test_SurfaceMaskFilter_ExclusiveSurfaceTags_Function(EditorSharedTest):
from .EditorScripts import SurfaceMaskFilter_ExclusionList as test_module
class test_SurfaceMaskFilter_InclusiveSurfaceTags_Function(EditorSharedTest):
from .EditorScripts import SurfaceMaskFilter_InclusionList as test_module
class test_SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected(EditorSharedTest):
from .EditorScripts import SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected as test_module
class test_SystemSettings_SectorPointDensity(EditorSharedTest):
from .EditorScripts import SystemSettings_SectorPointDensity as test_module
class test_SystemSettings_SectorSize(EditorSharedTest):
from .EditorScripts import SystemSettings_SectorSize as test_module
class test_VegetationInstances_DespawnWhenOutOfRange(EditorSharedTest):
from .EditorScripts import VegetationInstances_DespawnWhenOutOfRange as test_module
@@ -1,192 +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 EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
@pytest.mark.SUITE_main
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(EditorTestSuite):
class test_AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude(EditorParallelTest):
from .EditorScripts import AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude as test_module
class test_AltitudeFilter_FilterStageToggle(EditorParallelTest):
from .EditorScripts import AltitudeFilter_FilterStageToggle as test_module
class test_AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude(EditorParallelTest):
from .EditorScripts import AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude as test_module
@pytest.mark.SUITE_main
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation_PrefabNotEnabled(EditorTestSuite):
enable_prefab_system = False
# Helpers for test asset cleanup
def cleanup_test_level(self, workspace):
file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")],
True, True)
def cleanup_test_slices(self, workspace):
file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "slices",
"TestSlice_1.slice")], True, True)
file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "slices",
"TestSlice_2.slice")], True, True)
class test_DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks(EditorParallelTest):
from .EditorScripts import DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks as test_module
class test_EmptyInstanceSpawner_EmptySpawnerWorks(EditorParallelTest):
from .EditorScripts import EmptyInstanceSpawner_EmptySpawnerWorks as test_module
class test_SpawnerSlices_SliceCreationAndVisibilityToggleWorks(EditorSingleTest):
# Custom teardown to remove slice asset created during test
def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
TestAutomation_PrefabNotEnabled.cleanup_test_slices(self, workspace)
from .EditorScripts import SpawnerSlices_SliceCreationAndVisibilityToggleWorks as test_module
class test_AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea(EditorParallelTest):
from .EditorScripts import AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea as test_module
class test_AssetWeightSelector_InstancesExpressBasedOnWeight(EditorParallelTest):
from .EditorScripts import AssetWeightSelector_InstancesExpressBasedOnWeight as test_module
@pytest.mark.skip(reason="https://github.com/o3de/o3de/issues/4155")
class test_DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius(EditorParallelTest):
from .EditorScripts import DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius as test_module
@pytest.mark.skip(reason="https://github.com/o3de/o3de/issues/4155")
class test_DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius(EditorParallelTest):
from .EditorScripts import DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius as test_module
class test_SurfaceDataRefreshes_RemainsStable(EditorParallelTest):
from .EditorScripts import SurfaceDataRefreshes_RemainsStable as test_module
class test_VegetationInstances_DespawnWhenOutOfRange(EditorParallelTest):
from .EditorScripts import VegetationInstances_DespawnWhenOutOfRange as test_module
class test_InstanceSpawnerPriority_LayerAndSubPriority_HigherValuesPlantOverLower(EditorParallelTest):
from .EditorScripts import InstanceSpawnerPriority_LayerAndSubPriority as test_module
class test_LayerBlocker_InstancesBlockedInConfiguredArea(EditorParallelTest):
from .EditorScripts import LayerBlocker_InstancesBlockedInConfiguredArea as test_module
class test_LayerSpawner_InheritBehaviorFlag(EditorParallelTest):
from .EditorScripts import LayerSpawner_InheritBehaviorFlag as test_module
class test_LayerSpawner_InstancesPlantInAllSupportedShapes(EditorParallelTest):
from .EditorScripts import LayerSpawner_InstancesPlantInAllSupportedShapes as test_module
class test_LayerSpawner_FilterStageToggle(EditorParallelTest):
from .EditorScripts import LayerSpawner_FilterStageToggle as test_module
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2038")
class test_LayerSpawner_InstancesRefreshUsingCorrectViewportCamera(EditorParallelTest):
from .EditorScripts import LayerSpawner_InstancesRefreshUsingCorrectViewportCamera as test_module
class test_MeshBlocker_InstancesBlockedByMesh(EditorParallelTest):
from .EditorScripts import MeshBlocker_InstancesBlockedByMesh as test_module
class test_MeshBlocker_InstancesBlockedByMeshHeightTuning(EditorParallelTest):
from .EditorScripts import MeshBlocker_InstancesBlockedByMeshHeightTuning as test_module
class test_MeshSurfaceTagEmitter_DependentOnMeshComponent(EditorParallelTest):
from .EditorScripts import MeshSurfaceTagEmitter_DependentOnMeshComponent as test_module
class test_MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(EditorParallelTest):
from .EditorScripts import MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully as test_module
class test_PhysXColliderSurfaceTagEmitter_E2E_Editor(EditorParallelTest):
from .EditorScripts import PhysXColliderSurfaceTagEmitter_E2E_Editor as test_module
class test_PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets(EditorParallelTest):
from .EditorScripts import PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets as test_module
class test_PositionModifier_AutoSnapToSurfaceWorks(EditorParallelTest):
from .EditorScripts import PositionModifier_AutoSnapToSurfaceWorks as test_module
class test_RotationModifier_InstancesRotateWithinRange(EditorParallelTest):
from .EditorScripts import RotationModifier_InstancesRotateWithinRange as test_module
class test_RotationModifierOverrides_InstancesRotateWithinRange(EditorParallelTest):
from .EditorScripts import RotationModifierOverrides_InstancesRotateWithinRange as test_module
class test_ScaleModifier_InstancesProperlyScale(EditorParallelTest):
from .EditorScripts import ScaleModifier_InstancesProperlyScale as test_module
class test_ScaleModifierOverrides_InstancesProperlyScale(EditorParallelTest):
from .EditorScripts import ScaleModifierOverrides_InstancesProperlyScale as test_module
class test_ShapeIntersectionFilter_InstancesPlantInAssignedShape(EditorParallelTest):
from .EditorScripts import ShapeIntersectionFilter_InstancesPlantInAssignedShape as test_module
class test_ShapeIntersectionFilter_FilterStageToggle(EditorParallelTest):
from .EditorScripts import ShapeIntersectionFilter_FilterStageToggle as test_module
class test_SlopeAlignmentModifier_InstanceSurfaceAlignment(EditorParallelTest):
from .EditorScripts import SlopeAlignmentModifier_InstanceSurfaceAlignment as test_module
class test_SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment(EditorParallelTest):
from .EditorScripts import SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment as test_module
class test_SurfaceMaskFilter_BasicSurfaceTagCreation(EditorParallelTest):
from .EditorScripts import SurfaceMaskFilter_BasicSurfaceTagCreation as test_module
class test_SurfaceMaskFilter_ExclusiveSurfaceTags_Function(EditorParallelTest):
from .EditorScripts import SurfaceMaskFilter_ExclusionList as test_module
class test_SurfaceMaskFilter_InclusiveSurfaceTags_Function(EditorParallelTest):
from .EditorScripts import SurfaceMaskFilter_InclusionList as test_module
class test_SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected(EditorParallelTest):
from .EditorScripts import SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected as test_module
class test_SystemSettings_SectorPointDensity(EditorParallelTest):
from .EditorScripts import SystemSettings_SectorPointDensity as test_module
class test_SystemSettings_SectorSize(EditorParallelTest):
from .EditorScripts import SystemSettings_SectorSize as test_module
class test_SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlopes(EditorParallelTest):
from .EditorScripts import SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlope as test_module
class test_DynamicSliceInstanceSpawner_Embedded_E2E_Editor(EditorSingleTest):
from .EditorScripts import DynamicSliceInstanceSpawner_Embedded_E2E as test_module
# Custom setup/teardown to remove test level created during test
def setup(self, request, workspace, editor, editor_test_results, launcher_platform):
TestAutomation_PrefabNotEnabled.cleanup_test_level(self, workspace)
def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
TestAutomation_PrefabNotEnabled.cleanup_test_level(self, workspace)
class test_DynamicSliceInstanceSpawner_External_E2E_Editor(EditorSingleTest):
from .EditorScripts import DynamicSliceInstanceSpawner_External_E2E as test_module
# Custom setup/teardown to remove test level created during test
def setup(self, request, workspace, editor, editor_test_results, launcher_platform):
TestAutomation_PrefabNotEnabled.cleanup_test_level(self, workspace)
def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
TestAutomation_PrefabNotEnabled.cleanup_test_level(self, workspace)
class test_LayerBlender_E2E_Editor(EditorSingleTest):
from .EditorScripts import LayerBlender_E2E_Editor as test_module
# Custom setup/teardown to remove test level created during test
def setup(self, request, workspace, editor, editor_test_results, launcher_platform):
TestAutomation_PrefabNotEnabled.cleanup_test_level(self, workspace)
def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
TestAutomation_PrefabNotEnabled.cleanup_test_level(self, workspace)
@@ -7,277 +7,17 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
import os
import pytest
import sys
import ly_test_tools.environment.waiter as waiter
import ly_test_tools.environment.file_system as file_system
import editor_python_test_tools.hydra_test_utils as hydra
from ly_remote_console.remote_console_commands import RemoteConsole as RemoteConsole
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../automatedtesting_shared')
from base import TestAutomationBase
@pytest.fixture
def remove_test_slice(request, workspace, project):
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice_1.slice")], True,
True)
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice_2.slice")], True,
True)
def teardown():
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice_1.slice")], True,
True)
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice_2.slice")], True,
True)
request.addfinalizer(teardown)
@pytest.fixture
def remote_console_instance(request):
console = RemoteConsole()
def teardown():
if console.connected:
console.stop()
request.addfinalizer(teardown)
return console
from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
@pytest.mark.SUITE_periodic
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(TestAutomationBase):
class TestAutomation(EditorTestSuite):
def test_AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude as test_module
self._run_test(request, workspace, editor, test_module)
global_extra_cmdline_args = ["-BatchMode", "-autotest_mode"]
def test_AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude as test_module
self._run_test(request, workspace, editor, test_module)
def test_AltitudeFilter_FilterStageToggle(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AltitudeFilter_FilterStageToggle as test_module
self._run_test(request, workspace, editor, test_module)
def test_SpawnerSlices_SliceCreationAndVisibilityToggleWorks(self, request, workspace, editor, remove_test_slice, launcher_platform):
from .EditorScripts import SpawnerSlices_SliceCreationAndVisibilityToggleWorks as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_AssetWeightSelector_InstancesExpressBasedOnWeight(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AssetWeightSelector_InstancesExpressBasedOnWeight as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/4155")
def test_DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius(self, request, workspace, editor, launcher_platform):
from .EditorScripts import DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/4155")
def test_DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius(self, request, workspace, editor, launcher_platform):
from .EditorScripts import DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SurfaceDataRefreshes_RemainsStable(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SurfaceDataRefreshes_RemainsStable as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_VegetationInstances_DespawnWhenOutOfRange(self, request, workspace, editor, launcher_platform):
from .EditorScripts import VegetationInstances_DespawnWhenOutOfRange as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_InstanceSpawnerPriority_LayerAndSubPriority_HigherValuesPlantOverLower(self, request, workspace, editor, launcher_platform):
from .EditorScripts import InstanceSpawnerPriority_LayerAndSubPriority as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LayerBlocker_InstancesBlockedInConfiguredArea(self, request, workspace, editor, launcher_platform):
from .EditorScripts import LayerBlocker_InstancesBlockedInConfiguredArea as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LayerSpawner_InheritBehaviorFlag(self, request, workspace, editor, launcher_platform):
from .EditorScripts import LayerSpawner_InheritBehaviorFlag as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LayerSpawner_InstancesPlantInAllSupportedShapes(self, request, workspace, editor, launcher_platform):
from .EditorScripts import LayerSpawner_InstancesPlantInAllSupportedShapes as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LayerSpawner_FilterStageToggle(self, request, workspace, editor, launcher_platform):
from .EditorScripts import LayerSpawner_FilterStageToggle as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2038")
def test_LayerSpawner_InstancesRefreshUsingCorrectViewportCamera(self, request, workspace, editor, launcher_platform):
from .EditorScripts import LayerSpawner_InstancesRefreshUsingCorrectViewportCamera as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_MeshBlocker_InstancesBlockedByMesh(self, request, workspace, editor, launcher_platform):
from .EditorScripts import MeshBlocker_InstancesBlockedByMesh as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_MeshBlocker_InstancesBlockedByMeshHeightTuning(self, request, workspace, editor, launcher_platform):
from .EditorScripts import MeshBlocker_InstancesBlockedByMeshHeightTuning as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_MeshSurfaceTagEmitter_DependentOnMeshComponent(self, request, workspace, editor, launcher_platform):
from .EditorScripts import MeshSurfaceTagEmitter_DependentOnMeshComponent as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(self, request, workspace, editor, launcher_platform):
from .EditorScripts import MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_PhysXColliderSurfaceTagEmitter_E2E_Editor(self, request, workspace, editor, launcher_platform):
from .EditorScripts import PhysXColliderSurfaceTagEmitter_E2E_Editor as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets(self, request, workspace, editor, launcher_platform):
from .EditorScripts import PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_PositionModifier_AutoSnapToSurfaceWorks(self, request, workspace, editor, launcher_platform):
from .EditorScripts import PositionModifier_AutoSnapToSurfaceWorks as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_RotationModifier_InstancesRotateWithinRange(self, request, workspace, editor, launcher_platform):
from .EditorScripts import RotationModifier_InstancesRotateWithinRange as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_RotationModifierOverrides_InstancesRotateWithinRange(self, request, workspace, editor, launcher_platform):
from .EditorScripts import RotationModifierOverrides_InstancesRotateWithinRange as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ScaleModifier_InstancesProperlyScale(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ScaleModifier_InstancesProperlyScale as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ScaleModifierOverrides_InstancesProperlyScale(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ScaleModifierOverrides_InstancesProperlyScale as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ShapeIntersectionFilter_InstancesPlantInAssignedShape(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ShapeIntersectionFilter_InstancesPlantInAssignedShape as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ShapeIntersectionFilter_FilterStageToggle(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ShapeIntersectionFilter_FilterStageToggle as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SlopeAlignmentModifier_InstanceSurfaceAlignment(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SlopeAlignmentModifier_InstanceSurfaceAlignment as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SurfaceMaskFilter_BasicSurfaceTagCreation(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SurfaceMaskFilter_BasicSurfaceTagCreation as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SurfaceMaskFilter_ExclusiveSurfaceTags_Function(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SurfaceMaskFilter_ExclusionList as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SurfaceMaskFilter_InclusiveSurfaceTags_Function(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SurfaceMaskFilter_InclusionList as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SystemSettings_SectorPointDensity(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SystemSettings_SectorPointDensity as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SystemSettings_SectorSize(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SystemSettings_SectorSize as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlopes(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlope as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.SUITE_periodic
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("level", ["tmp_level"])
class TestAutomationE2E(TestAutomationBase):
# The following tests must run in order, please do not move tests out of order
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
def test_DynamicSliceInstanceSpawner_Embedded_E2E_Editor(self, request, workspace, project, level, editor, launcher_platform):
# Ensure our test level does not already exist
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
from .EditorScripts import DynamicSliceInstanceSpawner_Embedded_E2E as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.parametrize("launcher_platform", ['windows'])
def test_DynamicSliceInstanceSpawner_Embedded_E2E_Launcher(self, workspace, launcher, level,
remote_console_instance, project, launcher_platform):
expected_lines = [
"Instances found in area = 400"
]
hydra.launch_and_validate_results_launcher(launcher, level, remote_console_instance, expected_lines, launch_ap=False)
# Cleanup our temp level
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
def test_DynamicSliceInstanceSpawner_External_E2E_Editor(self, request, workspace, project, level, editor, launcher_platform):
# Ensure our test level does not already exist
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
from .EditorScripts import DynamicSliceInstanceSpawner_External_E2E as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.parametrize("launcher_platform", ['windows'])
def test_DynamicSliceInstanceSpawner_External_E2E_Launcher(self, workspace, launcher, level,
remote_console_instance, project, launcher_platform):
expected_lines = [
"Instances found in area = 400"
]
hydra.launch_and_validate_results_launcher(launcher, level, remote_console_instance, expected_lines, launch_ap=False)
# Cleanup our temp level
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
def test_LayerBlender_E2E_Editor(self, request, workspace, project, level, editor, launcher_platform):
# Ensure our test level does not already exist
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
from .EditorScripts import LayerBlender_E2E_Editor as test_module
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.parametrize("launcher_platform", ['windows'])
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/4170")
def test_LayerBlender_E2E_Launcher(self, workspace, launcher, level,
remote_console_instance, project, launcher_platform):
launcher.args.extend(["-rhi=Null"])
launcher.start(launch_ap=False)
assert launcher.is_alive(), "Launcher failed to start"
# Wait for test script to quit the launcher. If wait_for returns exc, test was not successful
waiter.wait_for(lambda: not launcher.is_alive(), timeout=300)
# Verify launcher quit successfully and did not crash
ret_code = launcher.get_returncode()
assert ret_code == 0, "Test failed. See Game.log for details"
# Cleanup our temp level
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
class test_DynVegUtils_TempPrefabCreationWorks(EditorSharedTest):
from .EditorScripts import DynVegUtils_TempPrefabCreationWorks as test_module
@@ -1,23 +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 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 = ["-BatchMode", "-autotest_mode"]
class test_DynVegUtils_TempPrefabCreationWorks(EditorSharedTest):
from .EditorScripts import DynVegUtils_TempPrefabCreationWorks as test_module
@@ -65,8 +65,7 @@ def GradientGenerators_Incompatibilities():
}
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# For every gradient generator component, verify that they are incompatible
# which each vegetation area component
@@ -74,8 +74,7 @@ def GradientModifiers_Incompatibilities():
}
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# For every gradient modifier component, verify that they are incompatible
# which each vegetation area and gradient generator/modifier component
@@ -86,8 +86,7 @@ def GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin():
return entity
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# 2) Create entity with Random Noise gradient and verify gradient position after clearing pinned entity
clear_entityid_check_position(
@@ -90,8 +90,7 @@ def GradientPreviewSettings_DefaultPinnedEntityIsSelf():
]
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
for param in param_list:
execute_test(param.required_components[param.accessed_component],
@@ -61,8 +61,7 @@ def GradientSampling_GradientReferencesAddRemoveSuccessfully():
Report.result(gradient_cleared_from_modifier, entity.Equal(EntityId.EntityId()))
# 1) Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# 2) Create a new entity with components "Random Noise Gradient", "Gradient Transform Modifier" and "Box Shape"
entity_position = math.Vector3(125.0, 136.0, 32.0)
@@ -42,8 +42,7 @@ def GradientSurfaceTagEmitter_ComponentDependencies():
return editor.EditorComponentAPIBus(bus.Broadcast, "IsComponentEnabled", EntityComponentIdPair)
# Open an existing simple level
helper.init_idle()
helper.open_level("Physics", "Base")
hydra.open_base_level()
# Create an entity with Gradient Surface Tag Emitter component
position = math.Vector3(512.0, 512.0, 32.0)

Some files were not shown because too many files have changed in this diff Show More