ScriptCanvas_PostUpdateEvent.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. """
  2. Copyright (c) Contributors to the Open 3D Engine Project.
  3. For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. SPDX-License-Identifier: Apache-2.0 OR MIT
  5. """
  6. # Test case ID : C14195074
  7. # Test Case Title : Verify Postsimulate Events
  8. # fmt: off
  9. class Tests:
  10. enter_game_mode = ("Entered game mode", "Failed to enter game mode")
  11. exit_game_mode = ("Exited game mode", "Failed to exit game mode")
  12. lead_sphere_found = ("Lead_Sphere is valid", "Lead_Sphere is not valid")
  13. follow_sphere_found = ("Follow_Sphere is valid", "Follow_Sphere is not valid")
  14. no_movement = ("Spheres start with no movement", "Spheres not stationary")
  15. initial_position = ("Initial position is valid", "Initial position is not valid")
  16. lead_sphere_velocity = ("Lead_Sphere has valid velocity", "Lead_Sphere velocity not valid")
  17. spheres_moving = ("Spheres have both moved", "Both sphere have not moved before timeout")
  18. follow_condition_true = ("Follow_Sphere is correctly trailing", "Follow_Sphere follow distance not valid")
  19. # fmt: on
  20. def ScriptCanvas_PostUpdateEvent():
  21. """
  22. Summary: Verifies that Postsimulate Event node in Script Canvas works as expected.
  23. Level Description:
  24. Lead_Sphere - Directly next to Follow_sphere on the +x axis; has rigid body(gravity disabled), sphere shape
  25. collider, sphere shape
  26. Follow_Sphere - Directly next to Lead_Sphere on the -x axis; has rigid body (gravity disabled, kinematic
  27. enabled), sphere shape collider, sphere shape, script canvas
  28. Script Canvas - After every PhysX frame is calculated Follow_Sphere is moved to directly next to the
  29. Lead_sphere before being presented in the viewer
  30. PhysX Configuration - The PhysX configuration file was modified to lower the frame rate to 20 Hz for visual debug
  31. Expected Behavior: Follow_Sphere follows Lead_spheres position, staying within direct contact no matter the speed
  32. Test Steps:
  33. 1) Open Level
  34. 2) Enter Game Mode
  35. 3) Create and Validate entities
  36. 4) Validate spheres are not moving
  37. 5) Check Position of Spheres
  38. 6) Start moving sphere and check that it acts correctly
  39. 7) Wait until Lead_Sphere has moved a set distance
  40. 8) Verify Follow_Sphere follow distance
  41. 9) Log results
  42. 10) Exit Game Mode
  43. 11) Close Editor
  44. Note:
  45. - This test file must be called from the Open 3D Engine Editor command terminal
  46. - Any passed and failed tests are written to the Editor.log file.
  47. Parsing the file or running a log_monitor are required to observe the test results.
  48. :return: None
  49. """
  50. import os
  51. import sys
  52. from editor_python_test_tools.utils import Report
  53. from editor_python_test_tools.utils import TestHelper as helper
  54. import azlmbr
  55. import azlmbr.legacy.general as general
  56. import azlmbr.bus
  57. import azlmbr.math as math
  58. # Constants
  59. FLOAT_THRESHOLD = sys.float_info.epsilon
  60. TIMEOUT = 5
  61. INITIAL_OFFSET = 1
  62. REQUIRED_MOVEMENT = 2
  63. LEAD_SPHERE_VELOCITY = 10.0
  64. FINAL_OFFSET = INITIAL_OFFSET
  65. # Helper Functions
  66. class Entity:
  67. def __init__(self, name):
  68. self.id = general.find_game_entity(name)
  69. self.name = name
  70. self.initial_position = self.position
  71. self.final_position = None
  72. # Validate Entities
  73. found = Tests.__dict__[self.name.lower() + "_found"]
  74. Report.critical_result(found, self.id.isValid())
  75. @property
  76. def position(self):
  77. return azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
  78. @property
  79. def velocity(self):
  80. return azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", self.id)
  81. def set_velocity(self, x_velocity, y_velocity, z_velocity):
  82. velocity = math.Vector3(x_velocity, y_velocity, z_velocity)
  83. azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "SetLinearVelocity", self.id, velocity)
  84. def moved_enough(self):
  85. current_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
  86. return abs(self.initial_position.x - current_position.x) >= REQUIRED_MOVEMENT
  87. def report_values(self):
  88. Report.info_vector3(self.initial_position, "{} initial position: ".format(self.name))
  89. Report.info_vector3(self.final_position, "{} final position: ".format(self.name))
  90. def check_relative_position(lead_sphere_position, follow_sphere_position, offset):
  91. return (
  92. abs((lead_sphere_position.x - follow_sphere_position.x) - offset) < FLOAT_THRESHOLD
  93. and abs(lead_sphere_position.y - follow_sphere_position.y) < FLOAT_THRESHOLD
  94. and abs(lead_sphere_position.z - follow_sphere_position.z) < FLOAT_THRESHOLD
  95. )
  96. def velocity_zero(sphere_velocity):
  97. return (
  98. abs(sphere_velocity.x) < FLOAT_THRESHOLD
  99. and abs(sphere_velocity.y) < FLOAT_THRESHOLD
  100. and abs(sphere_velocity.z) < FLOAT_THRESHOLD
  101. )
  102. def velocity_valid(lead_sphere_velocity):
  103. return (
  104. lead_sphere_velocity.x == LEAD_SPHERE_VELOCITY
  105. and abs(lead_sphere_velocity.y) < FLOAT_THRESHOLD
  106. and abs(lead_sphere_velocity.z) < FLOAT_THRESHOLD
  107. )
  108. # Main Script
  109. helper.init_idle()
  110. # 1) Open Level
  111. helper.open_level("Physics", "ScriptCanvas_PostUpdateEvent")
  112. # 2) Enter Game Mode
  113. helper.enter_game_mode(Tests.enter_game_mode)
  114. # 3) Create and validate entities
  115. lead_sphere = Entity("Lead_Sphere")
  116. follow_sphere = Entity("Follow_Sphere")
  117. # 4) Validate Spheres are not moving
  118. Report.critical_result(
  119. Tests.no_movement, velocity_zero(lead_sphere.velocity) and velocity_zero(follow_sphere.velocity)
  120. )
  121. # 5) Check Position of Spheres
  122. Report.result(
  123. Tests.initial_position,
  124. check_relative_position(lead_sphere.initial_position, follow_sphere.initial_position, INITIAL_OFFSET),
  125. )
  126. # 6) Start moving sphere and check that it acts correctly
  127. lead_sphere.set_velocity(LEAD_SPHERE_VELOCITY, 0.0, 0.0)
  128. Report.result(Tests.lead_sphere_velocity, velocity_valid(lead_sphere.velocity))
  129. # 7) Wait until Lead_Sphere has moved a set distance
  130. Report.result(Tests.spheres_moving, helper.wait_for_condition(lead_sphere.moved_enough, TIMEOUT))
  131. # 8) Verify Follow_Sphere follow distance
  132. lead_sphere.final_position = lead_sphere.position
  133. follow_sphere.final_position = follow_sphere.position
  134. Report.result(
  135. Tests.follow_condition_true, check_relative_position(lead_sphere.final_position, follow_sphere.final_position, FINAL_OFFSET)
  136. )
  137. # 9) Log results
  138. lead_sphere.report_values()
  139. follow_sphere.report_values()
  140. # 10) Exit Game Mode
  141. helper.exit_game_mode(Tests.exit_game_mode)
  142. if __name__ == "__main__":
  143. from editor_python_test_tools.utils import Report
  144. Report.start_test(ScriptCanvas_PostUpdateEvent)