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.
194 lines
9.2 KiB
Python
194 lines
9.2 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 : C4925580
|
|
# Test Case Title : Verify that Material can be assigned to Ragdoll Bones and they behave as per their material
|
|
|
|
|
|
|
|
# fmt: off
|
|
class Tests:
|
|
enter_game_mode = ("Entered game mode", "Failed to enter game mode")
|
|
terrain_found_valid = ("PhysX Terrain found and validated", "PhysX Terrain not found and validated")
|
|
concrete_ragdoll_found_valid = ("Concrete Ragdoll found and validated", "Concrete Ragdoll not found and validated")
|
|
rubber_ragdoll_found_valid = ("Rubber Ragdoll found and validated", "Rubber Ragdoll not found and validated")
|
|
concrete_ragdoll_above_terrain = ("Concrete Ragdoll is above terrain", "Concrete Ragdoll is not above terrain")
|
|
rubber_ragdoll_above_terrain = ("Rubber Ragdoll is above terrain", "Rubber Ragdoll is not above terrain")
|
|
terrain_collision_detected = ("Collision was detected on a ragdoll with terrain", "Collision detection timed out")
|
|
concrete_ragdoll_contacted_terrain = ("Concrete Ragdoll contacted terrain", "Concrete Ragdoll did not contact terrain")
|
|
rubber_ragdoll_contacted_terrain = ("Rubber Ragdoll contacted terrain", "Rubber Ragdoll did not contact terrain")
|
|
rubber_ragdoll_bounced_higher = ("Rubber Ragdoll bounced higher than Concrete Ragdoll", "Rubber Ragdoll did not bounce higher than Concrete Ragdoll")
|
|
concrete_ragdoll_bounced_as_expected = ("Concrete ragdoll bounced to expected height", "Concrete ragdoll did not bounce to expected height")
|
|
rubber_ragdoll_bounced_as_expected = ("Rubber ragdoll bounced to expected height", "Rubber ragdoll did not bounce to expected height")
|
|
exit_game_mode = ("Exited game mode", "Failed to exit game mode")
|
|
# fmt: on
|
|
|
|
|
|
def C4925580_Material_RagdollBonesMaterial():
|
|
"""
|
|
Summary:
|
|
This script runs an automated test to verify that assigning material to the skeleton of an actor entity with PhysX
|
|
ragdoll will cause the entity to behave according to the nature of the material.
|
|
|
|
Level Description:
|
|
Two ragdoll entities (entity: Concrete Ragdoll) and (entity: Rubber Ragdoll) are above a PhysX terrain (entity:
|
|
PhysX Terrain). Each ragdoll has an actor, an animation graph, and a PhysX ragdoll component. Gravity is enabled for
|
|
each joint which is present on the ragdolls. The ragdolls are identical except for their textures, skeleton
|
|
materials, and x-positions. Concrete Ragdoll's texture is blue, while Rubber Ragdoll's texture is red. Concrete
|
|
Ragdoll's skeleton material is concrete, while Rubber Ragdoll's skeleton material is rubber.
|
|
|
|
Expected behavior:
|
|
The ragdolls will fall and hit the terrain at the same time. The rubber ragdoll will bounce higher than the concrete
|
|
ragdoll.
|
|
|
|
Test Steps:
|
|
1) Open level and enter game mode
|
|
2) Retrieve and validate entities
|
|
3) Check that each ragdoll is above the terrain
|
|
4) Wait for the initial collision between a ragdoll and the terrain or timeout
|
|
5) Check for the maximum bounce height of each ragdoll for a given period of time
|
|
6) Verify that the rubber ragdoll bounced higher than the concrete ragdoll
|
|
7) Verify that each ragdoll bounced approximately to its expected maximum height
|
|
8) 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
|
|
"""
|
|
# Setup path
|
|
import os
|
|
import sys
|
|
import azlmbr.legacy.general as general
|
|
import azlmbr.bus
|
|
import azlmbr.components
|
|
import azlmbr.physics
|
|
from editor_python_test_tools.utils import Report
|
|
from editor_python_test_tools.utils import TestHelper as helper
|
|
|
|
# Constants
|
|
TIME_OUT_SECONDS = 3.0
|
|
TERRAIN_START_Z = 32.0
|
|
CONCRETE_EXPECTED_MAX_BOUNCE_HEIGHT = 0.039
|
|
RUBBER_EXPECTED_MAX_BOUNCE_HEIGHT = 1.2
|
|
TOLERANCE = 0.5
|
|
|
|
class Entity:
|
|
def __init__(self, name, found_valid_test):
|
|
self.name = name
|
|
self.id = general.find_game_entity(name)
|
|
self.found_valid_test = found_valid_test
|
|
|
|
class Ragdoll(Entity):
|
|
def __init__(self, name, found_valid_test, target_terrain, above_terrain_test, contacted_terrain_test):
|
|
Entity.__init__(self, name, found_valid_test)
|
|
self.target_terrain = target_terrain
|
|
self.above_terrain_test = above_terrain_test
|
|
self.contacted_terrain_test = contacted_terrain_test
|
|
self.contacted_terrain = False
|
|
self.max_bounce_height = 0
|
|
self.reached_max_bounce = False
|
|
|
|
# Set up collision notification handler
|
|
self.handler = azlmbr.physics.CollisionNotificationBusHandler()
|
|
self.handler.connect(self.id)
|
|
self.handler.add_callback("OnCollisionBegin", self.on_collision_begin)
|
|
|
|
def get_z_position(self):
|
|
z_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", self.id)
|
|
return z_position
|
|
|
|
# Set up collision detection with the terrain
|
|
def on_collision_begin(self, args):
|
|
other_id = args[0]
|
|
if other_id.Equal(self.target_terrain.id):
|
|
Report.info("{} collision began with {}".format(self.name, self.target_terrain.name))
|
|
if not self.contacted_terrain:
|
|
self.hit_terrain_z = self.get_z_position()
|
|
self.contacted_terrain = True
|
|
|
|
# 1) Open level and enter game mode
|
|
helper.init_idle()
|
|
helper.open_level("Physics", "C4925580_Material_RagdollBonesMaterial")
|
|
helper.enter_game_mode(Tests.enter_game_mode)
|
|
|
|
# 2) Retrieve and validate entities
|
|
terrain = Entity("PhysX Terrain", Tests.terrain_found_valid)
|
|
Report.critical_result(terrain.found_valid_test, terrain.id.IsValid())
|
|
|
|
concrete_ragdoll = Ragdoll(
|
|
"Concrete Ragdoll",
|
|
Tests.concrete_ragdoll_found_valid,
|
|
terrain,
|
|
Tests.concrete_ragdoll_above_terrain,
|
|
Tests.concrete_ragdoll_contacted_terrain,
|
|
)
|
|
|
|
rubber_ragdoll = Ragdoll(
|
|
"Rubber Ragdoll",
|
|
Tests.rubber_ragdoll_found_valid,
|
|
terrain,
|
|
Tests.rubber_ragdoll_above_terrain,
|
|
Tests.rubber_ragdoll_contacted_terrain,
|
|
)
|
|
|
|
ragdolls = [concrete_ragdoll, rubber_ragdoll]
|
|
for ragdoll in ragdolls:
|
|
Report.critical_result(ragdoll.found_valid_test, ragdoll.id.IsValid())
|
|
|
|
# 3) Check that each ragdoll is above the terrain
|
|
Report.critical_result(ragdoll.above_terrain_test, ragdoll.get_z_position() > TERRAIN_START_Z)
|
|
|
|
# 4) Wait for the initial collision between the ragdolls and the terrain or timeout
|
|
terrain_collision_detected = helper.wait_for_condition(
|
|
lambda: concrete_ragdoll.contacted_terrain and rubber_ragdoll.contacted_terrain, TIME_OUT_SECONDS
|
|
)
|
|
Report.critical_result(Tests.terrain_collision_detected, terrain_collision_detected)
|
|
for ragdoll in ragdolls:
|
|
Report.result(ragdoll.contacted_terrain_test, ragdoll.contacted_terrain)
|
|
|
|
# 5) Check for the maximum bounce height of each ragdoll for a given period of time
|
|
def check_for_max_bounce_heights(ragdolls):
|
|
for ragdoll in ragdolls:
|
|
if ragdoll.contacted_terrain:
|
|
bounce_height = ragdoll.get_z_position() - ragdoll.hit_terrain_z
|
|
if bounce_height >= ragdoll.max_bounce_height:
|
|
ragdoll.max_bounce_height = bounce_height
|
|
elif ragdoll.max_bounce_height > 0.0:
|
|
ragdoll.reached_max_bounce = True
|
|
return concrete_ragdoll.reached_max_bounce and rubber_ragdoll.reached_max_bounce
|
|
|
|
helper.wait_for_condition(lambda: check_for_max_bounce_heights(ragdolls), TIME_OUT_SECONDS)
|
|
for ragdoll in ragdolls:
|
|
Report.info("{}'s maximum bounce height: {}".format(ragdoll.name, ragdoll.max_bounce_height))
|
|
|
|
# 6) Verify that the rubber ragdoll bounced higher than the concrete ragdoll
|
|
Report.result(
|
|
Tests.rubber_ragdoll_bounced_higher, rubber_ragdoll.max_bounce_height > concrete_ragdoll.max_bounce_height
|
|
)
|
|
|
|
# 7) Verify that each ragdoll bounced approximately to its expected maximum height
|
|
Report.result(
|
|
Tests.concrete_ragdoll_bounced_as_expected,
|
|
abs(concrete_ragdoll.max_bounce_height - CONCRETE_EXPECTED_MAX_BOUNCE_HEIGHT) < TOLERANCE,
|
|
)
|
|
Report.result(
|
|
Tests.rubber_ragdoll_bounced_as_expected,
|
|
abs(rubber_ragdoll.max_bounce_height - RUBBER_EXPECTED_MAX_BOUNCE_HEIGHT) < TOLERANCE,
|
|
)
|
|
|
|
# 8) Exit game mode and close editor
|
|
helper.exit_game_mode(Tests.exit_game_mode)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
from editor_python_test_tools.utils import Report
|
|
Report.start_test(C4925580_Material_RagdollBonesMaterial)
|