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...

197 lines
8.5 KiB
Python

"""
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
"""
# 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)