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.
310 lines
15 KiB
Python
310 lines
15 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 : C4044697
|
|
# Test Case Title : Verify that each surface picks up the material assigned to it and behaves accordingly.
|
|
|
|
|
|
# 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")
|
|
initial_orientaition_valid = ("Initial entity orientation valid", "Initial entity orientation not valid")
|
|
final_orientation_valid = ("Final entity orientation valid", "Final entity orientation not valid")
|
|
speed_comparision = ("Sphere 1 is faster than Sphere 2", "Sphere 1 is not faster than Sphere 2")
|
|
|
|
# Sphere 0
|
|
Sphere_0_found = ("Sphere 0 is valid", "Sphere 0 is not valid")
|
|
Sphere_0_position_found = ("Sphere 0 position is found", "Sphere 0 position is not found")
|
|
Sphere_0_velocity_found = ("Sphere 0 velocity is found", "Sphere 0 velocity is not found")
|
|
Sphere_0_velocity_valid = ("Sphere 0 velocity is valid", "Sphere 0 velocity is not valid")
|
|
Sphere_0_collided_with_perface = ("Sphere 0 collided w/Perface Entity", "Sphere 0 has not collided")
|
|
Sphere_0_final_velocity_valid = ("Sphere 0 final velocity is valid", "Sphere 0 final velocity is not valid")
|
|
|
|
# Sphere 1
|
|
Sphere_1_found = ("Sphere 1 is valid", "Sphere 1 is not valid")
|
|
Sphere_1_position_found = ("Sphere 1 position is found", "Sphere 1 position is not found")
|
|
Sphere_1_velocity_found = ("Sphere 1 velocity is found", "Sphere 1 velocity is not found")
|
|
Sphere_1_velocity_valid = ("Sphere 1 velocity is valid", "Sphere 1 velocity is not valid")
|
|
Sphere_1_collided_with_perface = ("Sphere 1 collided w/Perface Entity", "Sphere 1 has not collided")
|
|
Sphere_1_final_velocity_valid = ("Sphere 1 final velocity is valid", "Sphere 1 final velocity is not valid")
|
|
|
|
# Sphere 2
|
|
Sphere_2_found = ("Sphere 2 is valid", "Sphere 2 is not valid")
|
|
Sphere_2_position_found = ("Sphere 2 position is found", "Sphere 2 position is not found")
|
|
Sphere_2_velocity_found = ("Sphere 2 velocity is found", "Sphere 2 velocity is not found")
|
|
Sphere_2_velocity_valid = ("Sphere 2 velocity is valid", "Sphere 2 velocity is not valid")
|
|
Sphere_2_collided_with_perface = ("Sphere 2 collided w/Perface Entity", "Sphere 2 has not collided")
|
|
Sphere_2_final_velocity_valid = ("Sphere 2 final velocity is valid", "Sphere 2 final velocity is not valid")
|
|
|
|
# Perface Entity
|
|
Perface_Entity_found = ("Perface entity is valid", "Perface entity is not valid")
|
|
Perface_Entity_position_found = ("Perface entity position found", "Perface entity position not found")
|
|
|
|
# fmt: on
|
|
|
|
|
|
def C4044697_Material_PerfaceMaterialValidation():
|
|
"""
|
|
Summary: The perface has three different faces that can pick up different materials. To check that each face
|
|
picks up the material assigned to it I send three spheres of the same material at each face to see the
|
|
different reactions. If each sphere bounces away with the correct relative velocity it can be assumed
|
|
that the Perface entity is picking up the materials properly.
|
|
|
|
Level Description:
|
|
Perface Entity - The perface entity is an entity with a custom mesh that allows for multiple materials to be
|
|
applied to different parts of the mesh. In this case there seems to be three different areas of the mesh
|
|
that can be assigned with different materials and interacted. One of three spheres is lined up to interact
|
|
with one of each of the three areas. The mesh is included in the level "test.fbx". The entity is stationary
|
|
with three spheres inline along the x and y axis: has a PhysX collider and a Mesh component.
|
|
Sphere 0 - This entity is inline with the perface entity on the y axis and heading torward it with a velocity in
|
|
the -y direction: has a sphere shaped PhysX Collider, a PhysX Rigid Body, and a Sphere Shape.
|
|
Sphere 1 - This entity is inline with the perface entity on the x axis and heading torward it with a velocity in
|
|
the -x direction: has a sphere shaped PhysX Collider, a PhysX Rigid Body, and a Sphere Shape.
|
|
Sphere 2 - This entity is inline with the perface entity on the x axis and heading torward it with a velocity in
|
|
the +x direction: has a sphere shaped PhysX Collider, a PhysX Rigid Body, and a Sphere Shape.
|
|
|
|
Materials:
|
|
Bounce - All three spheres and the Perface mesh area lined up with Sphere 1 have the Bounce material applied to
|
|
them. This material interacts with other materials by bouncing with the restitution factor of an average of
|
|
each entity that collides restitution value. Has restitution value: 1
|
|
PartialBounce - The Perface mesh area lined up with Sphere 2 has the partial bounce material applied. This material
|
|
interacts with other materials by responding with a restitution factor that is an average of the two materials
|
|
that interact. Has restitution value: 0
|
|
NoBounce - The Perface mesh area lined up with Sphere 0 have the NoBounce material. This material interacts with
|
|
other materials by bouncing with the restitution factor of the material with the lowest restitution value.
|
|
Has restitution value: 0
|
|
|
|
Expected Behavior: Sphere 0 will not bounce, Sphere 1 will bounce away from the Perface Entity faster than
|
|
Sphere 2 will.
|
|
|
|
Test Steps:
|
|
1) Open Level
|
|
2) Enter Game Mode
|
|
3) Create Entity objects
|
|
4) Iterate through all entities and validate them
|
|
5) Validate that Entities Exist
|
|
6) Iterate through each of the three spheres and test their bounces
|
|
7) Further evaluate that sphere entities exist
|
|
8) Validate Initial Positions and Velocities
|
|
9) Set up handler and wait for collision
|
|
10) Get and Validate Final Positions and Velocities
|
|
11) Log Results
|
|
12) Validate Orientations and Final Velocities
|
|
13) Exit Game Mode
|
|
14) 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.legacy.general as general
|
|
import azlmbr.bus
|
|
import azlmbr.math as math
|
|
|
|
# Constants
|
|
FLOAT_THRESHOLD = sys.float_info.epsilon
|
|
FINAL_VELOCITY_THRESHOLD = 0.01
|
|
STATIONARY_SPHERE_THRESHOLD = 2
|
|
TIMEOUT = 1.0
|
|
|
|
# Helper Functions
|
|
class Entity:
|
|
def __init__(self, name, expected_initial_velocity=None, expected_final_velocity=None):
|
|
self.id = general.find_game_entity(name)
|
|
self.name = name
|
|
self.EXPECTED_INITIAL_VELOCITY = expected_initial_velocity
|
|
self.EXPECTED_FINAL_VELOCITY = expected_final_velocity
|
|
self.initial_velocity = None
|
|
self.final_velocity = None
|
|
self.initial_position = None
|
|
self.final_position = None
|
|
self.collision_happened = False
|
|
self.handler = None
|
|
|
|
class Entity_Tests:
|
|
found = None
|
|
found_position = None
|
|
found_velocity = None
|
|
valid_init_velocity = None
|
|
valid_final_velocity = None
|
|
collision_happened = None
|
|
|
|
def check_id(self):
|
|
self.Entity_Tests.found = Tests.__dict__[self.name + "_found"]
|
|
Report.critical_result(self.Entity_Tests.found, self.id.isValid())
|
|
|
|
def activate_entity(self):
|
|
Report.info("Activating Entity : " + self.name)
|
|
azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "ActivateGameEntity", self.id)
|
|
|
|
def values_found(self):
|
|
self.Entity_Tests.found_position = Tests.__dict__[self.name + "_position_found"]
|
|
self.Entity_Tests.found_velocity = Tests.__dict__[self.name + "_velocity_found"]
|
|
|
|
Report.critical_result(self.Entity_Tests.found_position, vector_valid(self.initial_position, False))
|
|
Report.critical_result(self.Entity_Tests.found_velocity, vector_valid(self.initial_velocity, False))
|
|
|
|
def perface_values_found(self):
|
|
self.Entity_Tests.found_position = Tests.__dict__[self.name + "_position_found"]
|
|
Report.critical_result(self.Entity_Tests.found_position, vector_valid(self.initial_position, False))
|
|
|
|
def get_initial_position_and_velocity(self):
|
|
self.initial_velocity = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", self.id)
|
|
self.initial_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
|
|
|
|
def get_final_position_and_velocity(self):
|
|
self.final_velocity = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", self.id)
|
|
self.final_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
|
|
|
|
def validate_sphere_velocity(self):
|
|
if self.collision_happened:
|
|
velocity_valid = (
|
|
abs(self.final_velocity.x - self.EXPECTED_FINAL_VELOCITY.x) < FINAL_VELOCITY_THRESHOLD
|
|
and abs(self.final_velocity.y - self.EXPECTED_FINAL_VELOCITY.y) < FINAL_VELOCITY_THRESHOLD
|
|
and abs(self.final_velocity.z - self.EXPECTED_FINAL_VELOCITY.z) < FINAL_VELOCITY_THRESHOLD
|
|
)
|
|
self.Entity_Tests.valid_final_velocity = Tests.__dict__[self.name + "_final_velocity_valid"]
|
|
Report.result(self.Entity_Tests.valid_final_velocity, velocity_valid)
|
|
else:
|
|
velocity_valid = (
|
|
abs(self.initial_velocity.x - self.EXPECTED_INITIAL_VELOCITY.x) < FLOAT_THRESHOLD
|
|
and abs(self.initial_velocity.y - self.EXPECTED_INITIAL_VELOCITY.y) < FLOAT_THRESHOLD
|
|
and abs(self.initial_velocity.z - self.EXPECTED_INITIAL_VELOCITY.z) < FLOAT_THRESHOLD
|
|
)
|
|
self.Entity_Tests.valid_init_velocity = Tests.__dict__[self.name + "_velocity_valid"]
|
|
Report.critical_result(self.Entity_Tests.valid_init_velocity, velocity_valid)
|
|
|
|
def on_collision_begin(self, args):
|
|
if self.id.equal(args[0]):
|
|
self.collision_happened = True
|
|
|
|
def set_handler(self, id):
|
|
self.handler = azlmbr.physics.CollisionNotificationBusHandler()
|
|
self.handler.connect(id)
|
|
self.handler.add_callback("OnCollisionBegin", self.on_collision_begin)
|
|
|
|
def report_sphere_values(entity):
|
|
Report.info_vector3(entity.initial_position, "{} initial position: ".format(entity.name))
|
|
Report.info_vector3(entity.initial_velocity, "{} initial velocity: ".format(entity.name))
|
|
|
|
Report.info_vector3(entity.final_position, "{} final position: ".format(entity.name))
|
|
Report.info_vector3(entity.final_velocity, "{} final velocity: ".format(entity.name))
|
|
|
|
def report_perface_values(entity):
|
|
Report.info_vector3(entity.initial_position, "{} initial position: ".format(entity.name))
|
|
|
|
def validate_positions():
|
|
# Initial orientation is confirmed by z axis values, if there are further issues a collision
|
|
# will not as expected.
|
|
Report.info("Checking Initial Orientation")
|
|
initial_orientaition = (
|
|
sphere_0.initial_position.z
|
|
== sphere_1.initial_position.z
|
|
== sphere_2.initial_position.z
|
|
== perface_entity.initial_position.z
|
|
)
|
|
Report.result(Tests.initial_orientaition_valid, initial_orientaition)
|
|
# Final orientation is confirmed if Sphere 0 stopped next to the Perface Entity.
|
|
Report.info("Checking Final Orientation")
|
|
final_orientation = (
|
|
abs(perface_entity.final_position.x - sphere_0.final_position.x) < FLOAT_THRESHOLD
|
|
and abs(perface_entity.final_position.z - sphere_0.final_position.z) < FLOAT_THRESHOLD
|
|
and abs(perface_entity.final_position.y - sphere_0.final_position.y) < STATIONARY_SPHERE_THRESHOLD
|
|
)
|
|
|
|
Report.result(Tests.final_orientation_valid, final_orientation)
|
|
|
|
def vector_valid(vector, can_be_zero):
|
|
if can_be_zero:
|
|
return vector != None
|
|
else:
|
|
return vector != None and not vector.IsZero()
|
|
|
|
# Main Script
|
|
helper.init_idle()
|
|
# 1) Open Level
|
|
helper.open_level("Physics", "C4044697_Material_PerfaceMaterialValidation")
|
|
|
|
# 2) Enter Game Mode
|
|
helper.enter_game_mode(Tests.enter_game_mode)
|
|
|
|
# 3) Create entity objects
|
|
sphere_0 = Entity("Sphere_0", math.Vector3(0.0, -10.0, 0.0), math.Vector3(0.0, 0.0, 0.0))
|
|
sphere_1 = Entity("Sphere_1", math.Vector3(-10.0, 0.0, 0.0), math.Vector3(10.09, 1.85, 1.18))
|
|
sphere_2 = Entity("Sphere_2", math.Vector3(10.0, 0.0, 0.0), math.Vector3(-5.0, 0.0, 0.0))
|
|
perface_entity = Entity("Perface_Entity")
|
|
entity_list = [sphere_0, sphere_1, sphere_2, perface_entity]
|
|
spheres = [sphere_0, sphere_1, sphere_2]
|
|
|
|
# 4) Iterate through all entities and validate them
|
|
for entity in entity_list:
|
|
# 5) Validate that Entities Exist
|
|
entity.check_id()
|
|
# Extra steps for Perface Entity as it will no longer be iterated
|
|
perface_entity.get_initial_position_and_velocity()
|
|
perface_entity.perface_values_found()
|
|
perface_entity.get_final_position_and_velocity()
|
|
report_perface_values(perface_entity)
|
|
|
|
# 6) Iterate through each of the three spheres and test their bounces
|
|
for entity in spheres:
|
|
# 7) Further evaluate that sphere entities exist
|
|
entity.activate_entity()
|
|
entity.get_initial_position_and_velocity()
|
|
|
|
# 8) Validate Initial Positions and Velocities
|
|
entity.values_found()
|
|
entity.validate_sphere_velocity()
|
|
|
|
# 9) Set up handler and wait for collision
|
|
entity.set_handler(perface_entity.id)
|
|
|
|
# Wait for collision
|
|
helper.wait_for_condition(lambda: entity.collision_happened, TIMEOUT)
|
|
# Report Collision
|
|
entity.Entity_Tests.collision_happened = Tests.__dict__[entity.name + "_collided_with_perface"]
|
|
Report.result(entity.Entity_Tests.collision_happened, entity.collision_happened)
|
|
|
|
# 10) Get and Validate Final Positions and Velocities
|
|
entity.get_final_position_and_velocity()
|
|
entity.validate_sphere_velocity()
|
|
|
|
# 11) Log Results
|
|
report_sphere_values(entity)
|
|
|
|
# 12) Validate Orientations and Final Velocities
|
|
validate_positions()
|
|
Report.result(
|
|
Tests.speed_comparision, sphere_1.final_velocity.GetLength() > sphere_2.final_velocity.GetLength()
|
|
)
|
|
|
|
# 13) 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(C4044697_Material_PerfaceMaterialValidation)
|