123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- /*
- * 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
- *
- */
- #pragma once
- #include <AzCore/EBus/EBus.h>
- #include <AzCore/Component/ComponentBus.h>
- #include <AzCore/Component/Entity.h>
- #include <AzCore/std/containers/array.h>
- #include <AzFramework/Physics/Common/PhysicsSceneQueries.h>
- namespace EMotionFX
- {
- class ActorInstance;
- class MotionInstance;
- namespace Integration
- {
- /**
- * EMotion FX System Request Bus
- * Used for making global requests to the EMotion FX system.
- */
- class SystemRequests
- : public AZ::EBusTraits
- {
- public:
- static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
- static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
- };
- using SystemRequestBus = AZ::EBus<SystemRequests>;
- /**
- * EMotion FX System Notification Bus
- * Used for monitoring EMotion FX system-level events.
- */
- class SystemNotifications
- : public AZ::EBusTraits
- {
- public:
- static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
- static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
- // Use this bus to register custom EMotionFX plugin.
- virtual void OnRegisterPlugin() = 0;
- };
- using SystemNotificationBus = AZ::EBus<SystemNotifications>;
- /**
- * Motion event descriptor.
- */
- struct MotionEvent
- {
- public:
- AZ_TYPE_INFO(MotionEvent, "{0C899DAC-6B19-4BDD-AD8C-8A11EF2A6729}");
- // Use fixed buffer for parameter string to avoid allocations for motion events, which can be sent at high frequency.
- enum { kMaxParameterStringLength = 64 - 1 };
- typedef AZStd::array<char, kMaxParameterStringLength + 1> ParameterStringStorage;
- ParameterStringStorage m_parameterStorage;
- AZ::EntityId m_entityId; ///< EntityId associated with the originating actor
- const char* m_parameter; ///< Optional string parameter
- EMotionFX::ActorInstance* m_actorInstance; ///< Pointer to the actor instance on which the event is playing
- const EMotionFX::MotionInstance* m_motionInstance; ///< Pointer to the motion instance from which the event was fired
- float m_time; ///< Time value of the event, in seconds
- AZ::u32 m_eventType; ///< Type Id of the event. m_eventTypeName stores the string representation.
- const char* m_eventTypeName; ///< Event type in string form
- float m_globalWeight; ///< Global weight of the event
- float m_localWeight; ///< Local weight of the event
- bool m_isEventStart; ///< Is this the start of a ranged event? This is always true for one-shot events.
- MotionEvent()
- : m_actorInstance(nullptr)
- , m_motionInstance(nullptr)
- , m_time(0.f)
- , m_eventType(0)
- , m_eventTypeName(nullptr)
- , m_globalWeight(0.f)
- , m_localWeight(0.f)
- , m_isEventStart(false)
- {
- m_parameterStorage[0] = '\0';
- m_parameter = m_parameterStorage.data();
- }
- MotionEvent(const MotionEvent& rhs)
- : m_actorInstance(rhs.m_actorInstance)
- , m_motionInstance(rhs.m_motionInstance)
- , m_time(rhs.m_time)
- , m_eventType(rhs.m_eventType)
- , m_eventTypeName(rhs.m_eventTypeName)
- , m_globalWeight(rhs.m_globalWeight)
- , m_localWeight(rhs.m_localWeight)
- , m_isEventStart(rhs.m_isEventStart)
- {
- m_parameterStorage = rhs.m_parameterStorage;
- m_parameter = m_parameterStorage.data();
- }
- void SetParameterString(const char* str, size_t length)
- {
- if (length)
- {
- const size_t truncatedLength = AZStd::GetMin<size_t>(length, MotionEvent::kMaxParameterStringLength);
- azstrncpy(m_parameterStorage.data(), m_parameterStorage.size(), str, truncatedLength);
- m_parameterStorage[truncatedLength] = '\0';
- }
- else
- {
- m_parameterStorage[0] = '\0';
- }
- }
- };
- /**
- * EMotion FX Actor Notification Bus
- * Used for monitoring EMotion FX per-actor events.
- */
- class ActorNotifications
- : public AZ::ComponentBus
- {
- public:
- /// Bus is accessed from job threads as well as simulation threads.
- /// This allows events to be safely queued from anywhere, and flushed from the main simulation thread.
- static const bool EnableEventQueue = true;
- typedef AZStd::recursive_mutex MutexType;
- /// A motion event has fired during playback.
- /// \param motionEvent information about the event.
- virtual void OnMotionEvent(MotionEvent /*motionEvent*/) {}
- /// A motion has looped.
- /// \param motionName name of the motion.
- virtual void OnMotionLoop(const char* /*motionName*/) {}
- /// A anim graph state is about to be entered.
- /// \param stateName name of the state.
- virtual void OnStateEntering(const char* /*stateName*/) {}
- /// A anim graph state has been entered.
- /// \param stateName name of the state.
- virtual void OnStateEntered(const char* /*stateName*/) {}
- /// A anim graph state is about to be exited.
- /// \param stateName name of the state.
- virtual void OnStateExiting(const char* /*stateName*/) {}
- /// A anim graph state has been exited.
- /// \param stateName name of the state.
- virtual void OnStateExited(const char* /*stateName*/) {}
- /// A transition between states is beginning.
- /// \param fromState name of source state.
- /// \param toState name of target state.
- virtual void OnStateTransitionStart(const char* /*fromState*/, const char* /*toState*/) {}
- /// A transition between states has completed.
- /// \param fromState name of source state.
- /// \param toState name of target state.
- virtual void OnStateTransitionEnd(const char* /*fromState*/, const char* /*toState*/) {}
- };
- using ActorNotificationBus = AZ::EBus<ActorNotifications>;
- /**
- * The raycast request interface, which EMotion FX calls in order to perform ray cast tests.
- * This allows you to perform custom filtering.
- */
- class IRaycastRequests
- {
- public:
- AZ_TYPE_INFO(IRaycastRequests, "{DDA90B91-6F1D-4C83-A0E1-9DE1540B0968}");
- enum class UsecaseHint : AZ::u32
- {
- Generic, /**< A generic raycast, so a non-specific use case. */
- FootPlant /**< We are using this for foot planting. */
- };
- struct RaycastRequest
- {
- AZ::Vector3 m_start; /**< The start position of the ray in world space. */
- AZ::Vector3 m_direction; /**< The direction vector (has to be normalized). */
- float m_distance; /**< The maximum distance (has to be positive and larger than zero). */
- AzPhysics::SceneQuery::QueryType m_queryType = AzPhysics::SceneQuery::QueryType::StaticAndDynamic;
- UsecaseHint m_hint = UsecaseHint::Generic; /**< The use case hint. */
- };
- struct RaycastResult
- {
- AZ::Vector3 m_position = AZ::Vector3::CreateZero(); /**< The intersection point. */
- AZ::Vector3 m_normal = AZ::Vector3(0.0f, 0.0f, 1.0f); /**< The normal at the intersection point. */
- bool m_intersected = false; /**< Did we intersect? In case this is false, the m_position and m_normal should be ignored. */
- };
-
- /**
- * Perform a raycast to try to find the intersecion point with the world.
- * Your game should implement this.
- * @param entityId The entity that is requesting this raycast. This entity will have an Actor component on it.
- * @param rayRequest The ray information, containing the start point, direction and length of the ray.
- * @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.
- */
- virtual RaycastResult Raycast(AZ::EntityId entityId, const RaycastRequest& rayRequest) = 0;
- virtual void EnableRayRequests() {}
- virtual void DisableRayRequests() {}
- };
- } // namespace Integration
- } // namespace EMotionFX
|