SceneNode.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Scene/SceneNode.h>
  6. #include <AnKi/Scene/SceneGraph.h>
  7. #include <AnKi/Scene/Components/SceneComponent.h>
  8. #include <AnKi/Scene/Components/MoveComponent.h>
  9. #include <AnKi/Scene/Components/BodyComponent.h>
  10. #include <AnKi/Scene/Components/CameraComponent.h>
  11. #include <AnKi/Scene/Components/DecalComponent.h>
  12. #include <AnKi/Scene/Components/FogDensityComponent.h>
  13. #include <AnKi/Scene/Components/GlobalIlluminationProbeComponent.h>
  14. #include <AnKi/Scene/Components/JointComponent.h>
  15. #include <AnKi/Scene/Components/LensFlareComponent.h>
  16. #include <AnKi/Scene/Components/LightComponent.h>
  17. #include <AnKi/Scene/Components/ModelComponent.h>
  18. #include <AnKi/Scene/Components/MoveComponent.h>
  19. #include <AnKi/Scene/Components/ParticleEmitterComponent.h>
  20. #include <AnKi/Scene/Components/PlayerControllerComponent.h>
  21. #include <AnKi/Scene/Components/ReflectionProbeComponent.h>
  22. #include <AnKi/Scene/Components/ScriptComponent.h>
  23. #include <AnKi/Scene/Components/SkinComponent.h>
  24. #include <AnKi/Scene/Components/SkyboxComponent.h>
  25. #include <AnKi/Scene/Components/TriggerComponent.h>
  26. #include <AnKi/Scene/Components/UiComponent.h>
  27. namespace anki {
  28. // Specialize newComponent(). Do that first
  29. #define ANKI_DEFINE_SCENE_COMPONENT(name, weight) \
  30. template<> \
  31. name##Component* SceneNode::newComponent<name##Component>() \
  32. { \
  33. auto it = SceneGraph::getSingleton().getComponentArrays().get##name##s().emplace(this); \
  34. it->setArrayIndex(it.getArrayIndex()); \
  35. newComponentInternal(&(*it)); \
  36. return &(*it); \
  37. }
  38. #include <AnKi/Scene/Components/SceneComponentClasses.def.h>
  39. SceneNode::SceneNode(CString name)
  40. : m_uuid(SceneGraph::getSingleton().getNewUuid())
  41. {
  42. if(name)
  43. {
  44. m_name = name;
  45. }
  46. // Add the implicit MoveComponent
  47. newComponent<MoveComponent>();
  48. }
  49. SceneNode::~SceneNode()
  50. {
  51. for(SceneComponent* comp : m_components)
  52. {
  53. comp->onDestroy(*this);
  54. switch(comp->getType())
  55. {
  56. #define ANKI_DEFINE_SCENE_COMPONENT(name, weight) \
  57. case SceneComponentType::k##name: \
  58. SceneGraph::getSingleton().getComponentArrays().get##name##s().erase(comp->getArrayIndex()); \
  59. break;
  60. #include <AnKi/Scene/Components/SceneComponentClasses.def.h>
  61. }
  62. }
  63. }
  64. void SceneNode::setMarkedForDeletion()
  65. {
  66. // Mark for deletion only when it's not already marked because we don't want to increase the counter again
  67. if(!getMarkedForDeletion())
  68. {
  69. m_markedForDeletion = true;
  70. SceneGraph::getSingleton().increaseObjectsMarkedForDeletion();
  71. }
  72. [[maybe_unused]] const Error err = visitChildren([](SceneNode& obj) -> Error {
  73. obj.setMarkedForDeletion();
  74. return Error::kNone;
  75. });
  76. }
  77. void SceneNode::newComponentInternal(SceneComponent* newc)
  78. {
  79. m_componentTypeMask |= 1 << SceneComponentTypeMask(newc->getType());
  80. // Inform all other components that some component was added
  81. for(SceneComponent* other : m_components)
  82. {
  83. other->onOtherComponentRemovedOrAdded(newc, true);
  84. }
  85. // Inform the current component about others
  86. for(SceneComponent* other : m_components)
  87. {
  88. newc->onOtherComponentRemovedOrAdded(other, true);
  89. }
  90. m_components.emplaceBack(newc);
  91. // Sort based on update weight
  92. std::sort(m_components.getBegin(), m_components.getEnd(), [](const SceneComponent* a, const SceneComponent* b) {
  93. const F32 weightA = SceneComponent::getUpdateOrderWeight(a->getType());
  94. const F32 weightB = SceneComponent::getUpdateOrderWeight(b->getType());
  95. if(weightA != weightB)
  96. {
  97. return weightA < weightB;
  98. }
  99. else
  100. {
  101. return a->getType() < b->getType();
  102. }
  103. });
  104. }
  105. Bool SceneNode::updateTransform()
  106. {
  107. const Bool needsUpdate = m_localTransformDirty;
  108. m_localTransformDirty = false;
  109. const Bool updatedLastFrame = m_transformUpdatedThisFrame;
  110. m_transformUpdatedThisFrame = needsUpdate;
  111. if(needsUpdate || updatedLastFrame)
  112. {
  113. m_prevWTrf = m_wtrf;
  114. }
  115. // Update world transform
  116. if(needsUpdate)
  117. {
  118. const SceneNode* parent = getParent();
  119. if(parent == nullptr || m_ignoreParentNodeTransform)
  120. {
  121. m_wtrf = m_ltrf;
  122. }
  123. else
  124. {
  125. m_wtrf = parent->getWorldTransform().combineTransformations(m_ltrf);
  126. }
  127. // Make children dirty as well. Don't walk the whole tree because you will re-walk it later
  128. [[maybe_unused]] const Error err = visitChildrenMaxDepth(1, [](SceneNode& childNode) -> Error {
  129. childNode.m_localTransformDirty = true;
  130. return Error::kNone;
  131. });
  132. }
  133. return needsUpdate;
  134. }
  135. } // end namespace anki