123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 |
- """
- 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 : C15096737
- # Test Case Title : Verify that a change in the default material library material information
- # affects all the materials that reference it, even non-defaulted
- # exactly like if the library was selected
- # fmt: off
- class Tests:
- # level
- enter_game_mode_0 = ("Entered game mode 0", "Failed to enter game mode 0")
- exit_game_mode_0 = ("Exited game mode 0", "Couldn't exit game mode 0")
- enter_game_mode_1 = ("Entered game mode 1", "Failed to enter game mode 1")
- exit_game_mode_1 = ("Exited game mode 1", "Couldn't exit game mode 1")
-
- # targets
- terrain_found = ("Terrain found in each test", "TERRAIN NOT FOUND in a test")
- target_character_rubber_found = ("target_character_rubber found in each test", "target_character_rubber NOT FOUND in a test")
- target_character_concrete_found = ("target_character_concrete found in each test", "target_character_concrete NOT FOUND in a test")
- # collider activity
- rubber_sphere_found = ("rubber_sphere found in each test", "rubber_sphere NOT FOUND in a test in a test")
- rubber_sphere_trigger_found = ("rubber_sphere_trigger found in each test", "rubber_sphere_trigger NOT FOUND in a test")
- rubber_sphere_collided = ("rubber_sphere collided in each test", "rubber_sphere DIDN'T COLLIDE in a test")
-
- concrete_sphere_found = ("concrete_sphere found in each test", "concrete_sphere NOT FOUND in a test")
- concrete_sphere_trigger_found = ("concrete_sphere_trigger found in each test", "concrete_sphere_trigger NOT FOUND in a test")
- concrete_sphere_collided = ("concrete_sphere collided in each test", "concrete_sphere DIDN'T COLLIDE in a test")
-
- character_rubber_found = ("character_rubber found in each test", "character_rubber NOT FOUND in a test")
- character_rubber_trigger_found = ("character_rubber_trigger found in each test", "character_rubber_trigger NOT FOUND in a test")
- character_rubber_collided = ("character_rubber collided in each test", "character_rubber DIDN'T COLLIDE in a test")
-
- character_concrete_found = ("character_concrete found in each test", "character_concrete NOT FOUND in a test")
- character_concrete_trigger_found = ("character_concrete_trigger found in each test", "character_concrete_trigger NOT FOUND in a test")
- character_concrete_collided = ("character_concrete collided in each test", "character_concrete DIDN'T COLLIDE in a test")
-
- terrain_rubber_found = ("terrain_rubber found in each test", "terrain_rubber NOT FOUND in a test")
- terrain_rubber_trigger_found = ("terrain_rubber_trigger found in each test", "terrain_rubber_trigger NOT FOUND in a test")
- terrain_rubber_collided = ("terrain_rubber collided in each test", "terrain_rubber DIDN'T COLLIDE in a test")
-
- terrain_concrete_found = ("terrain_concrete found in each test", "terrain_concrete NOT FOUND in a test")
- terrain_concrete_trigger_found = ("terrain_concrete_trigger found in each test", "terrain_concrete_trigger NOT FOUND in a test")
- terrain_concrete_collided = ("terrain_concrete collided in each test", "terrain_concrete DIDN'T COLLIDE in a test")
-
- ragdoll_rubber_found = ("ragdoll_rubber found in each test", "ragdoll_rubber NOT FOUND in a test")
- ragdoll_rubber_trigger_found = ("ragdoll_rubber_trigger found in each test", "ragdoll_rubber_trigger NOT FOUND in a test")
- ragdoll_rubber_collided = ("ragdoll_rubber collided in each test", "ragdoll_rubber DIDN'T COLLIDE in a test")
-
- ragdoll_concrete_found = ("ragdoll_concrete found in each test", "ragdoll_concrete NOT FOUND in a test")
- ragdoll_concrete_trigger_found = ("ragdoll_concrete_trigger found in each test", "ragdoll_concrete_trigger NOT FOUND in a test")
- ragdoll_concrete_collided = ("ragdoll_concrete collided in each test", "ragdoll_concrete DIDN'T COLLIDE in a test")
- # Verification
- material_library_updated = ("Default material library updated", "Default material library not updated")
- rubber_material_changed = ("Rubber material changed correctly", "Rubber didn't react correctly")
- concrete_material_changed = ("Concrete material changed correctly", "Concrete didn't react correctly")
- # fmt: on
- def Material_DefaultMaterialLibraryChangesWork():
- """
- Summary: Runs an automated test to verify that material selected in the default material library is applied to PhysX
- colliders, character controller, terrain texture layers and ragdolls and that material can respond to change.
- PhysX Config Description:
- A PhysX material library called all_ones is set as the default material library in PhysX Config File.
- The library has two materials surfaces: rubber with Restitution = 1.0, Restitution Combine = Maximum
- and concrete with Restitution = 0.0, Restitution combine = Multiply.
- The custom config file is loaded before editor is launched.
- Level Description:
- Consists of 4 sets of entities.
- Each entity has either rubber or concrete material assigned to it. Each entity has a corresponding trigger placed
- between the entity and its collision target entity (terrain or character controller).
- The entities, their triggers and their target are colored blue if they have rubber material, or red for concrete.
- Expected Behavior:
- The entities start their movement once the level is loaded. They should touch their corresponding triggers first,
- then collide with their target entity. The ones with rubber material are supposed to bounce back and touch the
- triggers. The ones with concrete material are supposed to stick to the target and stop moving, therefore not
- touching the triggers anymore. After the edits to material library the affect will be swapped.
- Main Script Steps:
- 1) Loads the level
- 2) Setup targets and colliders
- 3) Run Test 0
- 4) Edit Material Library
- 5) Run Test 1
- 6) Validate Results
- 7) Close editor
- Test Steps:
- 1) Enter Game Mode
- 2) Validate target Id's
- 3) Validate all Colliders and setup targets
- 4) Wait for Collision, Report Results
- 5) Allow Time to Hit trigger
- 6) Exit Game Mode
- """
- import os
- import sys
- from editor_python_test_tools.utils import Report
- from editor_python_test_tools.utils import TestHelper as helper
- import azlmbr.legacy.general as general
- import azlmbr.bus
- from Physmaterial_Editor import Physmaterial_Editor
- # Constants
- TIME_OUT = 2.0
- PROPAGATION_FRAMES = 180
- def get_test(entity_name, suffix):
- return Tests.__dict__[entity_name + suffix]
- # Base class for triggers, targets and colliders
- class Entity(object):
- # Global Holding Variable for test index
- current_test = None
- def __init__(self, name):
- self.name = name
- self.found_in_before_test = False
- # Validates entity ids reports if the ids are valid for both test cases
- # Fast fails if any id is invalid
- def validate_id(self):
- self.id = general.find_game_entity(self.name)
- if Entity.current_test == 0 and self.id.IsValid():
- self.found_in_before_test = True
- elif Entity.current_test == 1:
- Report.critical_result(get_test(self.name, "_found"), self.id.IsValid() and self.found_in_before_test)
- else:
- helper.fail_fast("{} was not found in test {}".format(self.name, Entity.current_test))
- @property
- def position(self):
- return azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
- @property
- def velocity(self):
- return azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", self.id)
- class Collider(Entity):
- def __init__(self, name, target):
- Entity.__init__(self, name)
- self.target = target
- # Data holding variables
- self.collided_with_target_0 = False
- self.collided_with_target_1 = False
- self.hit_trigger_0 = False
- self.hit_trigger_1 = False
- # Initialized target collisions
- def setup_target(self):
- self.target.validate_id
- # Watch target for collision with collider
- self.collision_handler = azlmbr.physics.CollisionNotificationBusHandler()
- self.collision_handler.connect(self.id)
- self.collision_handler.add_callback("OnCollisionBegin", self.detect_collision_target)
- def activate_trigger(self):
- azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "ActivateGameEntity", self.trigger.id)
- Report.info("{} activated".format(self.trigger.name))
-
- # Sets up trigger and activates it post-collision with target
- def setup_trigger(self):
- if Entity.current_test == 0:
- self.trigger = Entity(self.name + "_trigger")
- self.trigger.validate_id()
- self.activate_trigger()
- # Watch for collider entrance
- self.trigger.handler = azlmbr.physics.TriggerNotificationBusHandler()
- self.trigger.handler.connect(self.trigger.id)
- self.trigger.handler.add_callback("OnTriggerEnter", self.on_trigger_enter)
- def on_trigger_enter(self, args):
- if self.id.equal(args[0]) and not getattr(self, "hit_trigger_{}".format(Entity.current_test)):
- Report.info("{} entered {} in test {}".format(self.name, self.trigger.name, Entity.current_test))
- setattr(self, "hit_trigger_{}".format(Entity.current_test), True)
- def detect_collision_target(self, args):
- print("Collision_going_on")
- if self.target.id.equal(args[0]) and not getattr(self, "collided_with_target_{}".format(Entity.current_test)):
- Report.info("{} collided with {}".format(self.name, self.target.name))
- setattr(self, "collided_with_target_{}".format(Entity.current_test), True)
- self.setup_trigger()
- def edit_material_library():
- # Flips the Restitution values of rubber and concrete
- material_library = Physmaterial_Editor("all_ones_1.physmaterial")
- rubber_restitution = material_library.modify_material("rubber", "Restitution", 0)
- rubber_restitution_combine = material_library.modify_material("rubber", "RestitutionCombine", "Multiply")
- concrete_restitution = material_library.modify_material("concrete", "Restitution", 1)
- concrete_restitution_combine = material_library.modify_material("concrete", "RestitutionCombine", "Average")
- material_library.save_changes()
- return rubber_restitution and rubber_restitution_combine and concrete_restitution and concrete_restitution_combine
- def check_rubber_material_updated(rubber_colliders):
- # Checks that all rubber colliders hit the trigger on test 0 and not on test 1
- before_test_passed = all([collider.hit_trigger_0 for collider in rubber_colliders])
- after_test_passed = all([not collider.hit_trigger_1 for collider in rubber_colliders])
- return before_test_passed and after_test_passed
- def check_concrete_material_updated(concrete_colliders):
- # Checks that all concrete colliders didn't hit the trigger on test 0 and did on test 1
- before_test_passed = all([not collider.hit_trigger_0 for collider in concrete_colliders])
- after_test_passed = all([collider.hit_trigger_1 for collider in concrete_colliders])
- return before_test_passed and after_test_passed
- def test_run(index, all_colliders):
- Entity.current_test = index
- # 1) Enter Game Mode
- helper.enter_game_mode(get_test("enter_game_mode_", str(index)))
- # 2) Validate target Ids
- terrain.validate_id()
- target_character_concrete.validate_id()
- target_character_rubber.validate_id()
- # 3) Validate all Colliders and setup targets
- for collider in all_colliders:
- collider.validate_id()
- collider.setup_target()
- # 4) Wait for Collision, Report Results
- if not helper.wait_for_condition(lambda: all([getattr(collider, "collided_with_target_{}".format(index)) for collider in all_colliders]), TIME_OUT):
- failed_colliders = ", ".join([collider.name for collider in all_colliders if not getattr(collider, "collided_with_target_{}".format(index))])
- helper.fail_fast("A collision with target did not occur for these colliders: {}".format(failed_colliders))
- elif index == 1:
- for collider in all_colliders:
- Report.result(get_test(collider.name, "_collided"), collider.collided_with_target_0 and collider.collided_with_target_1)
- # 5) Allow time to hit trigger
- general.idle_wait_frames(PROPAGATION_FRAMES)
- # 6) Exit Game Mode
- helper.exit_game_mode(get_test("exit_game_mode_", str(index)))
- # Main Script
- helper.init_idle()
- # 1) Load the level
- helper.open_level("Physics", "Material_DefaultMaterialLibraryChangesWork")
- # 2) Setup targets and colliders
- terrain = Entity("terrain")
- target_character_rubber = Entity("target_character_rubber")
- target_character_concrete = Entity("target_character_concrete")
- rubber_sphere = Collider(name="rubber_sphere", target=terrain)
- concrete_sphere = Collider(name="concrete_sphere", target=terrain)
- character_rubber = Collider(name="character_rubber", target=target_character_rubber)
- character_concrete = Collider(name="character_concrete", target=target_character_concrete)
- terrain_rubber = Collider(name="terrain_rubber", target=terrain)
- terrain_concrete = Collider(name="terrain_concrete", target=terrain)
- ragdoll_rubber = Collider(name="ragdoll_rubber", target=terrain)
- ragdoll_concrete = Collider(name="ragdoll_concrete", target=terrain)
- rubber_test_entities = [rubber_sphere, character_rubber, terrain_rubber, ragdoll_rubber]
- concrete_test_entities = [concrete_sphere, character_concrete, terrain_concrete, ragdoll_concrete]
- test_entities = rubber_test_entities + concrete_test_entities
- # 3) Run test 0
- test_run(index=0, all_colliders=test_entities)
- # 4) Edit Material Library
- Report.critical_result(Tests.material_library_updated, edit_material_library())
- # Wait for material library changes to propagate
- general.idle_wait_frames(PROPAGATION_FRAMES)
- # 5) Run test 1
- test_run(index=1, all_colliders=test_entities)
- # 6) Validate Results
- Report.result(Tests.concrete_material_changed, check_concrete_material_updated(concrete_test_entities))
- Report.result(Tests.rubber_material_changed, check_rubber_material_updated(rubber_test_entities))
- if __name__ == "__main__":
- from editor_python_test_tools.utils import Report
- Report.start_test(Material_DefaultMaterialLibraryChangesWork)
|