AnimationBus.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #pragma once
  9. #include <AzCore/EBus/EBus.h>
  10. #include <AzCore/Component/ComponentBus.h>
  11. #include <AzCore/Component/Entity.h>
  12. #include <AzCore/std/containers/array.h>
  13. #include <AzFramework/Physics/Common/PhysicsSceneQueries.h>
  14. namespace EMotionFX
  15. {
  16. class ActorInstance;
  17. class MotionInstance;
  18. namespace Integration
  19. {
  20. /**
  21. * EMotion FX System Request Bus
  22. * Used for making global requests to the EMotion FX system.
  23. */
  24. class SystemRequests
  25. : public AZ::EBusTraits
  26. {
  27. public:
  28. static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
  29. static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
  30. };
  31. using SystemRequestBus = AZ::EBus<SystemRequests>;
  32. /**
  33. * EMotion FX System Notification Bus
  34. * Used for monitoring EMotion FX system-level events.
  35. */
  36. class SystemNotifications
  37. : public AZ::EBusTraits
  38. {
  39. public:
  40. static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
  41. static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
  42. // Use this bus to register custom EMotionFX plugin.
  43. virtual void OnRegisterPlugin() = 0;
  44. };
  45. using SystemNotificationBus = AZ::EBus<SystemNotifications>;
  46. /**
  47. * Motion event descriptor.
  48. */
  49. struct MotionEvent
  50. {
  51. public:
  52. AZ_TYPE_INFO(MotionEvent, "{0C899DAC-6B19-4BDD-AD8C-8A11EF2A6729}");
  53. // Use fixed buffer for parameter string to avoid allocations for motion events, which can be sent at high frequency.
  54. enum { kMaxParameterStringLength = 64 - 1 };
  55. typedef AZStd::array<char, kMaxParameterStringLength + 1> ParameterStringStorage;
  56. ParameterStringStorage m_parameterStorage;
  57. AZ::EntityId m_entityId; ///< EntityId associated with the originating actor
  58. const char* m_parameter; ///< Optional string parameter
  59. EMotionFX::ActorInstance* m_actorInstance; ///< Pointer to the actor instance on which the event is playing
  60. const EMotionFX::MotionInstance* m_motionInstance; ///< Pointer to the motion instance from which the event was fired
  61. float m_time; ///< Time value of the event, in seconds
  62. AZ::u32 m_eventType; ///< Type Id of the event. m_eventTypeName stores the string representation.
  63. const char* m_eventTypeName; ///< Event type in string form
  64. float m_globalWeight; ///< Global weight of the event
  65. float m_localWeight; ///< Local weight of the event
  66. bool m_isEventStart; ///< Is this the start of a ranged event? This is always true for one-shot events.
  67. MotionEvent()
  68. : m_actorInstance(nullptr)
  69. , m_motionInstance(nullptr)
  70. , m_time(0.f)
  71. , m_eventType(0)
  72. , m_eventTypeName(nullptr)
  73. , m_globalWeight(0.f)
  74. , m_localWeight(0.f)
  75. , m_isEventStart(false)
  76. {
  77. m_parameterStorage[0] = '\0';
  78. m_parameter = m_parameterStorage.data();
  79. }
  80. MotionEvent(const MotionEvent& rhs)
  81. : m_actorInstance(rhs.m_actorInstance)
  82. , m_motionInstance(rhs.m_motionInstance)
  83. , m_time(rhs.m_time)
  84. , m_eventType(rhs.m_eventType)
  85. , m_eventTypeName(rhs.m_eventTypeName)
  86. , m_globalWeight(rhs.m_globalWeight)
  87. , m_localWeight(rhs.m_localWeight)
  88. , m_isEventStart(rhs.m_isEventStart)
  89. {
  90. m_parameterStorage = rhs.m_parameterStorage;
  91. m_parameter = m_parameterStorage.data();
  92. }
  93. void SetParameterString(const char* str, size_t length)
  94. {
  95. if (length)
  96. {
  97. const size_t truncatedLength = AZStd::GetMin<size_t>(length, MotionEvent::kMaxParameterStringLength);
  98. azstrncpy(m_parameterStorage.data(), m_parameterStorage.size(), str, truncatedLength);
  99. m_parameterStorage[truncatedLength] = '\0';
  100. }
  101. else
  102. {
  103. m_parameterStorage[0] = '\0';
  104. }
  105. }
  106. };
  107. /**
  108. * EMotion FX Actor Notification Bus
  109. * Used for monitoring EMotion FX per-actor events.
  110. */
  111. class ActorNotifications
  112. : public AZ::ComponentBus
  113. {
  114. public:
  115. /// Bus is accessed from job threads as well as simulation threads.
  116. /// This allows events to be safely queued from anywhere, and flushed from the main simulation thread.
  117. static const bool EnableEventQueue = true;
  118. typedef AZStd::recursive_mutex MutexType;
  119. /// A motion event has fired during playback.
  120. /// \param motionEvent information about the event.
  121. virtual void OnMotionEvent(MotionEvent /*motionEvent*/) {}
  122. /// A motion has looped.
  123. /// \param motionName name of the motion.
  124. virtual void OnMotionLoop(const char* /*motionName*/) {}
  125. /// A anim graph state is about to be entered.
  126. /// \param stateName name of the state.
  127. virtual void OnStateEntering(const char* /*stateName*/) {}
  128. /// A anim graph state has been entered.
  129. /// \param stateName name of the state.
  130. virtual void OnStateEntered(const char* /*stateName*/) {}
  131. /// A anim graph state is about to be exited.
  132. /// \param stateName name of the state.
  133. virtual void OnStateExiting(const char* /*stateName*/) {}
  134. /// A anim graph state has been exited.
  135. /// \param stateName name of the state.
  136. virtual void OnStateExited(const char* /*stateName*/) {}
  137. /// A transition between states is beginning.
  138. /// \param fromState name of source state.
  139. /// \param toState name of target state.
  140. virtual void OnStateTransitionStart(const char* /*fromState*/, const char* /*toState*/) {}
  141. /// A transition between states has completed.
  142. /// \param fromState name of source state.
  143. /// \param toState name of target state.
  144. virtual void OnStateTransitionEnd(const char* /*fromState*/, const char* /*toState*/) {}
  145. };
  146. using ActorNotificationBus = AZ::EBus<ActorNotifications>;
  147. /**
  148. * The raycast request interface, which EMotion FX calls in order to perform ray cast tests.
  149. * This allows you to perform custom filtering.
  150. */
  151. class IRaycastRequests
  152. {
  153. public:
  154. AZ_TYPE_INFO(IRaycastRequests, "{DDA90B91-6F1D-4C83-A0E1-9DE1540B0968}");
  155. enum class UsecaseHint : AZ::u32
  156. {
  157. Generic, /**< A generic raycast, so a non-specific use case. */
  158. FootPlant /**< We are using this for foot planting. */
  159. };
  160. struct RaycastRequest
  161. {
  162. AZ::Vector3 m_start; /**< The start position of the ray in world space. */
  163. AZ::Vector3 m_direction; /**< The direction vector (has to be normalized). */
  164. float m_distance; /**< The maximum distance (has to be positive and larger than zero). */
  165. AzPhysics::SceneQuery::QueryType m_queryType = AzPhysics::SceneQuery::QueryType::StaticAndDynamic;
  166. UsecaseHint m_hint = UsecaseHint::Generic; /**< The use case hint. */
  167. };
  168. struct RaycastResult
  169. {
  170. AZ::Vector3 m_position = AZ::Vector3::CreateZero(); /**< The intersection point. */
  171. AZ::Vector3 m_normal = AZ::Vector3(0.0f, 0.0f, 1.0f); /**< The normal at the intersection point. */
  172. bool m_intersected = false; /**< Did we intersect? In case this is false, the m_position and m_normal should be ignored. */
  173. };
  174. /**
  175. * Perform a raycast to try to find the intersecion point with the world.
  176. * Your game should implement this.
  177. * @param entityId The entity that is requesting this raycast. This entity will have an Actor component on it.
  178. * @param rayRequest The ray information, containing the start point, direction and length of the ray.
  179. * @result The resulting intersection, if there is any. If there is none the m_intersected member of the RaycastResult object returned will be set to false.
  180. */
  181. virtual RaycastResult Raycast(AZ::EntityId entityId, const RaycastRequest& rayRequest) = 0;
  182. virtual void EnableRayRequests() {}
  183. virtual void DisableRayRequests() {}
  184. };
  185. } // namespace Integration
  186. } // namespace EMotionFX