SceneSelection.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. #include <Atomic/IO/Log.h>
  2. #include <Atomic/Core/CoreEvents.h>
  3. #include <Atomic/Graphics/Graphics.h>
  4. #include <Atomic/Graphics/Drawable.h>
  5. #include <Atomic/Graphics/DebugRenderer.h>
  6. #include <Atomic/Atomic3D/Terrain.h>
  7. #include <Atomic/Scene/SceneEvents.h>
  8. #include <Atomic/Scene/Node.h>
  9. #include <Atomic/Scene/Scene.h>
  10. #include "SceneEditor3D.h"
  11. #include "SceneEditor3DEvents.h"
  12. #include "SceneSelection.h"
  13. namespace AtomicEditor
  14. {
  15. SceneSelection::SceneSelection(Context* context, SceneEditor3D *sceneEditor) : Object(context)
  16. {
  17. sceneEditor3D_ = sceneEditor;
  18. scene_ = sceneEditor3D_->GetScene();
  19. SubscribeToEvent(E_POSTRENDERUPDATE, HANDLER(SceneSelection, HandlePostRenderUpdate));
  20. SubscribeToEvent(scene_, E_NODEREMOVED, HANDLER(SceneSelection, HandleNodeRemoved));
  21. }
  22. SceneSelection::~SceneSelection()
  23. {
  24. }
  25. Node* SceneSelection::GetSelectedNode(unsigned index) const
  26. {
  27. if (index > nodes_.Size())
  28. return 0;
  29. return nodes_[index];
  30. }
  31. bool SceneSelection::Contains(Node* node)
  32. {
  33. SharedPtr<Node> _node(node);
  34. return nodes_.Contains(_node);
  35. }
  36. void SceneSelection::AddNode(Node* node, bool clear)
  37. {
  38. if (clear)
  39. Clear();
  40. SharedPtr<Node> _node(node);
  41. if (!nodes_.Contains(_node))
  42. {
  43. nodes_.Push(_node);
  44. VariantMap eventData;
  45. eventData[SceneNodeSelected::P_SCENE] = scene_;
  46. eventData[SceneNodeSelected::P_NODE] = node;
  47. eventData[SceneNodeSelected::P_SELECTED] = true;
  48. scene_->SendEvent(E_SCENENODESELECTED, eventData);
  49. }
  50. }
  51. void SceneSelection::RemoveNode(Node* node)
  52. {
  53. SharedPtr<Node> _node(node);
  54. if(!nodes_.Contains(_node))
  55. return;
  56. nodes_.Remove(_node);
  57. VariantMap eventData;
  58. eventData[SceneNodeSelected::P_SCENE] = scene_;
  59. eventData[SceneNodeSelected::P_NODE] = node;
  60. eventData[SceneNodeSelected::P_SELECTED] = false;
  61. scene_->SendEvent(E_SCENENODESELECTED, eventData);
  62. }
  63. void SceneSelection::Clear()
  64. {
  65. Vector<SharedPtr<Node>> nodes = nodes_;
  66. for (unsigned i = 0; i < nodes.Size(); i++)
  67. {
  68. RemoveNode(nodes[i]);
  69. }
  70. }
  71. void SceneSelection::Paste()
  72. {
  73. /*
  74. if (clipboardNode_.NotNull() && selectedNode_.NotNull())
  75. {
  76. SharedPtr<Node> pasteNode(clipboardNode_->Clone());
  77. VariantMap eventData;
  78. eventData[EditorActiveNodeChange::P_NODE] = pasteNode;
  79. SendEvent(E_EDITORACTIVENODECHANGE, eventData);
  80. VariantMap editData;
  81. editData[SceneEditNodeAddedRemoved::P_SCENE] = scene_;
  82. editData[SceneEditNodeAddedRemoved::P_NODE] = pasteNode;
  83. editData[SceneEditNodeAddedRemoved::P_ADDED] = true;
  84. scene_->SendEvent(E_SCENEEDITNODEADDEDREMOVED, editData);
  85. }
  86. */
  87. }
  88. void SceneSelection::Copy()
  89. {
  90. /*
  91. if (selectedNode_.NotNull())
  92. {
  93. clipboardNode_ = selectedNode_;
  94. }
  95. */
  96. }
  97. void SceneSelection::Delete()
  98. {
  99. Vector<SharedPtr<Node>> nodes = nodes_;
  100. Clear();
  101. VariantMap eventData;
  102. eventData[SceneEditAddRemoveNodes::P_END] = false;
  103. scene_->SendEvent(E_SCENEEDITADDREMOVENODES, eventData);
  104. for (unsigned i = 0; i < nodes.Size(); i++)
  105. {
  106. nodes[i]->Remove();
  107. }
  108. eventData[SceneEditAddRemoveNodes::P_END] = true;
  109. scene_->SendEvent(E_SCENEEDITADDREMOVENODES, eventData);
  110. }
  111. void SceneSelection::GetBounds(BoundingBox& bbox)
  112. {
  113. bbox.Clear();
  114. if (!nodes_.Size())
  115. return;
  116. // Get all the drawables, which define the bounding box of the selection
  117. PODVector<Drawable*> drawables;
  118. for (unsigned i = 0; i < nodes_.Size(); i++)
  119. {
  120. Node* node = nodes_[i];
  121. node->GetDerivedComponents<Drawable>(drawables, true, false);
  122. }
  123. if (!drawables.Size())
  124. return;
  125. // Calculate the combined bounding box of all drawables
  126. for (unsigned i = 0; i < drawables.Size(); i++ )
  127. {
  128. Drawable* drawable = drawables[i];
  129. bbox.Merge(drawable->GetWorldBoundingBox());
  130. }
  131. }
  132. void SceneSelection::DrawNodeDebug(Node* node, DebugRenderer* debug, bool drawNode)
  133. {
  134. if (drawNode)
  135. debug->AddNode(node, 1.0, false);
  136. // Exception for the scene to avoid bringing the editor to its knees: drawing either the whole hierarchy or the subsystem-
  137. // components can have a large performance hit. Also do not draw terrain child nodes due to their large amount
  138. // (TerrainPatch component itself draws nothing as debug geometry)
  139. if (node != scene_ && !node->GetComponent<Terrain>())
  140. {
  141. const Vector<SharedPtr<Component> >& components = node->GetComponents();
  142. for (unsigned j = 0; j < components.Size(); ++j)
  143. components[j]->DrawDebugGeometry(debug, false);
  144. // To avoid cluttering the view, do not draw the node axes for child nodes
  145. for (unsigned k = 0; k < node->GetNumChildren(); ++k)
  146. DrawNodeDebug(node->GetChild(k), debug, false);
  147. }
  148. }
  149. void SceneSelection::HandleNodeRemoved(StringHash eventType, VariantMap& eventData)
  150. {
  151. Node* node = (Node*) (eventData[NodeRemoved::P_NODE].GetPtr());
  152. RemoveNode(node);
  153. }
  154. void SceneSelection::HandlePostRenderUpdate(StringHash eventType, VariantMap& eventData)
  155. {
  156. if (!nodes_.Size())
  157. return;
  158. // Visualize the currently selected nodes
  159. DebugRenderer* debugRenderer = sceneEditor3D_->GetSceneView3D()->GetDebugRenderer();
  160. for (unsigned i = 0; i < nodes_.Size(); i++)
  161. {
  162. DrawNodeDebug(nodes_[i], debugRenderer);
  163. }
  164. }
  165. }