rename to tmp name
This commit is contained in:
+200
@@ -0,0 +1,200 @@
|
||||
"""
|
||||
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 : C12712452
|
||||
# Test Case Title : Verify ScriptCanvas Collision Events
|
||||
|
||||
|
||||
|
||||
# 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")
|
||||
sphere_found_valid = ("Sphere found and validated", "Sphere not found and validated")
|
||||
begin_signal_found_valid = ("Begin Signal found and validated", "Begin Signal not found and validated")
|
||||
persist_signal_found_valid = ("Persist Signal found and validated", "Persist Signal not found and validated")
|
||||
end_signal_found_valid = ("End Signal found and validated", "End Signal not found and validated")
|
||||
sphere_above_terrain = ("Sphere is above terrain", "Sphere is not above terrain")
|
||||
sphere_gravity_enabled = ("Gravity is enabled on Sphere", "Gravity is not enabled on Sphere")
|
||||
sphere_started_bouncing = ("Sphere started bouncing", "Sphere did not start bouncing")
|
||||
sphere_stopped_bouncing = ("Sphere stopped bouncing", "Sphere did not stop bouncing")
|
||||
event_records_match = ("Event records match", "Event records do not match")
|
||||
exit_game_mode = ("Exited game mode", "Failed to exit game mode")
|
||||
# fmt: on
|
||||
|
||||
|
||||
def ScriptCanvas_CollisionEvents():
|
||||
"""
|
||||
Summary:
|
||||
This script runs an automated test to verify that the Script Canvas nodes "On Collision Begin", "On Collision
|
||||
Persist", and "On Collision End" will function as intended for the entity to which their Script Canvas is attached.
|
||||
|
||||
Level Description:
|
||||
A sphere (entity: Sphere) is above a terrain (entity: PhysX Terrain). The sphere has a PhysX Rigid Body, a PhysX
|
||||
Collider with shape Sphere, and gravity enabled. The sphere has a Script Canvas attached to it which will toggle the
|
||||
activation of three signal entities (entity: Begin Signal), (entity: Persist Signal), and (entity: End Signal).
|
||||
Begin Signal's activation will toggle (switch from activated to deactivated or vice versa) when a collision begins
|
||||
with the sphere, Persist Signal's activation will toggle when a collision persists with the sphere, and End Signal's
|
||||
activation will toggle when a collision ends with the sphere.
|
||||
|
||||
Expected behavior:
|
||||
The sphere will fall toward and collide with the terrain. The sphere will bounce until it comes to rest. The Script
|
||||
Canvas will cause the signal entities to activate and deactivate in the same pattern as the collision events which
|
||||
occur on the sphere.
|
||||
|
||||
Test Steps:
|
||||
1) Open level and enter game mode
|
||||
2) Retrieve and validate entities
|
||||
3) Check that the sphere is above the terrain
|
||||
4) Check that gravity is enabled on the sphere
|
||||
5) Wait for the initial collision between the sphere and the terrain or timeout
|
||||
6) Wait for the sphere to stop bouncing
|
||||
7 Check that the event records match
|
||||
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.entity
|
||||
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
|
||||
SPHERE_RADIUS = 1.0
|
||||
|
||||
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 Sphere(Entity):
|
||||
def __init__(self, name, found_valid_test, event_records_match_test):
|
||||
Entity.__init__(self, name, found_valid_test)
|
||||
self.event_records_match_test = event_records_match_test
|
||||
self.collided = False
|
||||
self.stopped_bouncing = False
|
||||
self.collision_event_record = []
|
||||
self.script_canvas_event_record = []
|
||||
|
||||
# Set up collision notification handler
|
||||
self.handler = azlmbr.physics.CollisionNotificationBusHandler()
|
||||
self.handler.connect(self.id)
|
||||
self.handler.add_callback("OnCollisionBegin", self.on_collision_begin)
|
||||
self.handler.add_callback("OnCollisionPersist", self.on_collision_persist)
|
||||
self.handler.add_callback("OnCollisionEnd", self.on_collision_end)
|
||||
|
||||
def get_z_position(self):
|
||||
z_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", self.id)
|
||||
Report.info("{}'s z-position: {}".format(self.name, z_position))
|
||||
return z_position
|
||||
|
||||
def is_gravity_enabled(self):
|
||||
return azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "IsGravityEnabled", self.id)
|
||||
|
||||
# Set up reporting of the event records and whether they match
|
||||
def match_event_records(self):
|
||||
Report.info("{} collision event record: {}".format(self.name, self.collision_event_record))
|
||||
Report.info("Script Canvas event record: {}".format(self.script_canvas_event_record))
|
||||
return self.collision_event_record == self.script_canvas_event_record
|
||||
|
||||
# Set up collision event detection and update collision event record
|
||||
def on_collision(self, event, other_id):
|
||||
if not self.collided:
|
||||
self.collided = True
|
||||
other_name = azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "GetEntityName", other_id)
|
||||
Report.info("{} collision {}s with {}".format(self.name, event, other_name))
|
||||
self.collision_event_record.append(event)
|
||||
|
||||
def on_collision_begin(self, args):
|
||||
self.on_collision("begin", args[0])
|
||||
|
||||
def on_collision_persist(self, args):
|
||||
self.on_collision("persist", args[0])
|
||||
|
||||
def on_collision_end(self, args):
|
||||
self.on_collision("end", args[0])
|
||||
|
||||
# Set up detection of the sphere coming to rest
|
||||
def bouncing_stopped(self):
|
||||
if not azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "IsAwake", self.id):
|
||||
self.stopped_bouncing = True
|
||||
return self.stopped_bouncing
|
||||
|
||||
class SignalEntity(Entity):
|
||||
def __init__(self, name, found_valid_test, monitored_entity, event):
|
||||
Entity.__init__(self, name, found_valid_test)
|
||||
self.monitored_entity = monitored_entity
|
||||
self.event = event
|
||||
|
||||
# Set up activation and deactivation notification handler
|
||||
self.handler = azlmbr.entity.EntityBusHandler()
|
||||
self.handler.connect(self.id)
|
||||
self.handler.add_callback("OnEntityActivated", self.on_entity_activated)
|
||||
self.handler.add_callback("OnEntityDeactivated", self.on_entity_deactivated)
|
||||
|
||||
# Set up activation and deactivation detection and update Script Canvas event record
|
||||
def on_entity_activated(self, args):
|
||||
self.monitored_entity.script_canvas_event_record.append(self.event)
|
||||
|
||||
def on_entity_deactivated(self, args):
|
||||
self.monitored_entity.script_canvas_event_record.append(self.event)
|
||||
|
||||
# 1) Open level and enter game mode
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "ScriptCanvas_CollisionEvents")
|
||||
helper.enter_game_mode(Tests.enter_game_mode)
|
||||
|
||||
# 2) Retrieve and validate entities
|
||||
terrain = Entity("PhysX Terrain", Tests.terrain_found_valid)
|
||||
sphere = Sphere("Sphere", Tests.sphere_found_valid, Tests.event_records_match)
|
||||
begin_signal = SignalEntity("Begin Signal", Tests.begin_signal_found_valid, sphere, "begin")
|
||||
persist_signal = SignalEntity("Persist Signal", Tests.persist_signal_found_valid, sphere, "persist")
|
||||
end_signal = SignalEntity("End Signal", Tests.end_signal_found_valid, sphere, "end")
|
||||
|
||||
entities = [terrain, sphere, begin_signal, persist_signal, end_signal]
|
||||
for entity in entities:
|
||||
Report.critical_result(entity.found_valid_test, entity.id.IsValid())
|
||||
|
||||
# 3) Check that the sphere is above the terrain
|
||||
Report.critical_result(Tests.sphere_above_terrain, sphere.get_z_position() - SPHERE_RADIUS > TERRAIN_START_Z)
|
||||
|
||||
# 4) Check that gravity is enabled on the sphere
|
||||
Report.critical_result(Tests.sphere_gravity_enabled, sphere.is_gravity_enabled())
|
||||
|
||||
# 5) Wait for the initial collision between the sphere and the terrain or timeout
|
||||
helper.wait_for_condition(lambda: sphere.collided, TIME_OUT_SECONDS)
|
||||
Report.critical_result(Tests.sphere_started_bouncing, sphere.collided)
|
||||
|
||||
# 6) Wait for the sphere to stop bouncing
|
||||
helper.wait_for_condition(sphere.bouncing_stopped, TIME_OUT_SECONDS)
|
||||
Report.result(Tests.sphere_stopped_bouncing, sphere.stopped_bouncing)
|
||||
|
||||
# 7 Check that the event records match
|
||||
Report.result(Tests.event_records_match, sphere.match_event_records())
|
||||
|
||||
# 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(ScriptCanvas_CollisionEvents)
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
"""
|
||||
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 : C19536274
|
||||
Test Case Title : Verify that the Get Collision Layer Name node prints the name of the collision layer
|
||||
|
||||
"""
|
||||
|
||||
|
||||
# fmt: off
|
||||
class Tests():
|
||||
test_entity_enabled = ("Test entity was enabled", "Test entity failed to enable")
|
||||
game_mode_entered = ("Successfully entered Game Mode", "Failed to enter Game Mode")
|
||||
# fmt: on
|
||||
|
||||
|
||||
def ScriptCanvas_GetCollisionNameReturnsName():
|
||||
"""
|
||||
Summary:
|
||||
Loads a level that contains an entity with script canvas and PhysX Collider components
|
||||
|
||||
Level Description:
|
||||
Mostly empty level that contains a few different entities (one for each test using the level).
|
||||
Each entity is named after the testrail id for the respective test. Each entity contains PhysX Collider component
|
||||
and a Script Canvas Component with a matching .scriptcanvas file provided in the testrail.
|
||||
|
||||
Expected Behavior:
|
||||
The level loads, enters game mode, and the script canvas prints out "Layer Name: Right"
|
||||
|
||||
Test Steps:
|
||||
1) Load the test level
|
||||
2) Find and enable the test entity
|
||||
3) Enter game mode
|
||||
|
||||
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
|
||||
"""
|
||||
# Helper Files
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity as Entity
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
ACTIVE_STATUS = azlmbr.globals.property.EditorEntityStartStatus_StartActive
|
||||
|
||||
helper.init_idle()
|
||||
# 1) Load the test level
|
||||
helper.open_level("Physics", "NameNode_Prints")
|
||||
|
||||
# 2) Find and enable the test entity
|
||||
test_entity = Entity.find_editor_entity("C19536274")
|
||||
test_entity.set_start_status("active")
|
||||
Report.result(Tests.test_entity_enabled, test_entity.get_start_status() == ACTIVE_STATUS)
|
||||
|
||||
# 3) Enter game mode
|
||||
helper.enter_game_mode(Tests.game_mode_entered)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(ScriptCanvas_GetCollisionNameReturnsName)
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
"""
|
||||
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 : C19536277
|
||||
Test Case Title : Verify that when a group is modified using ToggleCollisionLayer node such that the new group is not in the pre-existing groups, GetCollisionGroupName node prints no value
|
||||
|
||||
"""
|
||||
|
||||
|
||||
# fmt: off
|
||||
class Tests():
|
||||
test_entity_enabled = ("Test Entity successfully enabled", "Failed to enable Test Entity")
|
||||
game_mode_entered = ("Successfully entered Game Mode", "Failed to enter Game Mode")
|
||||
# fmt: on
|
||||
|
||||
|
||||
def ScriptCanvas_GetCollisionNameReturnsNothingWhenHasToggledLayer():
|
||||
"""
|
||||
Summary:
|
||||
Loads a level that contains an entity with script canvas and PhysX Collider components
|
||||
|
||||
Level Description:
|
||||
Mostly empty level that contains a few different entities (one for each test using the level).
|
||||
Each entity is named after the testrail id for the respective test. Each entity contains PhysX Collider component
|
||||
and a Script Canvas Component with a matching .scriptcanvas file provided in the testrail.
|
||||
|
||||
Expected Behavior:
|
||||
The level loads, enters game mode, and the script canvas prints out "GroupName: "
|
||||
|
||||
Test Steps:
|
||||
1) Load the test level
|
||||
2) Find and enable the test entity
|
||||
3) Enter game mode
|
||||
|
||||
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
|
||||
"""
|
||||
# Helper Files
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity as Entity
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
ACTIVE_STATUS = azlmbr.globals.property.EditorEntityStartStatus_StartActive
|
||||
|
||||
helper.init_idle()
|
||||
# 1) Load the test level
|
||||
helper.open_level("Physics", "NameNode_Prints")
|
||||
|
||||
# 2) Find and enable the test entity
|
||||
test_entity = Entity.find_editor_entity("C19536277")
|
||||
test_entity.set_start_status("active")
|
||||
Report.result(Tests.test_entity_enabled, test_entity.get_start_status() == ACTIVE_STATUS)
|
||||
|
||||
# 3) Enter game mode
|
||||
helper.enter_game_mode(Tests.game_mode_entered)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(ScriptCanvas_GetCollisionNameReturnsNothingWhenHasToggledLayer)
|
||||
+198
@@ -0,0 +1,198 @@
|
||||
"""
|
||||
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 : C12712453
|
||||
# Test Case Title : Verify Raycast Multiple Node
|
||||
|
||||
|
||||
# fmt:off
|
||||
class Tests:
|
||||
enter_game_mode = ("Entered game mode", "Failed to enter game mode")
|
||||
exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
|
||||
test_completed = ("The test successfully completed", "The test timed out")
|
||||
# entities found
|
||||
caster_found = ("Caster entity found", "Caster entity NOT found")
|
||||
multi_target_close_found = ("Multicast close target entity found", "Multicast close target NOT found")
|
||||
multi_target_far_found = ("Multicast far target entity found", "Multicast far target NOT found")
|
||||
single_target_found = ("Single close target entity found", "Single close target NOT found")
|
||||
fail_entities_found = ("Found all fail entities", "Failed to find at least one fail entities")
|
||||
# entity results
|
||||
caster_result = ("Caster was activated", "Caster was NOT activated")
|
||||
multi_target_close_result = ("Multicast close target was hit with a ray", "Multicast close target WAS NOT hit with a ray")
|
||||
multi_target_far_result = ("Multicast far target was hit with a ray", "Multicast far target WAS NOT hit with a ray")
|
||||
single_target_result = ("Single target was hit with a ray", "Single target WAS NOT hit with a ray")
|
||||
|
||||
# fmt:on
|
||||
|
||||
|
||||
# Lines to search for by the log monitor
|
||||
class Lines:
|
||||
# FAILURE (in all caps) is used as the failure flag for both this python script and ScriptCanvas.
|
||||
# If this is present in the log, something has gone fatally wrong and the test will fail.
|
||||
# Additional details as to why the test fails will be printed in the log accompanying this entry.
|
||||
unexpected = ["FAILURE"]
|
||||
|
||||
|
||||
def ScriptCanvas_MultipleRaycastNode():
|
||||
"""
|
||||
Summary:
|
||||
Uses script canvas to cast two types of rays in game mode (multiple raycast and single raycast). Script canvas
|
||||
validates the results from the raycasts, then deactivates any entities hit. This python script ensures only
|
||||
the expected entities were deactivated.
|
||||
|
||||
Level Description:
|
||||
Caster - A sphere with gravity disabled and a scriptcanvas component for emitting raycasts. Caster starts inactive.
|
||||
Targets - Three spheres with gravity disabled. They are the expected targets of the raycasts.
|
||||
Fail Boxes - These boxes are positioned in various places where no ray should collide with them. They are set
|
||||
up print a fail message if any ray should hit them.
|
||||
ScriptCanvas - The ScriptCanvas script is attached to the Caster entity, and is set to start on entity Activation.
|
||||
The script will activate two different raycast nodes, a single raycast and a multiple raycast. For every raycast
|
||||
hit, the script validates all properties of a raycast (while printing to log) and then deactivates any entity
|
||||
that is [raycast] hit. This ScriptCanvas file can be found in this test's level folder named
|
||||
"Raycast.scrpitcanvas".
|
||||
|
||||
Expected Behavior:
|
||||
The level should load and appear to instantly close. After setup the Caster sphere should emit the raycasts which
|
||||
should deactivate all expected Targets (via script canvas). The python script waits for the Targets to be
|
||||
deactivated then prints the results.
|
||||
|
||||
Steps:
|
||||
1) Load level / enter game mode
|
||||
2) Retrieve entities
|
||||
3) Start the test (activate the caster entity)
|
||||
4) Wait for Target entities to deactivate
|
||||
5) Exit game mode and close the editor
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
# Disabled until Script Canvas merges the new backend
|
||||
return
|
||||
|
||||
import os
|
||||
import sys
|
||||
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
|
||||
import azlmbr
|
||||
|
||||
# Constants
|
||||
TIME_OUT = 1.0
|
||||
FAIL_ENTITIES = 5
|
||||
|
||||
# Entity base class handles very general entity initialization
|
||||
class EntityBase:
|
||||
def __init__(self, name):
|
||||
# type: (str) -> None
|
||||
self.name = name
|
||||
self.id = general.find_game_entity(name)
|
||||
|
||||
# Stores entity "is active" state. Most entities start as "Active"
|
||||
self.activated = True
|
||||
|
||||
# Caster starts deactivated. When the caster is activated the script canvas test will begin.
|
||||
class Caster(EntityBase):
|
||||
def __init__(self, name):
|
||||
# type: (str) -> None
|
||||
EntityBase.__init__(self, name)
|
||||
found_tuple = Tests.__dict__[name.lower() + "_found"]
|
||||
Report.critical_result(found_tuple, self.id.isValid())
|
||||
|
||||
# Caster starts as "Inactive" because the script canvas starts when Caster is Activated
|
||||
self.activated = False
|
||||
|
||||
# Activates the Caster which starts it's ScriptCanvas script (and the test)
|
||||
def activate(self):
|
||||
# type: () -> None
|
||||
azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "ActivateGameEntity", self.id)
|
||||
self.activated = True
|
||||
Report.success(Tests.__dict__[self.name + "_result"])
|
||||
|
||||
# Targets start activated and only get deactivated by the ScriptCanvas script.
|
||||
# Successful execution means every Target gets deactivated via ScriptCanvas
|
||||
class Target(EntityBase):
|
||||
def __init__(self, name):
|
||||
# type: (str) -> None
|
||||
EntityBase.__init__(self, name)
|
||||
found_tuple = Tests.__dict__[name.lower() + "_found"]
|
||||
Report.critical_result(found_tuple, self.id.isValid())
|
||||
|
||||
self.handler = azlmbr.entity.EntityBusHandler()
|
||||
self.handler.connect(self.id)
|
||||
self.handler.add_callback("OnEntityDeactivated", self.on_deactivation)
|
||||
|
||||
# Callback: gets called when entity is deactivated. This is expected for Target entities.
|
||||
def on_deactivation(self, args):
|
||||
# type: ([EntityId, ...]) -> None
|
||||
if args[0].Equal(self.id):
|
||||
Report.success(Tests.__dict__[self.name + "_result"])
|
||||
self.activated = False
|
||||
|
||||
# Disconnects event handler.
|
||||
# (Needed so the deactivation callback doesn't not get called on level clean up)
|
||||
def disconnect(self):
|
||||
# type: () -> None
|
||||
self.handler.disconnect()
|
||||
self.handler = None
|
||||
|
||||
# Failure entities start activated and get deactivated via the ScriptCanvas. Ideally none will be deactivated
|
||||
# during the test. If one is deactivated, and Failure message is logged that will be caught by the log monitor.
|
||||
class Failure(EntityBase):
|
||||
def __init__(self, num):
|
||||
# type: (int) -> None
|
||||
EntityBase.__init__(self, "fail_" + str(num))
|
||||
if not self.id.IsValid():
|
||||
Report.info("FAILURE: {} could not be found".format(self.name))
|
||||
self.handler = azlmbr.entity.EntityBusHandler()
|
||||
self.handler.connect(self.id)
|
||||
self.handler.add_callback("OnEntityDeactivated", self.on_deactivation)
|
||||
|
||||
# Callback: gets called when entity is deactivated. This is expected for Target entities.
|
||||
def on_deactivation(self, args):
|
||||
# type: ([EntityId, ...]) -> None
|
||||
if args[0].Equal(self.id):
|
||||
Report.info("{}: FAILURE".format(self.name))
|
||||
self.activated = False
|
||||
|
||||
# Disconnects event handler.
|
||||
# (Needed so the deactivation callback doesn't not get called on level clean up)
|
||||
def disconnect(self):
|
||||
# type: () -> None
|
||||
self.handler.disconnect()
|
||||
self.handler = None
|
||||
|
||||
# 1) Open level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "ScriptCanvas_MultipleRaycastNode")
|
||||
helper.enter_game_mode(Tests.enter_game_mode)
|
||||
|
||||
# 2) Retrieve entities
|
||||
caster = Caster("caster")
|
||||
targets = [Target("multi_target_close"), Target("multi_target_far"), Target("single_target")]
|
||||
fails = [Failure(i) for i in range(FAIL_ENTITIES)]
|
||||
Report.critical_result(Tests.fail_entities_found, all(entity.id.isValid() for entity in fails))
|
||||
|
||||
# 3) Start the test
|
||||
caster.activate()
|
||||
|
||||
# 4) Wait for Target entities to deactivate
|
||||
test_completed = helper.wait_for_condition(lambda: all(not target.activated for target in targets), TIME_OUT)
|
||||
Report.result(Tests.test_completed, test_completed)
|
||||
|
||||
# Disconnect all "on deactivated" event handlers so they don't get called implicitly on level cleanup
|
||||
for entity in targets + fails:
|
||||
entity.disconnect()
|
||||
|
||||
# 5) Close test
|
||||
helper.exit_game_mode(Tests.exit_game_mode)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(ScriptCanvas_MultipleRaycastNode)
|
||||
+319
@@ -0,0 +1,319 @@
|
||||
"""
|
||||
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 : 12712454
|
||||
# Test Case Title : Verify overlap nodes in script canvas
|
||||
|
||||
|
||||
# fmt: off
|
||||
class Tests:
|
||||
enter_game_mode = ("Entered game mode", "Failed to enter game mode")
|
||||
exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
|
||||
# comm entities are used for communication between script canvas and the python script.
|
||||
comm_entities_found = ("All comm entities found", "All comm entities not found")
|
||||
script_canvas_entity_found = ("Script_Canvas_Entity Found", "Script_Canvas_Entity not found")
|
||||
test_array_found = ("8x8 entity array found", "8x8 entity array not found")
|
||||
all_tests_passed = ("All tests have expected results", "Some tests had unexpected results")
|
||||
|
||||
# Test 0
|
||||
test_0_finished = ("Test 0 has ended", "Test 0 has not ended correctly")
|
||||
test_0_results_logged = ("Test 0 logged expected results", "Test 0 logged unexpected results")
|
||||
test_0_entity_reset = ("Test 0: entities moved back", "Test 0: not all entities moved back")
|
||||
|
||||
# Test 1
|
||||
test_1_finished = ("Test 1 has ended", "Test 1 has not ended correctly")
|
||||
test_1_results_logged = ("Test 1 logged expected results", "Test 1 logged unexpected results")
|
||||
test_1_entity_reset = ("Test 1: entities moved back", "Test 1: not all entities moved back")
|
||||
|
||||
# Test 2
|
||||
test_2_finished = ("Test 2 has ended", "Test 2 has not ended correctly")
|
||||
test_2_results_logged = ("Test 2 logged expected results", "Test 2 logged unexpected results")
|
||||
test_2_entity_reset = ("Test 2: entities moved back", "Test 2: not all entities moved back")
|
||||
# fmt: on
|
||||
|
||||
|
||||
def ScriptCanvas_OverlapNode():
|
||||
"""
|
||||
Summary: Verifies that the three script canvas overlap nodes (box, sphere, capsule) work as expected. Test
|
||||
script starts and verifies each case one by one.
|
||||
|
||||
Level Description:
|
||||
Test Array - 8x8 array of sphere entities lined up edge to edge along an y-z plane, they are names with
|
||||
'Sphere_row_column' convention; has PhysX rigid body, sphere shaped PhysX collider, sphere shape.
|
||||
Comm From Test- 3 communication entities that start inactive, used by the test script to initiate each of the three cases
|
||||
by activation of the relevent sphere; has sphere shape.
|
||||
Comm To Test- 3 communication entities that start inactive, used by the script canvas to initiate when each of the three
|
||||
cases are completed by activation of the relevent sphere; has sphere shape.
|
||||
Script Canvas Entity - Entity is centered in the test array and oriented with a 90 degree angle along the y
|
||||
axis as to allow the capsule overlap node to overlap more entities; has script canvas component
|
||||
|
||||
Script Canvas - Has three execution cases, one for each overlap node type. Each case goes through a similar path
|
||||
- Waits for relevant Comm From Test entity to be activated by the test script
|
||||
- Creates an array of all entities in Test Array that overlap
|
||||
- Uses this array to draw a blue sphere at every sphere that overlaps
|
||||
- Uses the same array to move each overlapping entity 5 m along the +x axis
|
||||
- Activates the relevant Comm To Test entity
|
||||
The test script then logs the results and resets the Test Array before activating the next path.
|
||||
Values for the overlaps:
|
||||
Box: x = 4.5, y = 4.5, z = 4.5
|
||||
Sphere: r = 4
|
||||
Capsule: r = 0.5, h = 5
|
||||
Note: For this script canvas to run properly it requires the custom .physxconfiguration file.
|
||||
|
||||
Tests Runs - Each loop runs a different overlap node
|
||||
- test_0: Box
|
||||
- test_1: Sphere
|
||||
- test_2: Capsule
|
||||
|
||||
Expected Behavior: The script canvas will run it's three different overlap nodes. Each run the overlapped
|
||||
spheres in the Test Array will be drawn in over in blue and then offset in the x direction so that this test
|
||||
script can confirm that it worked correctly.
|
||||
|
||||
Test Steps:
|
||||
1) Open Level
|
||||
2) Enter Game Mode
|
||||
3) Create Entity Objects
|
||||
4) Validate Entities
|
||||
5) Begin Testing
|
||||
6) Signal Script Canvas to begin test
|
||||
7) Wait until script canvas signals that it has completed the test
|
||||
8) Check which entities in array have been moved
|
||||
9) Validate and log results of test
|
||||
10) Place all entities back into correct positions in entity array
|
||||
11) Log results of all tests
|
||||
12) Exit Game Mode
|
||||
13) 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
|
||||
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
|
||||
import azlmbr.math as math
|
||||
|
||||
# Constants
|
||||
FLOAT_THRESHOLD = 0.0001
|
||||
# Timeout for a failed test in seconds
|
||||
TIMEOUT = 1.0
|
||||
ARRAY_X = 500.0
|
||||
ARRAY_COLUMN_0 = 530.0
|
||||
ARRAY_ROW_0 = 45.0
|
||||
|
||||
# Helper Functions
|
||||
class Entity:
|
||||
def __init__(self, name, activated):
|
||||
self.id = general.find_game_entity(name)
|
||||
self.name = name
|
||||
self.activated = activated
|
||||
self.handler = None
|
||||
|
||||
def activate_entity(self):
|
||||
Report.info("Activating Entity : " + self.name)
|
||||
azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "ActivateGameEntity", self.id)
|
||||
self.activated = True
|
||||
|
||||
def entity_activated(self, args):
|
||||
self.activated = True
|
||||
|
||||
def set_handler(self):
|
||||
self.handler = azlmbr.entity.EntityBusHandler()
|
||||
self.handler.connect(self.id)
|
||||
self.handler.add_callback("OnEntityActivated", self.entity_activated)
|
||||
|
||||
class Sphere_Entities:
|
||||
def __init__(self, row, column):
|
||||
self.name = "Sphere_{}_{}".format(row, column)
|
||||
self.id = general.find_game_entity(self.name)
|
||||
self.y = column + ARRAY_COLUMN_0
|
||||
self.z = ARRAY_ROW_0 - row
|
||||
self.array_position = math.Vector3(ARRAY_X, self.y, self.z)
|
||||
self.current_position = self.array_position
|
||||
|
||||
def check_id(self):
|
||||
return self.id.isValid()
|
||||
|
||||
def move_entity_back(self):
|
||||
azlmbr.components.TransformBus(azlmbr.bus.Event, "SetWorldTranslation", self.id, self.array_position)
|
||||
|
||||
def in_position(self):
|
||||
current_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
|
||||
return abs(current_position.x - self.array_position.x) < FLOAT_THRESHOLD
|
||||
|
||||
class Script_Canvas_Test:
|
||||
def __init__(self, index):
|
||||
self.index = index
|
||||
self.name = "test_{}".format(index)
|
||||
self.got_expected_result = False
|
||||
self.test_finish = None
|
||||
self.results_logged = None
|
||||
self.array_reset = None
|
||||
|
||||
def report_test_start(self):
|
||||
Report.info("Test {} has begun".format(self.index))
|
||||
|
||||
def report_test_finished(self, finished):
|
||||
self.test_finish = Tests.__dict__["test_{}_finished".format(self.index)]
|
||||
Report.result(self.test_finish, finished)
|
||||
|
||||
def report_results_logged(self):
|
||||
self.results_logged = Tests.__dict__["test_{}_results_logged".format(self.index)]
|
||||
Report.result(self.results_logged, self.got_expected_result)
|
||||
|
||||
def report_test_array_reset(self, entities_in_position):
|
||||
self.array_reset = Tests.__dict__["test_{}_entity_reset".format(self.index)]
|
||||
Report.result(self.array_reset, entities_in_position)
|
||||
|
||||
# fmt: off
|
||||
class Result_Arrays:
|
||||
true_bool_array = [[True for column in range(8)] for row in range(8)]
|
||||
# Comparison Array for box overlap node
|
||||
test_0_bool_array = [
|
||||
[True, True, True, True, True, True, True, True],
|
||||
[True, False, False, False, False, False, False, True],
|
||||
[True, True, False, False, False, False, False, True],
|
||||
[True, False, False, False, False, False, False, True],
|
||||
[True, True, False, False, False, False, False, True],
|
||||
[True, True, False, False, False, False, False, True],
|
||||
[True, True, False, False, False, False, False, True],
|
||||
[True, True, True, True, True, True, True, True],
|
||||
]
|
||||
|
||||
# Comparison Array for sphere overlap node
|
||||
test_1_bool_array = [
|
||||
[True, True, True, True, True, True, True, True],
|
||||
[True, True, False, False, False, False, True, True],
|
||||
[True, False, False, False, False, False, False, True],
|
||||
[True, False, False, False, False, False, False, True],
|
||||
[True, False, False, False, False, False, False, True],
|
||||
[True, False, False, False, False, False, False, True],
|
||||
[True, True, False, False, False, False, True, True],
|
||||
[True, True, True, True, True, True, True, True],
|
||||
]
|
||||
|
||||
# Comparison Array for capsule overlap node
|
||||
test_2_bool_array = [
|
||||
[True, True, True, True, True, True, True, True],
|
||||
[True, True, True, False, False, True, True, True],
|
||||
[True, True, True, False, False, True, True, True],
|
||||
[True, True, True, False, False, True, True, True],
|
||||
[True, True, True, False, False, True, True, True],
|
||||
[True, True, True, False, False, True, True, True],
|
||||
[True, True, True, False, False, True, True, True],
|
||||
[True, True, True, True, True, True, True, True],
|
||||
]
|
||||
# fmt on
|
||||
|
||||
def create_test_Sphere_Entities():
|
||||
return [[Sphere_Entities(row, column) for column in range(8)] for row in range(8)]
|
||||
|
||||
def sphere_array_isvalid(array):
|
||||
for row in range(len(array)):
|
||||
for column in range(len(array[0])):
|
||||
if not array[row][column].id.isValid():
|
||||
return False
|
||||
return True
|
||||
|
||||
def check_comm_entities(comm_list):
|
||||
for entity in comm_list:
|
||||
if not entity.id.isValid():
|
||||
return False
|
||||
return True
|
||||
|
||||
def check_array_movement(array):
|
||||
return [[True if entity.in_position() else False for entity in row] for row in array]
|
||||
|
||||
def reset_array(array):
|
||||
for row in array:
|
||||
for entity in row:
|
||||
entity.move_entity_back()
|
||||
|
||||
def is_array_in_position(array):
|
||||
return arrays_are_the_same(Result_Arrays.true_bool_array, check_array_movement(array))
|
||||
|
||||
def arrays_are_the_same(array_0, array_1):
|
||||
differences = [row for row in array_0 if row not in array_1] + [row for row in array_1 if row not in array_0]
|
||||
return differences == []
|
||||
|
||||
# Main Script
|
||||
helper.init_idle()
|
||||
# 1) Open Level
|
||||
helper.open_level("Physics", "ScriptCanvas_OverlapNode")
|
||||
|
||||
# 2) Enter Game Mode
|
||||
helper.enter_game_mode(Tests.enter_game_mode)
|
||||
|
||||
# 3) Create Entity and Script_Canvas_Test Objects
|
||||
test_Sphere_Entities = create_test_Sphere_Entities()
|
||||
script_canvas_entity = Entity("Script_Canvas_Entity", True)
|
||||
comm_from_test_0 = Entity("Comm_From_Test_0", False)
|
||||
comm_from_test_1 = Entity("Comm_From_Test_1", False)
|
||||
comm_from_test_2 = Entity("Comm_From_Test_2", False)
|
||||
comm_to_test_0 = Entity("Comm_To_Test_0", False)
|
||||
comm_to_test_1 = Entity("Comm_To_Test_1", False)
|
||||
comm_to_test_2 = Entity("Comm_To_Test_2", False)
|
||||
comm_from_entity_list = (comm_from_test_0, comm_from_test_1, comm_from_test_2)
|
||||
comm_to_entity_list = (comm_to_test_0, comm_to_test_1, comm_to_test_2)
|
||||
|
||||
test_0 = Script_Canvas_Test(0)
|
||||
test_1 = Script_Canvas_Test(1)
|
||||
test_2 = Script_Canvas_Test(2)
|
||||
test_list = (test_0, test_1, test_2)
|
||||
|
||||
# 4) Validate Entities
|
||||
Report.critical_result(Tests.script_canvas_entity_found, script_canvas_entity.id.isValid())
|
||||
Report.critical_result(
|
||||
Tests.comm_entities_found, check_comm_entities(comm_from_entity_list + comm_to_entity_list)
|
||||
)
|
||||
Report.critical_result(Tests.test_array_found, sphere_array_isvalid(test_Sphere_Entities))
|
||||
|
||||
# 5) Begin Testing
|
||||
for test in test_list:
|
||||
# 6) Signal Script Canvas to begin test
|
||||
comm_from_entity_list[test.index].activate_entity()
|
||||
test.report_test_start()
|
||||
|
||||
# 7) Wait until script canvas signals that it has completed the test
|
||||
comm_to_entity_list[test.index].set_handler()
|
||||
test.report_test_finished(helper.wait_for_condition(lambda: comm_to_entity_list[test.index].activated, TIMEOUT))
|
||||
|
||||
# 8) Check which entities in array have been moved
|
||||
result_bool_array = check_array_movement(test_Sphere_Entities)
|
||||
|
||||
# 9) Validate and log results of test
|
||||
test.got_expected_result = arrays_are_the_same(
|
||||
result_bool_array, Result_Arrays.__dict__["test_{}_bool_array".format(test.index)]
|
||||
)
|
||||
test.report_results_logged()
|
||||
|
||||
if test.index == 0:
|
||||
Report.info(result_bool_array)
|
||||
|
||||
# 10) Place all entities back into correct positions in entity array
|
||||
reset_array(test_Sphere_Entities)
|
||||
test.report_test_array_reset(is_array_in_position(test_Sphere_Entities))
|
||||
|
||||
# 11) Log results of all tests
|
||||
Report.result(
|
||||
Tests.all_tests_passed, test_0.got_expected_result and test_1.got_expected_result and test_2.got_expected_result
|
||||
)
|
||||
|
||||
# 12) Exit Game Mode
|
||||
helper.exit_game_mode(Tests.exit_game_mode)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(ScriptCanvas_OverlapNode)
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
"""
|
||||
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 : C14902098
|
||||
# Test Case Title : Check that force region simulation with Postsimulate works independently from rendering tick
|
||||
|
||||
|
||||
|
||||
# fmt: off
|
||||
class Tests():
|
||||
enter_game_mode = ("Entered game mode", "Failed to enter game mode")
|
||||
find_sphere = ("Sphere found", "Sphere not found")
|
||||
find_force_region = ("Force Region is found", "Force Region is not found")
|
||||
exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
|
||||
# fmt: on
|
||||
|
||||
|
||||
class LogLines:
|
||||
"""
|
||||
These lines are added to the expected lines in the test suite.
|
||||
"""
|
||||
|
||||
expected_lines = [
|
||||
"OnTick Event: The Sphere position did not change from previous position",
|
||||
"OnTick Event: The Sphere position changed from previous position",
|
||||
"OnPostPhysicsSubtick Event: The Sphere position changed from previous position",
|
||||
]
|
||||
unexpected_lines = ["OnPostPhysicsSubtick Event: The Sphere position did not change from previous position"]
|
||||
|
||||
|
||||
def ScriptCanvas_PostPhysicsUpdate():
|
||||
|
||||
"""
|
||||
Summary:
|
||||
Check that force region simulation with Postsimulate works independently from rendering tick.
|
||||
|
||||
Level Description:
|
||||
A Sphere is placed inside a Force Region. The "Fixed Time Step" in PhysX Configuration is set to 0.05.
|
||||
ForceRegion (entity) - Entity with PhysX Collider, PhysX Force Region (World Space force with magnitude 5.0) and
|
||||
Box Shape components
|
||||
Sphere (entity) - Entity with PhysX Rigid Body, PhysX Collider, Mesh and 2 Script Canvas components
|
||||
Script Canvas:
|
||||
onpostphysicsupdate - The script checks the position of the sphere on every On Postsimulate event and prints
|
||||
debug statements as per the position of the sphere relative to its previous position.
|
||||
ontick - The script checks the position of the sphere on every On Tick event and prints
|
||||
debug statements as per the position of the sphere relative to its previous position.
|
||||
|
||||
Expected Behavior:
|
||||
The position of the sphere needs to be changed relative to its previous position for every
|
||||
OnPostPhysicsSubtick event.
|
||||
The position of the sphere sometimes change and sometimes remains in the same position as before
|
||||
for OnTick event.
|
||||
|
||||
Test Steps:
|
||||
1) Open level
|
||||
2) Enter game mode
|
||||
3) Retrieve and validate entities
|
||||
4) Wait for WAIT_TIME for the events to occur
|
||||
5) Exit game mode
|
||||
6) Close the 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
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
# Constants
|
||||
WAIT_TIME = 0.5
|
||||
|
||||
helper.init_idle()
|
||||
# 1) Open level
|
||||
helper.open_level("Physics", "ScriptCanvas_PostPhysicsUpdate")
|
||||
|
||||
# 2) Enter game mode
|
||||
helper.enter_game_mode(Tests.enter_game_mode)
|
||||
|
||||
# 3) Retrieve and validate entities
|
||||
sphere_id = general.find_game_entity("Sphere")
|
||||
Report.critical_result(Tests.find_sphere, sphere_id.IsValid())
|
||||
force_region_id = general.find_game_entity("ForceRegion")
|
||||
Report.critical_result(Tests.find_force_region, force_region_id.IsValid())
|
||||
|
||||
# 4) Wait for WAIT_TIME for the events to occur
|
||||
general.idle_wait(WAIT_TIME)
|
||||
|
||||
# 5) Exit game mode
|
||||
helper.exit_game_mode(Tests.exit_game_mode)
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(ScriptCanvas_PostPhysicsUpdate)
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
"""
|
||||
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 : C14195074
|
||||
# Test Case Title : Verify Postsimulate 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 is not 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 ScriptCanvas_PostUpdateEvent():
|
||||
"""
|
||||
Summary: Verifies that Postsimulate Event 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 - After every PhysX frame is calculated Follow_Sphere is moved to directly next to the
|
||||
Lead_sphere before being presented in 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, staying within direct contact no matter the speed
|
||||
|
||||
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
|
||||
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 = sys.float_info.epsilon
|
||||
TIMEOUT = 5
|
||||
INITIAL_OFFSET = 1
|
||||
REQUIRED_MOVEMENT = 2
|
||||
LEAD_SPHERE_VELOCITY = 10.0
|
||||
FINAL_OFFSET = INITIAL_OFFSET
|
||||
|
||||
# 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) < FLOAT_THRESHOLD
|
||||
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", "ScriptCanvas_PostUpdateEvent")
|
||||
|
||||
# 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 Spheres
|
||||
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()
|
||||
|
||||
# 10) Exit Game Mode
|
||||
helper.exit_game_mode(Tests.exit_game_mode)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(ScriptCanvas_PostUpdateEvent)
|
||||
+191
@@ -0,0 +1,191 @@
|
||||
"""
|
||||
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 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
|
||||
|
||||
|
||||
|
||||
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", "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__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(ScriptCanvas_PreUpdateEvent)
|
||||
+219
@@ -0,0 +1,219 @@
|
||||
"""
|
||||
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 : C14976308
|
||||
# Title : Verify that SetKinematicTarget on PhysX rigid body updates transform for kinematic entities and vice versa
|
||||
|
||||
|
||||
|
||||
# fmt: off
|
||||
class Tests:
|
||||
enter_game_mode = ("Entered game mode", "Failed to enter game mode")
|
||||
sphere_found_valid = ("Sphere found and validated", "Sphere not found and validated")
|
||||
kinematic_target_found_valid = ("Kinematic_Target found and validated", "Kinematic_Target not found and validated")
|
||||
transform_target_found_valid = ("Transform_Target found and validated", "Transform_Target not found and validated")
|
||||
signal_found_valid = ("Signal found and validated", "Signal not found and validated")
|
||||
sphere_gravity_disabled = ("Gravity is disabled on Sphere", "Gravity is not disabled on Sphere")
|
||||
sphere_kinematic = ("Sphere is kinematic", "Sphere is not kinematic")
|
||||
entity_translations_differ = ("Each entity has a different initial translation", "Each entity does not have a different initial translation")
|
||||
entity_rotations_differ = ("Each entity has a different initial rotation", "Each entity does not have a different initial rotation")
|
||||
entity_scales_differ = ("Each entity has a different initial scale", "Each entity does not have a different initial scale")
|
||||
sphere_translation_1_valid = ("Set Kinematic Target updated Sphere's translation to the new value", "Set Kinematic Target failed to update Sphere's translation to the new value")
|
||||
sphere_rotation_1_valid = ("Set Kinematic Target updated Sphere's rotation to the new value", "Set Kinematic Target failed to update Sphere's rotation to the new value")
|
||||
sphere_transform_2_valid = ("Set World Transform updated Sphere's transform to the new value", "Set World Transform failed to update Sphere's transform to the new value")
|
||||
exit_game_mode = ("Exited game mode", "Failed to exit game mode")
|
||||
# fmt: on
|
||||
|
||||
|
||||
def ScriptCanvas_SetKinematicTargetTransform():
|
||||
"""
|
||||
Summary:
|
||||
This script runs an automated test to verify the results of two Script Canvas nodes acting on a kinematic rigid
|
||||
body:
|
||||
1) Set Kinematic Target will update the kinematic rigid body's translation and rotation to those of the transform
|
||||
which the node passes to it.
|
||||
2) Set World Transform will update a kinematic rigid body's transform to the transform which the node passes to it.
|
||||
|
||||
Level Description:
|
||||
Entity: Sphere: PhysX Rigid Body, PhysX Collider with sphere shape, and Mesh with sphere asset
|
||||
Gravity disabled, kinematic enabled
|
||||
Translate (79.0, 39.0, 34.0) in meters
|
||||
Rotate (1.0, 2.0, 3.0) in degrees
|
||||
Scale (1.0, 1.0, 1.0)
|
||||
Entity: Kinematic_Target: Mesh with cube asset
|
||||
Translate (48.0, 56.0, 36.0) in meters
|
||||
Rotate (11.0, 12.0, 13.0) in degrees
|
||||
Scale (1.1, 1.2, 1.3)
|
||||
Entity: Transform_Target: Mesh with cube asset
|
||||
Translate (72.0, 80.0, 38.0) in meters
|
||||
Rotate (21.0, 22.0, 23.0) in degrees
|
||||
Scale (2.1, 2.2, 2.3)
|
||||
Entity: Signal: Start inactive, attached Script Canvas asset which will cause the following:
|
||||
On Signal Activated will Set Kinematic Target on Sphere to Kinematic_Target's transform
|
||||
On Signal Deactivated will Set World Transform on Sphere to Transform_Target's transform
|
||||
Other than the signal, the entities all have different translations, rotations, and scales.
|
||||
|
||||
Expected behavior:
|
||||
When the script activates Signal, Sphere's translation and rotation will update to those of Kinematic_Target. When
|
||||
the script deactivates Signal, Sphere's transform will update to that of Transform_Target.
|
||||
NOTE: There is a known bug (LY-107723) which causes the rotation to update to a value that is not sufficiently close
|
||||
to the expected result when using Set Kinematic Target which will cause the test to fail:
|
||||
LY-107723
|
||||
|
||||
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 is kinematic
|
||||
5) Check that each entity except the signal has a different initial translation
|
||||
6) Check that each entity except the signal has a different initial rotation
|
||||
7) Check that each entity except the signal has a different initial scale
|
||||
8) Activate the signal entity to trigger the Set Kinematic Target node in Script Canvas
|
||||
9) Wait one frame and check that the sphere's translation has updated to that of Kinematic_Target
|
||||
10) Check that the sphere's rotation has updated to that of Kinematic_Target
|
||||
11) Deactivate the signal entity to trigger the Set World Transform node in Script Canvas
|
||||
12) Check that the sphere's transform has updated to that of Transform_Target
|
||||
13) 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.math
|
||||
import azlmbr.physics
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
import itertools
|
||||
|
||||
class Entity:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.id = general.find_game_entity(name)
|
||||
self.found_valid_test = Tests.__dict__[self.name.lower() + "_found_valid"]
|
||||
Report.critical_result(self.found_valid_test, self.id.IsValid())
|
||||
|
||||
def is_gravity_disabled(self):
|
||||
return not azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "IsGravityEnabled", self.id)
|
||||
|
||||
def is_kinematic(self):
|
||||
return azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "IsKinematic", self.id)
|
||||
|
||||
def get_world_transform(self):
|
||||
transform = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTM", self.id)
|
||||
Report.info_vector3(transform.position, "{}'s position:".format(self.name))
|
||||
Report.info_vector3(transform.basisX, "{}'s basisX:".format(self.name))
|
||||
Report.info_vector3(transform.basisY, "{}'s basisY:".format(self.name))
|
||||
Report.info_vector3(transform.basisZ, "{}'s basisZ:".format(self.name))
|
||||
return transform
|
||||
|
||||
def get_world_translation(self):
|
||||
translation = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
|
||||
Report.info_vector3(translation, "{}'s Translation:".format(self.name))
|
||||
return translation
|
||||
|
||||
def get_world_rotation(self):
|
||||
rotation = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldRotation", self.id)
|
||||
Report.info_vector3(rotation, "{}'s Rotation:".format(self.name))
|
||||
return rotation
|
||||
|
||||
def get_world_scale(self):
|
||||
scale = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldScale", self.id)
|
||||
Report.info_vector3(scale, "{}'s Scale:".format(self.name))
|
||||
return scale
|
||||
|
||||
def transform_matches(self, other):
|
||||
return self.get_world_transform().Equal(other.get_world_transform())
|
||||
|
||||
def translation_matches(self, other):
|
||||
return self.get_world_translation().Equal(other.get_world_translation())
|
||||
|
||||
def rotation_matches(self, other):
|
||||
return self.get_world_rotation().Equal(other.get_world_rotation())
|
||||
|
||||
def scale_matches(self, other):
|
||||
return self.get_world_scale().Equal(other.get_world_scale())
|
||||
|
||||
def entities_translations_differ(entities):
|
||||
for entity_a, entity_b in itertools.combinations(entities, 2):
|
||||
if entity_a.translation_matches(entity_b):
|
||||
return False
|
||||
return True
|
||||
|
||||
def entities_rotations_differ(entities):
|
||||
for entity_a, entity_b in itertools.combinations(entities, 2):
|
||||
if entity_a.rotation_matches(entity_b):
|
||||
return False
|
||||
return True
|
||||
|
||||
def entities_scales_differ(entities):
|
||||
for entity_a, entity_b in itertools.combinations(entities, 2):
|
||||
if entity_a.scale_matches(entity_b):
|
||||
return False
|
||||
return True
|
||||
|
||||
# 1) Open level and enter game mode
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "ScriptCanvas_SetKinematicTargetTransform")
|
||||
helper.enter_game_mode(Tests.enter_game_mode)
|
||||
|
||||
# 2) Retrieve and validate entities
|
||||
sphere = Entity("Sphere")
|
||||
kinematic_target = Entity("Kinematic_Target")
|
||||
transform_target = Entity("Transform_Target")
|
||||
signal = Entity("Signal")
|
||||
non_signal_entities = (sphere, kinematic_target, transform_target)
|
||||
|
||||
# 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 is kinematic
|
||||
Report.critical_result(Tests.sphere_kinematic, sphere.is_kinematic())
|
||||
|
||||
# 5) Check that each entity except the signal has a different initial translation
|
||||
Report.critical_result(Tests.entity_translations_differ, entities_translations_differ(non_signal_entities))
|
||||
|
||||
# 6) Check that each entity except the signal has a different initial rotation
|
||||
Report.critical_result(Tests.entity_rotations_differ, entities_rotations_differ(non_signal_entities))
|
||||
|
||||
# 7) Check that each entity except the signal has a different initial scale
|
||||
Report.critical_result(Tests.entity_scales_differ, entities_scales_differ(non_signal_entities))
|
||||
|
||||
# 8) Activate the signal entity to trigger the Set Kinematic Target node in Script Canvas
|
||||
azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "ActivateGameEntity", signal.id)
|
||||
|
||||
# 9) Wait one frame and check that the sphere's translation has updated to that of Kinematic_Target
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.sphere_translation_1_valid, sphere.translation_matches(kinematic_target))
|
||||
|
||||
# 10) Check that the sphere's rotation has updated to that of Kinematic_Target
|
||||
# NOTE: This test currently fails due to a known bug (LY-107723)
|
||||
Report.result(Tests.sphere_rotation_1_valid, sphere.rotation_matches(kinematic_target))
|
||||
|
||||
# 11) Deactivate the signal entity to trigger the Set World Transform node in Script Canvas
|
||||
azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "DeactivateGameEntity", signal.id)
|
||||
|
||||
# 12) Check that the sphere's transform has updated to that of Transform_Target
|
||||
Report.result(Tests.sphere_transform_2_valid, sphere.transform_matches(transform_target))
|
||||
|
||||
# 13) 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(ScriptCanvas_SetKinematicTargetTransform)
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
"""
|
||||
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 : C12712455
|
||||
# Test Case Title : Verify shape cast nodes in SC
|
||||
|
||||
|
||||
# fmt: off
|
||||
class Tests:
|
||||
enter_game_mode = ("Entered game mode", "Failed to enter game mode")
|
||||
Ball_0_found = ("Ball_0 entity is found", "Ball_0 entity is not found")
|
||||
Ball_1_found = ("Ball_1 entity is found", "Ball_1 entity is not found")
|
||||
Notification_Entity_0_found = ("Notification_Entity_0 entity found", "Notification_Entity_0 entity invalid")
|
||||
Notification_Entity_1_found = ("Notification_Entity_1 entity found", "Notification_Entity_1 entity invalid")
|
||||
Notification_Entity_2_found = ("Notification_Entity_2 entity found", "Notification_Entity_2 entity invalid")
|
||||
Ball_0_gravity = ("Ball_0 gravity is disabled", "Ball_0 gravity is enabled")
|
||||
Ball_1_gravity = ("Ball_1 gravity is disabled", "Ball_1 gravity is enabled")
|
||||
Notification_Entity_0_gravity = ("Notification_Entity_0 gravity disabled", "Notification_Entity_0 gravity enabled")
|
||||
Notification_Entity_1_gravity = ("Notification_Entity_1 gravity disabled", "Notification_Entity_1 gravity enabled")
|
||||
Notification_Entity_2_gravity = ("Notification_Entity_2 gravity disabled", "Notification_Entity_2 gravity enabled")
|
||||
script_canvas_translation_node = ("Script canvas through translation node", "Script canvas failed translation node")
|
||||
script_canvas_sphere_cast_node = ("Script canvas through sphere cast node", "Script canvas failed sphere cast node")
|
||||
script_canvas_draw_sphere_node = ("Script canvas through draw sphere node", "Script canvas failed draw sphere node")
|
||||
exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
|
||||
# fmt: on
|
||||
|
||||
|
||||
def ScriptCanvas_ShapeCast():
|
||||
"""
|
||||
Summary: Verifies that shape cast nodes in script editor function properly.
|
||||
|
||||
Level Description:
|
||||
Ball_0 - Starts stationary with gravity disabled on -y axis from Ball_1; has Sphere shape collider, Rigid Body,
|
||||
Sphere Shape, Script Canvas
|
||||
Ball_1 - Starts stationary with gravity disabled on +y axis from Ball_0; has Sphere shape collider, Rigid Body,
|
||||
Sphere Shape
|
||||
Notification_Entity_0 - Starts stationary with gravity disabled; has rigid body, Sphere shape
|
||||
Notification_Entity_1 - Starts stationary with gravity disabled; has rigid body, Sphere shape
|
||||
Notification_Entity_2 - Starts stationary with gravity disabled; has rigid body, Sphere shape
|
||||
Script Canvas - Creates a sphere cast from Ball_0 to Ball_1 and draws the sphere in. As the script progresses
|
||||
through the translation, sphere cast, and sphere draw nodes it enables gravity on the spheres in order to
|
||||
show that each node has been passed.
|
||||
|
||||
Expected Behavior: A sphere will be drawn on ball_1 in from ball_0. The three notification_entities will fall as
|
||||
gravity is enabled on them in order.
|
||||
|
||||
Test Steps:
|
||||
1) Open Level
|
||||
2) Enter Game Mode
|
||||
3) Create entity objects
|
||||
4) Verify entities and check gravity
|
||||
5) Wait for conditions or timeout
|
||||
6) Log results
|
||||
7) Exit Game Mode
|
||||
8) 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
|
||||
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
|
||||
|
||||
# Helper Functions
|
||||
class Entity:
|
||||
# Constants
|
||||
GRAVITY_WAIT_TIMEOUT = 1
|
||||
|
||||
def __init__(self, name, expected_initial_velocity=None, expected_final_velocity=None):
|
||||
self.id = general.find_game_entity(name)
|
||||
self.name = name
|
||||
self.gravity_was_enabled = False
|
||||
self.handler = None
|
||||
# 4) Verify entities and check gravity
|
||||
try:
|
||||
self.found_test = Tests.__dict__[self.name + "_found"]
|
||||
self.gravity_disabled_test = Tests.__dict__[self.name + "_gravity"]
|
||||
except Exception as e:
|
||||
Report.info("Can not find specified tuples in Tests class")
|
||||
Report.info(e)
|
||||
raise ValueError
|
||||
Report.critical_result(self.found_test, self.id.isValid())
|
||||
gravity_enabled = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "IsGravityEnabled", self.id)
|
||||
Report.critical_result(self.gravity_disabled_test, not gravity_enabled)
|
||||
|
||||
def check_gravity_enabled(self):
|
||||
self.gravity_was_enabled = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "IsGravityEnabled", self.id)
|
||||
return self.gravity_was_enabled
|
||||
|
||||
def wait_for_gravity_enabled(self):
|
||||
helper.wait_for_condition(self.check_gravity_enabled, Entity.GRAVITY_WAIT_TIMEOUT)
|
||||
|
||||
# Main Script
|
||||
helper.init_idle()
|
||||
# 1) Open Level
|
||||
helper.open_level("Physics", "ScriptCanvas_ShapeCast")
|
||||
|
||||
# 2) Enter Game Mode
|
||||
helper.enter_game_mode(Tests.enter_game_mode)
|
||||
|
||||
# 3) Create entity objects
|
||||
ball_0 = Entity("Ball_0")
|
||||
ball_1 = Entity("Ball_1")
|
||||
notification_entity_0 = Entity("Notification_Entity_0")
|
||||
notification_entity_1 = Entity("Notification_Entity_1")
|
||||
notification_entity_2 = Entity("Notification_Entity_2")
|
||||
|
||||
# 5) Wait for conditions or timeout
|
||||
notification_list = [notification_entity_0, notification_entity_1, notification_entity_2]
|
||||
for entity in notification_list:
|
||||
entity.wait_for_gravity_enabled()
|
||||
|
||||
# 6) Log results
|
||||
Report.result(Tests.script_canvas_translation_node, notification_entity_0.gravity_was_enabled)
|
||||
Report.result(Tests.script_canvas_sphere_cast_node, notification_entity_1.gravity_was_enabled)
|
||||
Report.result(Tests.script_canvas_draw_sphere_node, notification_entity_2.gravity_was_enabled)
|
||||
|
||||
# 7) Exit Game Mode
|
||||
helper.exit_game_mode(Tests.exit_game_mode)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(ScriptCanvas_ShapeCast)
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
"""
|
||||
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 : C6224408
|
||||
# Test Case Title : Entity using PhysX nodes in Script Canvas can be spawned.
|
||||
|
||||
|
||||
# fmt: off
|
||||
class Tests:
|
||||
enter_game_mode = ("Entered game mode", "Failed to enter game mode")
|
||||
spawn_point_position = ("Spawn_Point is above the terrain", "Spawn_Point is below the terrain")
|
||||
Ball_0_found = ("Ball_0 entity is valid", "Ball_0 entity is not valid")
|
||||
Spawn_Point_found = ("Spawn_Point entity is valid", "Spawn_Point entity is not valid")
|
||||
Terrain_found = ("Terrain entity is valid", "Terrain entity is not valid")
|
||||
ball_spawned = ("A ball has been spawned", "A ball has not been spawned")
|
||||
exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
|
||||
|
||||
# fmt: on
|
||||
|
||||
|
||||
def ScriptCanvas_SpawnEntityWithPhysComponents():
|
||||
"""
|
||||
Summary:
|
||||
A spawner is set to spawn a sphere with downward velocity after a set amount of time. This action is controlled
|
||||
by a scriptcanvas.
|
||||
|
||||
Level Description:
|
||||
Ball_0 - Existing only for user reference, a dynamic slice is taken from Ball_0 and used by the Spawn_point entity.
|
||||
Is set with velocity in the negative -z direction; has sphere shaped Collider, Rigid Body, Sphere shape, and
|
||||
Script Canvas (can be placed anywhere on the level). Velocity set to zero and script canvas added after dynamic
|
||||
slice taken.
|
||||
Spawn_Point - Activated by the associated Script canvas to spawn the associated dynamic slice; has spawner
|
||||
Terrain - Surface for spawned ball to bounce against; has terrain
|
||||
|
||||
Script Canvas - The script canvas after a delay of 0.5 seconds tells the Spawn_Point entity to spawn.
|
||||
|
||||
Expected Behavior:
|
||||
After a set amount of time dictated by the script canvas a ball will spawn and collide with the terrain component.
|
||||
|
||||
Test Steps:
|
||||
1) Open Level
|
||||
2) Enter Game Mode
|
||||
3) Initialize and validate entities
|
||||
4) Set up handler for terrain collision
|
||||
5) Wait for terrain collision
|
||||
6) Log Results
|
||||
7) Exit Game Mode
|
||||
8) 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
|
||||
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
|
||||
import azlmbr.entity
|
||||
|
||||
# Constants
|
||||
FLOAT_THRESHOLD = sys.float_info.epsilon
|
||||
TIMEOUT = 3.0
|
||||
|
||||
# Global Variables
|
||||
id_list = []
|
||||
|
||||
# Helper Functions
|
||||
class Collision:
|
||||
collision_on_terrain = False
|
||||
|
||||
class Entity:
|
||||
def __init__(self, name, has_rigid_body):
|
||||
self.id = general.find_game_entity(name)
|
||||
self.name = name
|
||||
self.initial_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
|
||||
id_list.append(self.id)
|
||||
|
||||
class Tests:
|
||||
found = None
|
||||
|
||||
def validate_entity(self):
|
||||
self.Tests.found = Tests.__dict__[self.name + "_found"]
|
||||
Report.critical_result(self.Tests.found, self.id.isValid())
|
||||
|
||||
def spawn_point_position_check(spawn_point, terrain):
|
||||
position_valid = (
|
||||
spawn_point.initial_position.z > terrain.initial_position.z
|
||||
)
|
||||
Report.critical_result(Tests.spawn_point_position, position_valid)
|
||||
|
||||
def on_terrain_collision(arg):
|
||||
if arg[0] not in id_list: # ensures that the collision is with a new entity
|
||||
Collision.collision_on_terrain = True
|
||||
Report.info("Something new has collided with the Terrain")
|
||||
|
||||
# Main Script
|
||||
helper.init_idle()
|
||||
# 1) Open Level
|
||||
helper.open_level("physics", "ScriptCanvas_SpawnEntityWithPhysComponents")
|
||||
|
||||
# 2) Enter Game Mode
|
||||
helper.enter_game_mode(Tests.enter_game_mode)
|
||||
|
||||
# 3) Initialize and validated entities
|
||||
ball_0 = Entity("Ball_0", True)
|
||||
spawn_point = Entity("Spawn_Point", False)
|
||||
terrain = Entity("Terrain", False)
|
||||
|
||||
entity_list = [ball_0, spawn_point, terrain]
|
||||
for entity in entity_list:
|
||||
entity.validate_entity()
|
||||
|
||||
spawn_point_position_check(spawn_point, terrain)
|
||||
|
||||
# 4) Set up handler for terrain collision
|
||||
handler = azlmbr.physics.CollisionNotificationBusHandler()
|
||||
handler.connect(terrain.id)
|
||||
handler.add_callback("OnCollisionBegin", on_terrain_collision)
|
||||
|
||||
# 5) Wait for terrain collision
|
||||
helper.wait_for_condition(lambda: Collision.collision_on_terrain, TIMEOUT)
|
||||
|
||||
# 6) Log Results
|
||||
Report.result(Tests.ball_spawned, Collision.collision_on_terrain)
|
||||
|
||||
# 7) Exit Game Mode
|
||||
helper.exit_game_mode(Tests.exit_game_mode)
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(ScriptCanvas_SpawnEntityWithPhysComponents)
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
"""
|
||||
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 : C6274125
|
||||
# Test Case Title : Verify ScriptCanvas Trigger Events.
|
||||
|
||||
|
||||
|
||||
# fmt: off
|
||||
class Tests():
|
||||
enter_game_mode = ("Entered game mode", "Failed to enter game mode")
|
||||
find_box = ("Box entity found", "Box entity not found")
|
||||
find_sphere = ("Sphere entity found", "Sphere entity not found")
|
||||
sphere_enter_triggerarea = ("Sphere entered the trigger area", "Sphere did not entered trigger area")
|
||||
sphere_exit_triggerarea = ("Sphere exited the trigger area", "Sphere did not exited the trigger area")
|
||||
exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
|
||||
# fmt: on
|
||||
|
||||
|
||||
class LogLines:
|
||||
"""
|
||||
These lines are added to the expected lines in the test suite.
|
||||
"""
|
||||
|
||||
expected_lines = [
|
||||
"Scriptcanvas:Sphere entered the trigger Area",
|
||||
"Scriptcanvas:Sphere exited the trigger Area",
|
||||
]
|
||||
|
||||
|
||||
def ScriptCanvas_TriggerEvents():
|
||||
"""
|
||||
Summary:
|
||||
Verify ScriptCanvas Trigger Events.
|
||||
|
||||
Level Description:
|
||||
BoxCollider (entity) - Entity contains PhysX Collider (Box shape) and trigger is enabled for it.
|
||||
ScriptCanvas is attached to the PhysX box shape collider entity. ScriptCanvas has two trigger events.
|
||||
ScriptCanvas trigger events are OnTriggerEnter and OnTriggerExit.
|
||||
Sphere (entity) - Entity contains PhysX Collider(Sphere shape) with PhysX Rigid Body.
|
||||
|
||||
Expected Behavior:
|
||||
When game mode is entered, Sphere should enter and exit from ScriptCanvas Trigger area. ScriptCanvas prints
|
||||
the name of the entity when it enters and exits the ScriptCanvas trigger area.
|
||||
|
||||
Test Steps:
|
||||
1) Open level
|
||||
2) Enter game mode
|
||||
3) Retrieve and validate entities
|
||||
4) Verify Sphere enter and exit from ScriptCanvas Trigger area
|
||||
5) Exit game mode
|
||||
6) Close the 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 azlmbr.legacy.general as general
|
||||
import azlmbr.bus
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
helper.init_idle()
|
||||
|
||||
# Constants
|
||||
TIMEOUT = 2.5
|
||||
|
||||
# 1) Open level
|
||||
helper.open_level("Physics", "ScriptCanvas_TriggerEvents")
|
||||
|
||||
# 2) Enter game mode
|
||||
helper.enter_game_mode(Tests.enter_game_mode)
|
||||
|
||||
# 3) Retrieve and validate entities
|
||||
box_id = general.find_game_entity("Box")
|
||||
Report.critical_result(Tests.find_box, box_id.IsValid())
|
||||
|
||||
sphere_id = general.find_game_entity("Sphere")
|
||||
Report.critical_result(Tests.find_sphere, sphere_id.IsValid())
|
||||
|
||||
# 4) Verify Sphere enter and exit from ScriptCanvas Trigger area
|
||||
class BoxTrigger:
|
||||
entered = False
|
||||
exited = False
|
||||
|
||||
def on_enter(args):
|
||||
other_id = args[0]
|
||||
if other_id.Equal(sphere_id):
|
||||
Report.info("Trigger entered")
|
||||
BoxTrigger.entered = True
|
||||
|
||||
def on_exit(args):
|
||||
other_id = args[0]
|
||||
if other_id.Equal(sphere_id):
|
||||
Report.info("Trigger exited")
|
||||
BoxTrigger.exited = True
|
||||
|
||||
handler = azlmbr.physics.TriggerNotificationBusHandler()
|
||||
handler.connect(box_id)
|
||||
handler.add_callback("OnTriggerEnter", on_enter)
|
||||
handler.add_callback("OnTriggerExit", on_exit)
|
||||
|
||||
helper.wait_for_condition(lambda: BoxTrigger.entered, TIMEOUT)
|
||||
Report.result(Tests.sphere_enter_triggerarea, BoxTrigger.entered)
|
||||
helper.wait_for_condition(lambda: BoxTrigger.exited, TIMEOUT)
|
||||
Report.result(Tests.sphere_exit_triggerarea, BoxTrigger.exited)
|
||||
|
||||
# 5) Exit game mode
|
||||
helper.exit_game_mode(Tests.exit_game_mode)
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(ScriptCanvas_TriggerEvents)
|
||||
Reference in New Issue
Block a user