1 /*************************************************************************/ 2 /* spatial_editor_plugin.h */ 3 /*************************************************************************/ 4 /* This file is part of: */ 5 /* GODOT ENGINE */ 6 /* https://godotengine.org */ 7 /*************************************************************************/ 8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ 9 /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ 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 #ifndef SPATIAL_EDITOR_PLUGIN_H 31 #define SPATIAL_EDITOR_PLUGIN_H 32 33 #include "editor/editor_node.h" 34 #include "editor/editor_plugin.h" 35 #include "scene/3d/immediate_geometry.h" 36 #include "scene/3d/light.h" 37 #include "scene/3d/visual_instance.h" 38 #include "scene/gui/panel_container.h" 39 /** 40 @author Juan Linietsky <reduzio@gmail.com> 41 */ 42 43 class Camera; 44 class SpatialEditor; 45 class SpatialEditorGizmos; 46 47 class SpatialEditorGizmo : public SpatialGizmo { 48 49 OBJ_TYPE(SpatialEditorGizmo, SpatialGizmo); 50 51 bool selected; 52 53 public: set_selected(bool p_selected)54 void set_selected(bool p_selected) { selected = p_selected; } is_selected()55 bool is_selected() const { return selected; } 56 57 virtual String get_handle_name(int p_idx) const; 58 virtual Variant get_handle_value(int p_idx) const; 59 virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point); 60 virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false); 61 62 virtual bool intersect_frustum(const Camera *p_camera, const Vector<Plane> &p_frustum); 63 virtual bool intersect_ray(const Camera *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle = NULL, bool p_sec_first = false); 64 SpatialEditorGizmo(); 65 }; 66 67 class SpatialEditorViewport : public Control { 68 69 OBJ_TYPE(SpatialEditorViewport, Control); 70 friend class SpatialEditor; 71 enum { 72 73 VIEW_TOP, 74 VIEW_BOTTOM, 75 VIEW_LEFT, 76 VIEW_RIGHT, 77 VIEW_FRONT, 78 VIEW_REAR, 79 VIEW_CENTER_TO_ORIGIN, 80 VIEW_CENTER_TO_SELECTION, 81 VIEW_ALIGN_SELECTION_WITH_VIEW, 82 VIEW_PERSPECTIVE, 83 VIEW_ENVIRONMENT, 84 VIEW_ORTHOGONAL, 85 VIEW_AUDIO_LISTENER, 86 VIEW_GIZMOS, 87 VIEW_FPS, 88 }; 89 90 public: 91 enum { 92 GIZMO_BASE_LAYER = 27, 93 GIZMO_EDIT_LAYER = 26, 94 GIZMO_GRID_LAYER = 25 95 }; 96 97 private: 98 int index; 99 String name; 100 void _menu_option(int p_option); 101 Size2 prev_size; 102 103 EditorNode *editor; 104 EditorSelection *editor_selection; 105 UndoRedo *undo_redo; 106 107 Button *preview_camera; 108 109 MenuButton *view_menu; 110 111 Control *surface; 112 Viewport *viewport; 113 Camera *camera; 114 bool transforming; 115 bool orthogonal; 116 float gizmo_scale; 117 118 PanelContainer *fps; 119 Label *fps_label; 120 121 struct _RayResult { 122 123 Spatial *item; 124 float depth; 125 int handle; 126 _FORCE_INLINE_ bool operator<(const _RayResult &p_rr) const { return depth < p_rr.depth; } 127 }; 128 129 void _update_name(); 130 void _compute_edit(const Point2 &p_point); 131 void _clear_selected(); 132 void _select_clicked(bool p_append, bool p_single); 133 void _select(Spatial *p_node, bool p_append, bool p_single); 134 ObjectID _select_ray(const Point2 &p_pos, bool p_append, bool &r_includes_current, int *r_gizmo_handle = NULL, bool p_alt_select = false); 135 void _find_items_at_pos(const Point2 &p_pos, bool &r_includes_current, Vector<_RayResult> &results, bool p_alt_select = false); 136 Vector3 _get_ray_pos(const Vector2 &p_pos) const; 137 Vector3 _get_ray(const Vector2 &p_pos); 138 Point2 _point_to_screen(const Vector3 &p_point); 139 Transform _get_camera_transform() const; 140 int get_selected_count() const; 141 142 Vector3 _get_camera_pos() const; 143 Vector3 _get_camera_normal() const; 144 Vector3 _get_screen_to_space(const Vector3 &p_vector3); 145 146 void _select_region(); 147 bool _gizmo_select(const Vector2 &p_screenpos, bool p_hilite_only = false); 148 149 float get_znear() const; 150 float get_zfar() const; 151 float get_fov() const; 152 153 ObjectID clicked; 154 Vector<_RayResult> selection_results; 155 bool clicked_includes_current; 156 bool clicked_wants_append; 157 158 PopupMenu *selection_menu; 159 160 enum NavigationScheme { 161 NAVIGATION_GODOT, 162 NAVIGATION_MAYA, 163 NAVIGATION_MODO, 164 }; 165 NavigationScheme _get_navigation_schema(const String &p_property); 166 167 enum NavigationZoomStyle { 168 NAVIGATION_ZOOM_VERTICAL, 169 NAVIGATION_ZOOM_HORIZONTAL 170 }; 171 NavigationZoomStyle _get_navigation_zoom_style(const String &p_property); 172 173 enum NavigationMode { 174 NAVIGATION_NONE, 175 NAVIGATION_PAN, 176 NAVIGATION_ZOOM, 177 NAVIGATION_ORBIT 178 }; 179 enum TransformMode { 180 TRANSFORM_NONE, 181 TRANSFORM_ROTATE, 182 TRANSFORM_TRANSLATE, 183 TRANSFORM_SCALE 184 185 }; 186 enum TransformPlane { 187 TRANSFORM_VIEW, 188 TRANSFORM_X_AXIS, 189 TRANSFORM_Y_AXIS, 190 TRANSFORM_Z_AXIS, 191 }; 192 193 struct EditData { 194 TransformMode mode; 195 TransformPlane plane; 196 Transform original; 197 Vector3 click_ray; 198 Vector3 click_ray_pos; 199 Vector3 center; 200 Vector3 orig_gizmo_pos; 201 int edited_gizmo; 202 Point2 mouse_pos; 203 bool snap; 204 Ref<SpatialEditorGizmo> gizmo; 205 int gizmo_handle; 206 Variant gizmo_initial_value; 207 Vector3 gizmo_initial_pos; 208 } _edit; 209 210 struct Cursor { 211 212 Vector3 cursor_pos; 213 214 Vector3 pos; 215 float x_rot, y_rot, distance; 216 bool region_select; 217 Point2 region_begin, region_end; 218 CursorCursor219 Cursor() { 220 x_rot = y_rot = 0.5; 221 distance = 4; 222 region_select = false; 223 } 224 } cursor; 225 226 RID move_gizmo_instance[3], rotate_gizmo_instance[3]; 227 228 String last_message; 229 String message; 230 float message_time; 231 232 void set_message(String p_message, float p_time = 5); 233 234 // 235 void _update_camera(); 236 void _draw(); 237 238 void _smouseenter(); 239 void _sinput(const InputEvent &p_ie); 240 SpatialEditor *spatial_editor; 241 242 Camera *previewing; 243 Camera *preview; 244 245 void _preview_exited_scene(); 246 void _toggle_camera_preview(bool); 247 void _init_gizmo_instance(int p_idx); 248 void _finish_gizmo_instances(); 249 void _selection_result_pressed(int); 250 void _selection_menu_hide(); 251 void _list_select(InputEventMouseButton b); 252 253 protected: 254 void _notification(int p_what); 255 static void _bind_methods(); 256 257 public: 258 void update_transform_gizmo_view(); 259 260 void set_can_preview(Camera *p_preview); 261 void set_state(const Dictionary &p_state); 262 Dictionary get_state() const; 263 void reset(); get_viewport_node()264 Viewport *get_viewport_node() { return viewport; } 265 266 SpatialEditorViewport(SpatialEditor *p_spatial_editor, EditorNode *p_editor, int p_index); 267 }; 268 269 class SpatialEditorSelectedItem : public Object { 270 271 OBJ_TYPE(SpatialEditorSelectedItem, Object); 272 273 public: 274 AABB aabb; 275 Transform original; // original location when moving 276 Transform last_xform; // last transform 277 Spatial *sp; 278 RID sbox_instance; 279 SpatialEditorSelectedItem()280 SpatialEditorSelectedItem() { sp = NULL; } 281 ~SpatialEditorSelectedItem(); 282 }; 283 284 class SpatialEditor : public VBoxContainer { 285 286 OBJ_TYPE(SpatialEditor, VBoxContainer); 287 288 public: 289 enum ToolMode { 290 291 TOOL_MODE_SELECT, 292 TOOL_MODE_MOVE, 293 TOOL_MODE_ROTATE, 294 TOOL_MODE_SCALE, 295 TOOL_MODE_LIST_SELECT, 296 TOOL_MAX 297 298 }; 299 300 private: 301 EditorNode *editor; 302 EditorSelection *editor_selection; 303 304 Control *viewport_base; 305 SpatialEditorViewport *viewports[4]; 306 VSplitContainer *shader_split; 307 HSplitContainer *palette_split; 308 309 ///// 310 311 ToolMode tool_mode; 312 bool orthogonal; 313 314 VisualServer::ScenarioDebugMode scenario_debug; 315 316 RID light; 317 RID light_instance; 318 Transform light_transform; 319 320 RID origin; 321 RID origin_instance; 322 RID grid[3]; 323 RID grid_instance[3]; 324 bool grid_visible[3]; //currently visible 325 float last_grid_snap; 326 bool grid_enable[3]; //should be always visible if true 327 bool grid_enabled; 328 329 Ref<Mesh> move_gizmo[3], rotate_gizmo[3]; 330 Ref<FixedMaterial> gizmo_color[3]; 331 Ref<FixedMaterial> gizmo_hl; 332 333 int over_gizmo_handle; 334 335 Ref<Mesh> selection_box; 336 RID indicators; 337 RID indicators_instance; 338 RID cursor_mesh; 339 RID cursor_instance; 340 RID indicator_mat; 341 RID cursor_material; 342 343 /* 344 struct Selected { 345 AABB aabb; 346 Transform original; // original location when moving 347 Transform last_xform; // last transform 348 Spatial *sp; 349 RID poly_instance; 350 }; 351 352 Map<uint32_t,Selected> selected; 353 */ 354 struct Gizmo { 355 356 bool visible; 357 float scale; 358 Transform transform; 359 } gizmo; 360 361 enum MenuOption { 362 363 MENU_TOOL_SELECT, 364 MENU_TOOL_MOVE, 365 MENU_TOOL_ROTATE, 366 MENU_TOOL_SCALE, 367 MENU_TOOL_LIST_SELECT, 368 MENU_TRANSFORM_USE_SNAP, 369 MENU_TRANSFORM_CONFIGURE_SNAP, 370 MENU_TRANSFORM_LOCAL_COORDS, 371 MENU_TRANSFORM_DIALOG, 372 MENU_VIEW_USE_1_VIEWPORT, 373 MENU_VIEW_USE_2_VIEWPORTS, 374 MENU_VIEW_USE_2_VIEWPORTS_ALT, 375 MENU_VIEW_USE_3_VIEWPORTS, 376 MENU_VIEW_USE_3_VIEWPORTS_ALT, 377 MENU_VIEW_USE_4_VIEWPORTS, 378 MENU_VIEW_USE_DEFAULT_LIGHT, 379 MENU_VIEW_USE_DEFAULT_SRGB, 380 MENU_VIEW_DISPLAY_NORMAL, 381 MENU_VIEW_DISPLAY_WIREFRAME, 382 MENU_VIEW_DISPLAY_OVERDRAW, 383 MENU_VIEW_DISPLAY_SHADELESS, 384 MENU_VIEW_ORIGIN, 385 MENU_VIEW_GRID, 386 MENU_VIEW_CAMERA_SETTINGS, 387 388 }; 389 390 Button *tool_button[TOOL_MAX]; 391 Button *instance_button; 392 393 MenuButton *transform_menu; 394 MenuButton *view_menu; 395 396 ConfirmationDialog *snap_dialog; 397 ConfirmationDialog *xform_dialog; 398 ConfirmationDialog *settings_dialog; 399 400 bool snap_enabled; 401 LineEdit *snap_translate; 402 LineEdit *snap_rotate; 403 LineEdit *snap_scale; 404 PanelContainer *menu_panel; 405 406 LineEdit *xform_translate[3]; 407 LineEdit *xform_rotate[3]; 408 LineEdit *xform_scale[3]; 409 OptionButton *xform_type; 410 411 VBoxContainer *settings_vbc; 412 SpinBox *settings_fov; 413 SpinBox *settings_znear; 414 SpinBox *settings_zfar; 415 DirectionalLight *settings_dlight; 416 ImmediateGeometry *settings_sphere; 417 Camera *settings_camera; 418 float settings_default_light_rot_x; 419 float settings_default_light_rot_y; 420 421 Control *settings_light_base; 422 Viewport *settings_light_vp; 423 ColorPickerButton *settings_ambient_color; 424 Image settings_light_dir_image; 425 426 void _xform_dialog_action(); 427 void _menu_item_pressed(int p_option); 428 429 HBoxContainer *hbc_menu; 430 431 // 432 // 433 void _generate_selection_box(); 434 UndoRedo *undo_redo; 435 436 void _instance_scene(); 437 void _init_indicators(); 438 void _finish_indicators(); 439 440 void _toggle_maximize_view(Object *p_viewport); 441 442 Node *custom_camera; 443 444 Object *_get_editor_data(Object *p_what); 445 446 Ref<Environment> viewport_environment; 447 448 Spatial *selected; 449 450 void _request_gizmo(Object *p_obj); 451 452 static SpatialEditor *singleton; 453 454 void _node_removed(Node *p_node); 455 SpatialEditorGizmos *gizmos; 456 SpatialEditor(); 457 458 void _update_ambient_light_color(const Color &p_color); 459 void _update_default_light_angle(); 460 void _default_light_angle_input(const InputEvent &p_event); 461 462 protected: 463 void _notification(int p_what); 464 //void _input_event(InputEvent p_event); 465 void _unhandled_key_input(InputEvent p_event); 466 467 static void _bind_methods(); 468 469 public: get_singleton()470 static SpatialEditor *get_singleton() { return singleton; } 471 void snap_cursor_to_plane(const Plane &p_plane); 472 get_znear()473 float get_znear() const { return settings_znear->get_val(); } get_zfar()474 float get_zfar() const { return settings_zfar->get_val(); } get_fov()475 float get_fov() const { return settings_fov->get_val(); } 476 get_gizmo_transform()477 Transform get_gizmo_transform() const { return gizmo.transform; } is_gizmo_visible()478 bool is_gizmo_visible() const { return gizmo.visible; } 479 get_tool_mode()480 ToolMode get_tool_mode() const { return tool_mode; } is_snap_enabled()481 bool is_snap_enabled() const { return snap_enabled; } get_translate_snap()482 float get_translate_snap() const { return snap_translate->get_text().to_double(); } get_rotate_snap()483 float get_rotate_snap() const { return snap_rotate->get_text().to_double(); } get_scale_snap()484 float get_scale_snap() const { return snap_scale->get_text().to_double(); } 485 get_move_gizmo(int idx)486 Ref<Mesh> get_move_gizmo(int idx) const { return move_gizmo[idx]; } get_rotate_gizmo(int idx)487 Ref<Mesh> get_rotate_gizmo(int idx) const { return rotate_gizmo[idx]; } 488 489 void update_transform_gizmo(); 490 491 void select_gizmo_highlight_axis(int p_axis); set_custom_camera(Node * p_camera)492 void set_custom_camera(Node *p_camera) { custom_camera = p_camera; } 493 set_undo_redo(UndoRedo * p_undo_redo)494 void set_undo_redo(UndoRedo *p_undo_redo) { undo_redo = p_undo_redo; } 495 Dictionary get_state() const; 496 void set_state(const Dictionary &p_state); 497 get_viewport_environment()498 Ref<Environment> get_viewport_environment() { return viewport_environment; } 499 get_undo_redo()500 UndoRedo *get_undo_redo() { return undo_redo; } 501 502 void add_control_to_menu_panel(Control *p_control); 503 504 VSplitContainer *get_shader_split(); 505 HSplitContainer *get_palette_split(); 506 get_selected()507 Spatial *get_selected() { return selected; } 508 get_over_gizmo_handle()509 int get_over_gizmo_handle() const { return over_gizmo_handle; } set_over_gizmo_handle(int idx)510 void set_over_gizmo_handle(int idx) { over_gizmo_handle = idx; } 511 512 void set_can_preview(Camera *p_preview); 513 get_editor_viewport(int p_idx)514 SpatialEditorViewport *get_editor_viewport(int p_idx) { 515 ERR_FAIL_INDEX_V(p_idx, 4, NULL); 516 return viewports[p_idx]; 517 } 518 get_camera()519 Camera *get_camera() { return NULL; } 520 void edit(Spatial *p_spatial); 521 void clear(); 522 SpatialEditor(EditorNode *p_editor); 523 ~SpatialEditor(); 524 }; 525 526 class SpatialEditorPlugin : public EditorPlugin { 527 528 OBJ_TYPE(SpatialEditorPlugin, EditorPlugin); 529 530 SpatialEditor *spatial_editor; 531 EditorNode *editor; 532 533 protected: 534 static void _bind_methods(); 535 536 public: 537 void snap_cursor_to_plane(const Plane &p_plane); 538 get_spatial_editor()539 SpatialEditor *get_spatial_editor() { return spatial_editor; } get_name()540 virtual String get_name() const { return "3D"; } has_main_screen()541 bool has_main_screen() const { return true; } 542 virtual void make_visible(bool p_visible); 543 virtual void edit(Object *p_object); 544 virtual bool handles(Object *p_object) const; 545 546 virtual Dictionary get_state() const; 547 virtual void set_state(const Dictionary &p_state); clear()548 virtual void clear() { spatial_editor->clear(); } 549 550 SpatialEditorPlugin(EditorNode *p_node); 551 ~SpatialEditorPlugin(); 552 }; 553 554 #endif 555