BsSceneObject.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsCorePrerequisites.h"
  5. #include "BsMatrix4.h"
  6. #include "BsVector3.h"
  7. #include "BsQuaternion.h"
  8. #include "BsRTTIType.h"
  9. #include "BsGameObjectManager.h"
  10. #include "BsGameObject.h"
  11. #include "BsComponent.h"
  12. namespace BansheeEngine
  13. {
  14. /** @addtogroup Scene
  15. * @{
  16. */
  17. /** Possible modifiers that can be applied to a SceneObject. */
  18. enum SceneObjectFlags
  19. {
  20. SOF_DontInstantiate = 0x01, /**< Object wont be in the main scene and its components won't receive updates. */
  21. SOF_DontSave = 0x02, /**< Object will be skipped when saving the scene hierarchy or a prefab. */
  22. SOF_Persistent = 0x04, /**< Object will remain in the scene even after scene clear, unless destroyed directly.
  23. This only works with top-level objects. */
  24. SOF_Internal = 0x08 /**< Provides a hint to external systems that his object is used by engine internals.
  25. For example, those systems might not want to display those objects together with the
  26. user created ones. */
  27. };
  28. /**
  29. * An object in the scene graph. It has a world position, place in the hierarchy and optionally a number of attached
  30. * components.
  31. */
  32. class BS_CORE_EXPORT SceneObject : public GameObject
  33. {
  34. /** Flags that signify which part of the SceneObject needs updating. */
  35. enum DirtyFlags
  36. {
  37. LocalTfrmDirty = 0x01,
  38. WorldTfrmDirty = 0x02
  39. };
  40. friend class CoreSceneManager;
  41. friend class Prefab;
  42. friend class PrefabDiff;
  43. friend class PrefabUtility;
  44. public:
  45. ~SceneObject();
  46. /**
  47. * Creates a new SceneObject with the specified name. Object will be placed in the top of the scene hierarchy.
  48. *
  49. * @param[in] name Name of the scene object.
  50. * @param[in] flags Optional flags that control object behavior. See SceneObjectFlags.
  51. */
  52. static HSceneObject create(const String& name, UINT32 flags = 0);
  53. /**
  54. * Destroys this object and any of its held components.
  55. *
  56. * @param[in] immediate If true, the object will be deallocated and become unusable right away. Otherwise the
  57. * deallocation will be delayed to the end of frame (preferred method).
  58. */
  59. void destroy(bool immediate = false);
  60. /** @copydoc GameObject::_setInstanceData */
  61. void _setInstanceData(GameObjectInstanceDataPtr& other) override;
  62. /** Returns a handle to this object. */
  63. HSceneObject getHandle() const { return mThisHandle; }
  64. /**
  65. * Returns the UUID of the prefab this object is linked to, if any.
  66. *
  67. * @note Requires a search of all parents potentially.
  68. */
  69. String getPrefabLink() const;
  70. /**
  71. * Returns the root object of the prefab instance that this object belongs to, if any. Returns null if the object
  72. * is not part of a prefab instance.
  73. */
  74. HSceneObject getPrefabParent() const;
  75. /**
  76. * Breaks the link between this prefab instance and its prefab. Object will retain all current values but will no
  77. * longer be influenced by modifications to its parent prefab.
  78. */
  79. void breakPrefabLink();
  80. /** Checks if the scene object has a specific bit flag set. */
  81. bool hasFlag(UINT32 flag) const;
  82. public: // ***** INTERNAL ******
  83. /** @cond INTERNAL */
  84. /** Register the scene object with the scene and activate all of its components. */
  85. void _instantiate();
  86. /**
  87. * Clears the internally stored prefab diff. If this object is updated from prefab its instance specific changes
  88. * will be lost.
  89. */
  90. void _clearPrefabDiff() { mPrefabDiff = nullptr; }
  91. /**
  92. * Returns the UUID of the prefab this object is linked to, if any. Unlike getPrefabLink() method this will not
  93. * search parents, but instead return only the value assigned to this object.
  94. */
  95. const String& _getPrefabLinkUUID() const { return mPrefabLinkUUID; }
  96. /**
  97. * Allows you to change the prefab link UUID of this object. Normally this should be accompanied by reassigning the
  98. * link IDs.
  99. */
  100. void _setPrefabLinkUUID(const String& UUID) { mPrefabLinkUUID = UUID; }
  101. /**
  102. * Returns a prefab diff object containing instance specific modifications of this object compared to its prefab
  103. * reference, if any.
  104. */
  105. const PrefabDiffPtr& _getPrefabDiff() const { return mPrefabDiff; }
  106. /** Assigns a new prefab diff object. Caller must ensure the prefab diff was generated for this object. */
  107. void _setPrefabDiff(const PrefabDiffPtr& diff) { mPrefabDiff = diff; }
  108. /** @endcond */
  109. private:
  110. SceneObject(const String& name, UINT32 flags);
  111. /**
  112. * Creates a new SceneObject instance, registers it with the game object manager, creates and returns a handle to
  113. * the new object.
  114. *
  115. * @note
  116. * When creating objects with DontInstantiate flag it is the callers responsibility to manually destroy the object,
  117. * otherwise it will leak.
  118. */
  119. static HSceneObject createInternal(const String& name, UINT32 flags = 0);
  120. /**
  121. * Creates a new SceneObject instance from an existing pointer, registers it with the game object manager, creates
  122. * and returns a handle to the object.
  123. *
  124. * @param[in] soPtr Pointer to the scene object register and return a handle to.
  125. * @param[in] originalId If the provided pointer was deserialized, this is the original object's ID at the time
  126. * of serialization. Used for resolving handles pointing to the object.
  127. */
  128. static HSceneObject createInternal(const SPtr<SceneObject>& soPtr, UINT64 originalId = 0);
  129. /**
  130. * Destroys this object and any of its held components.
  131. *
  132. * @param[in] handle Game object handle to this object.
  133. * @param[in] immediate If true, the object will be deallocated and become unusable right away. Otherwise the
  134. * deallocation will be delayed to the end of frame (preferred method).
  135. *
  136. * @note Unlike destroy(), does not remove the object from its parent.
  137. */
  138. void destroyInternal(GameObjectHandleBase& handle, bool immediate = false) override;
  139. /** Recursively enables the provided set of flags on this object and all children. */
  140. void setFlags(UINT32 flags);
  141. /** Recursively disables the provided set of flags on this object and all children. */
  142. void unsetFlags(UINT32 flags);
  143. /** Checks is the scene object instantiated and visible in the scene. */
  144. bool isInstantiated() const { return (mFlags & SOF_DontInstantiate) == 0; }
  145. private:
  146. HSceneObject mThisHandle;
  147. String mPrefabLinkUUID;
  148. PrefabDiffPtr mPrefabDiff;
  149. UINT32 mPrefabHash;
  150. UINT32 mFlags;
  151. /************************************************************************/
  152. /* Transform */
  153. /************************************************************************/
  154. public:
  155. /** Sets the local position of the object. */
  156. void setPosition(const Vector3& position);
  157. /** Gets the local position of the object. */
  158. const Vector3& getPosition() const { return mPosition; }
  159. /** Sets the world position of the object. */
  160. void setWorldPosition(const Vector3& position);
  161. /**
  162. * Gets the world position of the object.
  163. *
  164. * @note Performance warning: This might involve updating the transforms if the transform is dirty.
  165. */
  166. const Vector3& getWorldPosition() const;
  167. /** Sets the local rotation of the object. */
  168. void setRotation(const Quaternion& rotation);
  169. /** Gets the local rotation of the object. */
  170. const Quaternion& getRotation() const { return mRotation; }
  171. /** Sets the world rotation of the object. */
  172. void setWorldRotation(const Quaternion& rotation);
  173. /**
  174. * Gets world rotation of the object.
  175. *
  176. * @note Performance warning: This might involve updating the transforms if the transform is dirty.
  177. */
  178. const Quaternion& getWorldRotation() const;
  179. /** Sets the local scale of the object. */
  180. void setScale(const Vector3& scale);
  181. /** Gets the local scale of the object. */
  182. const Vector3& getScale() const { return mScale; }
  183. /**
  184. * Sets the world scale of the object.
  185. *
  186. * @note This will not work properly if this object or any of its parents have non-affine transform matrices.
  187. */
  188. void setWorldScale(const Vector3& scale);
  189. /**
  190. * Gets world scale of the object.
  191. *
  192. * @note Performance warning: This might involve updating the transforms if the transform is dirty.
  193. */
  194. const Vector3& getWorldScale() const;
  195. /**
  196. * Orients the object so it is looking at the provided @p location (world space) where @p up is used for
  197. * determining the location of the object's Y axis.
  198. */
  199. void lookAt(const Vector3& location, const Vector3& up = Vector3::UNIT_Y);
  200. /**
  201. * Gets the objects world transform matrix.
  202. *
  203. * @note Performance warning: This might involve updating the transforms if the transform is dirty.
  204. */
  205. const Matrix4& getWorldTfrm() const;
  206. /**
  207. * Gets the objects inverse world transform matrix.
  208. *
  209. * @note Performance warning: This might involve updating the transforms if the transform is dirty.
  210. */
  211. Matrix4 getInvWorldTfrm() const;
  212. /** Gets the objects local transform matrix. */
  213. const Matrix4& getLocalTfrm() const;
  214. /** Moves the object's position by the vector offset provided along world axes. */
  215. void move(const Vector3& vec);
  216. /** Moves the object's position by the vector offset provided along it's own axes (relative to orientation). */
  217. void moveRelative(const Vector3& vec);
  218. /**
  219. * Gets the Z (forward) axis of the object, in world space.
  220. *
  221. * @return Forward axis of the object.
  222. */
  223. Vector3 getForward() const { return getWorldRotation().rotate(-Vector3::UNIT_Z); }
  224. /**
  225. * Gets the Y (up) axis of the object, in world space.
  226. *
  227. * @return Up axis of the object.
  228. */
  229. Vector3 getUp() const { return getWorldRotation().rotate(Vector3::UNIT_Y); }
  230. /**
  231. * Gets the X (right) axis of the object, in world space.
  232. *
  233. * @return Right axis of the object.
  234. */
  235. Vector3 getRight() const { return getWorldRotation().rotate(Vector3::UNIT_X); }
  236. /**
  237. * Rotates the game object so it's forward axis faces the provided direction.
  238. *
  239. * @param[in] forwardDir The forward direction to face, in world space.
  240. *
  241. * @note Local forward axis is considered to be negative Z.
  242. */
  243. void setForward(const Vector3& forwardDir);
  244. /** Rotate the object around an arbitrary axis. */
  245. void rotate(const Vector3& axis, const Radian& angle);
  246. /** Rotate the object around an arbitrary axis using a Quaternion. */
  247. void rotate(const Quaternion& q);
  248. /**
  249. * Rotates around local Z axis.
  250. *
  251. * @param[in] angle Angle to rotate by.
  252. */
  253. void roll(const Radian& angle);
  254. /**
  255. * Rotates around Y axis.
  256. *
  257. * @param[in] angle Angle to rotate by.
  258. */
  259. void yaw(const Radian& angle);
  260. /**
  261. * Rotates around X axis
  262. *
  263. * @param[in] angle Angle to rotate by.
  264. */
  265. void pitch(const Radian& angle);
  266. /**
  267. * Forces any dirty transform matrices on this object to be updated.
  268. *
  269. * @note
  270. * Normally this is done internally when retrieving a transform, but sometimes it is useful to update transforms
  271. * manually.
  272. */
  273. void updateTransformsIfDirty();
  274. /**
  275. * Returns a hash value that changes whenever a scene objects transform gets updated. It allows you to detect
  276. * changes with the local or world transforms without directly comparing their values with some older state.
  277. */
  278. UINT32 getTransformHash() const { return mDirtyHash; }
  279. private:
  280. Vector3 mPosition;
  281. Quaternion mRotation;
  282. Vector3 mScale;
  283. mutable Vector3 mWorldPosition;
  284. mutable Quaternion mWorldRotation;
  285. mutable Vector3 mWorldScale;
  286. mutable Matrix4 mCachedLocalTfrm;
  287. mutable Matrix4 mCachedWorldTfrm;
  288. mutable UINT32 mDirtyFlags;
  289. mutable UINT32 mDirtyHash;
  290. /**
  291. * Notifies components and child scene object that a transform has been changed.
  292. *
  293. * @param flags Specifies in what way was the transform changed.
  294. */
  295. void notifyTransformChanged(TransformChangedFlags flags) const;
  296. /** Updates the local transform. Normally just reconstructs the transform matrix from the position/rotation/scale. */
  297. void updateLocalTfrm() const;
  298. /**
  299. * Updates the world transform. Reconstructs the local transform matrix and multiplies it with any parent transforms.
  300. *
  301. * @note If parent transforms are dirty they will be updated.
  302. */
  303. void updateWorldTfrm() const;
  304. /** Checks if cached local transform needs updating. */
  305. bool isCachedLocalTfrmUpToDate() const { return (mDirtyFlags & DirtyFlags::LocalTfrmDirty) == 0; }
  306. /** Checks if cached world transform needs updating. */
  307. bool isCachedWorldTfrmUpToDate() const { return (mDirtyFlags & DirtyFlags::WorldTfrmDirty) == 0; }
  308. /************************************************************************/
  309. /* Hierarchy */
  310. /************************************************************************/
  311. public:
  312. /**
  313. * Changes the parent of this object. Also removes the object from the current parent, and assigns it to the new
  314. * parent.
  315. *
  316. * @param[in] parent New parent.
  317. * @param[in] keepWorldPos Determines should the current transform be maintained even after the parent is
  318. * changed (this means the local transform will be modified accordingly).
  319. */
  320. void setParent(const HSceneObject& parent, bool keepWorldTransform = true);
  321. /**
  322. * Gets the parent of this object.
  323. *
  324. * @return Parent object, or nullptr if this SceneObject is at root level.
  325. */
  326. HSceneObject getParent() const { return mParent; }
  327. /**
  328. * Gets a child of this item.
  329. *
  330. * @param[in] idx The zero based index of the child.
  331. * @return SceneObject of the child.
  332. */
  333. HSceneObject getChild(UINT32 idx) const;
  334. /**
  335. * Find the index of the specified child. Don't persist this value as it may change whenever you add/remove children.
  336. *
  337. * @param[in] child The child to look for.
  338. * @return The zero-based index of the found child, or -1 if no match was found.
  339. */
  340. int indexOfChild(const HSceneObject& child) const;
  341. /** Gets the number of all child GameObjects. */
  342. UINT32 getNumChildren() const { return (UINT32)mChildren.size(); }
  343. /**
  344. * Searches the child objects for an object matching the specified name.
  345. *
  346. * @param[in] name Name of the object to locate.
  347. * @param[in] recursive If true all descendants of the scene object will be searched, otherwise only immediate
  348. * children.
  349. * @return First found scene object, or empty handle if none found.
  350. */
  351. HSceneObject findChild(const String& name, bool recursive = true);
  352. /**
  353. * Searches the child objects for objects matching the specified name.
  354. *
  355. * @param[in] name Name of the objects to locate.
  356. * @param[in] recursive If true all descendants of the scene object will be searched, otherwise only immediate
  357. * children.
  358. * @return All scene objects matching the specified name.
  359. */
  360. Vector<HSceneObject> findChildren(const String& name, bool recursive = true);
  361. /**
  362. * Enables or disables this object. Disabled objects also implicitly disable all their child objects. No components
  363. * on the disabled object are updated.
  364. */
  365. void setActive(bool active);
  366. /**
  367. * Returns whether or not an object is active.
  368. *
  369. * @param[in] self If true, the method will only check if this particular object was activated or deactivated
  370. * directly via setActive. If false we we also check if any of the objects parents are inactive.
  371. */
  372. bool getActive(bool self = false);
  373. /**
  374. * Makes a deep copy of this object.
  375. *
  376. * @param[in] instantiate If false, the cloned hierarchy will just be a memory copy, but will not be present in the
  377. * scene or otherwise active until ::instantiate() is called.
  378. */
  379. HSceneObject clone(bool instantiate = true);
  380. private:
  381. HSceneObject mParent;
  382. Vector<HSceneObject> mChildren;
  383. bool mActiveSelf;
  384. bool mActiveHierarchy;
  385. /**
  386. * Internal version of setParent() that allows you to set a null parent.
  387. *
  388. * @param[in] parent New parent.
  389. * @param[in] keepWorldPos Determines should the current transform be maintained even after the parent is
  390. * changed (this means the local transform will be modified accordingly).
  391. */
  392. void _setParent(const HSceneObject& parent, bool keepWorldTransform = true);
  393. /**
  394. * Adds a child to the child array. This method doesn't check for null or duplicate values.
  395. *
  396. * @param[in] object New child.
  397. */
  398. void addChild(const HSceneObject& object);
  399. /**
  400. * Removes the child from the object.
  401. *
  402. * @param[in] object Child to remove.
  403. */
  404. void removeChild(const HSceneObject& object);
  405. /** Changes the object active in hierarchy state, and triggers necessary events. */
  406. void setActiveHierarchy(bool active, bool triggerEvents = true);
  407. /************************************************************************/
  408. /* Component */
  409. /************************************************************************/
  410. public:
  411. /** Constructs a new component of the specified type and adds it to the internal component list. */
  412. template<class T, class... Args>
  413. GameObjectHandle<T> addComponent(Args &&... args)
  414. {
  415. static_assert((std::is_base_of<BansheeEngine::Component, T>::value),
  416. "Specified type is not a valid Component.");
  417. std::shared_ptr<T> gameObject(new (bs_alloc<T>()) T(mThisHandle,
  418. std::forward<Args>(args)...),
  419. &bs_delete<T>, StdAlloc<T>());
  420. GameObjectHandle<T> newComponent =
  421. GameObjectManager::instance().registerObject(gameObject);
  422. newComponent->mThisHandle = newComponent;
  423. mComponents.push_back(newComponent);
  424. if (isInstantiated())
  425. {
  426. newComponent->instantiate();
  427. newComponent->onInitialized();
  428. if (getActive())
  429. newComponent->onEnabled();
  430. }
  431. return newComponent;
  432. }
  433. /**
  434. * Searches for a component with the specific type and returns the first one it finds. Will also return components
  435. * derived from the type.
  436. *
  437. * @tparam typename T Type of the component.
  438. * @return Component if found, nullptr otherwise.
  439. *
  440. * @note
  441. * Don't call this too often as it is relatively slow. It is more efficient to call it once and store the result
  442. * for further use.
  443. */
  444. template <typename T>
  445. GameObjectHandle<T> getComponent()
  446. {
  447. static_assert((std::is_base_of<BansheeEngine::Component, T>::value),
  448. "Specified type is not a valid Component.");
  449. return static_object_cast<T>(getComponent(T::getRTTIStatic()));
  450. }
  451. /**
  452. * Returns all components with the specific type. Will also return components derived from the type.
  453. *
  454. * @tparam typename T Type of the component.
  455. * @return Array of found components.
  456. *
  457. * @note
  458. * Don't call this too often as it is relatively slow. It is more efficient to call it once and store the result
  459. * for further use.
  460. */
  461. template <typename T>
  462. Vector<GameObjectHandle<T>> getComponents()
  463. {
  464. static_assert((std::is_base_of<BansheeEngine::Component, T>::value),
  465. "Specified type is not a valid Component.");
  466. Vector<GameObjectHandle<T>> output;
  467. for (auto entry : mComponents)
  468. {
  469. if (entry->getRTTI()->isDerivedFrom(T::getRTTIStatic()))
  470. output.push_back(entry);
  471. }
  472. return output;
  473. }
  474. /**
  475. * Checks if the current object contains the specified component or components derived from the provided type.
  476. *
  477. * @tparam typename T Type of the component.
  478. * @return True if component exists on the object.
  479. *
  480. * @note Don't call this too often as it is relatively slow.
  481. */
  482. template <typename T>
  483. bool hasComponent()
  484. {
  485. static_assert((std::is_base_of<BansheeEngine::Component, T>::value),
  486. "Specified type is not a valid Component.");
  487. for (auto entry : mComponents)
  488. {
  489. if (entry->getRTTI()->isDerivedFrom(T::getRTTIStatic()))
  490. return true;
  491. }
  492. return false;
  493. }
  494. /**
  495. * Searches for a component with the specified type and returns the first one it finds. Will also return components
  496. * derived from the type.
  497. *
  498. * @param[in] type RTTI information for the type.
  499. * @return Component if found, nullptr otherwise.
  500. *
  501. * @note
  502. * Don't call this too often as it is relatively slow. It is more efficient to call it once and store the result
  503. * for further use.
  504. */
  505. HComponent getComponent(RTTITypeBase* type) const;
  506. /**
  507. * Removes the component from this object, and deallocates it.
  508. *
  509. * @param[in] component The component to destroy.
  510. * @param[in] immediate If true, the component will be deallocated and become unusable right away. Otherwise
  511. * the deallocation will be delayed to the end of frame (preferred method).
  512. */
  513. void destroyComponent(const HComponent component, bool immediate = false);
  514. /**
  515. * Removes the component from this object, and deallocates it.
  516. *
  517. * @param[in] component The component to destroy.
  518. * @param[in] immediate If true, the component will be deallocated and become unusable right away. Otherwise
  519. * the deallocation will be delayed to the end of frame (preferred method).
  520. */
  521. void destroyComponent(Component* component, bool immediate = false);
  522. /** Returns all components on this object. */
  523. const Vector<HComponent>& getComponents() const { return mComponents; }
  524. private:
  525. /** Creates an empty component with the default constructor. */
  526. template <typename T>
  527. static std::shared_ptr<T> createEmptyComponent()
  528. {
  529. static_assert((std::is_base_of<BansheeEngine::Component, T>::value), "Specified type is not a valid Component.");
  530. T* rawPtr = new (bs_alloc<T>()) T();
  531. std::shared_ptr<T> gameObject(rawPtr, &bs_delete<T>, StdAlloc<T>());
  532. return gameObject;
  533. }
  534. /** Adds the component to the internal component array. */
  535. void addComponentInternal(const std::shared_ptr<Component> component);
  536. Vector<HComponent> mComponents;
  537. /************************************************************************/
  538. /* RTTI */
  539. /************************************************************************/
  540. public:
  541. friend class GameObjectRTTI;
  542. friend class SceneObjectRTTI;
  543. static RTTITypeBase* getRTTIStatic();
  544. virtual RTTITypeBase* getRTTI() const override;
  545. };
  546. /** @} */
  547. }