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.
220 lines
11 KiB
Python
220 lines
11 KiB
Python
"""
|
|
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 : C4925582
|
|
# Test Case Title : Check that any change (Add/Delete/Modify) made to the material surface in the material library reflects immediately in the ragdoll bones
|
|
|
|
|
|
|
|
# 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_default_ragdoll_0 = ("Test 0) Default ragdoll was found", "Test 0) Default ragdoll was not found")
|
|
find_modified_ragdoll_0 = ("Test 0) Modified ragdoll was found", "Test 0) Modified ragdoll was not found")
|
|
default_ragdoll_bounced_0 = ("Test 0) Default ragdoll bounced", "Test 0) Default ragdoll did not bounce")
|
|
modified_ragdoll_bounced_0 = ("Test 0) Modified ragdoll bounced", "Test 0) Modified ragdoll did not bounce")
|
|
exit_game_mode_0 = ("Test 0) Exited game mode", "Test 0) Failed to exit game mode")
|
|
modified_less_than_default = ("Test 0) Modified ragdoll's bounce height was shorter than default", "Test 0) Modified ragdoll's bounce height was greater than default")
|
|
|
|
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_default_ragdoll_1 = ("Test 1) Default ragdoll was found", "Test 1) Default ragdoll was not found")
|
|
find_modified_ragdoll_1 = ("Test 1) Modified ragdoll was found", "Test 1) Modified ragdoll was not found")
|
|
default_ragdoll_bounced_1 = ("Test 1) Default ragdoll bounced", "Test 1) Default ragdoll did not bounce")
|
|
modified_ragdoll_bounced_1 = ("Test 1) Modified ragdoll bounced", "Test 1) Modified ragdoll did not bounce")
|
|
exit_game_mode_1 = ("Test 1) Exited game mode", "Test 1) Failed to exit game mode")
|
|
modified_greater_than_default = ("Test 1) Modified ragdoll's bounce height was higher than default's", "Test 1) Modified ragdoll's bounce height was not higher than default's")
|
|
|
|
enter_game_mode_2 = ("Test 2) Entered game mode", "Test 2) Failed to enter game mode")
|
|
find_terrain_2 = ("Test 2) The Terrain was found", "Test 2) The Terrain was not found")
|
|
find_default_ragdoll_2 = ("Test 2) Default ragdoll was found", "Test 2) Default ragdoll was not found")
|
|
find_modified_ragdoll_2 = ("Test 2) Modified ragdoll was found", "Test 2) Modified ragdoll was not found")
|
|
default_ragdoll_bounced_2 = ("Test 2) Default ragdoll bounced", "Test 2) Default ragdoll did not bounce")
|
|
modified_ragdoll_bounced_2 = ("Test 2) Modified ragdoll bounced", "Test 2) Modified ragdoll did not bounce")
|
|
exit_game_mode_2 = ("Test 2) Exited game mode", "Test 2) Failed to exit game mode")
|
|
default_equals_modified = ("Test 2) Modified and default ragdoll's bounce height were equal", "Test 2) Modified and default ragdoll's bounce height were not equal")
|
|
# fmt: on
|
|
|
|
|
|
def C4925582_Material_AddModifyDeleteOnRagdollBones():
|
|
"""
|
|
Summary:
|
|
Runs an automated test to verify that any change (Add/Delete/Modify) made to the material surface in the material
|
|
library reflects immediately in the ragdoll bones
|
|
|
|
Level Description:
|
|
Two ragdolls ("default_ragdoll" and "modified_ragdoll") sit above a terrain. The ragdolls are identical, save for
|
|
their physX material.
|
|
|
|
The ragdoll "default_ragdoll" is assigned the default physx material.
|
|
A new material library was created with 1 material, called "Modified", this is assigned to "modified_ragdoll":
|
|
dynamic friction: 0.5
|
|
static friction: 0.5
|
|
restitution: 0.25
|
|
|
|
Expected behavior:
|
|
For every iteration this test measures the bounce height of each entity. The ragdolls save their traveled distances
|
|
each iteration, to verify different behavior between each setup.
|
|
|
|
First the test verifies the two entities are assigned differing materials, without changing anything. With a lower
|
|
restitution value, the 'modified' should bounce much lower than 'default'
|
|
|
|
Next, the test modifies the restitution value for 'modified' (from 0.25 to 0.75). 'modified' should bounce height
|
|
than it did in the previous test, and greater than default.
|
|
|
|
Finally, we delete the 'modified' material entirely. 'modified_ragdoll' should then behave the same as
|
|
'default_ragdoll' box, and bounce the same distance.
|
|
|
|
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) Modify the restitution value of 'modified'
|
|
3.1 - 3.4) <same as above>
|
|
4) Delete 'modified_ragdoll's material
|
|
4.1 - 4.4) <same as above>
|
|
5) 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 editor_python_test_tools.utils import Report
|
|
from editor_python_test_tools.utils import TestHelper as helper
|
|
|
|
TIMEOUT = 3.0
|
|
BOUNCE_TOLERANCE = 0.05
|
|
|
|
class Ragdoll:
|
|
def __init__(self, name):
|
|
self.name = name
|
|
self.bounces = []
|
|
|
|
def find_and_reset(self):
|
|
self.hit_terrain_position = None
|
|
self.hit_terrain = False
|
|
self.max_bounce = 0.0
|
|
self.reached_max_bounce = False
|
|
self.id = general.find_game_entity(self.name)
|
|
return self.id.IsValid()
|
|
|
|
@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
|
|
terrain_id = general.find_game_entity("terrain")
|
|
Report.result(get_test("find_terrain_{}".format(test_number)), terrain_id.IsValid())
|
|
Report.result(get_test("find_default_ragdoll_{}".format(test_number)), default_ragdoll.find_and_reset())
|
|
Report.result(get_test("find_modified_ragdoll_{}".format(test_number)), modified_ragdoll.find_and_reset())
|
|
|
|
def on_collision_enter(args):
|
|
entering = args[0]
|
|
for ragdoll in ragdolls:
|
|
if ragdoll.id.Equal(entering):
|
|
if not ragdoll.hit_terrain:
|
|
ragdoll.hit_terrain_position = ragdoll.position
|
|
ragdoll.hit_terrain = True
|
|
|
|
handler = azlmbr.physics.CollisionNotificationBusHandler()
|
|
handler.connect(terrain_id)
|
|
handler.add_callback("OnCollisionBegin", on_collision_enter)
|
|
|
|
def wait_for_bounce():
|
|
for ragdoll in ragdolls:
|
|
if ragdoll.hit_terrain:
|
|
current_bounce_height = ragdoll.position.z - ragdoll.hit_terrain_position.z
|
|
if current_bounce_height >= ragdoll.max_bounce:
|
|
ragdoll.max_bounce = current_bounce_height
|
|
elif ragdoll.max_bounce > 0.0:
|
|
ragdoll.reached_max_bounce = True
|
|
return default_ragdoll.reached_max_bounce and modified_ragdoll.reached_max_bounce
|
|
|
|
# x.3) Wait for entities to bounce
|
|
helper.wait_for_condition(wait_for_bounce, TIMEOUT)
|
|
Report.result(get_test("default_ragdoll_bounced_{}".format(test_number)), default_ragdoll.reached_max_bounce)
|
|
Report.result(get_test("modified_ragdoll_bounced_{}".format(test_number)), modified_ragdoll.reached_max_bounce)
|
|
|
|
for ragdoll in ragdolls:
|
|
ragdoll.bounces.append(ragdoll.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", "C4925582_Material_AddModifyDeleteOnRagdollBones")
|
|
|
|
# Setup persisting entities
|
|
default_ragdoll = Ragdoll("default")
|
|
modified_ragdoll = Ragdoll("modified")
|
|
ragdolls = [default_ragdoll, modified_ragdoll]
|
|
|
|
# 2) Collect basis values without modifying anything
|
|
run_test(0)
|
|
Report.result(Tests.modified_less_than_default, default_ragdoll.bounces[0] > modified_ragdoll.bounces[0])
|
|
|
|
# 3) Modify the restitution value of 'modified'
|
|
material_editor = Physmaterial_Editor("ragdollbones.physmaterial")
|
|
material_editor.modify_material("Modified", "Restitution", 0.75)
|
|
material_editor.save_changes()
|
|
run_test(1)
|
|
Report.result(Tests.modified_greater_than_default, default_ragdoll.bounces[0] < modified_ragdoll.bounces[1])
|
|
|
|
# 4) Delete 'modified's material
|
|
material_editor.delete_material("Modified")
|
|
material_editor.save_changes()
|
|
run_test(2)
|
|
Report.result(
|
|
Tests.default_equals_modified,
|
|
lymath.Math_IsClose(default_ragdoll.bounces[2], modified_ragdoll.bounces[2], BOUNCE_TOLERANCE),
|
|
)
|
|
|
|
Report.info("Default hit terrain: " + str(default_ragdoll.hit_terrain))
|
|
Report.info("Modified hit terrain: " + str(modified_ragdoll.hit_terrain))
|
|
|
|
Report.info("Default max bounce: " + str(default_ragdoll.reached_max_bounce))
|
|
Report.info("Modified max bouce: " + str(modified_ragdoll.reached_max_bounce))
|
|
|
|
Report.info("Default max bounce: " + str(default_ragdoll.bounces[0]))
|
|
Report.info("Modified max bouce: " + str(modified_ragdoll.bounces[0]))
|
|
|
|
if __name__ == "__main__":
|
|
import ImportPathHelper as imports
|
|
imports.init()
|
|
|
|
from editor_python_test_tools.utils import Report
|
|
Report.start_test(C4925582_Material_AddModifyDeleteOnRagdollBones)
|