MoveComponent.cpp 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // Copyright (C) 2009-2022, 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/Components/MoveComponent.h>
  6. #include <AnKi/Scene/SceneNode.h>
  7. namespace anki {
  8. ANKI_SCENE_COMPONENT_STATICS(MoveComponent)
  9. MoveComponent::MoveComponent(SceneNode* node)
  10. : SceneComponent(node, getStaticClassId())
  11. , m_ignoreLocalTransform(false)
  12. , m_ignoreParentTransform(false)
  13. {
  14. getExternalSubsystems(*node).m_gpuSceneMemoryPool->allocate(sizeof(Mat3x4) * 2, alignof(F32), m_gpuSceneTransforms);
  15. markForUpdate();
  16. }
  17. MoveComponent::~MoveComponent()
  18. {
  19. }
  20. Error MoveComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
  21. {
  22. updated = updateWorldTransform(*info.m_node);
  23. return Error::kNone;
  24. }
  25. Bool MoveComponent::updateWorldTransform(SceneNode& node)
  26. {
  27. m_prevWTrf = m_wtrf;
  28. const Bool dirty = m_markedForUpdate;
  29. // If dirty then update world transform
  30. if(dirty)
  31. {
  32. const SceneNode* parent = node.getParent();
  33. if(parent)
  34. {
  35. const MoveComponent* parentMove = parent->tryGetFirstComponentOfType<MoveComponent>();
  36. if(parentMove == nullptr)
  37. {
  38. // Parent not movable
  39. m_wtrf = m_ltrf;
  40. }
  41. else if(m_ignoreParentTransform)
  42. {
  43. m_wtrf = m_ltrf;
  44. }
  45. else if(m_ignoreLocalTransform)
  46. {
  47. m_wtrf = parentMove->getWorldTransform();
  48. }
  49. else
  50. {
  51. m_wtrf = parentMove->getWorldTransform().combineTransformations(m_ltrf);
  52. }
  53. }
  54. else
  55. {
  56. // No parent
  57. m_wtrf = m_ltrf;
  58. }
  59. // Now it's a good time to cleanse parent
  60. m_markedForUpdate = false;
  61. }
  62. // If this is dirty then make children dirty as well. Don't walk the whole tree because you will re-walk it later
  63. if(dirty)
  64. {
  65. [[maybe_unused]] const Error err = node.visitChildrenMaxDepth(1, [](SceneNode& childNode) -> Error {
  66. childNode.iterateComponentsOfType<MoveComponent>([](MoveComponent& mov) {
  67. mov.markForUpdate();
  68. });
  69. return Error::kNone;
  70. });
  71. }
  72. return dirty;
  73. }
  74. void MoveComponent::onDestroy(SceneNode& node)
  75. {
  76. getExternalSubsystems(node).m_gpuSceneMemoryPool->free(m_gpuSceneTransforms);
  77. }
  78. } // end namespace anki