SceneSelection.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. //
  2. // Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
  3. // LICENSE: Atomic Game Engine Editor and Tools EULA
  4. // Please see LICENSE_ATOMIC_EDITOR_AND_TOOLS.md in repository root for
  5. // license information: https://github.com/AtomicGameEngine/AtomicGameEngine
  6. //
  7. #include <Atomic/IO/Log.h>
  8. #include <Atomic/Core/CoreEvents.h>
  9. #include <Atomic/Graphics/Graphics.h>
  10. #include <Atomic/Graphics/Drawable.h>
  11. #include <Atomic/Graphics/DebugRenderer.h>
  12. #include <Atomic/Atomic3D/Terrain.h>
  13. #include <Atomic/Scene/SceneEvents.h>
  14. #include <Atomic/Scene/Node.h>
  15. #include <Atomic/Scene/Scene.h>
  16. #include "SceneEditor3D.h"
  17. #include "SceneEditor3DEvents.h"
  18. #include "SceneSelection.h"
  19. namespace AtomicEditor
  20. {
  21. SceneSelection::SceneSelection(Context* context, SceneEditor3D *sceneEditor) : Object(context)
  22. {
  23. sceneEditor3D_ = sceneEditor;
  24. scene_ = sceneEditor3D_->GetScene();
  25. SubscribeToEvent(E_POSTRENDERUPDATE, HANDLER(SceneSelection, HandlePostRenderUpdate));
  26. SubscribeToEvent(scene_, E_NODEREMOVED, HANDLER(SceneSelection, HandleNodeRemoved));
  27. }
  28. SceneSelection::~SceneSelection()
  29. {
  30. }
  31. Node* SceneSelection::GetSelectedNode(unsigned index) const
  32. {
  33. if (index > nodes_.Size())
  34. return 0;
  35. return nodes_[index];
  36. }
  37. bool SceneSelection::Contains(Node* node)
  38. {
  39. SharedPtr<Node> _node(node);
  40. return nodes_.Contains(_node);
  41. }
  42. void SceneSelection::AddNode(Node* node, bool clear)
  43. {
  44. if (clear)
  45. Clear();
  46. SharedPtr<Node> _node(node);
  47. if (!nodes_.Contains(_node))
  48. {
  49. nodes_.Push(_node);
  50. VariantMap eventData;
  51. eventData[SceneNodeSelected::P_SCENE] = scene_;
  52. eventData[SceneNodeSelected::P_NODE] = node;
  53. eventData[SceneNodeSelected::P_SELECTED] = true;
  54. scene_->SendEvent(E_SCENENODESELECTED, eventData);
  55. }
  56. }
  57. void SceneSelection::RemoveNode(Node* node, bool quiet)
  58. {
  59. SharedPtr<Node> _node(node);
  60. if(!nodes_.Contains(_node))
  61. return;
  62. nodes_.Remove(_node);
  63. if (quiet)
  64. return;
  65. VariantMap eventData;
  66. eventData[SceneNodeSelected::P_SCENE] = scene_;
  67. eventData[SceneNodeSelected::P_NODE] = node;
  68. eventData[SceneNodeSelected::P_SELECTED] = false;
  69. scene_->SendEvent(E_SCENENODESELECTED, eventData);
  70. }
  71. void SceneSelection::Clear()
  72. {
  73. Vector<SharedPtr<Node>> nodes = nodes_;
  74. for (unsigned i = 0; i < nodes.Size(); i++)
  75. {
  76. RemoveNode(nodes[i]);
  77. }
  78. }
  79. void SceneSelection::Paste()
  80. {
  81. if (!clipBoardNodes_.Size())
  82. return;
  83. Vector<SharedPtr<Node>> newClipBoardNodes;
  84. Node* parent = scene_;
  85. if (nodes_.Size() >= 1)
  86. parent = nodes_[0]->GetParent();
  87. if (!parent)
  88. parent = scene_;
  89. Clear();
  90. VariantMap eventData;
  91. eventData[SceneEditAddRemoveNodes::P_END] = false;
  92. scene_->SendEvent(E_SCENEEDITADDREMOVENODES, eventData);
  93. for (unsigned i = 0; i < clipBoardNodes_.Size(); i++)
  94. {
  95. // Nodes must have a parent to clone, so first parent
  96. Node* clipNode = clipBoardNodes_[i];
  97. Matrix3x4 transform = clipNode->GetWorldTransform();
  98. clipNode->SetWorldTransform(transform.Translation(), transform.Rotation(), transform.Scale());
  99. parent->AddChild(clipNode);
  100. // clone
  101. newClipBoardNodes.Push(SharedPtr<Node>(clipNode->Clone()));
  102. // remove from parent
  103. newClipBoardNodes.Back()->Remove();
  104. newClipBoardNodes.Back()->SetWorldTransform(transform.Translation(), transform.Rotation(), transform.Scale());
  105. // generate scene edit event
  106. VariantMap nodeAddedEventData;
  107. nodeAddedEventData[SceneEditNodeAdded::P_NODE] = clipNode;
  108. nodeAddedEventData[SceneEditNodeAdded::P_PARENT] = parent;
  109. nodeAddedEventData[SceneEditNodeAdded::P_SCENE] = scene_;
  110. scene_->SendEvent(E_SCENEEDITNODEADDED, nodeAddedEventData);
  111. }
  112. eventData[SceneEditAddRemoveNodes::P_END] = true;
  113. scene_->SendEvent(E_SCENEEDITADDREMOVENODES, eventData);
  114. for (unsigned i = 0; i < clipBoardNodes_.Size(); i++)
  115. {
  116. AddNode(clipBoardNodes_[i], false);
  117. }
  118. clipBoardNodes_ = newClipBoardNodes;
  119. }
  120. void SceneSelection::Copy()
  121. {
  122. clipBoardNodes_.Clear();
  123. for (unsigned i = 0; i < nodes_.Size(); i++)
  124. {
  125. Node* node = nodes_[i];
  126. if (!node->GetParent())
  127. {
  128. clipBoardNodes_.Clear();
  129. LOGERROR("SceneSelection::Copy - unable to copy node to clipboard (no parent)");
  130. return;
  131. }
  132. for (unsigned j = 0; j < nodes_.Size(); j++)
  133. {
  134. if ( i == j )
  135. continue;
  136. PODVector<Node*> children;
  137. nodes_[j]->GetChildren(children, true);
  138. if (children.Contains(node))
  139. {
  140. node = 0;
  141. break;
  142. }
  143. }
  144. if (node)
  145. {
  146. SharedPtr<Node> clipNode(node->Clone());
  147. clipNode->Remove();
  148. clipBoardNodes_.Push(clipNode);
  149. }
  150. }
  151. }
  152. void SceneSelection::Delete()
  153. {
  154. Vector<SharedPtr<Node>> nodes = nodes_;
  155. Clear();
  156. VariantMap eventData;
  157. eventData[SceneEditAddRemoveNodes::P_END] = false;
  158. scene_->SendEvent(E_SCENEEDITADDREMOVENODES, eventData);
  159. for (unsigned i = 0; i < nodes.Size(); i++)
  160. {
  161. // generate scene edit event
  162. VariantMap nodeRemovedEventData;
  163. nodeRemovedEventData[SceneEditNodeAdded::P_NODE] = nodes[i];
  164. nodeRemovedEventData[SceneEditNodeAdded::P_PARENT] = nodes[i]->GetParent();
  165. nodeRemovedEventData[SceneEditNodeAdded::P_SCENE] = scene_;
  166. scene_->SendEvent(E_SCENEEDITNODEREMOVED, nodeRemovedEventData);
  167. nodes[i]->Remove();
  168. }
  169. eventData[SceneEditAddRemoveNodes::P_END] = true;
  170. scene_->SendEvent(E_SCENEEDITADDREMOVENODES, eventData);
  171. }
  172. void SceneSelection::GetBounds(BoundingBox& bbox)
  173. {
  174. bbox.Clear();
  175. if (!nodes_.Size())
  176. return;
  177. // Get all the drawables, which define the bounding box of the selection
  178. PODVector<Drawable*> drawables;
  179. for (unsigned i = 0; i < nodes_.Size(); i++)
  180. {
  181. Node* node = nodes_[i];
  182. node->GetDerivedComponents<Drawable>(drawables, true, false);
  183. }
  184. if (!drawables.Size())
  185. return;
  186. // Calculate the combined bounding box of all drawables
  187. for (unsigned i = 0; i < drawables.Size(); i++ )
  188. {
  189. Drawable* drawable = drawables[i];
  190. bbox.Merge(drawable->GetWorldBoundingBox());
  191. }
  192. }
  193. void SceneSelection::DrawNodeDebug(Node* node, DebugRenderer* debug, bool drawNode)
  194. {
  195. if (drawNode)
  196. debug->AddNode(node, 1.0, false);
  197. // Exception for the scene to avoid bringing the editor to its knees: drawing either the whole hierarchy or the subsystem-
  198. // components can have a large performance hit. Also do not draw terrain child nodes due to their large amount
  199. // (TerrainPatch component itself draws nothing as debug geometry)
  200. if (node != scene_ && !node->GetComponent<Terrain>())
  201. {
  202. const Vector<SharedPtr<Component> >& components = node->GetComponents();
  203. for (unsigned j = 0; j < components.Size(); ++j)
  204. components[j]->DrawDebugGeometry(debug, false);
  205. // To avoid cluttering the view, do not draw the node axes for child nodes
  206. for (unsigned k = 0; k < node->GetNumChildren(); ++k)
  207. DrawNodeDebug(node->GetChild(k), debug, false);
  208. }
  209. }
  210. void SceneSelection::HandleNodeRemoved(StringHash eventType, VariantMap& eventData)
  211. {
  212. Node* node = (Node*) (eventData[NodeRemoved::P_NODE].GetPtr());
  213. RemoveNode(node, true);
  214. }
  215. void SceneSelection::HandlePostRenderUpdate(StringHash eventType, VariantMap& eventData)
  216. {
  217. if (!nodes_.Size())
  218. return;
  219. // Visualize the currently selected nodes
  220. DebugRenderer* debugRenderer = sceneEditor3D_->GetSceneView3D()->GetDebugRenderer();
  221. for (unsigned i = 0; i < nodes_.Size(); i++)
  222. {
  223. DrawNodeDebug(nodes_[i], debugRenderer);
  224. }
  225. }
  226. }