SceneNode.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #include "SceneNode.h"
  2. #include "Scene.h"
  3. #include "util/Exception.h"
  4. #include <algorithm>
  5. #include <boost/lexical_cast.hpp>
  6. //==============================================================================
  7. // Statics =
  8. //==============================================================================
  9. uint SceneNode::uid = 0;
  10. //==============================================================================
  11. // Constructor =
  12. //==============================================================================
  13. SceneNode::SceneNode(SceneNodeType type_, Scene& scene_, ulong flags_,
  14. SceneNode* parent_)
  15. : type(type_),
  16. flags(flags_),
  17. parent(NULL),
  18. scene(scene_)
  19. {
  20. ++uid;
  21. getWorldTransform().setIdentity();
  22. getLocalTransform().setIdentity();
  23. name = boost::lexical_cast<std::string>(uid);
  24. enableFlag(SNF_ACTIVE);
  25. if(parent_ != NULL)
  26. {
  27. parent_->addChild(*this);
  28. }
  29. // This goes last
  30. scene.registerNode(this);
  31. }
  32. //==============================================================================
  33. // Destructor =
  34. //==============================================================================
  35. SceneNode::~SceneNode()
  36. {
  37. scene.unregisterNode(this);
  38. if(parent != NULL)
  39. {
  40. parent->removeChild(*this);
  41. }
  42. if(isFlagEnabled(SNF_ON_DELETE_DELETE_CHILDREN))
  43. {
  44. BOOST_REVERSE_FOREACH(SceneNode* child, children)
  45. {
  46. delete child;
  47. }
  48. }
  49. else
  50. {
  51. BOOST_REVERSE_FOREACH(SceneNode* child, children)
  52. {
  53. child->parent = NULL;
  54. }
  55. }
  56. }
  57. //==============================================================================
  58. // updateWorldTransform =
  59. //==============================================================================
  60. void SceneNode::updateWorldTransform()
  61. {
  62. prevWTrf = wTrf;
  63. if(parent)
  64. {
  65. if(isFlagEnabled(SNF_INHERIT_PARENT_TRANSFORM))
  66. {
  67. wTrf = parent->getWorldTransform();
  68. }
  69. else
  70. {
  71. wTrf = Transform::combineTransformations(
  72. parent->getWorldTransform(), lTrf);
  73. }
  74. }
  75. else // else copy
  76. {
  77. wTrf = lTrf;
  78. }
  79. }
  80. //==============================================================================
  81. // addChild =
  82. //==============================================================================
  83. void SceneNode::addChild(SceneNode& child)
  84. {
  85. ASSERT(child.parent == NULL); // Child already has parent
  86. child.parent = this;
  87. children.push_back(&child);
  88. }
  89. //==============================================================================
  90. // removeChild =
  91. //==============================================================================
  92. void SceneNode::removeChild(SceneNode& child)
  93. {
  94. Vec<SceneNode*>::iterator it = std::find(children.begin(), children.end(),
  95. &child);
  96. if(it == children.end())
  97. {
  98. throw EXCEPTION("Child not found");
  99. }
  100. children.erase(it);
  101. child.parent = NULL;
  102. }
  103. //==============================================================================
  104. // Move(s) =
  105. //==============================================================================
  106. void SceneNode::moveLocalX(float distance)
  107. {
  108. Vec3 x_axis = lTrf.getRotation().getColumn(0);
  109. getLocalTransform().getOrigin() += x_axis * distance;
  110. }
  111. void SceneNode::moveLocalY(float distance)
  112. {
  113. Vec3 y_axis = lTrf.getRotation().getColumn(1);
  114. getLocalTransform().getOrigin() += y_axis * distance;
  115. }
  116. void SceneNode::moveLocalZ(float distance)
  117. {
  118. Vec3 z_axis = lTrf.getRotation().getColumn(2);
  119. getLocalTransform().getOrigin() += z_axis * distance;
  120. }