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