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.
257 lines
13 KiB
Python
257 lines
13 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 : C15308221
|
|
# Test Case Title : Verify that material library and slots are always in sync and work consistently through the different places of usage
|
|
# Test Case URL : https://testrail.agscollab.com/index.php?/cases/view/15308221
|
|
|
|
|
|
# fmt: off
|
|
class Tests:
|
|
enter_game_mode_0 = ("Test 0) Entered game mode", "Test 0) Failed to enter game mode")
|
|
find_terrain_0 = ("Test 0) The Terrain was found", "Test 0) The Terrain was not found")
|
|
find_terrain_box_0 = ("Test 0) Terrain test box was found", "Test 0) Terrain test box was not found")
|
|
find_collider_0 = ("Test 0) Box collider was found", "Test 0) Box collider was not found")
|
|
find_ragdoll_0 = ("Test 0) Ragdoll was found", "Test 0) Ragdoll was not found")
|
|
find_character_controller_0 = ("Test 0) Character controller was found", "Test 0) Character controller was not found")
|
|
find_controller_box_0 = ("Test 0) Character controller test box was found", "Test 0) Character controller test box was not found")
|
|
|
|
terrain_box_bounced_0 = ("Test 0) Terrain test box bounced", "Test 0) Terrain test box did not bounce")
|
|
collider_bounced_0 = ("Test 0) Box collider bounced", "Test 0) Box collider did not bounce")
|
|
ragdoll_bounced_0 = ("Test 0) Modified ragdoll bounced", "Test 0) Modified ragdoll did not bounce")
|
|
controller_box_bounced_0 = ("Test 0) Character controller test box bounced", "Test 0) Character controller test box did not bounce")
|
|
exit_game_mode_0 = ("Test 0) Exited game mode", "Test 0) Failed to exit game mode")
|
|
all_bounced_equal_0 = ("Test 0) All entities bounced the same height", "Test 0) All entities did not bounce the same height")
|
|
|
|
enter_game_mode_1 = ("Test 1) Entered game mode", "Test 1) Failed to enter game mode")
|
|
find_terrain_1 = ("Test 1) The Terrain was found", "Test 1) The Terrain was not found")
|
|
find_terrain_box_1 = ("Test 1) Terrain test box was found", "Test 1) Terrain test box was not found")
|
|
find_collider_1 = ("Test 1) Box collider was found", "Test 1) Box collider was not found")
|
|
find_ragdoll_1 = ("Test 1) Ragdoll was found", "Test 1) Ragdoll was not found")
|
|
find_character_controller_1 = ("Test 1) Character controller was found", "Test 1) Character controller was not found")
|
|
find_controller_box_1 = ("Test 1) Character controller test box was found", "Test 1) Character controller test box was not found")
|
|
|
|
terrain_box_bounced_1 = ("Test 1) Terrain test box bounced", "Test 1) Terrain test box did not bounce")
|
|
collider_bounced_1 = ("Test 1) Box collider bounced", "Test 1) Box collider did not bounce")
|
|
ragdoll_bounced_1 = ("Test 1) Modified ragdoll bounced", "Test 1) Modified ragdoll did not bounce")
|
|
controller_box_bounced_1 = ("Test 1) Character controller test box bounced", "Test 1) Character controller test box did not bounce")
|
|
exit_game_mode_1 = ("Test 1) Exited game mode", "Test 1) Failed to exit game mode")
|
|
all_bounced_equal_1 = ("Test 1) All entities bounced the same height", "Test 1) All entities did not bounce the same height")
|
|
|
|
all_bounced_greater = ("All entities bounced higher on the second test", "All entities did not bounce higher on the second test")
|
|
# fmt: on
|
|
|
|
|
|
def C15308221_Material_ComponentsInSyncWithLibrary():
|
|
"""
|
|
Summary:
|
|
Runs an automated test to verify that the material library is always in sync between the different PhysX components
|
|
|
|
Level Description:
|
|
A new material library was created with 1 material, called "Modified":
|
|
dynamic friction: 0.5
|
|
static friction: 0.5
|
|
restitution: 0.25
|
|
|
|
There are 4 types of components we want to test for:
|
|
PhysX Ragdoll:
|
|
A ragdoll ("ragdoll") with the "Modified" material applied to all of its colliders. Positioned above the
|
|
terrain.
|
|
PhysX collider:
|
|
A PhysX box collider ("collider") with a the "Modified" material applied. Positioned above the terrain.
|
|
PhysX terrain:
|
|
A PhysX terrain ("terrain"), and a PhysX box collider ("terrain_box"). "terrain_box" is positioned above
|
|
"terrain". A new layer was created with the "Modified" material and painted onto the terrain under
|
|
"terrain_box". "terrain_box" has the default material applied.
|
|
PhysX character controller:
|
|
A character controller ("character_controller"), and a PhysX box collider ("controller_box").
|
|
"controller_box" is positioned above "character_controller" and is assigned the default material.
|
|
"character_controller" is assigned "Modified"
|
|
|
|
Expected behavior:
|
|
For every iteration this test measures the bounce height of each entity. The entities save their traveled distances
|
|
each iteration, to verify different behavior between each setup.
|
|
|
|
First the test verifies the entities all behave identically, without changing anything. All entities should bounce
|
|
the same height.
|
|
|
|
Next, the test modifies the restitution value for 'Modified' (from 0.25 to 0.75). All entities should again bounce
|
|
the same height. Additionally, all entities should bounce higher with the new restitution than they did previously.
|
|
|
|
Test Steps:
|
|
1) Open level
|
|
2) Collect basis values without modifying anything
|
|
2.1) Enter game mode
|
|
2.2) Find entities
|
|
2.3) Wait for entities to bounce
|
|
2.4) Exit game mode
|
|
3) Verify all entities behave the same as a baseline
|
|
4) Modify the restitution value of 'modified'
|
|
4.1 - 4.4) <same as 2.1 - 2.4>
|
|
5) Verify the entities all still behave the same
|
|
6) Verify that the material change was propagated correctly
|
|
7) 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 Physmaterial_Editor import Physmaterial_Editor
|
|
from utils import Report
|
|
from utils import TestHelper as helper
|
|
|
|
TIMEOUT = 3.0
|
|
BOUNCE_TOLERANCE = 0.1
|
|
|
|
class Entity:
|
|
def __init__(self, name, bounce_off_of_name):
|
|
self.name = name
|
|
self.bounce_off_of_name = bounce_off_of_name
|
|
self.bounces = []
|
|
|
|
def find_and_reset(self):
|
|
self.hit_position = None
|
|
self.hit_terrain = False
|
|
self.max_bounce = 0.0
|
|
self.reached_max_bounce = False
|
|
self.id = general.find_game_entity(self.name)
|
|
self.setup_handler()
|
|
return self.id.IsValid()
|
|
|
|
def on_collision_enter(self, args):
|
|
entering = args[0]
|
|
if entering.Equal(self.id):
|
|
if not self.hit_terrain:
|
|
self.hit_terrain_position = self.position
|
|
self.hit_terrain = True
|
|
|
|
def setup_handler(self):
|
|
self.bounce_off_of_id = general.find_game_entity(self.bounce_off_of_name)
|
|
self.handler = azlmbr.physics.CollisionNotificationBusHandler()
|
|
self.handler.connect(self.bounce_off_of_id)
|
|
self.handler.add_callback("OnCollisionBegin", self.on_collision_enter)
|
|
|
|
@property
|
|
def position(self):
|
|
return azlmbr.components.TransformBus(bus.Event, "GetWorldTranslation", self.id)
|
|
|
|
def get_test(test_name):
|
|
return Tests.__dict__[test_name]
|
|
|
|
def run_test(test_number):
|
|
# x.1) Enter game mode
|
|
helper.enter_game_mode(get_test("enter_game_mode_{}".format(test_number)))
|
|
|
|
# x.2) Find entities
|
|
controller_valid = general.find_game_entity("character_controller").IsValid()
|
|
terrain_valid = general.find_game_entity("terrain").IsValid()
|
|
|
|
Report.critical_result(get_test("find_character_controller_{}".format(test_number)), controller_valid)
|
|
Report.critical_result(get_test("find_terrain_{}".format(test_number)), terrain_valid)
|
|
|
|
collider_valid = collider.find_and_reset()
|
|
controller_box_valid = controller_box.find_and_reset()
|
|
ragdoll_valid = ragdoll.find_and_reset()
|
|
terrain_box_valid = terrain_box.find_and_reset()
|
|
|
|
Report.critical_result(get_test("find_collider_{}".format(test_number)), collider_valid)
|
|
Report.critical_result(get_test("find_controller_box_{}".format(test_number)), controller_box_valid)
|
|
Report.critical_result(get_test("find_ragdoll_{}".format(test_number)), ragdoll_valid)
|
|
Report.critical_result(get_test("find_terrain_box_{}".format(test_number)), terrain_box_valid)
|
|
|
|
def wait_for_bounce():
|
|
for entity in all_entities:
|
|
if entity.hit_terrain:
|
|
current_bounce_height = entity.position.z - entity.hit_terrain_position.z
|
|
if current_bounce_height >= entity.max_bounce:
|
|
entity.max_bounce = current_bounce_height
|
|
elif entity.max_bounce > 0.0:
|
|
entity.reached_max_bounce = True
|
|
return all([entity.reached_max_bounce for entity in all_entities])
|
|
|
|
# x.3) Wait for entities to bounce
|
|
helper.wait_for_condition(wait_for_bounce, TIMEOUT)
|
|
|
|
Report.result(get_test("collider_bounced_{}".format(test_number)), collider.reached_max_bounce)
|
|
Report.result(get_test("controller_box_bounced_{}".format(test_number)), controller_box.reached_max_bounce)
|
|
Report.result(get_test("ragdoll_bounced_{}".format(test_number)), ragdoll.reached_max_bounce)
|
|
Report.result(get_test("terrain_box_bounced_{}".format(test_number)), terrain_box.reached_max_bounce)
|
|
|
|
for entity in all_entities:
|
|
entity.bounces.append(entity.max_bounce)
|
|
|
|
# x.4) Exit game mode
|
|
helper.exit_game_mode(get_test("exit_game_mode_{}".format(test_number)))
|
|
|
|
# 1) Open level and enter game mode
|
|
helper.init_idle()
|
|
helper.open_level("Physics", "C15308221_Material_ComponentsInSyncWithLibrary")
|
|
|
|
# Setup persisting entities
|
|
collider = Entity("collider", "terrain")
|
|
controller_box = Entity("controller_box", "character_controller")
|
|
ragdoll = Entity("ragdoll", "terrain")
|
|
terrain_box = Entity("terrain_box", "terrain")
|
|
all_entities = [collider, controller_box, ragdoll, terrain_box]
|
|
|
|
# 2) Collect basis values without modifying anything
|
|
run_test(0)
|
|
|
|
# 3) Verify all entities behave the same as a baseline
|
|
test_0_max_bounce = max([entity.bounces[0] for entity in all_entities])
|
|
test_0_min_bounce = min([entity.bounces[0] for entity in all_entities])
|
|
Report.result(
|
|
Tests.all_bounced_equal_0, lymath.Math_IsClose(test_0_max_bounce, test_0_min_bounce, BOUNCE_TOLERANCE)
|
|
)
|
|
|
|
# 4) Modify the restitution value of 'modified'
|
|
material_editor = Physmaterial_Editor("c15308221_material_componentsinsyncwithlibrary.physmaterial")
|
|
material_editor.modify_material("Modified", "Restitution", 0.75)
|
|
material_editor.save_changes()
|
|
run_test(1)
|
|
|
|
# 5) Verify the entities all still behave the same
|
|
test_1_max_bounce = max([entity.bounces[1] for entity in all_entities])
|
|
test_1_min_bounce = min([entity.bounces[1] for entity in all_entities])
|
|
Report.result(
|
|
Tests.all_bounced_equal_1, lymath.Math_IsClose(test_1_max_bounce, test_1_min_bounce, BOUNCE_TOLERANCE)
|
|
)
|
|
|
|
# 6) Verify that the material change was propagated correctly
|
|
all_bounced_greater = all([entity.bounces[0] < entity.bounces[1] for entity in all_entities])
|
|
Report.result(Tests.all_bounced_greater, all_bounced_greater)
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import ImportPathHelper as imports
|
|
imports.init()
|
|
|
|
from utils import Report
|
|
Report.start_test(C15308221_Material_ComponentsInSyncWithLibrary)
|