123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- """
- 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 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 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", "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__":
- from editor_python_test_tools.utils import Report
- Report.start_test(Material_EmptyLibraryUsesDefault)
|