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

197 lines
7.5 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 : C14902097
# Test Case Title : Verify Presimulate Events
# fmt: off
class Tests:
enter_game_mode = ("Entered game mode", "Failed to enter game mode")
exit_game_mode = ("Exited game mode", "Failed to exit game mode")
lead_sphere_found = ("Lead_Sphere is valid", "Lead_Sphere is not valid")
follow_sphere_found = ("Follow_Sphere is valid", "Follow_Sphere is not valid")
no_movement = ("Spheres start with no movement", "Spheres not stationary")
initial_position = ("Initial position is valid", "Initial position isn't valid")
lead_sphere_velocity = ("Lead_Sphere has valid velocity", "Lead_Sphere velocity not valid")
spheres_moving = ("Spheres have both moved", "Both sphere have not moved before timeout")
follow_condition_true = ("Follow_Sphere is correctly trailing", "Follow_Sphere follow distance not valid")
# fmt: on
def C14902097_ScriptCanvas_PreUpdateEvent():
"""
Summary: Verifies that Presimulate node in Script Canvas works as expected.
Level Description:
Lead_Sphere - Directly next to Follow_sphere on the +x axis; has rigid body (gravity disabled), sphere shape
collider, sphere shape
Follow_Sphere - Directly next to Lead_Sphere on the -x axis; has rigid body (gravity disabled, kinematic
enabled), sphere shape collider, sphere shape, script canvas
Script Canvas - Before every frame of PhysX calculation the Follow_Sphere is moved directly next to the
Lead_Sphere, then PhysX calculates and moves the Lead_Sphere to a new position before presenting to
the viewer
PhysX Configuration - The PhysX configuration file was modified to lower the frame rate to 20 Hz for visual debug
Expected Behavior: Follow_Sphere follows Lead_spheres position with a lag that is dependent on the speed and the
inverse frame rate
Test Steps:
1) Open Level
2) Enter Game Mode
3) Create and Validate entities
4) Validate Spheres are not moving
5) Check Position of Spheres
6) Start moving sphere and check that it acts correctly
7) Wait until Lead_Sphere has moved a set distance
8) Verify Follow_Sphere follow distance
9) Log results
10) Exit Game Mode
11) 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()
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
import azlmbr
import azlmbr.legacy.general as general
import azlmbr.bus
import azlmbr.math as math
# Constants
FLOAT_THRESHOLD = 0.1
TIMEOUT = 5
INITIAL_OFFSET = 1
REQUIRED_MOVEMENT = 2
FIXED_TIME_STEP = 0.05 # must be changed in level as well
LEAD_SPHERE_VELOCITY = 10.0
FINAL_OFFSET = (LEAD_SPHERE_VELOCITY * FIXED_TIME_STEP) + INITIAL_OFFSET
OFFSET_TOLERANCE = FINAL_OFFSET * 0.25
# Helper Functions
class Entity:
def __init__(self, name):
self.id = general.find_game_entity(name)
self.name = name
self.initial_position = self.position
self.final_position = None
# Validate Entities
found = Tests.__dict__[self.name.lower() + "_found"]
Report.critical_result(found, self.id.isValid())
@property
def position(self):
return azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
@property
def velocity(self):
return azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", self.id)
def set_velocity(self, x_velocity, y_velocity, z_velocity):
velocity = math.Vector3(x_velocity, y_velocity, z_velocity)
azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "SetLinearVelocity", self.id, velocity)
def moved_enough(self):
current_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
return abs(self.initial_position.x - current_position.x) >= REQUIRED_MOVEMENT
def report_values(self):
Report.info_vector3(self.initial_position, "{} initial position: ".format(self.name))
Report.info_vector3(self.final_position, "{} final position: ".format(self.name))
def check_relative_position(lead_sphere_position, follow_sphere_position, offset):
return (
abs((lead_sphere_position.x - follow_sphere_position.x) - offset) < OFFSET_TOLERANCE
and abs(lead_sphere_position.y - follow_sphere_position.y) < FLOAT_THRESHOLD
and abs(lead_sphere_position.z - follow_sphere_position.z) < FLOAT_THRESHOLD
)
def velocity_zero(sphere_velocity):
return (
abs(sphere_velocity.x) < FLOAT_THRESHOLD
and abs(sphere_velocity.y) < FLOAT_THRESHOLD
and abs(sphere_velocity.z) < FLOAT_THRESHOLD
)
def velocity_valid(lead_sphere_velocity):
return (
lead_sphere_velocity.x == LEAD_SPHERE_VELOCITY
and abs(lead_sphere_velocity.y) < FLOAT_THRESHOLD
and abs(lead_sphere_velocity.z) < FLOAT_THRESHOLD
)
# Main Script
helper.init_idle()
# 1) Open Level
helper.open_level("Physics", "C14902097_ScriptCanvas_PreUpdateEvent")
# 2) Enter Game Mode
helper.enter_game_mode(Tests.enter_game_mode)
# 3) Create and validate entities
lead_sphere = Entity("Lead_Sphere")
follow_sphere = Entity("Follow_Sphere")
# 4) Validate Spheres are not moving
Report.critical_result(
Tests.no_movement, velocity_zero(lead_sphere.velocity) and velocity_zero(follow_sphere.velocity)
)
# 5) Check Position of Sphere
Report.result(
Tests.initial_position,
check_relative_position(lead_sphere.initial_position, follow_sphere.initial_position, INITIAL_OFFSET),
)
# 6) Start moving sphere and check that it acts correctly
lead_sphere.set_velocity(LEAD_SPHERE_VELOCITY, 0.0, 0.0)
Report.result(Tests.lead_sphere_velocity, velocity_valid(lead_sphere.velocity))
# 7) Wait until Lead_Sphere has moved a set distance
Report.result(Tests.spheres_moving, helper.wait_for_condition(lead_sphere.moved_enough, TIMEOUT))
# 8) Verify Follow_Sphere follow distance
lead_sphere.final_position = lead_sphere.position
follow_sphere.final_position = follow_sphere.position
Report.result(
Tests.follow_condition_true, check_relative_position(lead_sphere.final_position, follow_sphere.final_position, FINAL_OFFSET)
)
# 9) Log results
lead_sphere.report_values()
follow_sphere.report_values()
Report.info("Offset:" + str(FINAL_OFFSET))
# 10) 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(C14902097_ScriptCanvas_PreUpdateEvent)