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.
234 lines
12 KiB
Python
234 lines
12 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 : C4982595
|
|
# Test Case Title : Verify that when the Trigger Checkbox is ticked, the object no longer collides with another object
|
|
# but simply passes through it
|
|
|
|
|
|
|
|
# fmt: off
|
|
class Tests:
|
|
enter_game_mode = ("Entered game mode", "Failed to enter game mode")
|
|
sphere_found_valid = ("Sphere found and validated", "Failed to find and validate Sphere")
|
|
trigger_box_found_valid = ("Trigger Box found and validated", "Failed to find and validate Trigger Box")
|
|
physical_box_found_valid = ("Physical Box found and validated", "Failed to find and validate Physical Box")
|
|
sphere_gravity_disabled = ("Gravity is disabled on Sphere", "Gravity is enabled on Sphere")
|
|
sphere_positive_initial_x_velocity = ("Sphere has positive initial x-velocity", "Sphere does not have positive initial x-velocity")
|
|
sphere_entered_trigger_box = ("Sphere entered Trigger Box", "Sphere did not enter Trigger Box")
|
|
sphere_exited_trigger_box = ("Sphere exited Trigger Box", "Sphere did not exit Trigger Box")
|
|
sphere_passed_through_trigger_box = ("Sphere passed through Trigger Box", "Sphere did not pass through Trigger Box")
|
|
sphere_collided_with_physical_box = ("Sphere collided with Physical Box", "Sphere did not collide with Physical Box")
|
|
sphere_bounced_back = ("Sphere bounced back from Physical Box", "Sphere did not bounce back from Physical Box")
|
|
sphere_did_not_pass_through_physical_box = ("Sphere did not pass through Physical Box", "Sphere passed through Physical Box")
|
|
exit_game_mode = ("Exited game mode", "Failed to exit game mode")
|
|
# fmt: on
|
|
|
|
|
|
def C4982595_Collider_TriggerDisablesCollision():
|
|
"""
|
|
Summary:
|
|
This script runs an automated test to verify that when an entity's PhysX collider is set as a trigger, the entity no
|
|
longer collides with another entity.
|
|
|
|
Level Description:
|
|
Entity: Sphere: PhysX Rigid Body, PhysX Collider with sphere shape, and Mesh with sphere asset
|
|
Gravity disabled, Radius 1.0, Initial linear x-velocity +30 m/s, Position (36.0, 36.0, 36.0)
|
|
Entity: Trigger Box: PhysX Collider with box shape, and Mesh with cube asset
|
|
Trigger enabled, Dimensions (2.0, 2.0, 2.0), Z-offset 1.0, Position (42.0, 36.0, 35.0)
|
|
Entity: Physical Box: PhysX Collider with box shape, and Mesh with cube asset
|
|
Dimensions (2.0, 2.0, 2.0), Z-offset 1.0, Position (48.0, 36.0, 35.0)
|
|
The entities are aligned along the x-axis as follows:
|
|
_ _
|
|
O ---> !_! |_|
|
|
Sphere Trigger Box Physical Box
|
|
|
|
Expected behavior:
|
|
The sphere will pass through the trigger box, collide with the physical box, and bounce back without passing through
|
|
the physical box.
|
|
|
|
Test Steps:
|
|
1) Open level and enter game mode
|
|
2) Retrieve and validate entities
|
|
3) Check that gravity is disabled on the sphere
|
|
4) Check that the sphere has positive initial x-velocity
|
|
5) Wait for the sphere to enter the trigger box
|
|
6) Wait for the sphere to exit the trigger box
|
|
7) Check that the sphere passed through the trigger box
|
|
8) Wait for the sphere to collide with the physical box
|
|
9) Wait for the sphere to stop colliding with the physical box and check that the sphere bounced back
|
|
10) Check that the sphere did not pass through the physical box
|
|
11) 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
|
|
|
|
TIME_OUT_SECONDS = 3.0
|
|
SPHERE_RADIUS = 1.0
|
|
BOX_X_DIMENSION = 2.0
|
|
BOX_X_RADIUS = BOX_X_DIMENSION / 2
|
|
CLOSE_ENOUGH_BUFFER = 0.1
|
|
|
|
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
|
|
|
|
def get_x_position(self):
|
|
position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
|
|
Report.info_vector3(position, "{}'s position:".format(self.name))
|
|
return position.x
|
|
|
|
class Sphere(Entity):
|
|
def __init__(self, name, found_valid_test):
|
|
Entity.__init__(self, name, found_valid_test)
|
|
self.initial_x_velocity = self.get_x_velocity()
|
|
|
|
# Trigger state values
|
|
self.entered_trigger_target = False
|
|
self.trigger_enter_position = None
|
|
self.exited_trigger_target = False
|
|
self.trigger_exit_position = None
|
|
self.passed_through_trigger_target = False
|
|
|
|
# Collision state values
|
|
self.began_collision_with_collision_target = False
|
|
self.ended_collision_with_collision_target = False
|
|
self.bounced_back = False
|
|
self.did_not_pass_through_collision_target = None
|
|
|
|
def is_gravity_disabled(self):
|
|
return not azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "IsGravityEnabled", self.id)
|
|
|
|
def get_x_velocity(self):
|
|
velocity = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", self.id)
|
|
Report.info_vector3(velocity, "{}'s velocity:".format(self.name))
|
|
return velocity.x
|
|
|
|
class TriggerBox(Entity):
|
|
def __init__(self, name, found_valid_test, trigger_target):
|
|
Entity.__init__(self, name, found_valid_test)
|
|
self.trigger_target = trigger_target
|
|
|
|
# Set up trigger notification handler
|
|
self.handler = azlmbr.physics.TriggerNotificationBusHandler()
|
|
self.handler.connect(self.id)
|
|
self.handler.add_callback("OnTriggerEnter", self.on_trigger_enter)
|
|
self.handler.add_callback("OnTriggerExit", self.on_trigger_exit)
|
|
|
|
def on_trigger_enter(self, args):
|
|
other_id = args[0]
|
|
if other_id.Equal(self.trigger_target.id) and not self.trigger_target.entered_trigger_target:
|
|
self.trigger_target.trigger_enter_position = self.trigger_target.get_x_position()
|
|
self.trigger_target.entered_trigger_target = True
|
|
|
|
def on_trigger_exit(self, args):
|
|
other_id = args[0]
|
|
if other_id.Equal(self.trigger_target.id) and not self.trigger_target.exited_trigger_target:
|
|
self.trigger_target.trigger_exit_position = self.trigger_target.get_x_position()
|
|
self.trigger_target.exited_trigger_target = True
|
|
# Check that the sphere's position traveled at least the approximate x-length of the box measured from
|
|
# the point on the sphere where it entered the trigger to the point on the sphere where it exited
|
|
if (
|
|
self.trigger_target.trigger_exit_position - SPHERE_RADIUS + CLOSE_ENOUGH_BUFFER
|
|
>= self.trigger_target.trigger_enter_position + BOX_X_DIMENSION + SPHERE_RADIUS
|
|
):
|
|
self.trigger_target.passed_through_trigger_target = True
|
|
|
|
class PhysicalBox(Entity):
|
|
def __init__(self, name, found_valid_test, collision_target):
|
|
Entity.__init__(self, name, found_valid_test)
|
|
self.collision_target = collision_target
|
|
|
|
# Set up collision notification handler
|
|
self.collision_handler = azlmbr.physics.CollisionNotificationBusHandler()
|
|
self.collision_handler.connect(self.id)
|
|
self.collision_handler.add_callback("OnCollisionBegin", self.on_collision_begin)
|
|
self.collision_handler.add_callback("OnCollisionEnd", self.on_collision_end)
|
|
|
|
def on_collision_begin(self, args):
|
|
other_id = args[0]
|
|
if other_id.Equal(self.collision_target.id):
|
|
self.collision_target.began_collision_with_collision_target = True
|
|
|
|
def on_collision_end(self, args):
|
|
other_id = args[0]
|
|
if other_id.Equal(self.collision_target.id):
|
|
self.collision_target.ended_collision_with_collision_target = True
|
|
# Check that the sphere reversed its x-direction
|
|
if self.collision_target.get_x_velocity() < 0:
|
|
self.collision_target.bounced_back = True
|
|
# Check that the whole sphere is to the negative x-direction of the box
|
|
if sphere.get_x_position() + SPHERE_RADIUS <= physical_box.get_x_position() - BOX_X_RADIUS:
|
|
self.collision_target.did_not_pass_through_collision_target = True
|
|
|
|
# 1) Open level and enter game mode
|
|
helper.init_idle()
|
|
helper.open_level("Physics", "C4982595_Collider_TriggerDisablesCollision")
|
|
helper.enter_game_mode(Tests.enter_game_mode)
|
|
|
|
# 2) Retrieve and validate entities
|
|
sphere = Sphere("Sphere", Tests.sphere_found_valid)
|
|
trigger_box = TriggerBox("Trigger Box", Tests.trigger_box_found_valid, trigger_target=sphere)
|
|
physical_box = PhysicalBox("Physical Box", Tests.physical_box_found_valid, collision_target=sphere)
|
|
|
|
entities = (sphere, trigger_box, physical_box)
|
|
for entity in entities:
|
|
Report.critical_result(entity.found_valid_test, entity.id.IsValid())
|
|
|
|
# 3) Check that gravity is disabled on the sphere
|
|
Report.critical_result(Tests.sphere_gravity_disabled, sphere.is_gravity_disabled())
|
|
|
|
# 4) Check that the sphere has positive initial x-velocity
|
|
Report.critical_result(Tests.sphere_positive_initial_x_velocity, sphere.initial_x_velocity > 0)
|
|
|
|
# 5) Wait for the sphere to enter the trigger box
|
|
helper.wait_for_condition(lambda: sphere.entered_trigger_target, TIME_OUT_SECONDS)
|
|
Report.critical_result(Tests.sphere_entered_trigger_box, sphere.entered_trigger_target)
|
|
|
|
# 6) Wait for the sphere to exit the trigger box
|
|
helper.wait_for_condition(lambda: sphere.exited_trigger_target, TIME_OUT_SECONDS)
|
|
Report.critical_result(Tests.sphere_exited_trigger_box, sphere.exited_trigger_target)
|
|
|
|
# 7) Check that the sphere passed through the trigger box
|
|
Report.critical_result(Tests.sphere_passed_through_trigger_box, sphere.passed_through_trigger_target)
|
|
|
|
# 8) Wait for the sphere to collide with the physical box
|
|
helper.wait_for_condition(lambda: sphere.began_collision_with_collision_target, TIME_OUT_SECONDS)
|
|
Report.critical_result(Tests.sphere_collided_with_physical_box, sphere.began_collision_with_collision_target)
|
|
|
|
# 9) Wait for the sphere to stop colliding with the physical box and check that the sphere bounced back
|
|
helper.wait_for_condition(lambda: sphere.ended_collision_with_collision_target, TIME_OUT_SECONDS)
|
|
Report.result(Tests.sphere_bounced_back, sphere.bounced_back)
|
|
|
|
# 10) Check that the sphere did not pass through the physical box
|
|
Report.result(Tests.sphere_did_not_pass_through_physical_box, sphere.did_not_pass_through_collision_target)
|
|
|
|
# 11) 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(C4982595_Collider_TriggerDisablesCollision)
|