| 1 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// |
| 2 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// |
| 3 | #pragma once |
| 4 | |
| 5 | #include "BsCorePrerequisites.h" |
| 6 | #include "Scene/BsTransform.h" |
| 7 | |
| 8 | namespace bs |
| 9 | { |
| 10 | /** @addtogroup Scene-Internal |
| 11 | * @{ |
| 12 | */ |
| 13 | |
| 14 | /** Signals which portion of a scene actor is dirty. */ |
| 15 | enum class ActorDirtyFlag |
| 16 | { |
| 17 | Transform = 1 << 0, |
| 18 | Mobility = 1 << 1, |
| 19 | Active = 1 << 2, |
| 20 | Everything = 1 << 3, |
| 21 | Dependency = DIRTY_DEPENDENCY_MASK |
| 22 | }; |
| 23 | |
| 24 | typedef Flags<ActorDirtyFlag> ActorDirtyFlags; |
| 25 | BS_FLAGS_OPERATORS(ActorDirtyFlag) |
| 26 | |
| 27 | /** |
| 28 | * A base class for objects that can be placed in the scene. It has a transform object that allows it to be positioned, |
| 29 | * scaled and rotated, as well a properties that control its mobility (movable vs. immovable) and active status. |
| 30 | * |
| 31 | * In a way scene actors are similar to SceneObject%s, the main difference being that their implementations perform |
| 32 | * some functionality directly, rather than relying on attached Components. Scene actors can be considered as a |
| 33 | * lower-level alternative to SceneObject/Component model. In fact many Components internally just wrap scene actors. |
| 34 | */ |
| 35 | class BS_CORE_EXPORT SceneActor |
| 36 | { |
| 37 | public: |
| 38 | SceneActor() = default; |
| 39 | virtual ~SceneActor() = default; |
| 40 | |
| 41 | /** Determines the position, rotation and scale of the actor. */ |
| 42 | virtual void setTransform(const Transform& transform); |
| 43 | |
| 44 | /** @copydoc setTransform */ |
| 45 | const Transform& getTransform() const { return mTransform; } |
| 46 | |
| 47 | /** Shorthand for getTransform(). */ |
| 48 | const Transform& tfrm() const { return mTransform; } |
| 49 | |
| 50 | /** |
| 51 | * Determines if the actor is currently active. Deactivated actors act as if they have been destroyed, without |
| 52 | * actually being destroyed. |
| 53 | */ |
| 54 | virtual void setActive(bool active); |
| 55 | |
| 56 | /** @copydoc setActive */ |
| 57 | bool getActive() const { return mActive; } |
| 58 | |
| 59 | /** |
| 60 | * Determines the mobility of the actor. This is used primarily as a performance hint to engine systems. Objects |
| 61 | * with more restricted mobility will result in higher performance. Any transform changes to immobile actors will |
| 62 | * be ignored. By default actor's mobility is unrestricted. |
| 63 | */ |
| 64 | virtual void setMobility(ObjectMobility mobility); |
| 65 | |
| 66 | /** @copydoc setMobility */ |
| 67 | ObjectMobility getMobility() const { return mMobility; } |
| 68 | |
| 69 | /** |
| 70 | * @name Internal |
| 71 | * @{ |
| 72 | */ |
| 73 | |
| 74 | /** |
| 75 | * Updates the internal actor state by transfering the relevant state from the scene object. The system tracks |
| 76 | * the last state and only performs the update if the scene object was modified since the last call. You can force |
| 77 | * an update by setting the @p force parameter to true. |
| 78 | * |
| 79 | * This method is used by the scene manager to update actors that have been bound to a scene object. Never call this |
| 80 | * method for multiple different scene objects, as actor can only ever be bound to one during its lifetime. |
| 81 | */ |
| 82 | virtual void _updateState(const SceneObject& so, bool force = false); |
| 83 | |
| 84 | /** Enumerates all the fields in the type and executes the specified processor action for each field. */ |
| 85 | template<class P> |
| 86 | void rttiEnumFields(P p, ActorDirtyFlags flags = ActorDirtyFlag::Everything) |
| 87 | { |
| 88 | if (flags.isSetAny(ActorDirtyFlag::Transform | ActorDirtyFlag::Everything)) |
| 89 | p(mTransform); |
| 90 | |
| 91 | if (flags.isSetAny(ActorDirtyFlag::Active | ActorDirtyFlag::Everything)) |
| 92 | p(mActive); |
| 93 | |
| 94 | if (flags.isSetAny(ActorDirtyFlag::Mobility | ActorDirtyFlag::Everything)) |
| 95 | p(mMobility); |
| 96 | } |
| 97 | |
| 98 | /** @} */ |
| 99 | protected: |
| 100 | /** |
| 101 | * Marks the simulation thread object as dirty and notifies the system its data should be synced with its core |
| 102 | * thread counterpart. |
| 103 | */ |
| 104 | virtual void _markCoreDirty(ActorDirtyFlag flag = ActorDirtyFlag::Everything) { } |
| 105 | |
| 106 | protected: |
| 107 | friend class SceneManager; |
| 108 | |
| 109 | Transform mTransform; |
| 110 | ObjectMobility mMobility = ObjectMobility::Movable; |
| 111 | bool mActive = true; |
| 112 | UINT32 mHash = 0; |
| 113 | }; |
| 114 | |
| 115 | /** @} */ |
| 116 | } |
| 117 | |