Merge branch 'development' of https://github.com/o3de/o3de into jckand/LinuxCrashTest
Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com>
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
import azlmbr.bus
|
||||
import azlmbr.math
|
||||
|
||||
from scene_api.scene_data import PrimitiveShape, DecompositionMode
|
||||
from scene_helpers import *
|
||||
|
||||
|
||||
@@ -41,6 +42,35 @@ def add_material_component(entity_id):
|
||||
raise RuntimeError("UpdateComponentForEntity for editor_material_component failed")
|
||||
|
||||
|
||||
def add_physx_meshes(scene_manifest: sceneData.SceneManifest, source_file_name: str, mesh_name_list: List, all_node_paths: List[str]):
|
||||
first_mesh = mesh_name_list[0].get_path()
|
||||
|
||||
# Add a Box Primitive PhysX mesh with a comment
|
||||
physx_box = scene_manifest.add_physx_primitive_mesh_group(source_file_name + "_box", PrimitiveShape.BOX, 0.0, None)
|
||||
scene_manifest.physx_mesh_group_add_comment(physx_box, "This is a box primitive")
|
||||
# Select the first mesh, unselect every other node
|
||||
scene_manifest.physx_mesh_group_add_selected_node(physx_box, first_mesh)
|
||||
|
||||
for node in all_node_paths:
|
||||
if node != first_mesh:
|
||||
scene_manifest.physx_mesh_group_add_unselected_node(physx_box, node)
|
||||
|
||||
# Add a Convex Mesh PhysX mesh with a comment
|
||||
convex_mesh = scene_manifest.add_physx_convex_mesh_group(source_file_name + "_convex", 0.08, .0004,
|
||||
True, True, True, True, True, 24, True, "Glass")
|
||||
scene_manifest.physx_mesh_group_add_comment(convex_mesh, "This is a convex mesh")
|
||||
# Select/Unselect nodes using lists
|
||||
all_except_first_mesh = [x for x in all_node_paths if x != first_mesh]
|
||||
scene_manifest.physx_mesh_group_add_selected_unselected_nodes(convex_mesh, [first_mesh], all_except_first_mesh)
|
||||
|
||||
# Configure mesh decomposition for this mesh
|
||||
scene_manifest.physx_mesh_group_decompose_meshes(convex_mesh, 512, 32, .002, 100100, DecompositionMode.TETRAHEDRON,
|
||||
0.06, 0.055, 0.00015, 3, 3, True, False)
|
||||
|
||||
# Add a Triangle mesh
|
||||
triangle = scene_manifest.add_physx_triangle_mesh_group(source_file_name + "_triangle", False, True, True, True, True, True)
|
||||
scene_manifest.physx_mesh_group_add_selected_unselected_nodes(triangle, [first_mesh], all_except_first_mesh)
|
||||
|
||||
def update_manifest(scene):
|
||||
import uuid, os
|
||||
import azlmbr.scene.graph
|
||||
@@ -62,6 +92,8 @@ def update_manifest(scene):
|
||||
previous_entity_id = azlmbr.entity.InvalidEntityId
|
||||
first_mesh = True
|
||||
|
||||
add_physx_meshes(scene_manifest, source_filename_only, mesh_name_list, all_node_paths)
|
||||
|
||||
# Loop every mesh node in the scene
|
||||
for activeMeshIndex in range(len(mesh_name_list)):
|
||||
mesh_name = mesh_name_list[activeMeshIndex]
|
||||
@@ -106,6 +138,26 @@ def update_manifest(scene):
|
||||
if not result:
|
||||
raise RuntimeError("UpdateComponentForEntity failed for Mesh component")
|
||||
|
||||
# Add a physics component referencing the triangle mesh we made for the first node
|
||||
if previous_entity_id is None:
|
||||
physx_mesh_component = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "GetOrAddComponentByTypeName",
|
||||
entity_id, "{FD429282-A075-4966-857F-D0BBF186CFE6} EditorColliderComponent")
|
||||
|
||||
json_update = json.dumps({
|
||||
"ShapeConfiguration": {
|
||||
"PhysicsAsset": {
|
||||
"Asset": {
|
||||
"assetHint": os.path.join(source_relative_path, source_filename_only + "_triangle.pxmesh")
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id, physx_mesh_component, json_update)
|
||||
|
||||
if not result:
|
||||
raise RuntimeError("UpdateComponentForEntity failed for PhysX mesh component")
|
||||
|
||||
# an example of adding a material component to override the default material
|
||||
if previous_entity_id is not None and first_mesh:
|
||||
first_mesh = False
|
||||
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
"""
|
||||
Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
class HeightTests:
|
||||
single_gradient_height_correct = (
|
||||
"Successfully retrieved height for gradient1.",
|
||||
"Failed to retrieve height for gradient1."
|
||||
)
|
||||
double_gradient_height_correct = (
|
||||
"Successfully retrieved height when two gradients exist.",
|
||||
"Failed to retrieve height when two gradients exist."
|
||||
)
|
||||
triple_gradient_height_correct = (
|
||||
"Successfully retrieved height when three gradients exist.",
|
||||
"Failed to retrieve height when three gradients exist."
|
||||
)
|
||||
terrain_data_changed_call_count_correct = (
|
||||
"OnTerrainDataChanged called expected number of times.",
|
||||
"OnTerrainDataChanged call count incorrect."
|
||||
)
|
||||
|
||||
def TerrainHeightGradientList_AddRemoveGradientWorks():
|
||||
"""
|
||||
Summary:
|
||||
Test aspects of the TerrainHeightGradientList through the BehaviorContext and the Property Tree.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
import os
|
||||
import math as sys_math
|
||||
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.math as math
|
||||
import azlmbr.terrain as terrain
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.vegetation as vegetation
|
||||
import azlmbr.entity as EntityId
|
||||
|
||||
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
|
||||
import editor_python_test_tools.pyside_utils as pyside_utils
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
|
||||
terrain_changed_call_count = 0
|
||||
expected_terrain_changed_calls = 0
|
||||
|
||||
aabb_component_name = "Axis Aligned Box Shape"
|
||||
gradientlist_component_name = "Terrain Height Gradient List"
|
||||
layerspawner_component_name = "Terrain Layer Spawner"
|
||||
|
||||
gradient_value_path = "Configuration|Value"
|
||||
|
||||
def create_entity_at(entity_name, components_to_add, x, y, z):
|
||||
entity = hydra.Entity(entity_name)
|
||||
entity.create_entity(math.Vector3(x, y, z), components_to_add)
|
||||
|
||||
return entity
|
||||
|
||||
def on_terrain_changed(args):
|
||||
nonlocal terrain_changed_call_count
|
||||
|
||||
terrain_changed_call_count += 1
|
||||
|
||||
def set_component_path_val(entity, component, path, value):
|
||||
entity.get_set_test(component, path, value)
|
||||
|
||||
def set_gradients_check_height(main_entity, gradient_list, expected_height, test_results):
|
||||
nonlocal expected_terrain_changed_calls
|
||||
|
||||
test_tolerance = 0.01
|
||||
gradient_list_path = "Configuration|Gradient Entities"
|
||||
|
||||
set_component_path_val(main_entity, 1, gradient_list_path, gradient_list)
|
||||
|
||||
expected_terrain_changed_calls += 1
|
||||
|
||||
# Wait until the terrain data has been updated.
|
||||
helper.wait_for_condition(lambda: terrain_changed_call_count == expected_terrain_changed_calls, 2.0)
|
||||
|
||||
# Get the height at the origin.
|
||||
height = terrain.TerrainDataRequestBus(bus.Broadcast, "GetHeightFromFloats", 0.0, 0.0, 0)
|
||||
|
||||
Report.result(test_results, sys_math.isclose(height, expected_height, abs_tol=test_tolerance))
|
||||
|
||||
helper.init_idle()
|
||||
|
||||
# Open a level.
|
||||
helper.open_level("Physics", "Base")
|
||||
helper.wait_for_condition(lambda: general.get_current_level_name() == "Base", 2.0)
|
||||
|
||||
general.idle_wait_frames(1)
|
||||
|
||||
# Add a terrain world component
|
||||
world_component = hydra.add_level_component("Terrain World")
|
||||
|
||||
aabb_height = 1024.0
|
||||
box_dimensions = math.Vector3(1.0, 1.0, aabb_height);
|
||||
|
||||
# Create a main entity with a LayerSpawner, AAbb and HeightGradientList.
|
||||
main_entity = create_entity_at("entity2", [layerspawner_component_name, gradientlist_component_name, aabb_component_name], 0.0, 0.0, aabb_height/2.0)
|
||||
|
||||
# Create three gradient entities.
|
||||
gradient_entity1 = create_entity_at("Constant Gradient1", ["Constant Gradient"], 0.0, 0.0, 0.0);
|
||||
gradient_entity2 = create_entity_at("Constant Gradient2", ["Constant Gradient"], 0.0, 0.0, 0.0);
|
||||
gradient_entity3 = create_entity_at("Constant Gradient3", ["Constant Gradient"], 0.0, 0.0, 0.0);
|
||||
|
||||
# Give everything a chance to finish initializing.
|
||||
general.idle_wait_frames(1)
|
||||
|
||||
# Set the gradients to different values.
|
||||
gradient_values = [0.5, 0.8, 0.3]
|
||||
set_component_path_val(gradient_entity1, 0, gradient_value_path, gradient_values[0])
|
||||
set_component_path_val(gradient_entity2, 0, gradient_value_path, gradient_values[1])
|
||||
set_component_path_val(gradient_entity3, 0, gradient_value_path, gradient_values[2])
|
||||
|
||||
# Give the TerrainSystem time to tick.
|
||||
general.idle_wait_frames(1)
|
||||
|
||||
# Set the dimensions of the Aabb.
|
||||
set_component_path_val(main_entity, 2, "Axis Aligned Box Shape|Box Configuration|Dimensions", box_dimensions)
|
||||
|
||||
# Set up a handler to wait for notifications from the TerrainSystem.
|
||||
handler = azlmbr.terrain.TerrainDataNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback("OnTerrainDataChanged", on_terrain_changed)
|
||||
|
||||
# Add a gradient to GradientList, then check the height returned from the TerrainSystem is correct.
|
||||
set_gradients_check_height(main_entity, [gradient_entity1.id], aabb_height * gradient_values[0], HeightTests.single_gradient_height_correct)
|
||||
|
||||
# Add gradient2 and check height at the origin, this should have changed to match the second gradient value.
|
||||
set_gradients_check_height(main_entity, [gradient_entity1.id, gradient_entity2.id], aabb_height * gradient_values[1], HeightTests.double_gradient_height_correct)
|
||||
|
||||
# Add gradient3, the height should still be the second value, as that was the highest.
|
||||
set_gradients_check_height(main_entity, [gradient_entity1.id, gradient_entity2.id, gradient_entity3.id], aabb_height * gradient_values[1], HeightTests.triple_gradient_height_correct)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(TerrainHeightGradientList_AddRemoveGradientWorks)
|
||||
@@ -27,3 +27,6 @@ class TestAutomation(EditorTestSuite):
|
||||
|
||||
class test_Terrain_SupportsPhysics(EditorSharedTest):
|
||||
from .EditorScripts import Terrain_SupportsPhysics as test_module
|
||||
|
||||
class test_TerrainHeightGradientList_AddRemoveGradientWorks(EditorSharedTest):
|
||||
from .EditorScripts import TerrainHeightGradientList_AddRemoveGradientWorks as test_module
|
||||
|
||||
@@ -15,6 +15,7 @@ import logging
|
||||
|
||||
# Import LyTestTools
|
||||
import ly_test_tools.o3de.asset_processor as asset_processor_commands
|
||||
import ly_test_tools.o3de.asset_processor_utils
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -36,5 +37,8 @@ def asset_processor(request: pytest.fixture, workspace: pytest.fixture) -> asset
|
||||
ap.stop()
|
||||
|
||||
request.addfinalizer(teardown)
|
||||
for n in ly_test_tools.o3de.asset_processor_utils.processList:
|
||||
assert not ly_test_tools.o3de.asset_processor_utils.check_ap_running(n), f"{n} process did not shutdown correctly."
|
||||
|
||||
|
||||
return ap
|
||||
|
||||
+10
@@ -8,6 +8,8 @@ General Asset Processor Batch Tests
|
||||
"""
|
||||
|
||||
# Import builtin libraries
|
||||
from os import listdir
|
||||
|
||||
import pytest
|
||||
import logging
|
||||
import os
|
||||
@@ -724,3 +726,11 @@ class TestsAssetProcessorBatch_AllPlatforms(object):
|
||||
|
||||
assert error_line_found, "The error could not be found in the newest run of the AP Batch log."
|
||||
|
||||
@pytest.mark.assetpipeline
|
||||
def test_AssetProcessor_Log_On_Failure(self, asset_processor, ap_setup_fixture, workspace):
|
||||
asset_processor.prepare_test_environment(ap_setup_fixture["tests_dir"], "test_AP_Logs")
|
||||
result, output = asset_processor.batch_process(expect_failure=True, capture_output=True)
|
||||
assert result == False, f'AssetProcessorBatch should have failed because there is a bad asset, output was {output}'
|
||||
|
||||
jobLogs = listdir(workspace.paths.ap_job_logs() + "/test_AP_Logs")
|
||||
assert not len(jobLogs) == 0, 'No job logs where output during failure.'
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7c6b33c6137d6bd8c696f180c30a23089c95c1af398a630b4b13e080bec3254d
|
||||
size 18220
|
||||
Reference in New Issue
Block a user