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

319 lines
17 KiB
Python

"""
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 : C15425935
# Test Case Title : Verify that the change in Material Library gets updated across levels
# fmt: off
class Tests:
# Game Mode 0
enter_game_mode_0 = ("Entered game mode 0", "Failed to enter game mode 0")
modify_sphere_0_found = ("Test 0: modify_sphere was found", "Test 0: modify_sphere was not found")
delete_sphere_0_found = ("Test 0: delete_sphere was found", "Test 0: delete_sphere was not found")
terrain_0_found = ("Test 0: terrain Entity found", "Test 0: terrain Entity was not found")
trigger_0_found = ("Test 0: trigger entity found", "Test 0: trigger entity wasn't found")
sphere_initial_position_0 = ("Test 0: spheres initial position valid", "Test 0: spheres initial position not valid")
sphere_initial_velocity_0 = ("Test 0: spheres initial velocity valid", "Test 0: spheres initial velocity not valid")
sphere_collision_0 = ("Test 0: Both spheres collided", "Test 0: Both spheres did not collide")
exit_game_mode_0 = ("Exited game mode 0", "Couldn't exit game mode 0")
# Game Mode 1
enter_game_mode_1 = ("Entered game mode 1", "Failed to enter game mode 1")
modify_sphere_1_found = ("Test 1: modify_sphere was found", "Test 1: modify_sphere was not found")
delete_sphere_1_found = ("Test 1: delete_sphere was found", "Test 1: delete_sphere was not found")
terrain_1_found = ("Test 1: terrain Entity found", "Test 1: terrain Entity was not found")
trigger_1_found = ("Test 1: trigger entity found", "Test 1: trigger entity wasn't found")
sphere_initial_position_1 = ("Test 1: spheres initial position valid", "Test 1: spheres initial position not valid")
sphere_initial_velocity_1 = ("Test 1: spheres initial velocity valid", "Test 1: spheres initial velocity not valid")
sphere_collision_1 = ("Test 1: Both spheres collided", "Test 1: Both spheres did not collide")
exit_game_mode_1 = ("Exited game mode 1", "Couldn't exit game mode 1")
# Game Mode 2
enter_game_mode_2 = ("Entered game mode 2", "Failed to enter game mode 2")
modify_sphere_2_found = ("Test 2: modify_sphere was found", "Test 2: modify_sphere was not found")
delete_sphere_2_found = ("Test 2: delete_sphere was found", "Test 2: delete_sphere was not found")
terrain_2_found = ("Test 2: terrain Entity found", "Test 2: terrain Entity was not found")
trigger_2_found = ("Test 2: trigger entity found", "Test 2: trigger entity wasn't found")
sphere_initial_position_2 = ("Test 2: spheres initial position valid", "Test 2: spheres initial position not valid")
sphere_initial_velocity_2 = ("Test 2: spheres initial velocity valid", "Test 2: spheres initial velocity not valid")
sphere_collision_2 = ("Test 2: Both spheres collided", "Test 2: Both spheres did not collide")
exit_game_mode_2 = ("Exited game mode 2", "Couldn't exit game mode 2")
# Game Mode 3
enter_game_mode_3 = ("Entered game mode 3", "Failed to enter game mode 3")
modify_sphere_3_found = ("Test 3: modify_sphere was found", "Test 3: modify_sphere was not found")
delete_sphere_3_found = ("Test 3: delete_sphere was found", "Test 3: delete_sphere was not found")
terrain_3_found = ("Test 3: terrain Entity found", "Test 3: terrain Entity was not found")
trigger_3_found = ("Test 3: trigger entity found", "Test 3: trigger entity wasn't found")
sphere_initial_position_3 = ("Test 3: spheres initial position valid", "Test 3: spheres initial position not valid")
sphere_initial_velocity_3 = ("Test 3: spheres initial velocity valid", "Test 3: spheres initial velocity not valid")
sphere_collision_3 = ("Test 3: Both spheres collided", "Test 3: Both spheres did not collide")
exit_game_mode_3 = ("Test 3: Exited game mode 3", "Couldn't exit game mode 3")
# Test Verification
baseline_verified = ("Both levels are the same", "Both levels aren't the same")
material_delete_verified = ("Material delete updated spheres", "Material delete not updated spheres")
material_modify_verified = ("Material modify updated spheres", "Material modify not updated spheres")
post_change_verified = ("Both levels are still the same", "Both levels are not the same")
# fmt: on
def C15425935_Material_LibraryUpdatedAcrossLevels():
"""
Summary: Verify that the change in a physmaterial library gets updated across levels
Level Description: There are two levels that are being compared. Each are exact replicas with a shared
material library
modify_sphere - Starts between terrain and trigger with initial velocity in negative z direction and gravity disabled;
has physx collider in sphere shape with material "to_delete", had physx rigid body, and sphere_shape
delete_sphere - Starts between terrain and trigger with initial velocity in negative z direction and gravity disabled;
has physx collider in sphere shape with material "to_modify", had physx rigid body, and sphere_shape
terrain - Default terrain with transform inline; has physx terrain component
trigger - Above the spheres, trigger is enabled; has physx collider in box shape with dimensions (5.0, 10.0, 0.25)
and box shape with the same dimensions
Expected Behavior: Materials deleted or modified have their changes update across levels. Initially the spheres will
not bounce off the terrain after the change to the material library they will bounce up and hit the trigger
Material Tests:
Test 0 - Tests level 0 before the material change
Test 1 - Tests level 1 before the material change
Test 2 - Tests level 0 after the material change
Test 3 - Tests level 1 after the material change
Test 0 and 1 should be exactly the same. Test 2 and 3 should be exactly the same. Both modification to the material
library should allow the spheres to bounce in Test 2 and 3. Therefore, both spheres will have a higher velocity and
be able to trigger in Test 2 and 3 as compared to 0 and 1.
Iterated Game Mode steps:
1) Open the correct level for the test
2) Open Game Mode
3) Create and Verify Entities
4) Wait for Sphere collision with Terrain Entity
5) Wait for spheres to have a chance to hit trigger
6) Modify Material Library
7) Exit Game Mode
Test Steps:
1) Create Test Objects
2) Run Game Mode steps once for each test
3) Verify that spheres acted as expected
4) 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()
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
import azlmbr.math as math
from Physmaterial_Editor import Physmaterial_Editor
# Constants
FLOAT_THRESHOLD = sys.float_info.epsilon
TIMEOUT = 1
INITIAL_VELOCITY = math.Vector3(0.0, 0.0, -10.0)
VELOCITY_THRESHOLD = 0.1
# Helper Functions
class Entity:
def __init__(self, name, index):
self.id = general.find_game_entity(name)
self.name = name
self.collision_happened = False
self.index = index
# ID validation
self.found = Tests.__dict__[self.name + "_{}_found".format(index)]
Report.critical_result(self.found, self.id.IsValid())
@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 Sphere(Entity):
terrain_id = None
def __init__(self, name, index):
Entity.__init__(self, name, index)
# Set Handler
self.handler = azlmbr.physics.CollisionNotificationBusHandler()
self.handler.connect(self.id)
self.handler.add_callback("OnCollisionBegin", self.on_collision_begin)
def on_collision_begin(self, args):
if args[0].equal(Sphere.terrain_id):
self.collision_happened = True
class Material_Test:
def __init__(self, index, level_index):
# index is the test index 0-3 this allows for tests from the Tests class to be fetched
self.index = index
# level_index determins which level will be opened at the start of the test loop
self.level_index = level_index
# Data
self.modify_sphere_hit_trigger = False
self.delete_sphere_hit_trigger = False
self.entity_list = None
self.modify_sphere_final_velocity = None
self.delete_sphere_final_velocity = None
def sphere_initial_position(self, modify_sphere_position, delete_sphere_position, terrain_position, trigger_position):
position_valid = (
modify_sphere_position.z == delete_sphere_position.z
and modify_sphere_position.z > terrain_position.z
and trigger_position.z > modify_sphere_position.z
)
initial_position = Tests.__dict__["sphere_initial_position_{}".format(self.index)]
Report.critical_result(initial_position, position_valid)
def sphere_initial_velocity(self, modify_sphere_velocity, delete_sphere_velocity):
initial_velocity_string = Tests.__dict__["sphere_initial_velocity_{}".format(self.index)]
Report.critical_result(
initial_velocity_string,
modify_sphere_velocity.IsClose(INITIAL_VELOCITY, VELOCITY_THRESHOLD) and delete_sphere_velocity.IsClose(INITIAL_VELOCITY, VELOCITY_THRESHOLD),
)
def log_velocity(self):
self.modify_sphere_final_velocity = self.entity_list[0].velocity
self.delete_sphere_final_velocity = self.entity_list[1].velocity
def set_trigger(self):
# Type (Entity) -> None
# Sets handler for trigger
self.handler = azlmbr.physics.TriggerNotificationBusHandler()
self.handler.connect(self.entity_list[3].id)
self.handler.add_callback("OnTriggerEnter", self.on_trigger_enter)
def on_trigger_enter(self, args):
# Type () -> None
# When trigger entered the correct sphere is found boolean is flipped
if self.entity_list[0].id.Equal(args[0]):
self.modify_sphere_hit_trigger = True
if self.entity_list[1].id.Equal(args[0]):
self.delete_sphere_hit_trigger = True
def are_levels_consistent(level_a, level_b):
triggers_0 = level_a.modify_sphere_hit_trigger == level_b.modify_sphere_hit_trigger
triggers_1 = level_a.delete_sphere_hit_trigger == level_b.delete_sphere_hit_trigger
modify_sphere_velocities = (
abs(level_a.modify_sphere_final_velocity.z - level_b.modify_sphere_final_velocity.z) < FLOAT_THRESHOLD
)
delete_sphere_velocities = (
abs(level_a.delete_sphere_final_velocity.z - level_b.delete_sphere_final_velocity.z) < FLOAT_THRESHOLD
)
return triggers_0 and triggers_1 and modify_sphere_velocities and delete_sphere_velocities
def check_material_delete(test_0, test_3):
triggers = test_0.modify_sphere_hit_trigger != test_3.modify_sphere_hit_trigger
modify_sphere_velocities = test_0.modify_sphere_final_velocity.z < test_3.modify_sphere_final_velocity.z
return triggers and modify_sphere_velocities
def check_material_modify(test_0, test_3):
triggers = test_0.delete_sphere_hit_trigger != test_3.delete_sphere_hit_trigger
delete_sphere_velocities = test_0.delete_sphere_final_velocity.z < test_3.delete_sphere_final_velocity.z
return triggers and delete_sphere_velocities
def modify_material_library():
physmaterial_object = Physmaterial_Editor("C15425935_Material_LibraryUpdatedAcrossLevels.physmaterial")
physmaterial_object.delete_material("to_delete")
physmaterial_object.modify_material("to_modify", "Restitution", 1.0)
physmaterial_object.save_changes()
helper.init_idle()
# 1) Create Test Objects
# Each test object is given an index that will determine what tuples are pulled from the Tests class and are indicative of the order that they will be run.
# Each test object also has a level_index to determine which level will be opened during the test loop. Both levels 0 and 1 are looked at before and after
# the change to the material library
test_0 = Material_Test(index=0, level_index=0)
test_1 = Material_Test(index=1, level_index=1)
test_2 = Material_Test(index=2, level_index=0)
test_3 = Material_Test(index=3, level_index=1)
# Test list of all the tests in order of index
test_list = [test_0, test_1, test_2, test_3]
# 2) Run Game Mode steps once for each test
for test in test_list:
# 1) Open the correct level for the test
helper.open_level(
"physics",
"C15425935_Material_LibraryUpdatedAcrossLevels\\C15425935_Material_LibraryUpdatedAcrossLevels_{}".format(
test.level_index
),
)
# 2) Open Game Mode
helper.enter_game_mode(Tests.__dict__["enter_game_mode_{}".format(test.index)])
# 3) Create and Verify Entities
terrain = Entity("terrain", test.index)
Sphere.terrain_id = terrain.id
modify_sphere = Sphere("modify_sphere", test.index)
delete_sphere = Sphere("delete_sphere", test.index)
trigger = Entity("trigger", test.index)
test.entity_list = [modify_sphere, delete_sphere, terrain, trigger]
test.set_trigger()
test.sphere_initial_position(modify_sphere.position, delete_sphere.position, terrain.position, trigger.position)
test.sphere_initial_velocity(modify_sphere.velocity, delete_sphere.velocity)
# 4) Wait for Sphere collision with Terrain Entity
collisions_happened = helper.wait_for_condition(lambda: modify_sphere.collision_happened and delete_sphere.collision_happened, TIMEOUT)
Report.result(Tests.__dict__["sphere_collision_{}".format(test.index)], collisions_happened)
# 5) Wait for spheres to have a chance to hit trigger
helper.wait_for_condition(lambda: test.modify_sphere_hit_trigger and test.delete_sphere_hit_trigger, TIMEOUT)
# Report trigger
Report.info("modify_sphere{} hit trigger in test {}".format("" if test.modify_sphere_hit_trigger else " didn't", test.index))
Report.info("delete_sphere{} hit trigger in test {}".format("" if test.delete_sphere_hit_trigger else " didn't", test.index))
test.log_velocity()
# 6) Modify Material Library
if test.index == 1:
modify_material_library()
# 7) Exit Game Mode
helper.exit_game_mode(Tests.__dict__["exit_game_mode_{}".format(test.index)])
# 3) Verify that spheres acted as expected
Report.result(Tests.baseline_verified, are_levels_consistent(test_0, test_1))
Report.result(Tests.material_delete_verified, check_material_delete(test_0, test_3))
Report.result(Tests.material_modify_verified, check_material_modify(test_0, test_3))
Report.result(Tests.post_change_verified, are_levels_consistent(test_2, test_3))
if __name__ == "__main__":
import ImportPathHelper as imports
imports.init()
from editor_python_test_tools.utils import Report
Report.start_test(C15425935_Material_LibraryUpdatedAcrossLevels)