room_manager_editor_plugin.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. /**************************************************************************/
  2. /* room_manager_editor_plugin.cpp */
  3. /**************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /**************************************************************************/
  8. /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
  9. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /**************************************************************************/
  30. #include "room_manager_editor_plugin.h"
  31. #include "editor/spatial_editor_gizmos.h"
  32. void RoomManagerEditorPlugin::_flip_portals() {
  33. if (_room_manager) {
  34. _room_manager->rooms_flip_portals();
  35. }
  36. }
  37. void RoomManagerEditorPlugin::edit(Object *p_object) {
  38. RoomManager *s = Object::cast_to<RoomManager>(p_object);
  39. if (!s) {
  40. return;
  41. }
  42. _room_manager = s;
  43. }
  44. bool RoomManagerEditorPlugin::handles(Object *p_object) const {
  45. return p_object->is_class("RoomManager");
  46. }
  47. void RoomManagerEditorPlugin::make_visible(bool p_visible) {
  48. if (p_visible) {
  49. button_flip_portals->show();
  50. } else {
  51. button_flip_portals->hide();
  52. }
  53. SpatialEditor::get_singleton()->show_advanced_portal_tools(p_visible);
  54. }
  55. void RoomManagerEditorPlugin::_bind_methods() {
  56. ClassDB::bind_method("_flip_portals", &RoomManagerEditorPlugin::_flip_portals);
  57. }
  58. RoomManagerEditorPlugin::RoomManagerEditorPlugin(EditorNode *p_node) {
  59. editor = p_node;
  60. button_flip_portals = memnew(ToolButton);
  61. button_flip_portals->set_icon(editor->get_gui_base()->get_icon("Portal", "EditorIcons"));
  62. button_flip_portals->set_text(TTR("Flip Portals"));
  63. button_flip_portals->hide();
  64. button_flip_portals->connect("pressed", this, "_flip_portals");
  65. add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, button_flip_portals);
  66. _room_manager = nullptr;
  67. Ref<RoomGizmoPlugin> room_gizmo_plugin = Ref<RoomGizmoPlugin>(memnew(RoomGizmoPlugin));
  68. SpatialEditor::get_singleton()->add_gizmo_plugin(room_gizmo_plugin);
  69. Ref<PortalGizmoPlugin> portal_gizmo_plugin = Ref<PortalGizmoPlugin>(memnew(PortalGizmoPlugin));
  70. SpatialEditor::get_singleton()->add_gizmo_plugin(portal_gizmo_plugin);
  71. Ref<OccluderGizmoPlugin> occluder_gizmo_plugin = Ref<OccluderGizmoPlugin>(memnew(OccluderGizmoPlugin));
  72. SpatialEditor::get_singleton()->add_gizmo_plugin(occluder_gizmo_plugin);
  73. }
  74. RoomManagerEditorPlugin::~RoomManagerEditorPlugin() {
  75. }
  76. ///////////////////////
  77. void RoomEditorPlugin::_generate_points() {
  78. if (_room) {
  79. PoolVector<Vector3> old_pts = _room->get_points();
  80. // only generate points if none already exist
  81. if (_room->_bound_pts.size()) {
  82. _room->set_points(PoolVector<Vector3>());
  83. }
  84. PoolVector<Vector3> pts = _room->generate_points();
  85. // allow the user to undo generating points, because it is
  86. // frustrating to lose old data
  87. undo_redo->create_action(TTR("Room Generate Points"));
  88. undo_redo->add_do_property(_room, "points", pts);
  89. undo_redo->add_undo_property(_room, "points", old_pts);
  90. undo_redo->commit_action();
  91. }
  92. }
  93. void RoomEditorPlugin::edit(Object *p_object) {
  94. Room *s = Object::cast_to<Room>(p_object);
  95. if (!s) {
  96. return;
  97. }
  98. _room = s;
  99. if (SpatialEditor::get_singleton()->is_visible() && s->_planes.size()) {
  100. String string = String(s->get_name()) + " [" + itos(s->_planes.size()) + " planes]";
  101. SpatialEditor::get_singleton()->set_message(string);
  102. }
  103. }
  104. bool RoomEditorPlugin::handles(Object *p_object) const {
  105. return p_object->is_class("Room");
  106. }
  107. void RoomEditorPlugin::make_visible(bool p_visible) {
  108. if (p_visible) {
  109. button_generate->show();
  110. } else {
  111. button_generate->hide();
  112. }
  113. }
  114. void RoomEditorPlugin::_bind_methods() {
  115. ClassDB::bind_method("_generate_points", &RoomEditorPlugin::_generate_points);
  116. }
  117. RoomEditorPlugin::RoomEditorPlugin(EditorNode *p_node) {
  118. editor = p_node;
  119. button_generate = memnew(ToolButton);
  120. button_generate->set_icon(editor->get_gui_base()->get_icon("Room", "EditorIcons"));
  121. button_generate->set_text(TTR("Generate Points"));
  122. button_generate->hide();
  123. button_generate->connect("pressed", this, "_generate_points");
  124. add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, button_generate);
  125. _room = nullptr;
  126. undo_redo = EditorNode::get_undo_redo();
  127. }
  128. RoomEditorPlugin::~RoomEditorPlugin() {
  129. }
  130. ///////////////////////
  131. void PortalEditorPlugin::_flip_portal() {
  132. if (_portal) {
  133. _portal->flip();
  134. _portal->_changed();
  135. }
  136. }
  137. void PortalEditorPlugin::edit(Object *p_object) {
  138. Portal *p = Object::cast_to<Portal>(p_object);
  139. if (!p) {
  140. return;
  141. }
  142. _portal = p;
  143. }
  144. bool PortalEditorPlugin::handles(Object *p_object) const {
  145. return p_object->is_class("Portal");
  146. }
  147. void PortalEditorPlugin::make_visible(bool p_visible) {
  148. if (p_visible) {
  149. button_flip->show();
  150. } else {
  151. button_flip->hide();
  152. }
  153. }
  154. void PortalEditorPlugin::_bind_methods() {
  155. ClassDB::bind_method("_flip_portal", &PortalEditorPlugin::_flip_portal);
  156. }
  157. PortalEditorPlugin::PortalEditorPlugin(EditorNode *p_node) {
  158. editor = p_node;
  159. button_flip = memnew(ToolButton);
  160. button_flip->set_icon(editor->get_gui_base()->get_icon("Portal", "EditorIcons"));
  161. button_flip->set_text(TTR("Flip Portal"));
  162. button_flip->hide();
  163. button_flip->connect("pressed", this, "_flip_portal");
  164. add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, button_flip);
  165. _portal = nullptr;
  166. }
  167. PortalEditorPlugin::~PortalEditorPlugin() {
  168. }
  169. ///////////////////////
  170. void OccluderEditorPlugin::_center() {
  171. if (_occluder && _occluder->is_inside_tree()) {
  172. Ref<OccluderShape> ref = _occluder->get_shape();
  173. if (ref.is_valid()) {
  174. Spatial *parent = Object::cast_to<Spatial>(_occluder->get_parent());
  175. if (parent) {
  176. real_t snap = 0.0;
  177. if (Engine::get_singleton()->is_editor_hint()) {
  178. if (SpatialEditor::get_singleton() && SpatialEditor::get_singleton()->is_snap_enabled()) {
  179. snap = SpatialEditor::get_singleton()->get_translate_snap();
  180. }
  181. }
  182. Transform old_local_xform = _occluder->get_transform();
  183. Transform new_local_xform = ref->center_node(_occluder->get_global_transform(), parent->get_global_transform(), snap);
  184. _occluder->property_list_changed_notify();
  185. undo_redo->create_action(TTR("Occluder Set Transform"));
  186. undo_redo->add_do_method(_occluder, "set_transform", new_local_xform);
  187. undo_redo->add_undo_method(_occluder, "set_transform", old_local_xform);
  188. undo_redo->commit_action();
  189. _occluder->update_gizmo();
  190. }
  191. }
  192. }
  193. }
  194. void OccluderEditorPlugin::edit(Object *p_object) {
  195. Occluder *p = Object::cast_to<Occluder>(p_object);
  196. if (!p) {
  197. return;
  198. }
  199. _occluder = p;
  200. }
  201. bool OccluderEditorPlugin::handles(Object *p_object) const {
  202. return p_object->is_class("Occluder");
  203. }
  204. void OccluderEditorPlugin::make_visible(bool p_visible) {
  205. if (p_visible) {
  206. button_center->show();
  207. } else {
  208. button_center->hide();
  209. }
  210. }
  211. void OccluderEditorPlugin::_bind_methods() {
  212. ClassDB::bind_method("_center", &OccluderEditorPlugin::_center);
  213. }
  214. OccluderEditorPlugin::OccluderEditorPlugin(EditorNode *p_node) {
  215. editor = p_node;
  216. button_center = memnew(ToolButton);
  217. button_center->set_icon(editor->get_gui_base()->get_icon("EditorPosition", "EditorIcons"));
  218. button_center->set_text(TTR("Center Node"));
  219. button_center->hide();
  220. button_center->connect("pressed", this, "_center");
  221. add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, button_center);
  222. undo_redo = EditorNode::get_undo_redo();
  223. _occluder = nullptr;
  224. }
  225. OccluderEditorPlugin::~OccluderEditorPlugin() {
  226. }