node_3d_editor_plugin.h 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914
  1. /*************************************************************************/
  2. /* node_3d_editor_plugin.h */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2022 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 NODE_3D_EDITOR_PLUGIN_H
  31. #define NODE_3D_EDITOR_PLUGIN_H
  32. #include "editor/editor_plugin.h"
  33. #include "editor/editor_scale.h"
  34. #include "editor/editor_spin_slider.h"
  35. #include "editor/plugins/node_3d_editor_gizmos.h"
  36. #include "scene/3d/camera_3d.h"
  37. #include "scene/3d/light_3d.h"
  38. #include "scene/3d/visual_instance_3d.h"
  39. #include "scene/3d/world_environment.h"
  40. #include "scene/gui/color_picker.h"
  41. #include "scene/gui/panel_container.h"
  42. #include "scene/gui/spin_box.h"
  43. #include "scene/gui/split_container.h"
  44. #include "scene/resources/environment.h"
  45. #include "scene/resources/fog_material.h"
  46. #include "scene/resources/sky_material.h"
  47. class EditorData;
  48. class Node3DEditor;
  49. class Node3DEditorViewport;
  50. class SubViewportContainer;
  51. class DirectionalLight3D;
  52. class WorldEnvironment;
  53. class EditorUndoRedoManager;
  54. class ViewportRotationControl : public Control {
  55. GDCLASS(ViewportRotationControl, Control);
  56. struct Axis2D {
  57. Vector2i screen_point;
  58. float z_axis = -99.0;
  59. int axis = -1;
  60. };
  61. struct Axis2DCompare {
  62. _FORCE_INLINE_ bool operator()(const Axis2D &l, const Axis2D &r) const {
  63. return l.z_axis < r.z_axis;
  64. }
  65. };
  66. Node3DEditorViewport *viewport = nullptr;
  67. Vector<Color> axis_colors;
  68. Vector<int> axis_menu_options;
  69. Vector2i orbiting_mouse_start;
  70. bool orbiting = false;
  71. int focused_axis = -2;
  72. const float AXIS_CIRCLE_RADIUS = 8.0f * EDSCALE;
  73. protected:
  74. void _notification(int p_what);
  75. virtual void gui_input(const Ref<InputEvent> &p_event) override;
  76. void _draw();
  77. void _draw_axis(const Axis2D &p_axis);
  78. void _get_sorted_axis(Vector<Axis2D> &r_axis);
  79. void _update_focus();
  80. void _on_mouse_exited();
  81. public:
  82. void set_viewport(Node3DEditorViewport *p_viewport);
  83. };
  84. class Node3DEditorViewport : public Control {
  85. GDCLASS(Node3DEditorViewport, Control);
  86. friend class Node3DEditor;
  87. friend class ViewportRotationControl;
  88. enum {
  89. VIEW_TOP,
  90. VIEW_BOTTOM,
  91. VIEW_LEFT,
  92. VIEW_RIGHT,
  93. VIEW_FRONT,
  94. VIEW_REAR,
  95. VIEW_CENTER_TO_ORIGIN,
  96. VIEW_CENTER_TO_SELECTION,
  97. VIEW_ALIGN_TRANSFORM_WITH_VIEW,
  98. VIEW_ALIGN_ROTATION_WITH_VIEW,
  99. VIEW_PERSPECTIVE,
  100. VIEW_ENVIRONMENT,
  101. VIEW_ORTHOGONAL,
  102. VIEW_HALF_RESOLUTION,
  103. VIEW_AUDIO_LISTENER,
  104. VIEW_AUDIO_DOPPLER,
  105. VIEW_GIZMOS,
  106. VIEW_INFORMATION,
  107. VIEW_FRAME_TIME,
  108. VIEW_DISPLAY_NORMAL,
  109. VIEW_DISPLAY_WIREFRAME,
  110. VIEW_DISPLAY_OVERDRAW,
  111. VIEW_DISPLAY_SHADELESS,
  112. VIEW_DISPLAY_LIGHTING,
  113. VIEW_DISPLAY_ADVANCED,
  114. VIEW_DISPLAY_NORMAL_BUFFER,
  115. VIEW_DISPLAY_DEBUG_SHADOW_ATLAS,
  116. VIEW_DISPLAY_DEBUG_DIRECTIONAL_SHADOW_ATLAS,
  117. VIEW_DISPLAY_DEBUG_VOXEL_GI_ALBEDO,
  118. VIEW_DISPLAY_DEBUG_VOXEL_GI_LIGHTING,
  119. VIEW_DISPLAY_DEBUG_VOXEL_GI_EMISSION,
  120. VIEW_DISPLAY_DEBUG_SCENE_LUMINANCE,
  121. VIEW_DISPLAY_DEBUG_SSAO,
  122. VIEW_DISPLAY_DEBUG_SSIL,
  123. VIEW_DISPLAY_DEBUG_PSSM_SPLITS,
  124. VIEW_DISPLAY_DEBUG_DECAL_ATLAS,
  125. VIEW_DISPLAY_DEBUG_SDFGI,
  126. VIEW_DISPLAY_DEBUG_SDFGI_PROBES,
  127. VIEW_DISPLAY_DEBUG_GI_BUFFER,
  128. VIEW_DISPLAY_DEBUG_DISABLE_LOD,
  129. VIEW_DISPLAY_DEBUG_CLUSTER_OMNI_LIGHTS,
  130. VIEW_DISPLAY_DEBUG_CLUSTER_SPOT_LIGHTS,
  131. VIEW_DISPLAY_DEBUG_CLUSTER_DECALS,
  132. VIEW_DISPLAY_DEBUG_CLUSTER_REFLECTION_PROBES,
  133. VIEW_DISPLAY_DEBUG_OCCLUDERS,
  134. VIEW_DISPLAY_MOTION_VECTORS,
  135. VIEW_LOCK_ROTATION,
  136. VIEW_CINEMATIC_PREVIEW,
  137. VIEW_AUTO_ORTHOGONAL,
  138. VIEW_MAX
  139. };
  140. enum ViewType {
  141. VIEW_TYPE_USER,
  142. VIEW_TYPE_TOP,
  143. VIEW_TYPE_BOTTOM,
  144. VIEW_TYPE_LEFT,
  145. VIEW_TYPE_RIGHT,
  146. VIEW_TYPE_FRONT,
  147. VIEW_TYPE_REAR,
  148. };
  149. public:
  150. enum {
  151. GIZMO_BASE_LAYER = 27,
  152. GIZMO_EDIT_LAYER = 26,
  153. GIZMO_GRID_LAYER = 25,
  154. MISC_TOOL_LAYER = 24,
  155. FRAME_TIME_HISTORY = 20,
  156. };
  157. enum NavigationScheme {
  158. NAVIGATION_GODOT,
  159. NAVIGATION_MAYA,
  160. NAVIGATION_MODO,
  161. };
  162. enum FreelookNavigationScheme {
  163. FREELOOK_DEFAULT,
  164. FREELOOK_PARTIALLY_AXIS_LOCKED,
  165. FREELOOK_FULLY_AXIS_LOCKED,
  166. };
  167. private:
  168. double cpu_time_history[FRAME_TIME_HISTORY];
  169. int cpu_time_history_index;
  170. double gpu_time_history[FRAME_TIME_HISTORY];
  171. int gpu_time_history_index;
  172. int index;
  173. ViewType view_type;
  174. void _menu_option(int p_option);
  175. void _set_auto_orthogonal();
  176. Node3D *preview_node = nullptr;
  177. AABB *preview_bounds = nullptr;
  178. Vector<String> selected_files;
  179. AcceptDialog *accept = nullptr;
  180. Node *target_node = nullptr;
  181. Point2 drop_pos;
  182. EditorData *editor_data = nullptr;
  183. EditorSelection *editor_selection = nullptr;
  184. Ref<EditorUndoRedoManager> undo_redo;
  185. CheckBox *preview_camera = nullptr;
  186. SubViewportContainer *subviewport_container = nullptr;
  187. MenuButton *view_menu = nullptr;
  188. PopupMenu *display_submenu = nullptr;
  189. Control *surface = nullptr;
  190. SubViewport *viewport = nullptr;
  191. Camera3D *camera = nullptr;
  192. bool transforming = false;
  193. bool orthogonal;
  194. bool auto_orthogonal;
  195. bool lock_rotation;
  196. real_t gizmo_scale;
  197. bool freelook_active;
  198. real_t freelook_speed;
  199. Vector2 previous_mouse_position;
  200. Label *info_label = nullptr;
  201. Label *cinema_label = nullptr;
  202. Label *locked_label = nullptr;
  203. Label *zoom_limit_label = nullptr;
  204. Label *preview_material_label = nullptr;
  205. Label *preview_material_label_desc = nullptr;
  206. VBoxContainer *top_right_vbox = nullptr;
  207. ViewportRotationControl *rotation_control = nullptr;
  208. Gradient *frame_time_gradient = nullptr;
  209. Label *cpu_time_label = nullptr;
  210. Label *gpu_time_label = nullptr;
  211. Label *fps_label = nullptr;
  212. struct _RayResult {
  213. Node3D *item = nullptr;
  214. real_t depth = 0;
  215. _FORCE_INLINE_ bool operator<(const _RayResult &p_rr) const { return depth < p_rr.depth; }
  216. };
  217. void _update_name();
  218. void _compute_edit(const Point2 &p_point);
  219. void _clear_selected();
  220. void _select_clicked(bool p_allow_locked);
  221. ObjectID _select_ray(const Point2 &p_pos) const;
  222. void _find_items_at_pos(const Point2 &p_pos, Vector<_RayResult> &r_results, bool p_include_locked);
  223. Vector3 _get_ray_pos(const Vector2 &p_pos) const;
  224. Vector3 _get_ray(const Vector2 &p_pos) const;
  225. Point2 _point_to_screen(const Vector3 &p_point);
  226. Transform3D _get_camera_transform() const;
  227. int get_selected_count() const;
  228. void cancel_transform();
  229. void _update_shrink();
  230. Vector3 _get_camera_position() const;
  231. Vector3 _get_camera_normal() const;
  232. Vector3 _get_screen_to_space(const Vector3 &p_vector3);
  233. void _select_region();
  234. bool _transform_gizmo_select(const Vector2 &p_screenpos, bool p_highlight_only = false);
  235. void _transform_gizmo_apply(Node3D *p_node, const Transform3D &p_transform, bool p_local);
  236. void _nav_pan(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative);
  237. void _nav_zoom(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative);
  238. void _nav_orbit(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative);
  239. void _nav_look(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative);
  240. float get_znear() const;
  241. float get_zfar() const;
  242. float get_fov() const;
  243. ObjectID clicked;
  244. ObjectID material_target;
  245. Vector<_RayResult> selection_results;
  246. bool clicked_wants_append = false;
  247. bool selection_in_progress = false;
  248. PopupMenu *selection_menu = nullptr;
  249. enum NavigationZoomStyle {
  250. NAVIGATION_ZOOM_VERTICAL,
  251. NAVIGATION_ZOOM_HORIZONTAL
  252. };
  253. enum NavigationMode {
  254. NAVIGATION_NONE,
  255. NAVIGATION_PAN,
  256. NAVIGATION_ZOOM,
  257. NAVIGATION_ORBIT,
  258. NAVIGATION_LOOK
  259. };
  260. enum TransformMode {
  261. TRANSFORM_NONE,
  262. TRANSFORM_ROTATE,
  263. TRANSFORM_TRANSLATE,
  264. TRANSFORM_SCALE
  265. };
  266. enum TransformPlane {
  267. TRANSFORM_VIEW,
  268. TRANSFORM_X_AXIS,
  269. TRANSFORM_Y_AXIS,
  270. TRANSFORM_Z_AXIS,
  271. TRANSFORM_YZ,
  272. TRANSFORM_XZ,
  273. TRANSFORM_XY,
  274. };
  275. struct EditData {
  276. TransformMode mode;
  277. TransformPlane plane;
  278. Transform3D original;
  279. Vector3 click_ray;
  280. Vector3 click_ray_pos;
  281. Vector3 center;
  282. Point2 mouse_pos;
  283. Point2 original_mouse_pos;
  284. bool snap = false;
  285. bool show_rotation_line = false;
  286. Ref<EditorNode3DGizmo> gizmo;
  287. int gizmo_handle = 0;
  288. bool gizmo_handle_secondary = false;
  289. Variant gizmo_initial_value;
  290. bool original_local;
  291. bool instant;
  292. } _edit;
  293. struct Cursor {
  294. Vector3 pos;
  295. real_t x_rot, y_rot, distance, fov_scale;
  296. Vector3 eye_pos; // Used in freelook mode
  297. bool region_select;
  298. Point2 region_begin, region_end;
  299. Cursor() {
  300. // These rotations place the camera in +X +Y +Z, aka south east, facing north west.
  301. x_rot = 0.5;
  302. y_rot = -0.5;
  303. distance = 4;
  304. fov_scale = 1.0;
  305. region_select = false;
  306. }
  307. };
  308. // Viewport camera supports movement smoothing,
  309. // so one cursor is the real cursor, while the other can be an interpolated version.
  310. Cursor cursor; // Immediate cursor
  311. Cursor camera_cursor; // That one may be interpolated (don't modify this one except for smoothing purposes)
  312. void scale_fov(real_t p_fov_offset);
  313. void reset_fov();
  314. void scale_cursor_distance(real_t scale);
  315. void set_freelook_active(bool active_now);
  316. void scale_freelook_speed(real_t scale);
  317. real_t zoom_indicator_delay;
  318. int zoom_failed_attempts_count = 0;
  319. RID move_gizmo_instance[3], move_plane_gizmo_instance[3], rotate_gizmo_instance[4], scale_gizmo_instance[3], scale_plane_gizmo_instance[3], axis_gizmo_instance[3];
  320. String last_message;
  321. String message;
  322. double message_time;
  323. void set_message(String p_message, float p_time = 5);
  324. void _view_settings_confirmed(real_t p_interp_delta);
  325. void _update_camera(real_t p_interp_delta);
  326. Transform3D to_camera_transform(const Cursor &p_cursor) const;
  327. void _draw();
  328. void _surface_mouse_enter();
  329. void _surface_mouse_exit();
  330. void _surface_focus_enter();
  331. void _surface_focus_exit();
  332. void _sinput(const Ref<InputEvent> &p_event);
  333. void _update_freelook(real_t delta);
  334. Node3DEditor *spatial_editor = nullptr;
  335. Camera3D *previewing = nullptr;
  336. Camera3D *preview = nullptr;
  337. bool previewing_cinema;
  338. bool _is_node_locked(const Node *p_node);
  339. void _preview_exited_scene();
  340. void _toggle_camera_preview(bool);
  341. void _toggle_cinema_preview(bool);
  342. void _init_gizmo_instance(int p_idx);
  343. void _finish_gizmo_instances();
  344. void _selection_result_pressed(int);
  345. void _selection_menu_hide();
  346. void _list_select(Ref<InputEventMouseButton> b);
  347. Point2i _get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const;
  348. Vector3 _get_instance_position(const Point2 &p_pos) const;
  349. static AABB _calculate_spatial_bounds(const Node3D *p_parent, bool p_exclude_top_level_transform = true);
  350. Node *_sanitize_preview_node(Node *p_node) const;
  351. void _create_preview_node(const Vector<String> &files) const;
  352. void _remove_preview_node();
  353. bool _apply_preview_material(ObjectID p_target, const Point2 &p_point) const;
  354. void _reset_preview_material() const;
  355. void _remove_preview_material();
  356. bool _cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node);
  357. bool _create_instance(Node *parent, String &path, const Point2 &p_point);
  358. void _perform_drop_data();
  359. bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
  360. void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
  361. void _project_settings_changed();
  362. Transform3D _compute_transform(TransformMode p_mode, const Transform3D &p_original, const Transform3D &p_original_local, Vector3 p_motion, double p_extra, bool p_local, bool p_orthogonal);
  363. void begin_transform(TransformMode p_mode, bool instant);
  364. void commit_transform();
  365. void update_transform(Point2 p_mousepos, bool p_shift);
  366. void finish_transform();
  367. void register_shortcut_action(const String &p_path, const String &p_name, Key p_keycode);
  368. void shortcut_changed_callback(const Ref<Shortcut> p_shortcut, const String &p_shortcut_path);
  369. protected:
  370. void _notification(int p_what);
  371. static void _bind_methods();
  372. public:
  373. void update_surface() { surface->queue_redraw(); }
  374. void update_transform_gizmo_view();
  375. void set_can_preview(Camera3D *p_preview);
  376. void set_state(const Dictionary &p_state);
  377. Dictionary get_state() const;
  378. void reset();
  379. bool is_freelook_active() const { return freelook_active; }
  380. void focus_selection();
  381. void assign_pending_data_pointers(
  382. Node3D *p_preview_node,
  383. AABB *p_preview_bounds,
  384. AcceptDialog *p_accept);
  385. SubViewport *get_viewport_node() { return viewport; }
  386. Camera3D *get_camera_3d() { return camera; } // return the default camera object.
  387. Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p_index);
  388. ~Node3DEditorViewport();
  389. };
  390. class Node3DEditorSelectedItem : public Object {
  391. GDCLASS(Node3DEditorSelectedItem, Object);
  392. public:
  393. AABB aabb;
  394. Transform3D original; // original location when moving
  395. Transform3D original_local;
  396. Transform3D last_xform; // last transform
  397. bool last_xform_dirty;
  398. Node3D *sp = nullptr;
  399. RID sbox_instance;
  400. RID sbox_instance_offset;
  401. RID sbox_instance_xray;
  402. RID sbox_instance_xray_offset;
  403. Ref<EditorNode3DGizmo> gizmo;
  404. HashMap<int, Transform3D> subgizmos; // map ID -> initial transform
  405. Node3DEditorSelectedItem() {
  406. sp = nullptr;
  407. last_xform_dirty = true;
  408. }
  409. ~Node3DEditorSelectedItem();
  410. };
  411. class Node3DEditorViewportContainer : public Container {
  412. GDCLASS(Node3DEditorViewportContainer, Container);
  413. public:
  414. enum View {
  415. VIEW_USE_1_VIEWPORT,
  416. VIEW_USE_2_VIEWPORTS,
  417. VIEW_USE_2_VIEWPORTS_ALT,
  418. VIEW_USE_3_VIEWPORTS,
  419. VIEW_USE_3_VIEWPORTS_ALT,
  420. VIEW_USE_4_VIEWPORTS,
  421. };
  422. private:
  423. View view;
  424. bool mouseover;
  425. real_t ratio_h;
  426. real_t ratio_v;
  427. bool hovering_v;
  428. bool hovering_h;
  429. bool dragging_v;
  430. bool dragging_h;
  431. Vector2 drag_begin_pos;
  432. Vector2 drag_begin_ratio;
  433. virtual void gui_input(const Ref<InputEvent> &p_event) override;
  434. protected:
  435. void _notification(int p_what);
  436. public:
  437. void set_view(View p_view);
  438. View get_view();
  439. Node3DEditorViewportContainer();
  440. };
  441. class Node3DEditor : public VBoxContainer {
  442. GDCLASS(Node3DEditor, VBoxContainer);
  443. public:
  444. static const unsigned int VIEWPORTS_COUNT = 4;
  445. enum ToolMode {
  446. TOOL_MODE_SELECT,
  447. TOOL_MODE_MOVE,
  448. TOOL_MODE_ROTATE,
  449. TOOL_MODE_SCALE,
  450. TOOL_MODE_LIST_SELECT,
  451. TOOL_LOCK_SELECTED,
  452. TOOL_UNLOCK_SELECTED,
  453. TOOL_GROUP_SELECTED,
  454. TOOL_UNGROUP_SELECTED,
  455. TOOL_MAX
  456. };
  457. enum ToolOptions {
  458. TOOL_OPT_LOCAL_COORDS,
  459. TOOL_OPT_USE_SNAP,
  460. TOOL_OPT_OVERRIDE_CAMERA,
  461. TOOL_OPT_MAX
  462. };
  463. private:
  464. EditorSelection *editor_selection = nullptr;
  465. Node3DEditorViewportContainer *viewport_base = nullptr;
  466. Node3DEditorViewport *viewports[VIEWPORTS_COUNT];
  467. VSplitContainer *shader_split = nullptr;
  468. HSplitContainer *left_panel_split = nullptr;
  469. HSplitContainer *right_panel_split = nullptr;
  470. /////
  471. ToolMode tool_mode;
  472. RID origin;
  473. RID origin_instance;
  474. bool origin_enabled = false;
  475. RID grid[3];
  476. RID grid_instance[3];
  477. bool grid_visible[3]; //currently visible
  478. bool grid_enable[3]; //should be always visible if true
  479. bool grid_enabled = false;
  480. bool grid_init_draw = false;
  481. Camera3D::ProjectionType grid_camera_last_update_perspective = Camera3D::PROJECTION_PERSPECTIVE;
  482. Vector3 grid_camera_last_update_position = Vector3();
  483. Ref<ArrayMesh> move_gizmo[3], move_plane_gizmo[3], rotate_gizmo[4], scale_gizmo[3], scale_plane_gizmo[3], axis_gizmo[3];
  484. Ref<StandardMaterial3D> gizmo_color[3];
  485. Ref<StandardMaterial3D> plane_gizmo_color[3];
  486. Ref<ShaderMaterial> rotate_gizmo_color[3];
  487. Ref<StandardMaterial3D> gizmo_color_hl[3];
  488. Ref<StandardMaterial3D> plane_gizmo_color_hl[3];
  489. Ref<ShaderMaterial> rotate_gizmo_color_hl[3];
  490. Ref<Node3DGizmo> current_hover_gizmo;
  491. int current_hover_gizmo_handle;
  492. bool current_hover_gizmo_handle_secondary;
  493. real_t snap_translate_value;
  494. real_t snap_rotate_value;
  495. real_t snap_scale_value;
  496. Ref<ArrayMesh> selection_box_xray;
  497. Ref<ArrayMesh> selection_box;
  498. RID indicators;
  499. RID indicators_instance;
  500. RID cursor_mesh;
  501. RID cursor_instance;
  502. Ref<StandardMaterial3D> indicator_mat;
  503. Ref<ShaderMaterial> grid_mat[3];
  504. Ref<StandardMaterial3D> cursor_material;
  505. // Scene drag and drop support
  506. Node3D *preview_node = nullptr;
  507. AABB preview_bounds;
  508. Ref<Material> preview_material;
  509. Ref<Material> preview_reset_material;
  510. ObjectID preview_material_target;
  511. int preview_material_surface = -1;
  512. struct Gizmo {
  513. bool visible = false;
  514. real_t scale = 0;
  515. Transform3D transform;
  516. } gizmo;
  517. enum MenuOption {
  518. MENU_TOOL_SELECT,
  519. MENU_TOOL_MOVE,
  520. MENU_TOOL_ROTATE,
  521. MENU_TOOL_SCALE,
  522. MENU_TOOL_LIST_SELECT,
  523. MENU_TOOL_LOCAL_COORDS,
  524. MENU_TOOL_USE_SNAP,
  525. MENU_TOOL_OVERRIDE_CAMERA,
  526. MENU_TRANSFORM_CONFIGURE_SNAP,
  527. MENU_TRANSFORM_DIALOG,
  528. MENU_VIEW_USE_1_VIEWPORT,
  529. MENU_VIEW_USE_2_VIEWPORTS,
  530. MENU_VIEW_USE_2_VIEWPORTS_ALT,
  531. MENU_VIEW_USE_3_VIEWPORTS,
  532. MENU_VIEW_USE_3_VIEWPORTS_ALT,
  533. MENU_VIEW_USE_4_VIEWPORTS,
  534. MENU_VIEW_ORIGIN,
  535. MENU_VIEW_GRID,
  536. MENU_VIEW_GIZMOS_3D_ICONS,
  537. MENU_VIEW_CAMERA_SETTINGS,
  538. MENU_LOCK_SELECTED,
  539. MENU_UNLOCK_SELECTED,
  540. MENU_GROUP_SELECTED,
  541. MENU_UNGROUP_SELECTED,
  542. MENU_SNAP_TO_FLOOR
  543. };
  544. Button *tool_button[TOOL_MAX];
  545. Button *tool_option_button[TOOL_OPT_MAX];
  546. MenuButton *transform_menu = nullptr;
  547. PopupMenu *gizmos_menu = nullptr;
  548. MenuButton *view_menu = nullptr;
  549. AcceptDialog *accept = nullptr;
  550. ConfirmationDialog *snap_dialog = nullptr;
  551. ConfirmationDialog *xform_dialog = nullptr;
  552. ConfirmationDialog *settings_dialog = nullptr;
  553. bool snap_enabled;
  554. bool snap_key_enabled;
  555. LineEdit *snap_translate = nullptr;
  556. LineEdit *snap_rotate = nullptr;
  557. LineEdit *snap_scale = nullptr;
  558. LineEdit *xform_translate[3];
  559. LineEdit *xform_rotate[3];
  560. LineEdit *xform_scale[3];
  561. OptionButton *xform_type = nullptr;
  562. VBoxContainer *settings_vbc = nullptr;
  563. SpinBox *settings_fov = nullptr;
  564. SpinBox *settings_znear = nullptr;
  565. SpinBox *settings_zfar = nullptr;
  566. void _snap_changed();
  567. void _snap_update();
  568. void _xform_dialog_action();
  569. void _menu_item_pressed(int p_option);
  570. void _menu_item_toggled(bool pressed, int p_option);
  571. void _menu_gizmo_toggled(int p_option);
  572. void _update_camera_override_button(bool p_game_running);
  573. void _update_camera_override_viewport(Object *p_viewport);
  574. // Used for secondary menu items which are displayed depending on the currently selected node
  575. // (such as MeshInstance's "Mesh" menu).
  576. PanelContainer *context_menu_panel = nullptr;
  577. HBoxContainer *context_menu_hbox = nullptr;
  578. void _generate_selection_boxes();
  579. Ref<EditorUndoRedoManager> undo_redo;
  580. int camera_override_viewport_id;
  581. void _init_indicators();
  582. void _update_gizmos_menu();
  583. void _update_gizmos_menu_theme();
  584. void _init_grid();
  585. void _finish_indicators();
  586. void _finish_grid();
  587. void _toggle_maximize_view(Object *p_viewport);
  588. Node *custom_camera = nullptr;
  589. Object *_get_editor_data(Object *p_what);
  590. Ref<Environment> viewport_environment;
  591. Node3D *selected = nullptr;
  592. void _request_gizmo(Object *p_obj);
  593. void _set_subgizmo_selection(Object *p_obj, Ref<Node3DGizmo> p_gizmo, int p_id, Transform3D p_transform = Transform3D());
  594. void _clear_subgizmo_selection(Object *p_obj = nullptr);
  595. static Node3DEditor *singleton;
  596. void _node_added(Node *p_node);
  597. void _node_removed(Node *p_node);
  598. Vector<Ref<EditorNode3DGizmoPlugin>> gizmo_plugins_by_priority;
  599. Vector<Ref<EditorNode3DGizmoPlugin>> gizmo_plugins_by_name;
  600. void _register_all_gizmos();
  601. void _selection_changed();
  602. void _refresh_menu_icons();
  603. // Preview Sun and Environment
  604. uint32_t world_env_count = 0;
  605. uint32_t directional_light_count = 0;
  606. Button *sun_button = nullptr;
  607. Label *sun_state = nullptr;
  608. Label *sun_title = nullptr;
  609. VBoxContainer *sun_vb = nullptr;
  610. Popup *sun_environ_popup = nullptr;
  611. Control *sun_direction = nullptr;
  612. EditorSpinSlider *sun_angle_altitude = nullptr;
  613. EditorSpinSlider *sun_angle_azimuth = nullptr;
  614. ColorPickerButton *sun_color = nullptr;
  615. EditorSpinSlider *sun_energy = nullptr;
  616. EditorSpinSlider *sun_max_distance = nullptr;
  617. Button *sun_add_to_scene = nullptr;
  618. void _sun_direction_draw();
  619. void _sun_direction_input(const Ref<InputEvent> &p_event);
  620. void _sun_direction_angle_set();
  621. Vector2 sun_rotation;
  622. Ref<Shader> sun_direction_shader;
  623. Ref<ShaderMaterial> sun_direction_material;
  624. Button *environ_button = nullptr;
  625. Label *environ_state = nullptr;
  626. Label *environ_title = nullptr;
  627. VBoxContainer *environ_vb = nullptr;
  628. ColorPickerButton *environ_sky_color = nullptr;
  629. ColorPickerButton *environ_ground_color = nullptr;
  630. EditorSpinSlider *environ_energy = nullptr;
  631. Button *environ_ao_button = nullptr;
  632. Button *environ_glow_button = nullptr;
  633. Button *environ_tonemap_button = nullptr;
  634. Button *environ_gi_button = nullptr;
  635. Button *environ_add_to_scene = nullptr;
  636. Button *sun_environ_settings = nullptr;
  637. DirectionalLight3D *preview_sun = nullptr;
  638. WorldEnvironment *preview_environment = nullptr;
  639. Ref<Environment> environment;
  640. Ref<CameraAttributesPhysical> camera_attributes;
  641. Ref<ProceduralSkyMaterial> sky_material;
  642. bool sun_environ_updating = false;
  643. void _load_default_preview_settings();
  644. void _update_preview_environment();
  645. void _preview_settings_changed();
  646. void _sun_environ_settings_pressed();
  647. void _add_sun_to_scene(bool p_already_added_environment = false);
  648. void _add_environment_to_scene(bool p_already_added_sun = false);
  649. void _update_theme();
  650. protected:
  651. void _notification(int p_what);
  652. //void _gui_input(InputEvent p_event);
  653. virtual void shortcut_input(const Ref<InputEvent> &p_event) override;
  654. static void _bind_methods();
  655. public:
  656. static Node3DEditor *get_singleton() { return singleton; }
  657. Vector3 snap_point(Vector3 p_target, Vector3 p_start = Vector3(0, 0, 0)) const;
  658. float get_znear() const { return settings_znear->get_value(); }
  659. float get_zfar() const { return settings_zfar->get_value(); }
  660. float get_fov() const { return settings_fov->get_value(); }
  661. Transform3D get_gizmo_transform() const { return gizmo.transform; }
  662. bool is_gizmo_visible() const;
  663. ToolMode get_tool_mode() const { return tool_mode; }
  664. bool are_local_coords_enabled() const { return tool_option_button[Node3DEditor::TOOL_OPT_LOCAL_COORDS]->is_pressed(); }
  665. void set_local_coords_enabled(bool on) const { tool_option_button[Node3DEditor::TOOL_OPT_LOCAL_COORDS]->set_pressed(on); }
  666. bool is_snap_enabled() const { return snap_enabled ^ snap_key_enabled; }
  667. double get_translate_snap() const;
  668. double get_rotate_snap() const;
  669. double get_scale_snap() const;
  670. Ref<ArrayMesh> get_move_gizmo(int idx) const { return move_gizmo[idx]; }
  671. Ref<ArrayMesh> get_axis_gizmo(int idx) const { return axis_gizmo[idx]; }
  672. Ref<ArrayMesh> get_move_plane_gizmo(int idx) const { return move_plane_gizmo[idx]; }
  673. Ref<ArrayMesh> get_rotate_gizmo(int idx) const { return rotate_gizmo[idx]; }
  674. Ref<ArrayMesh> get_scale_gizmo(int idx) const { return scale_gizmo[idx]; }
  675. Ref<ArrayMesh> get_scale_plane_gizmo(int idx) const { return scale_plane_gizmo[idx]; }
  676. void update_grid();
  677. void update_transform_gizmo();
  678. void update_all_gizmos(Node *p_node = nullptr);
  679. void snap_selected_nodes_to_floor();
  680. void select_gizmo_highlight_axis(int p_axis);
  681. void set_custom_camera(Node *p_camera) { custom_camera = p_camera; }
  682. Dictionary get_state() const;
  683. void set_state(const Dictionary &p_state);
  684. Ref<Environment> get_viewport_environment() { return viewport_environment; }
  685. void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo);
  686. Ref<EditorUndoRedoManager> get_undo_redo();
  687. void add_control_to_menu_panel(Control *p_control);
  688. void remove_control_from_menu_panel(Control *p_control);
  689. void add_control_to_left_panel(Control *p_control);
  690. void remove_control_from_left_panel(Control *p_control);
  691. void add_control_to_right_panel(Control *p_control);
  692. void remove_control_from_right_panel(Control *p_control);
  693. void move_control_to_left_panel(Control *p_control);
  694. void move_control_to_right_panel(Control *p_control);
  695. VSplitContainer *get_shader_split();
  696. Node3D *get_single_selected_node() { return selected; }
  697. bool is_current_selected_gizmo(const EditorNode3DGizmo *p_gizmo);
  698. bool is_subgizmo_selected(int p_id);
  699. Vector<int> get_subgizmo_selection();
  700. Ref<EditorNode3DGizmo> get_current_hover_gizmo() const { return current_hover_gizmo; }
  701. void set_current_hover_gizmo(Ref<EditorNode3DGizmo> p_gizmo) { current_hover_gizmo = p_gizmo; }
  702. void set_current_hover_gizmo_handle(int p_id, bool p_secondary) {
  703. current_hover_gizmo_handle = p_id;
  704. current_hover_gizmo_handle_secondary = p_secondary;
  705. }
  706. int get_current_hover_gizmo_handle(bool &r_secondary) const {
  707. r_secondary = current_hover_gizmo_handle_secondary;
  708. return current_hover_gizmo_handle;
  709. }
  710. void set_can_preview(Camera3D *p_preview);
  711. void set_preview_material(Ref<Material> p_material) { preview_material = p_material; }
  712. Ref<Material> get_preview_material() { return preview_material; }
  713. void set_preview_reset_material(Ref<Material> p_material) { preview_reset_material = p_material; }
  714. Ref<Material> get_preview_reset_material() const { return preview_reset_material; }
  715. void set_preview_material_target(ObjectID p_object_id) { preview_material_target = p_object_id; }
  716. ObjectID get_preview_material_target() const { return preview_material_target; }
  717. void set_preview_material_surface(int p_surface) { preview_material_surface = p_surface; }
  718. int get_preview_material_surface() const { return preview_material_surface; }
  719. Node3DEditorViewport *get_editor_viewport(int p_idx) {
  720. ERR_FAIL_INDEX_V(p_idx, static_cast<int>(VIEWPORTS_COUNT), nullptr);
  721. return viewports[p_idx];
  722. }
  723. void add_gizmo_plugin(Ref<EditorNode3DGizmoPlugin> p_plugin);
  724. void remove_gizmo_plugin(Ref<EditorNode3DGizmoPlugin> p_plugin);
  725. void edit(Node3D *p_spatial);
  726. void clear();
  727. Node3DEditor();
  728. ~Node3DEditor();
  729. };
  730. class Node3DEditorPlugin : public EditorPlugin {
  731. GDCLASS(Node3DEditorPlugin, EditorPlugin);
  732. Node3DEditor *spatial_editor = nullptr;
  733. public:
  734. Node3DEditor *get_spatial_editor() { return spatial_editor; }
  735. virtual String get_name() const override { return "3D"; }
  736. bool has_main_screen() const override { return true; }
  737. virtual void make_visible(bool p_visible) override;
  738. virtual void edit(Object *p_object) override;
  739. virtual bool handles(Object *p_object) const override;
  740. virtual Dictionary get_state() const override;
  741. virtual void set_state(const Dictionary &p_state) override;
  742. virtual void clear() override { spatial_editor->clear(); }
  743. virtual void edited_scene_changed() override;
  744. Node3DEditorPlugin();
  745. ~Node3DEditorPlugin();
  746. };
  747. #endif // NODE_3D_EDITOR_PLUGIN_H