You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/AutomatedTesting/Gem/PythonTests/physics/C4044694_Material_EmptyLibr...

196 lines
8.4 KiB
Python

"""
Copyright (c) Contributors to the Open 3D Engine Project
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
# Test Case ID : C4044694
# Test Case Title : Verify that if we add an empty Material library in Collider Component, the object continues to use Default material values
# fmt: off
class Tests:
enter_game_mode = ("Entered game mode", "Failed to enter game mode")
find_terrain = ("The Terrain was found", "The Terrain was not found")
find_default_box = ("'default_box' was found", "'default_box' was not found")
find_empty_box = ("'empty_box' was found", "'empty_box' was not found")
find_default_sphere = ("'default_sphere' was found", "'default_sphere' was not found")
find_empty_sphere = ("'empty_sphere' was found", "'empty_sphere' was not found")
boxes_moved = ("All boxes moved", "Boxes failed to move")
boxes_at_rest = ("All boxes came to rest", "Boxes failed to come to rest")
default_sphere_bounced = ("'default_sphere' bounced", "'default_sphere' did not bounce")
empty_sphere_bounced = ("'empty_sphere' bounced", "'empty_sphere' did not bounce")
default_box_equals_empty = ("'default_box' and 'empty_box' traveled the same distance", "'default_box' and 'empty_box' did not travel the same distance")
default_sphere_equals_empty = ("'default_sphere' and 'empty_sphere' bounce heights were equal", "'default_sphere' and 'empty_sphere' bounce heights were not equal")
exit_game_mode = ("Exited game mode", "Failed to exit game mode")
# fmt: on
def C4044694_Material_EmptyLibraryUsesDefault():
"""
Summary:
Runs an automated test to verify that an object with an empty Material library in a Collider Component continues to
use the default material values
Level Description:
There are 5 entities.
One terrain entity ('terrain') with PhysX Terrain,
Two sphere entities ('empty_sphere' and 'default_sphere') with PhysX Rigid Body and PhysX Sphere Collider,
Two box entities ('empty_box' and 'default_box') with PhysX Rigid Body and PhysX Box Collider,
The spheres are positioned above the terrain, and the boxes are placed on the terrain.
The "empty" entities are assigned a material library that contains no materials. The "default" entities are assigned
the default material from the default material library.
Expected behavior:
The spheres fall and bounce the same height.
The boxes are pushed and travel the same distance.
Test Steps:
1) Open level and enter game mode
2) Find entities
3) Wait for spheres to bounce
4) Compare 'default_sphere' to 'empty_sphere'
5) Push the boxes and wait for them to come to rest
6) Compare 'default_box' to 'empty_box'
7) Exit game mode and close editor
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
import os
import sys
import ImportPathHelper as imports
imports.init()
import azlmbr.legacy.general as general
import azlmbr.bus as bus
import azlmbr.components
import azlmbr.physics
import azlmbr.math as lymath
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
FORCE_IMPULSE = lymath.Vector3(5.0, 0.0, 0.0)
TIMEOUT = 3.0
DISTANCE_TOLERANCE = 0.001
class Entity:
def __init__(self, name):
self.name = name
self.id = general.find_game_entity(self.name)
@property
def position(self):
return azlmbr.components.TransformBus(bus.Event, "GetWorldTranslation", self.id)
class Box(Entity):
def __init__(self, name):
Entity.__init__(self, name)
self.start_position = self.position
def is_stationary(self):
velocity = azlmbr.physics.RigidBodyRequestBus(bus.Event, "GetLinearVelocity", self.id)
return velocity.IsZero()
def push(self):
azlmbr.physics.RigidBodyRequestBus(bus.Event, "ApplyLinearImpulse", self.id, FORCE_IMPULSE)
class Sphere(Entity):
def __init__(self, name):
Entity.__init__(self, name)
self.hit_terrain_position = None
self.hit_terrain = False
self.max_bounce = 0.0
self.reached_max_bounce = False
def on_collision_enter(args):
entering = args[0]
for sphere in [default_sphere, empty_sphere]:
if sphere.id.Equal(entering):
if not sphere.hit_terrain:
sphere.hit_terrain_position = sphere.position
sphere.hit_terrain = True
# region wait_for_condition() functions
def wait_for_bounce():
for sphere in [default_sphere, empty_sphere]:
if sphere.hit_terrain:
current_bounce_height = sphere.position.z - sphere.hit_terrain_position.z
if current_bounce_height >= sphere.max_bounce:
sphere.max_bounce = current_bounce_height
elif sphere.max_bounce > 0.0:
sphere.reached_max_bounce = True
return default_sphere.reached_max_bounce and empty_sphere.reached_max_bounce
def boxes_moved():
return not default_box.is_stationary() and not empty_box.is_stationary()
def boxes_are_stationary():
return default_box.is_stationary() and empty_box.is_stationary()
# endregion
# 1) Open level and enter game mode
helper.init_idle()
helper.open_level("Physics", "C4044694_Material_EmptyLibraryUsesDefault")
helper.enter_game_mode(Tests.enter_game_mode)
# 2) Find entities
terrain_id = general.find_game_entity("terrain")
default_box = Box("default_box")
empty_box = Box("empty_box")
default_sphere = Sphere("default_sphere")
empty_sphere = Sphere("empty_sphere")
Report.result(Tests.find_terrain, terrain_id.IsValid())
Report.result(Tests.find_default_box, default_box.id.IsValid())
Report.result(Tests.find_empty_box, empty_box.id.IsValid())
Report.result(Tests.find_default_sphere, default_sphere.id.IsValid())
Report.result(Tests.find_empty_sphere, empty_sphere.id.IsValid())
# Setup terrain collision handler
handler = azlmbr.physics.CollisionNotificationBusHandler()
handler.connect(terrain_id)
handler.add_callback("OnCollisionBegin", on_collision_enter)
# 3) Wait for spheres to bounce
helper.wait_for_condition(wait_for_bounce, TIMEOUT)
Report.result(Tests.default_sphere_bounced, default_sphere.reached_max_bounce)
Report.result(Tests.empty_sphere_bounced, empty_sphere.reached_max_bounce)
# 4) Compare 'default_sphere' to 'empty_sphere'
sphere_bounces_equal = lymath.Math_IsClose(default_sphere.max_bounce, empty_sphere.max_bounce, DISTANCE_TOLERANCE)
Report.result(Tests.default_sphere_equals_empty, sphere_bounces_equal)
# 5) Push the boxes and wait for them to come to rest
default_box.push()
empty_box.push()
Report.result(Tests.boxes_moved, helper.wait_for_condition(boxes_moved, TIMEOUT))
Report.result(Tests.boxes_at_rest, helper.wait_for_condition(boxes_are_stationary, TIMEOUT))
# 6) Compare 'default_box' to 'empty_box'
default_distance = default_box.position.GetDistance(default_box.start_position)
empty_distance = empty_box.position.GetDistance(empty_box.start_position)
box_distances_equal = lymath.Math_IsClose(default_distance, empty_distance, DISTANCE_TOLERANCE)
Report.result(Tests.default_box_equals_empty, box_distances_equal)
# 7) Exit game mode and close editor
helper.exit_game_mode(Tests.exit_game_mode)
if __name__ == "__main__":
import ImportPathHelper as imports
imports.init()
from editor_python_test_tools.utils import Report
Report.start_test(C4044694_Material_EmptyLibraryUsesDefault)