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-2020 Juan Linietsky, Ariel Manzur. */ 9 /* Copyright (c) 2014-2020 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 31 #ifndef SPATIAL_EDITOR_PLUGIN_H 32 #define SPATIAL_EDITOR_PLUGIN_H 33 34 #include "editor/editor_node.h" 35 #include "editor/editor_plugin.h" 36 #include "editor/editor_scale.h" 37 #include "scene/3d/immediate_geometry.h" 38 #include "scene/3d/light.h" 39 #include "scene/3d/visual_instance.h" 40 #include "scene/gui/panel_container.h" 41 42 class Camera; 43 class SpatialEditor; 44 class EditorSpatialGizmoPlugin; 45 class ViewportContainer; 46 class SpatialEditorViewport; 47 48 class EditorSpatialGizmo : public SpatialGizmo { 49 50 GDCLASS(EditorSpatialGizmo, SpatialGizmo); 51 52 bool selected; 53 bool instanced; 54 55 public: set_selected(bool p_selected)56 void set_selected(bool p_selected) { selected = p_selected; } is_selected()57 bool is_selected() const { return selected; } 58 59 struct Instance { 60 61 RID instance; 62 Ref<ArrayMesh> mesh; 63 Ref<Material> material; 64 Ref<SkinReference> skin_reference; 65 RID skeleton; 66 bool billboard; 67 bool unscaled; 68 bool can_intersect; 69 bool extra_margin; InstanceInstance70 Instance() { 71 72 billboard = false; 73 unscaled = false; 74 can_intersect = false; 75 extra_margin = false; 76 } 77 78 void create_instance(Spatial *p_base, bool p_hidden = false); 79 }; 80 81 Vector<Vector3> collision_segments; 82 Ref<TriangleMesh> collision_mesh; 83 84 struct Handle { 85 Vector3 pos; 86 bool billboard; 87 }; 88 89 Vector<Vector3> handles; 90 Vector<Vector3> secondary_handles; 91 float selectable_icon_size; 92 bool billboard_handle; 93 94 bool valid; 95 bool hidden; 96 Spatial *base; 97 Vector<Instance> instances; 98 Spatial *spatial_node; 99 EditorSpatialGizmoPlugin *gizmo_plugin; 100 _set_spatial_node(Node * p_node)101 void _set_spatial_node(Node *p_node) { set_spatial_node(Object::cast_to<Spatial>(p_node)); } 102 103 protected: 104 static void _bind_methods(); 105 106 public: 107 void add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard = false, const Color &p_modulate = Color(1, 1, 1)); 108 void add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard = false, const Ref<SkinReference> &p_skin_reference = Ref<SkinReference>(), const Ref<Material> &p_material = Ref<Material>()); 109 void add_collision_segments(const Vector<Vector3> &p_lines); 110 void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh); 111 void add_unscaled_billboard(const Ref<Material> &p_material, float p_scale = 1, const Color &p_modulate = Color(1, 1, 1)); 112 void add_handles(const Vector<Vector3> &p_handles, const Ref<Material> &p_material, bool p_billboard = false, bool p_secondary = false); 113 void add_solid_box(Ref<Material> &p_material, Vector3 p_size, Vector3 p_position = Vector3()); 114 115 virtual bool is_handle_highlighted(int p_idx) const; 116 virtual String get_handle_name(int p_idx) const; 117 virtual Variant get_handle_value(int p_idx); 118 virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point); 119 virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false); 120 121 void set_spatial_node(Spatial *p_node); get_spatial_node()122 Spatial *get_spatial_node() const { return spatial_node; } get_plugin()123 Ref<EditorSpatialGizmoPlugin> get_plugin() const { return gizmo_plugin; } 124 Vector3 get_handle_pos(int p_idx) const; 125 bool intersect_frustum(const Camera *p_camera, const Vector<Plane> &p_frustum); 126 bool intersect_ray(Camera *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle = NULL, bool p_sec_first = false); 127 128 virtual void clear(); 129 virtual void create(); 130 virtual void transform(); 131 virtual void redraw(); 132 virtual void free(); 133 134 virtual bool is_editable() const; 135 136 void set_hidden(bool p_hidden); 137 void set_plugin(EditorSpatialGizmoPlugin *p_plugin); 138 139 EditorSpatialGizmo(); 140 ~EditorSpatialGizmo(); 141 }; 142 143 class ViewportRotationControl : public Control { 144 GDCLASS(ViewportRotationControl, Control); 145 146 struct Axis2D { 147 Vector2 screen_point; 148 float z_axis = -99.0; 149 int axis = -1; 150 }; 151 152 struct Axis2DCompare { operatorAxis2DCompare153 _FORCE_INLINE_ bool operator()(const Axis2D &l, const Axis2D &r) const { 154 return l.z_axis < r.z_axis; 155 } 156 }; 157 158 SpatialEditorViewport *viewport = nullptr; 159 Vector<Color> axis_colors; 160 Vector<int> axis_menu_options; 161 Vector2i orbiting_mouse_start; 162 bool orbiting = false; 163 int focused_axis = -2; 164 165 const float AXIS_CIRCLE_RADIUS = 8.0f * EDSCALE; 166 167 protected: 168 static void _bind_methods(); 169 void _notification(int p_what); 170 void _gui_input(Ref<InputEvent> p_event); 171 void _draw(); 172 void _draw_axis(const Axis2D &p_axis); 173 void _get_sorted_axis(Vector<Axis2D> &r_axis); 174 void _update_focus(); 175 void _on_mouse_exited(); 176 177 public: 178 void set_viewport(SpatialEditorViewport *p_viewport); 179 }; 180 181 class SpatialEditorViewport : public Control { 182 183 GDCLASS(SpatialEditorViewport, Control); 184 friend class SpatialEditor; 185 friend class ViewportRotationControl; 186 enum { 187 188 VIEW_TOP, 189 VIEW_BOTTOM, 190 VIEW_LEFT, 191 VIEW_RIGHT, 192 VIEW_FRONT, 193 VIEW_REAR, 194 VIEW_CENTER_TO_ORIGIN, 195 VIEW_CENTER_TO_SELECTION, 196 VIEW_ALIGN_TRANSFORM_WITH_VIEW, 197 VIEW_ALIGN_ROTATION_WITH_VIEW, 198 VIEW_PERSPECTIVE, 199 VIEW_ENVIRONMENT, 200 VIEW_ORTHOGONAL, 201 VIEW_HALF_RESOLUTION, 202 VIEW_AUDIO_LISTENER, 203 VIEW_AUDIO_DOPPLER, 204 VIEW_GIZMOS, 205 VIEW_INFORMATION, 206 VIEW_FPS, 207 VIEW_DISPLAY_NORMAL, 208 VIEW_DISPLAY_WIREFRAME, 209 VIEW_DISPLAY_OVERDRAW, 210 VIEW_DISPLAY_SHADELESS, 211 VIEW_LOCK_ROTATION, 212 VIEW_CINEMATIC_PREVIEW, 213 VIEW_AUTO_ORTHOGONAL 214 }; 215 216 public: 217 enum { 218 GIZMO_BASE_LAYER = 27, 219 GIZMO_EDIT_LAYER = 26, 220 GIZMO_GRID_LAYER = 25 221 }; 222 223 enum NavigationScheme { 224 NAVIGATION_GODOT, 225 NAVIGATION_MAYA, 226 NAVIGATION_MODO, 227 }; 228 229 enum FreelookNavigationScheme { 230 FREELOOK_DEFAULT, 231 FREELOOK_PARTIALLY_AXIS_LOCKED, 232 FREELOOK_FULLY_AXIS_LOCKED, 233 }; 234 235 private: 236 int index; 237 String name; 238 void _menu_option(int p_option); 239 void _set_auto_orthogonal(); 240 Spatial *preview_node; 241 AABB *preview_bounds; 242 Vector<String> selected_files; 243 AcceptDialog *accept; 244 245 Node *target_node; 246 Point2 drop_pos; 247 248 EditorNode *editor; 249 EditorData *editor_data; 250 EditorSelection *editor_selection; 251 UndoRedo *undo_redo; 252 253 CheckBox *preview_camera; 254 ViewportContainer *viewport_container; 255 256 MenuButton *view_menu; 257 258 Control *surface; 259 Viewport *viewport; 260 Camera *camera; 261 bool transforming; 262 bool orthogonal; 263 bool auto_orthogonal; 264 bool lock_rotation; 265 float gizmo_scale; 266 267 bool freelook_active; 268 real_t freelook_speed; 269 Vector2 previous_mouse_position; 270 271 Label *info_label; 272 Label *cinema_label; 273 Label *locked_label; 274 275 VBoxContainer *top_right_vbox; 276 ViewportRotationControl *rotation_control; 277 Label *fps_label; 278 279 struct _RayResult { 280 281 Spatial *item; 282 float depth; 283 int handle; 284 _FORCE_INLINE_ bool operator<(const _RayResult &p_rr) const { return depth < p_rr.depth; } 285 }; 286 287 void _update_name(); 288 void _compute_edit(const Point2 &p_point); 289 void _clear_selected(); 290 void _select_clicked(bool p_append, bool p_single); 291 void _select(Node *p_node, bool p_append, bool p_single); 292 ObjectID _select_ray(const Point2 &p_pos, bool p_append, bool &r_includes_current, int *r_gizmo_handle = NULL, bool p_alt_select = false); 293 void _find_items_at_pos(const Point2 &p_pos, bool &r_includes_current, Vector<_RayResult> &results, bool p_alt_select = false); 294 Vector3 _get_ray_pos(const Vector2 &p_pos) const; 295 Vector3 _get_ray(const Vector2 &p_pos) const; 296 Point2 _point_to_screen(const Vector3 &p_point); 297 Transform _get_camera_transform() const; 298 int get_selected_count() const; 299 300 Vector3 _get_camera_position() const; 301 Vector3 _get_camera_normal() const; 302 Vector3 _get_screen_to_space(const Vector3 &p_vector3); 303 304 void _select_region(); 305 bool _gizmo_select(const Vector2 &p_screenpos, bool p_highlight_only = false); 306 307 void _nav_pan(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative); 308 void _nav_zoom(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative); 309 void _nav_orbit(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative); 310 void _nav_look(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative); 311 312 float get_znear() const; 313 float get_zfar() const; 314 float get_fov() const; 315 316 ObjectID clicked; 317 Vector<_RayResult> selection_results; 318 bool clicked_includes_current; 319 bool clicked_wants_append; 320 321 PopupMenu *selection_menu; 322 323 enum NavigationZoomStyle { 324 NAVIGATION_ZOOM_VERTICAL, 325 NAVIGATION_ZOOM_HORIZONTAL 326 }; 327 328 enum NavigationMode { 329 NAVIGATION_NONE, 330 NAVIGATION_PAN, 331 NAVIGATION_ZOOM, 332 NAVIGATION_ORBIT, 333 NAVIGATION_LOOK 334 }; 335 enum TransformMode { 336 TRANSFORM_NONE, 337 TRANSFORM_ROTATE, 338 TRANSFORM_TRANSLATE, 339 TRANSFORM_SCALE 340 341 }; 342 enum TransformPlane { 343 TRANSFORM_VIEW, 344 TRANSFORM_X_AXIS, 345 TRANSFORM_Y_AXIS, 346 TRANSFORM_Z_AXIS, 347 TRANSFORM_YZ, 348 TRANSFORM_XZ, 349 TRANSFORM_XY, 350 }; 351 352 struct EditData { 353 TransformMode mode; 354 TransformPlane plane; 355 Transform original; 356 Vector3 click_ray; 357 Vector3 click_ray_pos; 358 Vector3 center; 359 Vector3 orig_gizmo_pos; 360 int edited_gizmo; 361 Point2 mouse_pos; 362 bool snap; 363 Ref<EditorSpatialGizmo> gizmo; 364 int gizmo_handle; 365 Variant gizmo_initial_value; 366 Vector3 gizmo_initial_pos; 367 } _edit; 368 369 struct Cursor { 370 371 Vector3 pos; 372 float x_rot, y_rot, distance; 373 Vector3 eye_pos; // Used in freelook mode 374 bool region_select; 375 Point2 region_begin, region_end; 376 CursorCursor377 Cursor() { 378 // These rotations place the camera in +X +Y +Z, aka south east, facing north west. 379 x_rot = 0.5; 380 y_rot = -0.5; 381 distance = 4; 382 region_select = false; 383 } 384 }; 385 // Viewport camera supports movement smoothing, 386 // so one cursor is the real cursor, while the other can be an interpolated version. 387 Cursor cursor; // Immediate cursor 388 Cursor camera_cursor; // That one may be interpolated (don't modify this one except for smoothing purposes) 389 390 void scale_cursor_distance(real_t scale); 391 392 void set_freelook_active(bool active_now); 393 void scale_freelook_speed(real_t scale); 394 395 real_t zoom_indicator_delay; 396 397 RID move_gizmo_instance[3], move_plane_gizmo_instance[3], rotate_gizmo_instance[3], scale_gizmo_instance[3], scale_plane_gizmo_instance[3]; 398 399 String last_message; 400 String message; 401 float message_time; 402 403 void set_message(String p_message, float p_time = 5); 404 405 // 406 void _update_camera(float p_interp_delta); 407 Transform to_camera_transform(const Cursor &p_cursor) const; 408 void _draw(); 409 410 void _surface_mouse_enter(); 411 void _surface_mouse_exit(); 412 void _surface_focus_enter(); 413 void _surface_focus_exit(); 414 415 void _sinput(const Ref<InputEvent> &p_event); 416 void _update_freelook(real_t delta); 417 SpatialEditor *spatial_editor; 418 419 Camera *previewing; 420 Camera *preview; 421 422 bool previewing_cinema; 423 bool _is_node_locked(const Node *p_node); 424 void _preview_exited_scene(); 425 void _toggle_camera_preview(bool); 426 void _toggle_cinema_preview(bool); 427 void _init_gizmo_instance(int p_idx); 428 void _finish_gizmo_instances(); 429 void _selection_result_pressed(int); 430 void _selection_menu_hide(); 431 void _list_select(Ref<InputEventMouseButton> b); 432 Point2i _get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const; 433 434 Vector3 _get_instance_position(const Point2 &p_pos) const; 435 static AABB _calculate_spatial_bounds(const Spatial *p_parent, bool p_exclude_toplevel_transform = true); 436 void _create_preview(const Vector<String> &files) const; 437 void _remove_preview(); 438 bool _cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node); 439 bool _create_instance(Node *parent, String &path, const Point2 &p_point); 440 void _perform_drop_data(); 441 442 bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; 443 void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); 444 445 protected: 446 void _notification(int p_what); 447 static void _bind_methods(); 448 449 public: update_surface()450 void update_surface() { surface->update(); } 451 void update_transform_gizmo_view(); 452 453 void set_can_preview(Camera *p_preview); 454 void set_state(const Dictionary &p_state); 455 Dictionary get_state() const; 456 void reset(); is_freelook_active()457 bool is_freelook_active() const { return freelook_active; } 458 459 void focus_selection(); 460 461 void assign_pending_data_pointers( 462 Spatial *p_preview_node, 463 AABB *p_preview_bounds, 464 AcceptDialog *p_accept); 465 get_viewport_node()466 Viewport *get_viewport_node() { return viewport; } get_camera()467 Camera *get_camera() { return camera; } // return the default camera object. 468 469 SpatialEditorViewport(SpatialEditor *p_spatial_editor, EditorNode *p_editor, int p_index); 470 }; 471 472 class SpatialEditorSelectedItem : public Object { 473 474 GDCLASS(SpatialEditorSelectedItem, Object); 475 476 public: 477 AABB aabb; 478 Transform original; // original location when moving 479 Transform original_local; 480 Transform last_xform; // last transform 481 bool last_xform_dirty; 482 Spatial *sp; 483 RID sbox_instance; 484 SpatialEditorSelectedItem()485 SpatialEditorSelectedItem() { 486 sp = NULL; 487 last_xform_dirty = true; 488 } 489 ~SpatialEditorSelectedItem(); 490 }; 491 492 class SpatialEditorViewportContainer : public Container { 493 494 GDCLASS(SpatialEditorViewportContainer, Container); 495 496 public: 497 enum View { 498 VIEW_USE_1_VIEWPORT, 499 VIEW_USE_2_VIEWPORTS, 500 VIEW_USE_2_VIEWPORTS_ALT, 501 VIEW_USE_3_VIEWPORTS, 502 VIEW_USE_3_VIEWPORTS_ALT, 503 VIEW_USE_4_VIEWPORTS, 504 }; 505 506 private: 507 View view; 508 bool mouseover; 509 float ratio_h; 510 float ratio_v; 511 512 bool hovering_v; 513 bool hovering_h; 514 515 bool dragging_v; 516 bool dragging_h; 517 Vector2 drag_begin_pos; 518 Vector2 drag_begin_ratio; 519 520 void _gui_input(const Ref<InputEvent> &p_event); 521 522 protected: 523 void _notification(int p_what); 524 static void _bind_methods(); 525 526 public: 527 void set_view(View p_view); 528 View get_view(); 529 530 SpatialEditorViewportContainer(); 531 }; 532 533 class SpatialEditor : public VBoxContainer { 534 535 GDCLASS(SpatialEditor, VBoxContainer); 536 537 public: 538 static const unsigned int VIEWPORTS_COUNT = 4; 539 540 enum ToolMode { 541 542 TOOL_MODE_SELECT, 543 TOOL_MODE_MOVE, 544 TOOL_MODE_ROTATE, 545 TOOL_MODE_SCALE, 546 TOOL_MODE_LIST_SELECT, 547 TOOL_LOCK_SELECTED, 548 TOOL_UNLOCK_SELECTED, 549 TOOL_GROUP_SELECTED, 550 TOOL_UNGROUP_SELECTED, 551 TOOL_MAX 552 }; 553 554 enum ToolOptions { 555 556 TOOL_OPT_LOCAL_COORDS, 557 TOOL_OPT_USE_SNAP, 558 TOOL_OPT_OVERRIDE_CAMERA, 559 TOOL_OPT_MAX 560 561 }; 562 563 private: 564 EditorNode *editor; 565 EditorSelection *editor_selection; 566 567 SpatialEditorViewportContainer *viewport_base; 568 SpatialEditorViewport *viewports[VIEWPORTS_COUNT]; 569 VSplitContainer *shader_split; 570 HSplitContainer *palette_split; 571 572 ///// 573 574 ToolMode tool_mode; 575 bool orthogonal; 576 577 VisualServer::ScenarioDebugMode scenario_debug; 578 579 RID origin; 580 RID origin_instance; 581 bool origin_enabled; 582 RID grid[3]; 583 RID grid_instance[3]; 584 bool grid_visible[3]; //currently visible 585 bool grid_enable[3]; //should be always visible if true 586 bool grid_enabled; 587 588 Ref<ArrayMesh> move_gizmo[3], move_plane_gizmo[3], rotate_gizmo[3], scale_gizmo[3], scale_plane_gizmo[3]; 589 Ref<SpatialMaterial> gizmo_color[3]; 590 Ref<SpatialMaterial> plane_gizmo_color[3]; 591 Ref<SpatialMaterial> gizmo_color_hl[3]; 592 Ref<SpatialMaterial> plane_gizmo_color_hl[3]; 593 594 int over_gizmo_handle; 595 float snap_translate_value; 596 float snap_rotate_value; 597 float snap_scale_value; 598 599 Ref<ArrayMesh> selection_box; 600 RID indicators; 601 RID indicators_instance; 602 RID cursor_mesh; 603 RID cursor_instance; 604 Ref<SpatialMaterial> indicator_mat; 605 Ref<SpatialMaterial> cursor_material; 606 607 // Scene drag and drop support 608 Spatial *preview_node; 609 AABB preview_bounds; 610 611 struct Gizmo { 612 613 bool visible; 614 float scale; 615 Transform transform; 616 } gizmo; 617 618 enum MenuOption { 619 620 MENU_TOOL_SELECT, 621 MENU_TOOL_MOVE, 622 MENU_TOOL_ROTATE, 623 MENU_TOOL_SCALE, 624 MENU_TOOL_LIST_SELECT, 625 MENU_TOOL_LOCAL_COORDS, 626 MENU_TOOL_USE_SNAP, 627 MENU_TOOL_OVERRIDE_CAMERA, 628 MENU_TRANSFORM_CONFIGURE_SNAP, 629 MENU_TRANSFORM_DIALOG, 630 MENU_VIEW_USE_1_VIEWPORT, 631 MENU_VIEW_USE_2_VIEWPORTS, 632 MENU_VIEW_USE_2_VIEWPORTS_ALT, 633 MENU_VIEW_USE_3_VIEWPORTS, 634 MENU_VIEW_USE_3_VIEWPORTS_ALT, 635 MENU_VIEW_USE_4_VIEWPORTS, 636 MENU_VIEW_ORIGIN, 637 MENU_VIEW_GRID, 638 MENU_VIEW_GIZMOS_3D_ICONS, 639 MENU_VIEW_CAMERA_SETTINGS, 640 MENU_LOCK_SELECTED, 641 MENU_UNLOCK_SELECTED, 642 MENU_GROUP_SELECTED, 643 MENU_UNGROUP_SELECTED, 644 MENU_SNAP_TO_FLOOR 645 }; 646 647 Button *tool_button[TOOL_MAX]; 648 Button *tool_option_button[TOOL_OPT_MAX]; 649 650 MenuButton *transform_menu; 651 PopupMenu *gizmos_menu; 652 MenuButton *view_menu; 653 654 AcceptDialog *accept; 655 656 ConfirmationDialog *snap_dialog; 657 ConfirmationDialog *xform_dialog; 658 ConfirmationDialog *settings_dialog; 659 660 bool snap_enabled; 661 bool snap_key_enabled; 662 LineEdit *snap_translate; 663 LineEdit *snap_rotate; 664 LineEdit *snap_scale; 665 PanelContainer *menu_panel; 666 667 LineEdit *xform_translate[3]; 668 LineEdit *xform_rotate[3]; 669 LineEdit *xform_scale[3]; 670 OptionButton *xform_type; 671 672 VBoxContainer *settings_vbc; 673 SpinBox *settings_fov; 674 SpinBox *settings_znear; 675 SpinBox *settings_zfar; 676 677 void _snap_changed(); 678 void _snap_update(); 679 void _xform_dialog_action(); 680 void _menu_item_pressed(int p_option); 681 void _menu_item_toggled(bool pressed, int p_option); 682 void _menu_gizmo_toggled(int p_option); 683 void _update_camera_override_button(bool p_game_running); 684 void _update_camera_override_viewport(Object *p_viewport); 685 686 HBoxContainer *hbc_menu; 687 688 void _generate_selection_box(); 689 UndoRedo *undo_redo; 690 691 int camera_override_viewport_id; 692 693 void _init_indicators(); 694 void _update_gizmos_menu(); 695 void _update_gizmos_menu_theme(); 696 void _init_grid(); 697 void _finish_indicators(); 698 void _finish_grid(); 699 700 void _toggle_maximize_view(Object *p_viewport); 701 702 Node *custom_camera; 703 704 Object *_get_editor_data(Object *p_what); 705 706 Ref<Environment> viewport_environment; 707 708 Spatial *selected; 709 710 void _request_gizmo(Object *p_obj); 711 712 static SpatialEditor *singleton; 713 714 void _node_removed(Node *p_node); 715 Vector<Ref<EditorSpatialGizmoPlugin> > gizmo_plugins_by_priority; 716 Vector<Ref<EditorSpatialGizmoPlugin> > gizmo_plugins_by_name; 717 718 void _register_all_gizmos(); 719 720 SpatialEditor(); 721 722 bool is_any_freelook_active() const; 723 724 void _refresh_menu_icons(); 725 726 protected: 727 void _notification(int p_what); 728 //void _gui_input(InputEvent p_event); 729 void _unhandled_key_input(Ref<InputEvent> p_event); 730 731 static void _bind_methods(); 732 733 public: get_singleton()734 static SpatialEditor *get_singleton() { return singleton; } 735 void snap_cursor_to_plane(const Plane &p_plane); 736 737 Vector3 snap_point(Vector3 p_target, Vector3 p_start = Vector3(0, 0, 0)) const; 738 get_znear()739 float get_znear() const { return settings_znear->get_value(); } get_zfar()740 float get_zfar() const { return settings_zfar->get_value(); } get_fov()741 float get_fov() const { return settings_fov->get_value(); } 742 get_gizmo_transform()743 Transform get_gizmo_transform() const { return gizmo.transform; } is_gizmo_visible()744 bool is_gizmo_visible() const { return gizmo.visible; } 745 get_tool_mode()746 ToolMode get_tool_mode() const { return tool_mode; } are_local_coords_enabled()747 bool are_local_coords_enabled() const { return tool_option_button[SpatialEditor::TOOL_OPT_LOCAL_COORDS]->is_pressed(); } is_snap_enabled()748 bool is_snap_enabled() const { return snap_enabled ^ snap_key_enabled; } 749 float get_translate_snap() const; 750 float get_rotate_snap() const; 751 float get_scale_snap() const; 752 get_move_gizmo(int idx)753 Ref<ArrayMesh> get_move_gizmo(int idx) const { return move_gizmo[idx]; } get_move_plane_gizmo(int idx)754 Ref<ArrayMesh> get_move_plane_gizmo(int idx) const { return move_plane_gizmo[idx]; } get_rotate_gizmo(int idx)755 Ref<ArrayMesh> get_rotate_gizmo(int idx) const { return rotate_gizmo[idx]; } get_scale_gizmo(int idx)756 Ref<ArrayMesh> get_scale_gizmo(int idx) const { return scale_gizmo[idx]; } get_scale_plane_gizmo(int idx)757 Ref<ArrayMesh> get_scale_plane_gizmo(int idx) const { return scale_plane_gizmo[idx]; } 758 759 void update_transform_gizmo(); 760 void update_all_gizmos(Node *p_node = NULL); 761 void snap_selected_nodes_to_floor(); 762 void select_gizmo_highlight_axis(int p_axis); set_custom_camera(Node * p_camera)763 void set_custom_camera(Node *p_camera) { custom_camera = p_camera; } 764 set_undo_redo(UndoRedo * p_undo_redo)765 void set_undo_redo(UndoRedo *p_undo_redo) { undo_redo = p_undo_redo; } 766 Dictionary get_state() const; 767 void set_state(const Dictionary &p_state); 768 get_viewport_environment()769 Ref<Environment> get_viewport_environment() { return viewport_environment; } 770 get_undo_redo()771 UndoRedo *get_undo_redo() { return undo_redo; } 772 773 void add_control_to_menu_panel(Control *p_control); 774 void remove_control_from_menu_panel(Control *p_control); 775 776 VSplitContainer *get_shader_split(); 777 HSplitContainer *get_palette_split(); 778 get_selected()779 Spatial *get_selected() { return selected; } 780 get_over_gizmo_handle()781 int get_over_gizmo_handle() const { return over_gizmo_handle; } set_over_gizmo_handle(int idx)782 void set_over_gizmo_handle(int idx) { over_gizmo_handle = idx; } 783 784 void set_can_preview(Camera *p_preview); 785 get_editor_viewport(int p_idx)786 SpatialEditorViewport *get_editor_viewport(int p_idx) { 787 ERR_FAIL_INDEX_V(p_idx, static_cast<int>(VIEWPORTS_COUNT), NULL); 788 return viewports[p_idx]; 789 } 790 791 void add_gizmo_plugin(Ref<EditorSpatialGizmoPlugin> p_plugin); 792 void remove_gizmo_plugin(Ref<EditorSpatialGizmoPlugin> p_plugin); 793 794 void edit(Spatial *p_spatial); 795 void clear(); 796 797 SpatialEditor(EditorNode *p_editor); 798 ~SpatialEditor(); 799 }; 800 801 class SpatialEditorPlugin : public EditorPlugin { 802 803 GDCLASS(SpatialEditorPlugin, EditorPlugin); 804 805 SpatialEditor *spatial_editor; 806 EditorNode *editor; 807 808 protected: 809 static void _bind_methods(); 810 811 public: 812 void snap_cursor_to_plane(const Plane &p_plane); 813 get_spatial_editor()814 SpatialEditor *get_spatial_editor() { return spatial_editor; } get_name()815 virtual String get_name() const { return "3D"; } has_main_screen()816 bool has_main_screen() const { return true; } 817 virtual void make_visible(bool p_visible); 818 virtual void edit(Object *p_object); 819 virtual bool handles(Object *p_object) const; 820 821 virtual Dictionary get_state() const; 822 virtual void set_state(const Dictionary &p_state); clear()823 virtual void clear() { spatial_editor->clear(); } 824 825 virtual void edited_scene_changed(); 826 827 SpatialEditorPlugin(EditorNode *p_node); 828 ~SpatialEditorPlugin(); 829 }; 830 831 class EditorSpatialGizmoPlugin : public Resource { 832 833 GDCLASS(EditorSpatialGizmoPlugin, Resource); 834 835 public: 836 static const int VISIBLE = 0; 837 static const int HIDDEN = 1; 838 static const int ON_TOP = 2; 839 840 protected: 841 int current_state; 842 List<EditorSpatialGizmo *> current_gizmos; 843 HashMap<String, Vector<Ref<SpatialMaterial> > > materials; 844 845 static void _bind_methods(); 846 virtual bool has_gizmo(Spatial *p_spatial); 847 virtual Ref<EditorSpatialGizmo> create_gizmo(Spatial *p_spatial); 848 849 public: 850 void create_material(const String &p_name, const Color &p_color, bool p_billboard = false, bool p_on_top = false, bool p_use_vertex_color = false); 851 void create_icon_material(const String &p_name, const Ref<Texture> &p_texture, bool p_on_top = false, const Color &p_albedo = Color(1, 1, 1, 1)); 852 void create_handle_material(const String &p_name, bool p_billboard = false); 853 void add_material(const String &p_name, Ref<SpatialMaterial> p_material); 854 855 Ref<SpatialMaterial> get_material(const String &p_name, const Ref<EditorSpatialGizmo> &p_gizmo = Ref<EditorSpatialGizmo>()); 856 857 virtual String get_name() const; 858 virtual int get_priority() const; 859 virtual bool can_be_hidden() const; 860 virtual bool is_selectable_when_hidden() const; 861 862 virtual void redraw(EditorSpatialGizmo *p_gizmo); 863 virtual String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const; 864 virtual Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const; 865 virtual void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point); 866 virtual void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false); 867 virtual bool is_handle_highlighted(const EditorSpatialGizmo *p_gizmo, int p_idx) const; 868 869 Ref<EditorSpatialGizmo> get_gizmo(Spatial *p_spatial); 870 void set_state(int p_state); 871 int get_state() const; 872 void unregister_gizmo(EditorSpatialGizmo *p_gizmo); 873 874 EditorSpatialGizmoPlugin(); 875 virtual ~EditorSpatialGizmoPlugin(); 876 }; 877 878 #endif 879