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

158 lines
6.6 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 : C5959759
# Test Case Title : Check that force region (sphere) exerts point force
# fmt: off
class Tests:
enter_game_mode = ("Entered game mode", "Failed to enter game mode")
find_cube = ("Entity Cube found", "Cube not found")
find_force_region = ("Entity force region found", "Force region not found")
gravity_works = ("Cube falls", "Cube did not fall")
sphere_gravity_enabled = ("Gravity is enabled on the cube", "Gravity is not enabled on the cube")
force_region_trigger = ("Cube entered and exited force region", "Cube did not enter adn exit force region")
force_calculated = ("OnCalculateNetForce calculated", "OnCalculateNetForce did not get calculated")
force_x_vector = ("Force x vector is positive", "Force x vector is not positive")
force_y_vector = ("Force y vector is positive", "Force y vector is not positive")
point_force_magnitude_value = ("Magnitude is set to 1000", "Magnitude is not set to 1000")
point_force_magnitude = ("Calculated magnitude is greater than set magnitude", "Calculated magnitude is not greater than set magnitude")
exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
# fmt: on
def C5959759_RigidBody_ForceRegionSpherePointForce():
"""
Level Setup
The level consists of a sherical force region with a point force of 1000.
A RigidBody cube with mass 1kg is positioned above the force region at an offset.
On entering game mode the cube will fall into the spherical point force region.
This should cause the cube to bounce off at considerable velocity.
We validate the point force observed is as expected
"""
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
EXPECTED_MAGNITUDE = 1000.0
NEGATIVE_VELOCITY = -0.001
TOLERANCE = 0.001
# 1) Open level and enter game mode
helper.init_idle()
helper.open_level("Physics", "C5959759_RigidBody_ForceRegionSpherePointForce")
helper.enter_game_mode(Tests.enter_game_mode)
# 2) Retrieve entities
cube_id = general.find_game_entity("CubeRigidBody")
Report.critical_result(Tests.find_cube, cube_id.IsValid())
sphere_force_region = general.find_game_entity("SphereForceRegion")
Report.critical_result(Tests.find_force_region, sphere_force_region.IsValid())
# 3) Gravity works
gravity_enabled = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "IsGravityEnabled", cube_id)
Report.result(Tests.sphere_gravity_enabled, gravity_enabled)
def is_going_down():
vel = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", cube_id)
return vel.z < NEGATIVE_VELOCITY
helper.wait_for_condition(is_going_down, 1.0)
cube_linear_velocity = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", cube_id)
Report.info("Cube z velocity from gravity: {}".format(cube_linear_velocity.z))
Report.result(Tests.gravity_works, cube_linear_velocity.z < NEGATIVE_VELOCITY)
# 4) Listen to trigger events and OnCalculateNetForce notification
class SphereForceRegion:
enter = False
exit = False
def on_enter(args):
other_id = args[0]
if other_id.Equal(cube_id):
Report.info("Cube touched spherical force region")
SphereForceRegion.enter = True
def on_exit(args):
other_id = args[0]
if other_id.Equal(cube_id):
Report.info("Cube touched spherical force region")
SphereForceRegion.exit = True
handler = azlmbr.physics.TriggerNotificationBusHandler()
handler.connect(sphere_force_region)
handler.add_callback("OnTriggerEnter", on_enter)
handler.add_callback("OnTriggerExit", on_exit)
class NetForce:
vector = None
magnitude = 0
def on_calc_net_force(args):
"""
args[0] - force region entity
args[1] - entity entering
args[2] - vector
args[3] - magnitude
"""
entering_entity = args[1]
if entering_entity.Equal(cube_id):
vector = args[2]
magnitude = args[3]
Report.info_vector3(vector, "Net Force vector", magnitude)
NetForce.vector = vector
NetForce.magnitude = magnitude
force_notification_handler = azlmbr.physics.ForceRegionNotificationBusHandler()
force_notification_handler.connect(None)
force_notification_handler.add_callback("OnCalculateNetForce", on_calc_net_force)
def force_region_enter_and_exit():
return SphereForceRegion.enter and SphereForceRegion.exit
helper.wait_for_condition(force_region_enter_and_exit, 3.0)
# 5) Report results
Report.result(Tests.force_region_trigger, force_region_enter_and_exit())
force_region_magnitude = azlmbr.physics.ForcePointRequestBus(azlmbr.bus.Event, "GetMagnitude", sphere_force_region)
Report.info("Force region magnitude = {}".format(force_region_magnitude))
# explicit check that the value is as expected
# set at level creation
Report.result(Tests.point_force_magnitude_value, force_region_magnitude == EXPECTED_MAGNITUDE)
# prevent the test from hanging if the force vector is not set
if NetForce.vector:
Report.success(Tests.force_calculated)
Report.result(Tests.force_x_vector, NetForce.vector.x > 0)
Report.result(Tests.force_y_vector, NetForce.vector.z > 0)
else:
Report.failure(Tests.force_calculated)
outcome = abs(NetForce.magnitude - force_region_magnitude) < TOLERANCE
Report.result(Tests.point_force_magnitude, outcome)
# 6) Exit game mode
helper.exit_game_mode(Tests.exit_game_mode)
if __name__ == "__main__":
import ImportPathHelper as imports
imports.init()
from editor_python_test_tools.utils import Report
Report.start_test(C5959759_RigidBody_ForceRegionSpherePointForce)