node_3d_editor_plugin.h 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087
  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) 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. #pragma once
  31. #include "core/math/dynamic_bvh.h"
  32. #include "editor/plugins/editor_plugin.h"
  33. #include "editor/plugins/node_3d_editor_gizmos.h"
  34. #include "editor/themes/editor_scale.h"
  35. #include "scene/gui/box_container.h"
  36. #include "scene/gui/button.h"
  37. #include "scene/gui/spin_box.h"
  38. #include "scene/resources/immediate_mesh.h"
  39. class AcceptDialog;
  40. class CheckBox;
  41. class ColorPickerButton;
  42. class ConfirmationDialog;
  43. class DirectionalLight3D;
  44. class EditorData;
  45. class EditorSelection;
  46. class EditorSpinSlider;
  47. class HSplitContainer;
  48. class LineEdit;
  49. class MenuButton;
  50. class Node3DEditor;
  51. class Node3DEditorViewport;
  52. class OptionButton;
  53. class PanelContainer;
  54. class ProceduralSkyMaterial;
  55. class SubViewport;
  56. class SubViewportContainer;
  57. class VSeparator;
  58. class VSplitContainer;
  59. class ViewportNavigationControl;
  60. class WorldEnvironment;
  61. class MeshInstance3D;
  62. class ViewportRotationControl : public Control {
  63. GDCLASS(ViewportRotationControl, Control);
  64. struct Axis2D {
  65. Vector2 screen_point;
  66. float z_axis = -99.0;
  67. int axis = -1;
  68. };
  69. struct Axis2DCompare {
  70. _FORCE_INLINE_ bool operator()(const Axis2D &l, const Axis2D &r) const {
  71. return l.z_axis < r.z_axis;
  72. }
  73. };
  74. Node3DEditorViewport *viewport = nullptr;
  75. Vector<Color> axis_colors;
  76. Vector<int> axis_menu_options;
  77. Vector2i orbiting_mouse_start;
  78. int orbiting_index = -1;
  79. int focused_axis = -2;
  80. bool gizmo_activated = false;
  81. const float AXIS_CIRCLE_RADIUS = 8.0f * EDSCALE;
  82. protected:
  83. void _notification(int p_what);
  84. virtual void gui_input(const Ref<InputEvent> &p_event) override;
  85. void _draw();
  86. void _draw_axis(const Axis2D &p_axis);
  87. void _get_sorted_axis(Vector<Axis2D> &r_axis);
  88. void _update_focus();
  89. void _process_click(int p_index, Vector2 p_position, bool p_pressed);
  90. void _process_drag(Ref<InputEventWithModifiers> p_event, int p_index, Vector2 p_position, Vector2 p_relative_position);
  91. public:
  92. void set_viewport(Node3DEditorViewport *p_viewport);
  93. };
  94. class Node3DEditorViewport : public Control {
  95. GDCLASS(Node3DEditorViewport, Control);
  96. friend class Node3DEditor;
  97. friend class ViewportNavigationControl;
  98. friend class ViewportRotationControl;
  99. enum {
  100. VIEW_TOP,
  101. VIEW_BOTTOM,
  102. VIEW_LEFT,
  103. VIEW_RIGHT,
  104. VIEW_FRONT,
  105. VIEW_REAR,
  106. VIEW_CENTER_TO_ORIGIN,
  107. VIEW_CENTER_TO_SELECTION,
  108. VIEW_ALIGN_TRANSFORM_WITH_VIEW,
  109. VIEW_ALIGN_ROTATION_WITH_VIEW,
  110. VIEW_PERSPECTIVE,
  111. VIEW_ENVIRONMENT,
  112. VIEW_ORTHOGONAL,
  113. VIEW_SWITCH_PERSPECTIVE_ORTHOGONAL,
  114. VIEW_HALF_RESOLUTION,
  115. VIEW_AUDIO_LISTENER,
  116. VIEW_AUDIO_DOPPLER,
  117. VIEW_GIZMOS,
  118. VIEW_TRANSFORM_GIZMO,
  119. VIEW_GRID,
  120. VIEW_INFORMATION,
  121. VIEW_FRAME_TIME,
  122. // < Keep in sync with menu.
  123. VIEW_DISPLAY_NORMAL,
  124. VIEW_DISPLAY_WIREFRAME,
  125. VIEW_DISPLAY_OVERDRAW,
  126. VIEW_DISPLAY_LIGHTING,
  127. VIEW_DISPLAY_UNSHADED,
  128. VIEW_DISPLAY_ADVANCED,
  129. // Advanced menu:
  130. VIEW_DISPLAY_DEBUG_PSSM_SPLITS,
  131. VIEW_DISPLAY_NORMAL_BUFFER,
  132. VIEW_DISPLAY_DEBUG_SHADOW_ATLAS,
  133. VIEW_DISPLAY_DEBUG_DIRECTIONAL_SHADOW_ATLAS,
  134. VIEW_DISPLAY_DEBUG_DECAL_ATLAS,
  135. VIEW_DISPLAY_DEBUG_VOXEL_GI_ALBEDO,
  136. VIEW_DISPLAY_DEBUG_VOXEL_GI_LIGHTING,
  137. VIEW_DISPLAY_DEBUG_VOXEL_GI_EMISSION,
  138. VIEW_DISPLAY_DEBUG_SDFGI,
  139. VIEW_DISPLAY_DEBUG_SDFGI_PROBES,
  140. VIEW_DISPLAY_DEBUG_SCENE_LUMINANCE,
  141. VIEW_DISPLAY_DEBUG_SSAO,
  142. VIEW_DISPLAY_DEBUG_SSIL,
  143. VIEW_DISPLAY_DEBUG_GI_BUFFER,
  144. VIEW_DISPLAY_DEBUG_DISABLE_LOD,
  145. VIEW_DISPLAY_DEBUG_CLUSTER_OMNI_LIGHTS,
  146. VIEW_DISPLAY_DEBUG_CLUSTER_SPOT_LIGHTS,
  147. VIEW_DISPLAY_DEBUG_CLUSTER_DECALS,
  148. VIEW_DISPLAY_DEBUG_CLUSTER_REFLECTION_PROBES,
  149. VIEW_DISPLAY_DEBUG_OCCLUDERS,
  150. VIEW_DISPLAY_MOTION_VECTORS,
  151. VIEW_DISPLAY_INTERNAL_BUFFER,
  152. VIEW_DISPLAY_MAX,
  153. // > Keep in sync with menu.
  154. VIEW_LOCK_ROTATION,
  155. VIEW_CINEMATIC_PREVIEW,
  156. VIEW_AUTO_ORTHOGONAL,
  157. VIEW_MAX
  158. };
  159. enum ViewType {
  160. VIEW_TYPE_USER,
  161. VIEW_TYPE_TOP,
  162. VIEW_TYPE_BOTTOM,
  163. VIEW_TYPE_LEFT,
  164. VIEW_TYPE_RIGHT,
  165. VIEW_TYPE_FRONT,
  166. VIEW_TYPE_REAR,
  167. };
  168. public:
  169. static constexpr int32_t GIZMO_BASE_LAYER = 27;
  170. static constexpr int32_t GIZMO_EDIT_LAYER = 26;
  171. static constexpr int32_t GIZMO_GRID_LAYER = 25;
  172. static constexpr int32_t MISC_TOOL_LAYER = 24;
  173. static constexpr int32_t FRAME_TIME_HISTORY = 20;
  174. enum NavigationScheme {
  175. NAVIGATION_GODOT = 0,
  176. NAVIGATION_MAYA = 1,
  177. NAVIGATION_MODO = 2,
  178. NAVIGATION_CUSTOM = 3,
  179. NAVIGATION_TABLET = 4,
  180. };
  181. enum FreelookNavigationScheme {
  182. FREELOOK_DEFAULT,
  183. FREELOOK_PARTIALLY_AXIS_LOCKED,
  184. FREELOOK_FULLY_AXIS_LOCKED,
  185. };
  186. enum ViewportNavMouseButton {
  187. NAVIGATION_LEFT_MOUSE,
  188. NAVIGATION_MIDDLE_MOUSE,
  189. NAVIGATION_RIGHT_MOUSE,
  190. NAVIGATION_MOUSE_4,
  191. NAVIGATION_MOUSE_5,
  192. };
  193. private:
  194. double cpu_time_history[FRAME_TIME_HISTORY];
  195. int cpu_time_history_index;
  196. double gpu_time_history[FRAME_TIME_HISTORY];
  197. int gpu_time_history_index;
  198. Node *ruler = nullptr;
  199. Node3D *ruler_start_point = nullptr;
  200. Node3D *ruler_end_point = nullptr;
  201. Ref<ImmediateMesh> geometry;
  202. MeshInstance3D *ruler_line = nullptr;
  203. MeshInstance3D *ruler_line_xray = nullptr;
  204. Label *ruler_label = nullptr;
  205. Ref<StandardMaterial3D> ruler_material;
  206. Ref<StandardMaterial3D> ruler_material_xray;
  207. int index;
  208. ViewType view_type;
  209. void _menu_option(int p_option);
  210. void _set_auto_orthogonal();
  211. Node3D *preview_node = nullptr;
  212. bool update_preview_node = false;
  213. Point2 preview_node_viewport_pos;
  214. Vector3 preview_node_pos;
  215. AABB *preview_bounds = nullptr;
  216. Vector<String> selected_files;
  217. AcceptDialog *accept = nullptr;
  218. Node *target_node = nullptr;
  219. Point2 drop_pos;
  220. EditorSelection *editor_selection = nullptr;
  221. CheckBox *preview_camera = nullptr;
  222. SubViewportContainer *subviewport_container = nullptr;
  223. MenuButton *view_display_menu = nullptr;
  224. PopupMenu *display_submenu = nullptr;
  225. Control *surface = nullptr;
  226. SubViewport *viewport = nullptr;
  227. Camera3D *camera = nullptr;
  228. bool transforming = false;
  229. bool orthogonal;
  230. bool auto_orthogonal;
  231. bool lock_rotation;
  232. bool transform_gizmo_visible = true;
  233. bool collision_reposition = false;
  234. real_t gizmo_scale;
  235. bool freelook_active;
  236. real_t freelook_speed;
  237. Vector2 previous_mouse_position;
  238. PanelContainer *info_panel = nullptr;
  239. Label *info_label = nullptr;
  240. Label *cinema_label = nullptr;
  241. Label *locked_label = nullptr;
  242. Label *zoom_limit_label = nullptr;
  243. Label *preview_material_label = nullptr;
  244. Label *preview_material_label_desc = nullptr;
  245. VBoxContainer *top_right_vbox = nullptr;
  246. VBoxContainer *bottom_center_vbox = nullptr;
  247. ViewportNavigationControl *position_control = nullptr;
  248. ViewportNavigationControl *look_control = nullptr;
  249. ViewportRotationControl *rotation_control = nullptr;
  250. Gradient *frame_time_gradient = nullptr;
  251. PanelContainer *frame_time_panel = nullptr;
  252. VBoxContainer *frame_time_vbox = nullptr;
  253. Label *cpu_time_label = nullptr;
  254. Label *gpu_time_label = nullptr;
  255. Label *fps_label = nullptr;
  256. struct _RayResult {
  257. Node3D *item = nullptr;
  258. real_t depth = 0;
  259. _FORCE_INLINE_ bool operator<(const _RayResult &p_rr) const { return depth < p_rr.depth; }
  260. };
  261. void _update_name();
  262. void _compute_edit(const Point2 &p_point);
  263. void _clear_selected();
  264. void _select_clicked(bool p_allow_locked);
  265. ObjectID _select_ray(const Point2 &p_pos) const;
  266. void _find_items_at_pos(const Point2 &p_pos, Vector<_RayResult> &r_results, bool p_include_locked);
  267. Transform3D _get_camera_transform() const;
  268. int get_selected_count() const;
  269. void cancel_transform();
  270. void _update_shrink();
  271. Vector3 _get_camera_position() const;
  272. Vector3 _get_camera_normal() const;
  273. Vector3 _get_screen_to_space(const Vector3 &p_vector3);
  274. void _select_region();
  275. bool _transform_gizmo_select(const Vector2 &p_screenpos, bool p_highlight_only = false);
  276. void _transform_gizmo_apply(Node3D *p_node, const Transform3D &p_transform, bool p_local);
  277. void _nav_pan(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative);
  278. void _nav_zoom(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative);
  279. void _nav_orbit(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative);
  280. void _nav_look(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative);
  281. bool _is_shortcut_empty(const String &p_name);
  282. bool _is_nav_modifier_pressed(const String &p_name);
  283. int _get_shortcut_input_count(const String &p_name);
  284. float get_znear() const;
  285. float get_zfar() const;
  286. float get_fov() const;
  287. ObjectID clicked;
  288. ObjectID material_target;
  289. Vector<Node3D *> selection_results;
  290. Vector<Node3D *> selection_results_menu;
  291. bool clicked_wants_append = false;
  292. bool selection_in_progress = false;
  293. PopupMenu *selection_menu = nullptr;
  294. enum NavigationZoomStyle {
  295. NAVIGATION_ZOOM_VERTICAL,
  296. NAVIGATION_ZOOM_HORIZONTAL
  297. };
  298. enum NavigationMode {
  299. NAVIGATION_NONE,
  300. NAVIGATION_PAN,
  301. NAVIGATION_ZOOM,
  302. NAVIGATION_ORBIT,
  303. NAVIGATION_LOOK,
  304. NAVIGATION_MOVE
  305. };
  306. enum TransformMode {
  307. TRANSFORM_NONE,
  308. TRANSFORM_ROTATE,
  309. TRANSFORM_TRANSLATE,
  310. TRANSFORM_SCALE
  311. };
  312. enum TransformPlane {
  313. TRANSFORM_VIEW,
  314. TRANSFORM_X_AXIS,
  315. TRANSFORM_Y_AXIS,
  316. TRANSFORM_Z_AXIS,
  317. TRANSFORM_YZ,
  318. TRANSFORM_XZ,
  319. TRANSFORM_XY,
  320. };
  321. struct EditData {
  322. TransformMode mode;
  323. TransformPlane plane;
  324. Transform3D original;
  325. Vector3 click_ray;
  326. Vector3 click_ray_pos;
  327. Vector3 center;
  328. Point2 mouse_pos;
  329. Point2 original_mouse_pos;
  330. bool snap = false;
  331. bool show_rotation_line = false;
  332. Ref<EditorNode3DGizmo> gizmo;
  333. int gizmo_handle = 0;
  334. bool gizmo_handle_secondary = false;
  335. Variant gizmo_initial_value;
  336. bool original_local;
  337. bool instant;
  338. // Numeric blender-style transforms (e.g. 'g5x').
  339. // numeric_input tracks the current input value, e.g. 1.23.
  340. // numeric_negate indicates whether '-' has been pressed to negate the value
  341. // while numeric_next_decimal is 0, numbers are input before the decimal point
  342. // after pressing '.', numeric next decimal changes to -1, and decrements after each press.
  343. double numeric_input = 0.0;
  344. bool numeric_negate = false;
  345. int numeric_next_decimal = 0;
  346. } _edit;
  347. struct Cursor {
  348. Vector3 pos;
  349. real_t x_rot, y_rot, distance, fov_scale;
  350. Vector3 eye_pos; // Used in freelook mode
  351. bool region_select;
  352. Point2 region_begin, region_end;
  353. Cursor() {
  354. // These rotations place the camera in +X +Y +Z, aka south east, facing north west.
  355. x_rot = 0.5;
  356. y_rot = -0.5;
  357. distance = 4;
  358. fov_scale = 1.0;
  359. region_select = false;
  360. }
  361. };
  362. // Viewport camera supports movement smoothing,
  363. // so one cursor is the real cursor, while the other can be an interpolated version.
  364. Cursor cursor; // Immediate cursor
  365. Cursor camera_cursor; // That one may be interpolated (don't modify this one except for smoothing purposes)
  366. Cursor previous_cursor; // Storing previous cursor state for canceling purposes
  367. void scale_fov(real_t p_fov_offset);
  368. void reset_fov();
  369. void scale_cursor_distance(real_t scale);
  370. struct ShortcutCheckSet {
  371. bool mod_pressed = false;
  372. bool shortcut_not_empty = true;
  373. int input_count = 0;
  374. ViewportNavMouseButton mouse_preference = NAVIGATION_LEFT_MOUSE;
  375. NavigationMode result_nav_mode = NAVIGATION_NONE;
  376. ShortcutCheckSet() {}
  377. ShortcutCheckSet(bool p_mod_pressed, bool p_shortcut_not_empty, int p_input_count, const ViewportNavMouseButton &p_mouse_preference, const NavigationMode &p_result_nav_mode) :
  378. mod_pressed(p_mod_pressed), shortcut_not_empty(p_shortcut_not_empty), input_count(p_input_count), mouse_preference(p_mouse_preference), result_nav_mode(p_result_nav_mode) {
  379. }
  380. };
  381. struct ShortcutCheckSetComparator {
  382. _FORCE_INLINE_ bool operator()(const ShortcutCheckSet &A, const ShortcutCheckSet &B) const {
  383. return A.input_count > B.input_count;
  384. }
  385. };
  386. NavigationMode _get_nav_mode_from_shortcut_check(ViewportNavMouseButton p_mouse_button, Vector<ShortcutCheckSet> p_shortcut_check_sets, bool p_use_not_empty);
  387. void set_freelook_active(bool active_now);
  388. void scale_freelook_speed(real_t scale);
  389. real_t zoom_indicator_delay;
  390. int zoom_failed_attempts_count = 0;
  391. 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];
  392. String last_message;
  393. String message;
  394. double message_time;
  395. void set_message(const String &p_message, float p_time = 5);
  396. void _view_settings_confirmed(real_t p_interp_delta);
  397. void _update_camera(real_t p_interp_delta);
  398. void _update_navigation_controls_visibility();
  399. Transform3D to_camera_transform(const Cursor &p_cursor) const;
  400. void _draw();
  401. // These allow tool scripts to set the 3D cursor location by updating the camera transform.
  402. Transform3D last_camera_transform;
  403. bool _camera_moved_externally();
  404. void _apply_camera_transform_to_cursor();
  405. void _surface_mouse_enter();
  406. void _surface_mouse_exit();
  407. void _surface_focus_enter();
  408. void _surface_focus_exit();
  409. void input(const Ref<InputEvent> &p_event) override;
  410. void _sinput(const Ref<InputEvent> &p_event);
  411. void _update_freelook(real_t delta);
  412. Node3DEditor *spatial_editor = nullptr;
  413. Camera3D *previewing = nullptr;
  414. Camera3D *preview = nullptr;
  415. bool previewing_camera = false;
  416. bool previewing_cinema = false;
  417. bool _is_node_locked(const Node *p_node) const;
  418. void _preview_exited_scene();
  419. void _toggle_camera_preview(bool);
  420. void _toggle_cinema_preview(bool);
  421. void _init_gizmo_instance(int p_idx);
  422. void _finish_gizmo_instances();
  423. void _selection_result_pressed(int);
  424. void _selection_menu_hide();
  425. void _list_select(Ref<InputEventMouseButton> b);
  426. Point2 _get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const;
  427. Vector3 _get_instance_position(const Point2 &p_pos, Node3D *p_node) const;
  428. static AABB _calculate_spatial_bounds(const Node3D *p_parent, bool p_omit_top_level = false, const Transform3D *p_bounds_orientation = nullptr);
  429. Node *_sanitize_preview_node(Node *p_node) const;
  430. void _create_preview_node(const Vector<String> &files) const;
  431. void _remove_preview_node();
  432. bool _apply_preview_material(ObjectID p_target, const Point2 &p_point) const;
  433. void _reset_preview_material() const;
  434. void _remove_preview_material();
  435. bool _cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node) const;
  436. bool _create_instance(Node *p_parent, const String &p_path, const Point2 &p_point);
  437. bool _create_audio_node(Node *p_parent, const String &p_path, const Point2 &p_point);
  438. void _perform_drop_data();
  439. bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
  440. void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
  441. void _project_settings_changed();
  442. 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);
  443. void begin_transform(TransformMode p_mode, bool instant);
  444. void commit_transform();
  445. void apply_transform(Vector3 p_motion, double p_snap);
  446. void update_transform(bool p_shift);
  447. void update_transform_numeric();
  448. void finish_transform();
  449. void register_shortcut_action(const String &p_path, const String &p_name, Key p_keycode, bool p_physical = false);
  450. void shortcut_changed_callback(const Ref<Shortcut> p_shortcut, const String &p_shortcut_path);
  451. // Supported rendering methods for advanced debug draw mode items.
  452. enum SupportedRenderingMethods {
  453. ALL,
  454. FORWARD_PLUS,
  455. FORWARD_PLUS_MOBILE,
  456. };
  457. void _set_lock_view_rotation(bool p_lock_rotation);
  458. void _add_advanced_debug_draw_mode_item(PopupMenu *p_popup, const String &p_name, int p_value, SupportedRenderingMethods p_rendering_methods = SupportedRenderingMethods::ALL, const String &p_tooltip = "");
  459. protected:
  460. void _notification(int p_what);
  461. static void _bind_methods();
  462. public:
  463. void update_surface() { surface->queue_redraw(); }
  464. void update_transform_gizmo_view();
  465. void set_can_preview(Camera3D *p_preview);
  466. void set_state(const Dictionary &p_state);
  467. Dictionary get_state() const;
  468. void reset();
  469. bool is_freelook_active() const { return freelook_active; }
  470. Vector3 get_ray_pos(const Vector2 &p_pos) const;
  471. Vector3 get_ray(const Vector2 &p_pos) const;
  472. Point2 point_to_screen(const Vector3 &p_point);
  473. void focus_selection();
  474. void assign_pending_data_pointers(
  475. Node3D *p_preview_node,
  476. AABB *p_preview_bounds,
  477. AcceptDialog *p_accept);
  478. SubViewport *get_viewport_node() { return viewport; }
  479. Camera3D *get_camera_3d() { return camera; } // return the default camera object.
  480. Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p_index);
  481. ~Node3DEditorViewport();
  482. };
  483. class Node3DEditorSelectedItem : public Object {
  484. GDCLASS(Node3DEditorSelectedItem, Object);
  485. public:
  486. AABB aabb;
  487. Transform3D original; // original location when moving
  488. Transform3D original_local;
  489. Transform3D last_xform; // last transform
  490. bool last_xform_dirty;
  491. Node3D *sp = nullptr;
  492. RID sbox_instance;
  493. RID sbox_instance_offset;
  494. RID sbox_instance_xray;
  495. RID sbox_instance_xray_offset;
  496. Ref<EditorNode3DGizmo> gizmo;
  497. HashMap<int, Transform3D> subgizmos; // Key: Subgizmo ID, Value: Initial subgizmo transform.
  498. Node3DEditorSelectedItem() {
  499. sp = nullptr;
  500. last_xform_dirty = true;
  501. }
  502. ~Node3DEditorSelectedItem();
  503. };
  504. class Node3DEditorViewportContainer : public Container {
  505. GDCLASS(Node3DEditorViewportContainer, Container);
  506. public:
  507. enum View {
  508. VIEW_USE_1_VIEWPORT,
  509. VIEW_USE_2_VIEWPORTS,
  510. VIEW_USE_2_VIEWPORTS_ALT,
  511. VIEW_USE_3_VIEWPORTS,
  512. VIEW_USE_3_VIEWPORTS_ALT,
  513. VIEW_USE_4_VIEWPORTS,
  514. };
  515. private:
  516. View view;
  517. bool mouseover;
  518. real_t ratio_h;
  519. real_t ratio_v;
  520. bool hovering_v;
  521. bool hovering_h;
  522. bool dragging_v;
  523. bool dragging_h;
  524. Vector2 drag_begin_pos;
  525. Vector2 drag_begin_ratio;
  526. virtual void gui_input(const Ref<InputEvent> &p_event) override;
  527. protected:
  528. void _notification(int p_what);
  529. public:
  530. void set_view(View p_view);
  531. View get_view();
  532. Node3DEditorViewportContainer();
  533. };
  534. class Node3DEditor : public VBoxContainer {
  535. GDCLASS(Node3DEditor, VBoxContainer);
  536. public:
  537. static const unsigned int VIEWPORTS_COUNT = 4;
  538. enum ToolMode {
  539. TOOL_MODE_SELECT,
  540. TOOL_MODE_MOVE,
  541. TOOL_MODE_ROTATE,
  542. TOOL_MODE_SCALE,
  543. TOOL_MODE_LIST_SELECT,
  544. TOOL_LOCK_SELECTED,
  545. TOOL_UNLOCK_SELECTED,
  546. TOOL_GROUP_SELECTED,
  547. TOOL_UNGROUP_SELECTED,
  548. TOOL_RULER,
  549. TOOL_MAX
  550. };
  551. enum ToolOptions {
  552. TOOL_OPT_LOCAL_COORDS,
  553. TOOL_OPT_USE_SNAP,
  554. TOOL_OPT_MAX
  555. };
  556. private:
  557. EditorSelection *editor_selection = nullptr;
  558. Node3DEditorViewportContainer *viewport_base = nullptr;
  559. Node3DEditorViewport *viewports[VIEWPORTS_COUNT];
  560. int last_used_viewport = 0;
  561. VSplitContainer *shader_split = nullptr;
  562. HSplitContainer *left_panel_split = nullptr;
  563. HSplitContainer *right_panel_split = nullptr;
  564. /////
  565. ToolMode tool_mode;
  566. RID origin_mesh;
  567. RID origin_multimesh;
  568. RID origin_instance;
  569. bool origin_enabled = false;
  570. RID grid[3];
  571. RID grid_instance[3];
  572. bool grid_visible[3] = { false, false, false }; //currently visible
  573. bool grid_enable[3] = { false, false, false }; //should be always visible if true
  574. bool grid_enabled = false;
  575. bool grid_init_draw = false;
  576. Camera3D::ProjectionType grid_camera_last_update_perspective = Camera3D::PROJECTION_PERSPECTIVE;
  577. Vector3 grid_camera_last_update_position;
  578. Ref<ArrayMesh> move_gizmo[3], move_plane_gizmo[3], rotate_gizmo[4], scale_gizmo[3], scale_plane_gizmo[3], axis_gizmo[3];
  579. Ref<StandardMaterial3D> gizmo_color[3];
  580. Ref<StandardMaterial3D> plane_gizmo_color[3];
  581. Ref<ShaderMaterial> rotate_gizmo_color[3];
  582. Ref<StandardMaterial3D> gizmo_color_hl[3];
  583. Ref<StandardMaterial3D> plane_gizmo_color_hl[3];
  584. Ref<ShaderMaterial> rotate_gizmo_color_hl[3];
  585. Ref<Node3DGizmo> current_hover_gizmo;
  586. int current_hover_gizmo_handle;
  587. bool current_hover_gizmo_handle_secondary;
  588. DynamicBVH gizmo_bvh;
  589. real_t snap_translate_value;
  590. real_t snap_rotate_value;
  591. real_t snap_scale_value;
  592. Ref<ArrayMesh> active_selection_box_xray;
  593. Ref<ArrayMesh> active_selection_box;
  594. Ref<ArrayMesh> selection_box_xray;
  595. Ref<ArrayMesh> selection_box;
  596. Ref<StandardMaterial3D> selection_box_mat = memnew(StandardMaterial3D);
  597. Ref<StandardMaterial3D> selection_box_mat_xray = memnew(StandardMaterial3D);
  598. Ref<StandardMaterial3D> active_selection_box_mat = memnew(StandardMaterial3D);
  599. Ref<StandardMaterial3D> active_selection_box_mat_xray = memnew(StandardMaterial3D);
  600. RID indicators;
  601. RID indicators_instance;
  602. RID cursor_mesh;
  603. RID cursor_instance;
  604. Ref<ShaderMaterial> origin_mat;
  605. Ref<ShaderMaterial> grid_mat[3];
  606. Ref<StandardMaterial3D> cursor_material;
  607. // Scene drag and drop support
  608. Node3D *preview_node = nullptr;
  609. AABB preview_bounds;
  610. Ref<Material> preview_material;
  611. Ref<Material> preview_reset_material;
  612. ObjectID preview_material_target;
  613. int preview_material_surface = -1;
  614. struct Gizmo {
  615. bool visible = false;
  616. real_t scale = 0;
  617. Transform3D transform;
  618. } gizmo;
  619. enum MenuOption {
  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_TRANSFORM_CONFIGURE_SNAP,
  628. MENU_TRANSFORM_DIALOG,
  629. MENU_VIEW_USE_1_VIEWPORT,
  630. MENU_VIEW_USE_2_VIEWPORTS,
  631. MENU_VIEW_USE_2_VIEWPORTS_ALT,
  632. MENU_VIEW_USE_3_VIEWPORTS,
  633. MENU_VIEW_USE_3_VIEWPORTS_ALT,
  634. MENU_VIEW_USE_4_VIEWPORTS,
  635. MENU_VIEW_ORIGIN,
  636. MENU_VIEW_GRID,
  637. MENU_VIEW_GIZMOS_3D_ICONS,
  638. MENU_VIEW_CAMERA_SETTINGS,
  639. MENU_LOCK_SELECTED,
  640. MENU_UNLOCK_SELECTED,
  641. MENU_GROUP_SELECTED,
  642. MENU_UNGROUP_SELECTED,
  643. MENU_SNAP_TO_FLOOR,
  644. MENU_RULER,
  645. };
  646. Button *tool_button[TOOL_MAX];
  647. Button *tool_option_button[TOOL_OPT_MAX];
  648. MenuButton *transform_menu = nullptr;
  649. PopupMenu *gizmos_menu = nullptr;
  650. MenuButton *view_layout_menu = nullptr;
  651. AcceptDialog *accept = nullptr;
  652. ConfirmationDialog *snap_dialog = nullptr;
  653. ConfirmationDialog *xform_dialog = nullptr;
  654. ConfirmationDialog *settings_dialog = nullptr;
  655. bool snap_enabled;
  656. bool snap_key_enabled;
  657. LineEdit *snap_translate = nullptr;
  658. LineEdit *snap_rotate = nullptr;
  659. LineEdit *snap_scale = nullptr;
  660. LineEdit *xform_translate[3];
  661. LineEdit *xform_rotate[3];
  662. LineEdit *xform_scale[3];
  663. OptionButton *xform_type = nullptr;
  664. VBoxContainer *settings_vbc = nullptr;
  665. SpinBox *settings_fov = nullptr;
  666. SpinBox *settings_znear = nullptr;
  667. SpinBox *settings_zfar = nullptr;
  668. void _snap_changed();
  669. void _snap_update();
  670. void _xform_dialog_action();
  671. void _menu_item_pressed(int p_option);
  672. void _menu_item_toggled(bool pressed, int p_option);
  673. void _menu_gizmo_toggled(int p_option);
  674. // Used for secondary menu items which are displayed depending on the currently selected node
  675. // (such as MeshInstance's "Mesh" menu).
  676. PanelContainer *context_toolbar_panel = nullptr;
  677. HBoxContainer *context_toolbar_hbox = nullptr;
  678. HashMap<Control *, VSeparator *> context_toolbar_separators;
  679. void _update_context_toolbar();
  680. void _generate_selection_boxes();
  681. void _init_indicators();
  682. void _update_gizmos_menu();
  683. void _update_gizmos_menu_theme();
  684. void _init_grid();
  685. void _finish_indicators();
  686. void _finish_grid();
  687. void _toggle_maximize_view(Object *p_viewport);
  688. void _viewport_clicked(int p_viewport_idx);
  689. Node *custom_camera = nullptr;
  690. Object *_get_editor_data(Object *p_what);
  691. Ref<Environment> viewport_environment;
  692. Node3D *selected = nullptr;
  693. void _request_gizmo(Object *p_obj);
  694. void _request_gizmo_for_id(ObjectID p_id);
  695. void _set_subgizmo_selection(Object *p_obj, Ref<Node3DGizmo> p_gizmo, int p_id, Transform3D p_transform = Transform3D());
  696. void _clear_subgizmo_selection(Object *p_obj = nullptr);
  697. static Node3DEditor *singleton;
  698. void _node_added(Node *p_node);
  699. void _node_removed(Node *p_node);
  700. Vector<Ref<EditorNode3DGizmoPlugin>> gizmo_plugins_by_priority;
  701. Vector<Ref<EditorNode3DGizmoPlugin>> gizmo_plugins_by_name;
  702. void _register_all_gizmos();
  703. void _selection_changed();
  704. void _refresh_menu_icons();
  705. bool do_snap_selected_nodes_to_floor = false;
  706. void _snap_selected_nodes_to_floor();
  707. // Preview Sun and Environment
  708. class PreviewSunEnvPopup : public PopupPanel {
  709. GDCLASS(PreviewSunEnvPopup, PopupPanel);
  710. protected:
  711. virtual void shortcut_input(const Ref<InputEvent> &p_event) override;
  712. };
  713. uint32_t world_env_count = 0;
  714. uint32_t directional_light_count = 0;
  715. Button *sun_button = nullptr;
  716. Label *sun_state = nullptr;
  717. Label *sun_title = nullptr;
  718. VBoxContainer *sun_vb = nullptr;
  719. Popup *sun_environ_popup = nullptr;
  720. Control *sun_direction = nullptr;
  721. EditorSpinSlider *sun_angle_altitude = nullptr;
  722. EditorSpinSlider *sun_angle_azimuth = nullptr;
  723. ColorPickerButton *sun_color = nullptr;
  724. EditorSpinSlider *sun_energy = nullptr;
  725. EditorSpinSlider *sun_shadow_max_distance = nullptr;
  726. Button *sun_add_to_scene = nullptr;
  727. Vector2 sun_rotation;
  728. Ref<Shader> sun_direction_shader;
  729. Ref<ShaderMaterial> sun_direction_material;
  730. Button *environ_button = nullptr;
  731. Label *environ_state = nullptr;
  732. Label *environ_title = nullptr;
  733. VBoxContainer *environ_vb = nullptr;
  734. ColorPickerButton *environ_sky_color = nullptr;
  735. ColorPickerButton *environ_ground_color = nullptr;
  736. EditorSpinSlider *environ_energy = nullptr;
  737. Button *environ_ao_button = nullptr;
  738. Button *environ_glow_button = nullptr;
  739. Button *environ_tonemap_button = nullptr;
  740. Button *environ_gi_button = nullptr;
  741. Button *environ_add_to_scene = nullptr;
  742. Button *sun_environ_settings = nullptr;
  743. DirectionalLight3D *preview_sun = nullptr;
  744. bool preview_sun_dangling = false;
  745. WorldEnvironment *preview_environment = nullptr;
  746. bool preview_env_dangling = false;
  747. Ref<Environment> environment;
  748. Ref<CameraAttributesPractical> camera_attributes;
  749. Ref<ProceduralSkyMaterial> sky_material;
  750. bool sun_environ_updating = false;
  751. void _sun_direction_draw();
  752. void _sun_direction_input(const Ref<InputEvent> &p_event);
  753. void _sun_direction_set_altitude(float p_altitude);
  754. void _sun_direction_set_azimuth(float p_azimuth);
  755. void _sun_set_color(const Color &p_color);
  756. void _sun_set_energy(float p_energy);
  757. void _sun_set_shadow_max_distance(float p_shadow_max_distance);
  758. void _environ_set_sky_color(const Color &p_color);
  759. void _environ_set_ground_color(const Color &p_color);
  760. void _environ_set_sky_energy(float p_energy);
  761. void _environ_set_ao();
  762. void _environ_set_glow();
  763. void _environ_set_tonemap();
  764. void _environ_set_gi();
  765. void _load_default_preview_settings();
  766. void _update_preview_environment();
  767. void _preview_settings_changed();
  768. void _sun_environ_settings_pressed();
  769. void _add_sun_to_scene(bool p_already_added_environment = false);
  770. void _add_environment_to_scene(bool p_already_added_sun = false);
  771. void _update_theme();
  772. protected:
  773. void _notification(int p_what);
  774. //void _gui_input(InputEvent p_event);
  775. virtual void shortcut_input(const Ref<InputEvent> &p_event) override;
  776. static void _bind_methods();
  777. public:
  778. static Node3DEditor *get_singleton() { return singleton; }
  779. static Size2i get_camera_viewport_size(Camera3D *p_camera);
  780. Vector3 snap_point(Vector3 p_target, Vector3 p_start = Vector3(0, 0, 0)) const;
  781. float get_znear() const { return settings_znear->get_value(); }
  782. float get_zfar() const { return settings_zfar->get_value(); }
  783. float get_fov() const { return settings_fov->get_value(); }
  784. Transform3D get_gizmo_transform() const { return gizmo.transform; }
  785. bool is_gizmo_visible() const;
  786. ToolMode get_tool_mode() const { return tool_mode; }
  787. bool are_local_coords_enabled() const { return tool_option_button[Node3DEditor::TOOL_OPT_LOCAL_COORDS]->is_pressed(); }
  788. void set_local_coords_enabled(bool on) const { tool_option_button[Node3DEditor::TOOL_OPT_LOCAL_COORDS]->set_pressed(on); }
  789. bool is_snap_enabled() const { return snap_enabled ^ snap_key_enabled; }
  790. real_t get_translate_snap() const;
  791. real_t get_rotate_snap() const;
  792. real_t get_scale_snap() const;
  793. Ref<ArrayMesh> get_move_gizmo(int idx) const { return move_gizmo[idx]; }
  794. Ref<ArrayMesh> get_axis_gizmo(int idx) const { return axis_gizmo[idx]; }
  795. Ref<ArrayMesh> get_move_plane_gizmo(int idx) const { return move_plane_gizmo[idx]; }
  796. Ref<ArrayMesh> get_rotate_gizmo(int idx) const { return rotate_gizmo[idx]; }
  797. Ref<ArrayMesh> get_scale_gizmo(int idx) const { return scale_gizmo[idx]; }
  798. Ref<ArrayMesh> get_scale_plane_gizmo(int idx) const { return scale_plane_gizmo[idx]; }
  799. void update_grid();
  800. void update_transform_gizmo();
  801. void update_all_gizmos(Node *p_node = nullptr);
  802. void snap_selected_nodes_to_floor();
  803. void select_gizmo_highlight_axis(int p_axis);
  804. void set_custom_camera(Node *p_camera) { custom_camera = p_camera; }
  805. Dictionary get_state() const;
  806. void set_state(const Dictionary &p_state);
  807. Ref<Environment> get_viewport_environment() { return viewport_environment; }
  808. void add_control_to_menu_panel(Control *p_control);
  809. void remove_control_from_menu_panel(Control *p_control);
  810. void add_control_to_left_panel(Control *p_control);
  811. void remove_control_from_left_panel(Control *p_control);
  812. void add_control_to_right_panel(Control *p_control);
  813. void remove_control_from_right_panel(Control *p_control);
  814. void move_control_to_left_panel(Control *p_control);
  815. void move_control_to_right_panel(Control *p_control);
  816. VSplitContainer *get_shader_split();
  817. Node3D *get_single_selected_node() { return selected; }
  818. bool is_current_selected_gizmo(const EditorNode3DGizmo *p_gizmo);
  819. bool is_subgizmo_selected(int p_id);
  820. Vector<int> get_subgizmo_selection();
  821. void clear_subgizmo_selection(Object *p_obj = nullptr);
  822. Ref<EditorNode3DGizmo> get_current_hover_gizmo() const { return current_hover_gizmo; }
  823. void set_current_hover_gizmo(Ref<EditorNode3DGizmo> p_gizmo) { current_hover_gizmo = p_gizmo; }
  824. void set_current_hover_gizmo_handle(int p_id, bool p_secondary) {
  825. current_hover_gizmo_handle = p_id;
  826. current_hover_gizmo_handle_secondary = p_secondary;
  827. }
  828. int get_current_hover_gizmo_handle(bool &r_secondary) const {
  829. r_secondary = current_hover_gizmo_handle_secondary;
  830. return current_hover_gizmo_handle;
  831. }
  832. void set_can_preview(Camera3D *p_preview);
  833. void set_preview_material(Ref<Material> p_material) { preview_material = p_material; }
  834. Ref<Material> get_preview_material() { return preview_material; }
  835. void set_preview_reset_material(Ref<Material> p_material) { preview_reset_material = p_material; }
  836. Ref<Material> get_preview_reset_material() const { return preview_reset_material; }
  837. void set_preview_material_target(ObjectID p_object_id) { preview_material_target = p_object_id; }
  838. ObjectID get_preview_material_target() const { return preview_material_target; }
  839. void set_preview_material_surface(int p_surface) { preview_material_surface = p_surface; }
  840. int get_preview_material_surface() const { return preview_material_surface; }
  841. Node3DEditorViewport *get_editor_viewport(int p_idx) {
  842. ERR_FAIL_INDEX_V(p_idx, static_cast<int>(VIEWPORTS_COUNT), nullptr);
  843. return viewports[p_idx];
  844. }
  845. Node3DEditorViewport *get_last_used_viewport();
  846. void add_gizmo_plugin(Ref<EditorNode3DGizmoPlugin> p_plugin);
  847. void remove_gizmo_plugin(Ref<EditorNode3DGizmoPlugin> p_plugin);
  848. DynamicBVH::ID insert_gizmo_bvh_node(Node3D *p_node, const AABB &p_aabb);
  849. void update_gizmo_bvh_node(DynamicBVH::ID p_id, const AABB &p_aabb);
  850. void remove_gizmo_bvh_node(DynamicBVH::ID p_id);
  851. Vector<Node3D *> gizmo_bvh_ray_query(const Vector3 &p_ray_start, const Vector3 &p_ray_end);
  852. Vector<Node3D *> gizmo_bvh_frustum_query(const Vector<Plane> &p_frustum);
  853. void edit(Node3D *p_spatial);
  854. void clear();
  855. Node3DEditor();
  856. ~Node3DEditor();
  857. };
  858. class Node3DEditorPlugin : public EditorPlugin {
  859. GDCLASS(Node3DEditorPlugin, EditorPlugin);
  860. Node3DEditor *spatial_editor = nullptr;
  861. public:
  862. Node3DEditor *get_spatial_editor() { return spatial_editor; }
  863. virtual String get_plugin_name() const override { return TTRC("3D"); }
  864. bool has_main_screen() const override { return true; }
  865. virtual void make_visible(bool p_visible) override;
  866. virtual void edit(Object *p_object) override;
  867. virtual bool handles(Object *p_object) const override;
  868. virtual Dictionary get_state() const override;
  869. virtual void set_state(const Dictionary &p_state) override;
  870. virtual void clear() override { spatial_editor->clear(); }
  871. virtual void edited_scene_changed() override;
  872. Node3DEditorPlugin();
  873. };
  874. class ViewportNavigationControl : public Control {
  875. GDCLASS(ViewportNavigationControl, Control);
  876. Node3DEditorViewport *viewport = nullptr;
  877. Vector2i focused_mouse_start;
  878. Vector2 focused_pos;
  879. bool hovered = false;
  880. int focused_index = -1;
  881. Node3DEditorViewport::NavigationMode nav_mode = Node3DEditorViewport::NavigationMode::NAVIGATION_NONE;
  882. const float AXIS_CIRCLE_RADIUS = 30.0f * EDSCALE;
  883. protected:
  884. void _notification(int p_what);
  885. virtual void gui_input(const Ref<InputEvent> &p_event) override;
  886. void _draw();
  887. void _process_click(int p_index, Vector2 p_position, bool p_pressed);
  888. void _process_drag(int p_index, Vector2 p_position, Vector2 p_relative_position);
  889. void _update_navigation();
  890. public:
  891. void set_navigation_mode(Node3DEditorViewport::NavigationMode p_nav_mode);
  892. void set_viewport(Node3DEditorViewport *p_viewport);
  893. };