""" All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or its licensors. For complete copyright and license terms please see the LICENSE at the root of this distribution (the "License"). All use of this software is governed by the License, or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. """ # 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 # Test Case URL : https://testrail.agscollab.com/index.php?/cases/view/4044694 # 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)