SceneSelection.cpp 5.5 KB

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