2014-02-10 01:10:30 +00:00
/*************************************************************************/
/* spatial_editor_plugin.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 12:16:55 +00:00
/* https://godotengine.org */
2014-02-10 01:10:30 +00:00
/*************************************************************************/
2020-01-01 10:16:22 +00:00
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
2014-02-10 01:10:30 +00:00
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
2018-01-04 23:50:27 +00:00
2014-02-10 01:10:30 +00:00
# include "spatial_editor_plugin.h"
2018-09-04 09:30:04 +00:00
# include "core/math/camera_matrix.h"
2017-03-22 20:18:47 +00:00
# include "core/os/input.h"
2018-09-04 09:30:04 +00:00
# include "core/os/keyboard.h"
# include "core/print_string.h"
# include "core/project_settings.h"
2019-02-12 12:30:56 +00:00
# include "core/sort_array.h"
2017-03-05 13:21:25 +00:00
# include "editor/editor_node.h"
2019-12-24 07:17:23 +00:00
# include "editor/editor_scale.h"
2017-03-05 13:21:25 +00:00
# include "editor/editor_settings.h"
2017-03-05 15:44:50 +00:00
# include "editor/plugins/animation_player_editor_plugin.h"
2017-09-02 19:47:16 +00:00
# include "editor/plugins/script_editor_plugin.h"
# include "editor/script_editor_debugger.h"
2017-03-05 13:21:25 +00:00
# include "editor/spatial_editor_gizmos.h"
2017-03-05 15:44:50 +00:00
# include "scene/3d/camera.h"
2018-09-04 09:30:04 +00:00
# include "scene/3d/collision_shape.h"
# include "scene/3d/mesh_instance.h"
# include "scene/3d/physics_body.h"
2017-03-05 15:44:50 +00:00
# include "scene/3d/visual_instance.h"
2019-12-24 07:17:23 +00:00
# include "scene/gui/viewport_container.h"
2017-09-02 19:47:16 +00:00
# include "scene/resources/packed_scene.h"
2017-03-05 15:44:50 +00:00
# include "scene/resources/surface_tool.h"
2016-01-17 23:03:57 +00:00
2014-02-10 01:10:30 +00:00
# define DISTANCE_DEFAULT 4
2017-09-21 21:11:56 +00:00
# define GIZMO_ARROW_SIZE 0.35
2014-02-10 01:10:30 +00:00
# define GIZMO_RING_HALF_WIDTH 0.1
# define GIZMO_SCALE_DEFAULT 0.15
2017-08-29 01:39:45 +00:00
# define GIZMO_PLANE_SIZE 0.2
# define GIZMO_PLANE_DST 0.3
2017-09-21 21:11:56 +00:00
# define GIZMO_CIRCLE_SIZE 1.1
# define GIZMO_SCALE_OFFSET (GIZMO_CIRCLE_SIZE + 0.3)
# define GIZMO_ARROW_OFFSET (GIZMO_CIRCLE_SIZE + 0.3)
2014-02-10 01:10:30 +00:00
2017-05-07 20:59:05 +00:00
# define ZOOM_MIN_DISTANCE 0.001
# define ZOOM_MULTIPLIER 1.08
# define ZOOM_INDICATOR_DELAY_S 1.5
2017-10-08 00:43:57 +00:00
# define FREELOOK_MIN_SPEED 0.01
# define FREELOOK_SPEED_MULTIPLIER 1.08
2017-05-07 20:59:05 +00:00
2017-08-04 11:23:10 +00:00
# define MIN_Z 0.01
2019-07-23 09:42:41 +00:00
# define MAX_Z 1000000.0
2017-08-04 11:23:10 +00:00
# define MIN_FOV 0.01
# define MAX_FOV 179
2019-10-23 09:46:26 +00:00
void ViewportRotationControl : : _notification ( int p_what ) {
if ( p_what = = NOTIFICATION_ENTER_TREE ) {
axis_menu_options . clear ( ) ;
axis_menu_options . push_back ( SpatialEditorViewport : : VIEW_RIGHT ) ;
axis_menu_options . push_back ( SpatialEditorViewport : : VIEW_TOP ) ;
axis_menu_options . push_back ( SpatialEditorViewport : : VIEW_FRONT ) ;
axis_menu_options . push_back ( SpatialEditorViewport : : VIEW_LEFT ) ;
axis_menu_options . push_back ( SpatialEditorViewport : : VIEW_BOTTOM ) ;
axis_menu_options . push_back ( SpatialEditorViewport : : VIEW_REAR ) ;
axis_colors . clear ( ) ;
axis_colors . push_back ( get_color ( " axis_x_color " , " Editor " ) ) ;
axis_colors . push_back ( get_color ( " axis_y_color " , " Editor " ) ) ;
axis_colors . push_back ( get_color ( " axis_z_color " , " Editor " ) ) ;
update ( ) ;
if ( ! is_connected ( " mouse_exited " , this , " _on_mouse_exited " ) ) {
connect ( " mouse_exited " , this , " _on_mouse_exited " ) ;
}
}
if ( p_what = = NOTIFICATION_DRAW & & viewport ! = nullptr ) {
_draw ( ) ;
}
}
void ViewportRotationControl : : _draw ( ) {
Vector2i center = get_size ( ) / 2.0 ;
float radius = get_size ( ) . x / 2.0 ;
if ( focused_axis > - 2 | | orbiting ) {
draw_circle ( center , radius , Color ( 0.5 , 0.5 , 0.5 , 0.25 ) ) ;
}
Vector < Axis2D > axis_to_draw ;
_get_sorted_axis ( axis_to_draw ) ;
for ( int i = 0 ; i < axis_to_draw . size ( ) ; + + i ) {
_draw_axis ( axis_to_draw [ i ] ) ;
}
}
void ViewportRotationControl : : _draw_axis ( const Axis2D & p_axis ) {
bool focused = focused_axis = = p_axis . axis ;
bool positive = p_axis . axis < 3 ;
bool front = ( Math : : abs ( p_axis . z_axis ) < = 0.001 & & positive ) | | p_axis . z_axis > 0.001 ;
int direction = p_axis . axis % 3 ;
Color axis_color = axis_colors [ direction ] ;
if ( ! front ) {
axis_color = axis_color . darkened ( 0.4 ) ;
}
Color c = focused ? Color ( 0.9 , 0.9 , 0.9 ) : axis_color ;
if ( positive ) {
Vector2i center = get_size ( ) / 2.0 ;
draw_line ( center , p_axis . screen_point , c , 1.5 * EDSCALE , true ) ;
}
if ( front ) {
String axis_name = direction = = 0 ? " X " : ( direction = = 1 ? " Y " : " Z " ) ;
draw_circle ( p_axis . screen_point , AXIS_CIRCLE_RADIUS , c ) ;
draw_char ( get_font ( " rotation_control " , " EditorFonts " ) , p_axis . screen_point + Vector2 ( - 4.0 , 5.0 ) * EDSCALE , axis_name , " " , Color ( 0.3 , 0.3 , 0.3 ) ) ;
} else {
draw_circle ( p_axis . screen_point , AXIS_CIRCLE_RADIUS * ( 0.55 + ( 0.2 * ( 1.0 + p_axis . z_axis ) ) ) , c ) ;
}
}
void ViewportRotationControl : : _get_sorted_axis ( Vector < Axis2D > & r_axis ) {
Vector2i center = get_size ( ) / 2.0 ;
float radius = get_size ( ) . x / 2.0 ;
float axis_radius = radius - AXIS_CIRCLE_RADIUS - 2.0 * EDSCALE ;
Basis camera_basis = viewport - > to_camera_transform ( viewport - > cursor ) . get_basis ( ) . inverse ( ) ;
for ( int i = 0 ; i < 3 ; + + i ) {
Vector3 axis_3d = camera_basis . get_axis ( i ) ;
Vector2i axis_vector = Vector2 ( axis_3d . x , - axis_3d . y ) * axis_radius ;
if ( Math : : abs ( axis_3d . z ) < 1.0 ) {
Axis2D pos_axis ;
pos_axis . axis = i ;
pos_axis . screen_point = center + axis_vector ;
pos_axis . z_axis = axis_3d . z ;
r_axis . push_back ( pos_axis ) ;
Axis2D neg_axis ;
neg_axis . axis = i + 3 ;
neg_axis . screen_point = center - axis_vector ;
neg_axis . z_axis = - axis_3d . z ;
r_axis . push_back ( neg_axis ) ;
} else {
// Special case when the camera is aligned with one axis
Axis2D axis ;
axis . axis = i + ( axis_3d . z < 0 ? 0 : 3 ) ;
axis . screen_point = center ;
axis . z_axis = 1.0 ;
r_axis . push_back ( axis ) ;
}
}
r_axis . sort_custom < Axis2DCompare > ( ) ;
}
void ViewportRotationControl : : _gui_input ( Ref < InputEvent > p_event ) {
const Ref < InputEventMouseButton > mb = p_event ;
if ( mb . is_valid ( ) & & mb - > get_button_index ( ) = = BUTTON_LEFT ) {
Vector2 pos = mb - > get_position ( ) ;
if ( mb - > is_pressed ( ) ) {
if ( pos . distance_to ( get_size ( ) / 2.0 ) < get_size ( ) . x / 2.0 ) {
orbiting = true ;
}
} else {
if ( focused_axis > - 1 ) {
viewport - > _menu_option ( axis_menu_options [ focused_axis ] ) ;
_update_focus ( ) ;
}
orbiting = false ;
2020-04-28 14:41:01 +00:00
if ( Input : : get_singleton ( ) - > get_mouse_mode ( ) = = Input : : MOUSE_MODE_CAPTURED ) {
Input : : get_singleton ( ) - > set_mouse_mode ( Input : : MOUSE_MODE_VISIBLE ) ;
Input : : get_singleton ( ) - > warp_mouse_position ( orbiting_mouse_start ) ;
}
2019-10-23 09:46:26 +00:00
}
}
const Ref < InputEventMouseMotion > mm = p_event ;
if ( mm . is_valid ( ) ) {
if ( orbiting ) {
2020-04-28 14:41:01 +00:00
if ( Input : : get_singleton ( ) - > get_mouse_mode ( ) = = Input : : MOUSE_MODE_VISIBLE ) {
Input : : get_singleton ( ) - > set_mouse_mode ( Input : : MOUSE_MODE_CAPTURED ) ;
orbiting_mouse_start = mm - > get_global_position ( ) ;
}
2019-10-23 09:46:26 +00:00
viewport - > _nav_orbit ( mm , viewport - > _get_warped_mouse_motion ( mm ) ) ;
focused_axis = - 1 ;
} else {
_update_focus ( ) ;
}
}
}
void ViewportRotationControl : : _update_focus ( ) {
int original_focus = focused_axis ;
focused_axis = - 2 ;
Vector2 mouse_pos = get_local_mouse_position ( ) ;
if ( mouse_pos . distance_to ( get_size ( ) / 2.0 ) < get_size ( ) . x / 2.0 ) {
focused_axis = - 1 ;
}
Vector < Axis2D > axes ;
_get_sorted_axis ( axes ) ;
for ( int i = 0 ; i < axes . size ( ) ; i + + ) {
const Axis2D & axis = axes [ i ] ;
if ( mouse_pos . distance_to ( axis . screen_point ) < AXIS_CIRCLE_RADIUS ) {
focused_axis = axis . axis ;
}
}
if ( focused_axis ! = original_focus ) {
update ( ) ;
}
}
void ViewportRotationControl : : _on_mouse_exited ( ) {
focused_axis = - 2 ;
update ( ) ;
}
void ViewportRotationControl : : set_viewport ( SpatialEditorViewport * p_viewport ) {
viewport = p_viewport ;
}
void ViewportRotationControl : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " _gui_input " ) , & ViewportRotationControl : : _gui_input ) ;
ClassDB : : bind_method ( D_METHOD ( " _on_mouse_exited " ) , & ViewportRotationControl : : _on_mouse_exited ) ;
}
2017-08-26 03:40:45 +00:00
void SpatialEditorViewport : : _update_camera ( float p_interp_delta ) {
2017-09-23 20:27:29 +00:00
bool is_orthogonal = camera - > get_projection ( ) = = Camera : : PROJECTION_ORTHOGONAL ;
2016-04-06 06:34:34 +00:00
2017-10-08 00:43:57 +00:00
Cursor old_camera_cursor = camera_cursor ;
camera_cursor = cursor ;
2017-09-16 15:12:11 +00:00
2017-10-08 00:43:57 +00:00
if ( p_interp_delta > 0 ) {
2017-09-16 15:12:11 +00:00
2017-10-08 00:43:57 +00:00
//-------
// Perform smoothing
2017-09-16 15:12:11 +00:00
2017-10-08 00:43:57 +00:00
if ( is_freelook_active ( ) ) {
2017-05-01 18:57:35 +00:00
2017-10-08 00:43:57 +00:00
// Higher inertia should increase "lag" (lerp with factor between 0 and 1)
// Inertia of zero should produce instant movement (lerp with factor of 1) in this case it returns a really high value and gets clamped to 1.
real_t inertia = EDITOR_GET ( " editors/3d/freelook/freelook_inertia " ) ;
inertia = MAX ( 0.001 , inertia ) ;
real_t factor = ( 1.0 / inertia ) * p_interp_delta ;
// We interpolate a different point here, because in freelook mode the focus point (cursor.pos) orbits around eye_pos
camera_cursor . eye_pos = old_camera_cursor . eye_pos . linear_interpolate ( cursor . eye_pos , CLAMP ( factor , 0 , 1 ) ) ;
float orbit_inertia = EDITOR_GET ( " editors/3d/navigation_feel/orbit_inertia " ) ;
orbit_inertia = MAX ( 0.0001 , orbit_inertia ) ;
camera_cursor . x_rot = Math : : lerp ( old_camera_cursor . x_rot , cursor . x_rot , MIN ( 1.f , p_interp_delta * ( 1 / orbit_inertia ) ) ) ;
camera_cursor . y_rot = Math : : lerp ( old_camera_cursor . y_rot , cursor . y_rot , MIN ( 1.f , p_interp_delta * ( 1 / orbit_inertia ) ) ) ;
2019-10-23 09:46:26 +00:00
if ( Math : : abs ( camera_cursor . x_rot - cursor . x_rot ) < 0.1 ) {
camera_cursor . x_rot = cursor . x_rot ;
}
if ( Math : : abs ( camera_cursor . y_rot - cursor . y_rot ) < 0.1 ) {
camera_cursor . y_rot = cursor . y_rot ;
}
2017-10-08 00:43:57 +00:00
Vector3 forward = to_camera_transform ( camera_cursor ) . basis . xform ( Vector3 ( 0 , 0 , - 1 ) ) ;
camera_cursor . pos = camera_cursor . eye_pos + forward * camera_cursor . distance ;
} else {
2017-08-26 12:10:57 +00:00
2017-10-08 00:43:57 +00:00
//when not being manipulated, move softly
float free_orbit_inertia = EDITOR_GET ( " editors/3d/navigation_feel/orbit_inertia " ) ;
float free_translation_inertia = EDITOR_GET ( " editors/3d/navigation_feel/translation_inertia " ) ;
//when being manipulated, move more quickly
float manip_orbit_inertia = EDITOR_GET ( " editors/3d/navigation_feel/manipulation_orbit_inertia " ) ;
float manip_translation_inertia = EDITOR_GET ( " editors/3d/navigation_feel/manipulation_translation_inertia " ) ;
2017-05-01 18:57:35 +00:00
2017-10-08 00:43:57 +00:00
float zoom_inertia = EDITOR_GET ( " editors/3d/navigation_feel/zoom_inertia " ) ;
2017-08-26 12:10:57 +00:00
2017-10-08 00:43:57 +00:00
//determine if being manipulated
bool manipulated = Input : : get_singleton ( ) - > get_mouse_button_mask ( ) & ( 2 | 4 ) ;
manipulated | = Input : : get_singleton ( ) - > is_key_pressed ( KEY_SHIFT ) ;
manipulated | = Input : : get_singleton ( ) - > is_key_pressed ( KEY_ALT ) ;
manipulated | = Input : : get_singleton ( ) - > is_key_pressed ( KEY_CONTROL ) ;
float orbit_inertia = MAX ( 0.00001 , manipulated ? manip_orbit_inertia : free_orbit_inertia ) ;
float translation_inertia = MAX ( 0.0001 , manipulated ? manip_translation_inertia : free_translation_inertia ) ;
zoom_inertia = MAX ( 0.0001 , zoom_inertia ) ;
camera_cursor . x_rot = Math : : lerp ( old_camera_cursor . x_rot , cursor . x_rot , MIN ( 1.f , p_interp_delta * ( 1 / orbit_inertia ) ) ) ;
camera_cursor . y_rot = Math : : lerp ( old_camera_cursor . y_rot , cursor . y_rot , MIN ( 1.f , p_interp_delta * ( 1 / orbit_inertia ) ) ) ;
2019-10-23 09:46:26 +00:00
if ( Math : : abs ( camera_cursor . x_rot - cursor . x_rot ) < 0.1 ) {
camera_cursor . x_rot = cursor . x_rot ;
}
if ( Math : : abs ( camera_cursor . y_rot - cursor . y_rot ) < 0.1 ) {
camera_cursor . y_rot = cursor . y_rot ;
}
2017-10-08 00:43:57 +00:00
camera_cursor . pos = old_camera_cursor . pos . linear_interpolate ( cursor . pos , MIN ( 1.f , p_interp_delta * ( 1 / translation_inertia ) ) ) ;
camera_cursor . distance = Math : : lerp ( old_camera_cursor . distance , cursor . distance , MIN ( 1.f , p_interp_delta * ( 1 / zoom_inertia ) ) ) ;
}
2017-08-26 03:40:45 +00:00
}
2017-10-08 00:43:57 +00:00
//-------
// Apply camera transform
2017-09-23 20:27:29 +00:00
float tolerance = 0.001 ;
2017-08-26 03:40:45 +00:00
bool equal = true ;
2017-09-23 20:27:29 +00:00
if ( Math : : abs ( old_camera_cursor . x_rot - camera_cursor . x_rot ) > tolerance | | Math : : abs ( old_camera_cursor . y_rot - camera_cursor . y_rot ) > tolerance ) {
2017-09-06 17:53:00 +00:00
equal = false ;
2017-09-23 20:27:29 +00:00
}
2017-08-26 03:40:45 +00:00
2017-09-23 20:27:29 +00:00
if ( equal & & old_camera_cursor . pos . distance_squared_to ( camera_cursor . pos ) > tolerance * tolerance ) {
2017-08-26 03:40:45 +00:00
equal = false ;
2017-09-23 20:27:29 +00:00
}
2017-08-26 03:40:45 +00:00
2017-09-23 20:27:29 +00:00
if ( equal & & Math : : abs ( old_camera_cursor . distance - camera_cursor . distance ) > tolerance ) {
2017-09-06 17:53:00 +00:00
equal = false ;
2017-09-23 20:27:29 +00:00
}
2017-08-26 03:40:45 +00:00
2017-09-23 20:27:29 +00:00
if ( ! equal | | p_interp_delta = = 0 | | is_freelook_active ( ) | | is_orthogonal ! = orthogonal ) {
2017-08-26 03:40:45 +00:00
2017-09-06 17:53:00 +00:00
camera - > set_global_transform ( to_camera_transform ( camera_cursor ) ) ;
2017-09-23 20:27:29 +00:00
2019-10-23 09:46:26 +00:00
if ( orthogonal ) {
float half_fov = Math : : deg2rad ( get_fov ( ) ) / 2.0 ;
float height = 2.0 * cursor . distance * Math : : tan ( half_fov ) ;
2020-04-04 23:16:11 +00:00
camera - > set_orthogonal ( height , get_znear ( ) , get_zfar ( ) ) ;
2019-10-23 09:46:26 +00:00
} else {
2017-09-23 20:27:29 +00:00
camera - > set_perspective ( get_fov ( ) , get_znear ( ) , get_zfar ( ) ) ;
2019-10-23 09:46:26 +00:00
}
2017-12-19 22:54:54 +00:00
update_transform_gizmo_view ( ) ;
2019-10-23 09:46:26 +00:00
rotation_control - > update ( ) ;
2017-05-01 18:57:35 +00:00
}
}
Transform SpatialEditorViewport : : to_camera_transform ( const Cursor & p_cursor ) const {
2016-04-06 06:34:34 +00:00
Transform camera_transform ;
2017-05-01 18:57:35 +00:00
camera_transform . translate ( p_cursor . pos ) ;
camera_transform . basis . rotate ( Vector3 ( 1 , 0 , 0 ) , - p_cursor . x_rot ) ;
camera_transform . basis . rotate ( Vector3 ( 0 , 1 , 0 ) , - p_cursor . y_rot ) ;
2016-04-06 06:34:34 +00:00
if ( orthogonal )
2020-04-04 23:16:11 +00:00
camera_transform . translate ( 0 , 0 , ( get_zfar ( ) - get_znear ( ) ) / 2.0 ) ;
2016-04-06 06:34:34 +00:00
else
2017-05-01 18:57:35 +00:00
camera_transform . translate ( 0 , 0 , p_cursor . distance ) ;
2016-04-06 06:34:34 +00:00
2017-05-01 18:57:35 +00:00
return camera_transform ;
2016-04-06 06:34:34 +00:00
}
2014-02-10 01:10:30 +00:00
int SpatialEditorViewport : : get_selected_count ( ) const {
2017-03-05 15:44:50 +00:00
Map < Node * , Object * > & selection = editor_selection - > get_selection ( ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
int count = 0 ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
for ( Map < Node * , Object * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 01:10:30 +00:00
2017-08-24 20:58:51 +00:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > key ( ) ) ;
2014-02-10 01:10:30 +00:00
if ( ! sp )
continue ;
2017-03-05 15:44:50 +00:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
2014-02-10 01:10:30 +00:00
if ( ! se )
continue ;
count + + ;
}
return count ;
}
float SpatialEditorViewport : : get_znear ( ) const {
2017-08-04 11:23:10 +00:00
return CLAMP ( spatial_editor - > get_znear ( ) , MIN_Z , MAX_Z ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-05 15:44:50 +00:00
float SpatialEditorViewport : : get_zfar ( ) const {
2014-02-10 01:10:30 +00:00
2017-08-04 11:23:10 +00:00
return CLAMP ( spatial_editor - > get_zfar ( ) , MIN_Z , MAX_Z ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-05 15:44:50 +00:00
float SpatialEditorViewport : : get_fov ( ) const {
2014-02-10 01:10:30 +00:00
2017-08-04 11:23:10 +00:00
return CLAMP ( spatial_editor - > get_fov ( ) , MIN_FOV , MAX_FOV ) ;
2014-02-10 01:10:30 +00:00
}
Transform SpatialEditorViewport : : _get_camera_transform ( ) const {
return camera - > get_global_transform ( ) ;
}
2017-09-10 13:37:49 +00:00
Vector3 SpatialEditorViewport : : _get_camera_position ( ) const {
2014-02-10 01:10:30 +00:00
return _get_camera_transform ( ) . origin ;
}
2017-03-05 15:44:50 +00:00
Point2 SpatialEditorViewport : : _point_to_screen ( const Vector3 & p_point ) {
2014-02-10 01:10:30 +00:00
2017-10-31 17:23:25 +00:00
return camera - > unproject_position ( p_point ) * viewport_container - > get_stretch_shrink ( ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-05 15:44:50 +00:00
Vector3 SpatialEditorViewport : : _get_ray_pos ( const Vector2 & p_pos ) const {
2014-02-10 01:10:30 +00:00
2017-10-31 17:23:25 +00:00
return camera - > project_ray_origin ( p_pos / viewport_container - > get_stretch_shrink ( ) ) ;
2014-02-10 01:10:30 +00:00
}
Vector3 SpatialEditorViewport : : _get_camera_normal ( ) const {
return - _get_camera_transform ( ) . basis . get_axis ( 2 ) ;
}
2017-09-02 19:47:16 +00:00
Vector3 SpatialEditorViewport : : _get_ray ( const Vector2 & p_pos ) const {
2014-02-10 01:10:30 +00:00
2017-10-31 17:23:25 +00:00
return camera - > project_ray_normal ( p_pos / viewport_container - > get_stretch_shrink ( ) ) ;
2014-02-10 01:10:30 +00:00
}
void SpatialEditorViewport : : _clear_selected ( ) {
editor_selection - > clear ( ) ;
}
2017-03-05 15:44:50 +00:00
void SpatialEditorViewport : : _select_clicked ( bool p_append , bool p_single ) {
2014-02-10 01:10:30 +00:00
if ( ! clicked )
return ;
2019-04-17 16:24:28 +00:00
Node * node = Object : : cast_to < Node > ( ObjectDB : : get_instance ( clicked ) ) ;
Spatial * selected = Object : : cast_to < Spatial > ( node ) ;
if ( ! selected )
2014-02-10 01:10:30 +00:00
return ;
2019-04-17 16:24:28 +00:00
// Replace the node by the group if grouped
while ( node & & node ! = editor - > get_edited_scene ( ) - > get_parent ( ) ) {
Spatial * selected_tmp = Object : : cast_to < Spatial > ( node ) ;
if ( selected_tmp & & node - > has_meta ( " _edit_group_ " ) ) {
selected = selected_tmp ;
}
node = node - > get_parent ( ) ;
}
2019-07-15 19:50:00 +00:00
if ( ! _is_node_locked ( selected ) )
_select ( selected , clicked_wants_append , true ) ;
2014-02-10 01:10:30 +00:00
}
2018-09-02 20:31:03 +00:00
void SpatialEditorViewport : : _select ( Node * p_node , bool p_append , bool p_single ) {
2014-02-10 01:10:30 +00:00
if ( ! p_append ) {
2018-05-06 18:49:22 +00:00
editor_selection - > clear ( ) ;
}
2014-02-10 01:10:30 +00:00
2018-05-06 18:49:22 +00:00
if ( editor_selection - > is_selected ( p_node ) ) {
//erase
editor_selection - > remove_node ( p_node ) ;
} else {
2014-02-10 01:10:30 +00:00
editor_selection - > add_node ( p_node ) ;
2018-05-06 18:49:22 +00:00
}
2014-02-10 01:10:30 +00:00
2018-05-06 18:49:22 +00:00
if ( p_single ) {
2018-02-07 06:27:39 +00:00
if ( Engine : : get_singleton ( ) - > is_editor_hint ( ) )
editor - > call ( " edit_node " , p_node ) ;
2014-02-10 01:10:30 +00:00
}
}
2017-03-05 15:44:50 +00:00
ObjectID SpatialEditorViewport : : _select_ray ( const Point2 & p_pos , bool p_append , bool & r_includes_current , int * r_gizmo_handle , bool p_alt_select ) {
2014-02-10 01:10:30 +00:00
if ( r_gizmo_handle )
2017-03-05 15:44:50 +00:00
* r_gizmo_handle = - 1 ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
Vector3 ray = _get_ray ( p_pos ) ;
Vector3 pos = _get_ray_pos ( p_pos ) ;
2019-12-18 22:49:37 +00:00
Vector2 shrinked_pos = p_pos / viewport_container - > get_stretch_shrink ( ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
Vector < ObjectID > instances = VisualServer : : get_singleton ( ) - > instances_cull_ray ( pos , ray , get_tree ( ) - > get_root ( ) - > get_world ( ) - > get_scenario ( ) ) ;
2018-07-24 22:08:49 +00:00
Set < Ref < EditorSpatialGizmo > > found_gizmos ;
2014-02-10 01:10:30 +00:00
2017-08-26 03:40:45 +00:00
Node * edited_scene = get_tree ( ) - > get_edited_scene_root ( ) ;
2017-03-05 15:44:50 +00:00
ObjectID closest = 0 ;
2018-08-27 14:02:49 +00:00
Node * item = NULL ;
2017-03-05 15:44:50 +00:00
float closest_dist = 1e20 ;
int selected_handle = - 1 ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < instances . size ( ) ; i + + ) {
2014-02-10 01:10:30 +00:00
2017-08-24 20:58:51 +00:00
Spatial * spat = Object : : cast_to < Spatial > ( ObjectDB : : get_instance ( instances [ i ] ) ) ;
2014-02-10 01:10:30 +00:00
if ( ! spat )
continue ;
2018-07-24 22:08:49 +00:00
Ref < EditorSpatialGizmo > seg = spat - > get_gizmo ( ) ;
2014-02-10 01:10:30 +00:00
2017-08-09 16:40:02 +00:00
if ( ( ! seg . is_valid ( ) ) | | found_gizmos . has ( seg ) ) {
2014-02-10 01:10:30 +00:00
continue ;
2017-08-09 16:40:02 +00:00
}
2014-02-10 01:10:30 +00:00
found_gizmos . insert ( seg ) ;
Vector3 point ;
Vector3 normal ;
2017-03-05 15:44:50 +00:00
int handle = - 1 ;
2019-12-18 22:49:37 +00:00
bool inters = seg - > intersect_ray ( camera , shrinked_pos , point , normal , & handle , p_alt_select ) ;
2014-02-10 01:10:30 +00:00
if ( ! inters )
continue ;
float dist = pos . distance_to ( point ) ;
2017-03-05 15:44:50 +00:00
if ( dist < 0 )
2014-02-10 01:10:30 +00:00
continue ;
2017-02-06 03:38:39 +00:00
if ( dist < closest_dist ) {
2018-09-02 20:31:03 +00:00
item = Object : : cast_to < Node > ( spat ) ;
while ( item - > get_owner ( ) & & item - > get_owner ( ) ! = edited_scene & & ! edited_scene - > is_editable_instance ( item - > get_owner ( ) ) ) {
item = item - > get_owner ( ) ;
2017-08-26 03:40:45 +00:00
}
2018-08-27 14:02:49 +00:00
closest = item - > get_instance_id ( ) ;
closest_dist = dist ;
selected_handle = handle ;
2017-02-06 03:38:39 +00:00
}
2014-02-10 01:10:30 +00:00
}
2017-02-06 03:38:39 +00:00
if ( ! item )
2014-02-10 01:10:30 +00:00
return 0 ;
2017-03-05 15:44:50 +00:00
if ( ! editor_selection - > is_selected ( item ) | | ( r_gizmo_handle & & selected_handle > = 0 ) ) {
2014-02-10 01:10:30 +00:00
if ( r_gizmo_handle )
2017-03-05 15:44:50 +00:00
* r_gizmo_handle = selected_handle ;
2014-02-10 01:10:30 +00:00
}
2017-02-06 03:38:39 +00:00
return closest ;
2014-02-10 01:10:30 +00:00
}
2017-03-05 15:44:50 +00:00
void SpatialEditorViewport : : _find_items_at_pos ( const Point2 & p_pos , bool & r_includes_current , Vector < _RayResult > & results , bool p_alt_select ) {
2015-11-04 21:39:07 +00:00
2017-03-05 15:44:50 +00:00
Vector3 ray = _get_ray ( p_pos ) ;
Vector3 pos = _get_ray_pos ( p_pos ) ;
2015-11-04 21:39:07 +00:00
2017-03-05 15:44:50 +00:00
Vector < ObjectID > instances = VisualServer : : get_singleton ( ) - > instances_cull_ray ( pos , ray , get_tree ( ) - > get_root ( ) - > get_world ( ) - > get_scenario ( ) ) ;
2018-07-24 22:08:49 +00:00
Set < Ref < EditorSpatialGizmo > > found_gizmos ;
2015-11-04 21:39:07 +00:00
2017-03-05 15:44:50 +00:00
r_includes_current = false ;
2015-11-04 21:39:07 +00:00
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < instances . size ( ) ; i + + ) {
2015-11-04 21:39:07 +00:00
2017-08-24 20:58:51 +00:00
Spatial * spat = Object : : cast_to < Spatial > ( ObjectDB : : get_instance ( instances [ i ] ) ) ;
2015-11-04 21:39:07 +00:00
if ( ! spat )
continue ;
2018-07-24 22:08:49 +00:00
Ref < EditorSpatialGizmo > seg = spat - > get_gizmo ( ) ;
2015-11-04 21:39:07 +00:00
if ( ! seg . is_valid ( ) )
continue ;
if ( found_gizmos . has ( seg ) )
continue ;
found_gizmos . insert ( seg ) ;
Vector3 point ;
Vector3 normal ;
2017-03-05 15:44:50 +00:00
int handle = - 1 ;
bool inters = seg - > intersect_ray ( camera , p_pos , point , normal , NULL , p_alt_select ) ;
2015-11-04 21:39:07 +00:00
if ( ! inters )
continue ;
float dist = pos . distance_to ( point ) ;
2017-03-05 15:44:50 +00:00
if ( dist < 0 )
2015-11-04 21:39:07 +00:00
continue ;
if ( editor_selection - > is_selected ( spat ) )
2017-03-05 15:44:50 +00:00
r_includes_current = true ;
2015-11-04 21:39:07 +00:00
_RayResult res ;
2017-03-05 15:44:50 +00:00
res . item = spat ;
res . depth = dist ;
res . handle = handle ;
2015-11-04 21:39:07 +00:00
results . push_back ( res ) ;
}
if ( results . empty ( ) )
return ;
results . sort ( ) ;
}
2017-08-12 16:52:50 +00:00
Vector3 SpatialEditorViewport : : _get_screen_to_space ( const Vector3 & p_vector3 ) {
2014-02-10 01:10:30 +00:00
CameraMatrix cm ;
2018-06-27 14:59:45 +00:00
if ( orthogonal ) {
cm . set_orthogonal ( camera - > get_size ( ) , get_size ( ) . aspect ( ) , get_znear ( ) + p_vector3 . z , get_zfar ( ) ) ;
} else {
cm . set_perspective ( get_fov ( ) , get_size ( ) . aspect ( ) , get_znear ( ) + p_vector3 . z , get_zfar ( ) ) ;
}
2020-01-21 18:39:16 +00:00
Vector2 screen_he = cm . get_viewport_half_extents ( ) ;
2014-02-10 01:10:30 +00:00
Transform camera_transform ;
2017-03-05 15:44:50 +00:00
camera_transform . translate ( cursor . pos ) ;
camera_transform . basis . rotate ( Vector3 ( 1 , 0 , 0 ) , - cursor . x_rot ) ;
camera_transform . basis . rotate ( Vector3 ( 0 , 1 , 0 ) , - cursor . y_rot ) ;
camera_transform . translate ( 0 , 0 , cursor . distance ) ;
2014-02-10 01:10:30 +00:00
2020-01-21 18:39:16 +00:00
return camera_transform . xform ( Vector3 ( ( ( p_vector3 . x / get_size ( ) . width ) * 2.0 - 1.0 ) * screen_he . x , ( ( 1.0 - ( p_vector3 . y / get_size ( ) . height ) ) * 2.0 - 1.0 ) * screen_he . y , - ( get_znear ( ) + p_vector3 . z ) ) ) ;
2014-02-10 01:10:30 +00:00
}
void SpatialEditorViewport : : _select_region ( ) {
2017-03-05 15:44:50 +00:00
if ( cursor . region_begin = = cursor . region_end )
2014-02-10 01:10:30 +00:00
return ; //nothing really
2018-05-06 18:49:22 +00:00
float z_offset = MAX ( 0.0 , 5.0 - get_znear ( ) ) ;
2017-03-05 15:44:50 +00:00
Vector3 box [ 4 ] = {
2014-02-10 01:10:30 +00:00
Vector3 (
2017-03-05 15:44:50 +00:00
MIN ( cursor . region_begin . x , cursor . region_end . x ) ,
MIN ( cursor . region_begin . y , cursor . region_end . y ) ,
2018-05-06 18:49:22 +00:00
z_offset ) ,
2014-02-10 01:10:30 +00:00
Vector3 (
2017-03-05 15:44:50 +00:00
MAX ( cursor . region_begin . x , cursor . region_end . x ) ,
MIN ( cursor . region_begin . y , cursor . region_end . y ) ,
2018-05-06 18:49:22 +00:00
z_offset ) ,
2014-02-10 01:10:30 +00:00
Vector3 (
2017-03-05 15:44:50 +00:00
MAX ( cursor . region_begin . x , cursor . region_end . x ) ,
MAX ( cursor . region_begin . y , cursor . region_end . y ) ,
2018-05-06 18:49:22 +00:00
z_offset ) ,
2014-02-10 01:10:30 +00:00
Vector3 (
2017-03-05 15:44:50 +00:00
MIN ( cursor . region_begin . x , cursor . region_end . x ) ,
MAX ( cursor . region_begin . y , cursor . region_end . y ) ,
2018-05-06 18:49:22 +00:00
z_offset )
2014-02-10 01:10:30 +00:00
} ;
Vector < Plane > frustum ;
2017-09-10 13:37:49 +00:00
Vector3 cam_pos = _get_camera_position ( ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < 4 ; i + + ) {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
Vector3 a = _get_screen_to_space ( box [ i ] ) ;
Vector3 b = _get_screen_to_space ( box [ ( i + 1 ) % 4 ] ) ;
2018-06-27 14:59:45 +00:00
if ( orthogonal ) {
frustum . push_back ( Plane ( a , ( a - b ) . normalized ( ) ) ) ;
} else {
frustum . push_back ( Plane ( a , b , cam_pos ) ) ;
}
2014-02-10 01:10:30 +00:00
}
2020-04-29 00:14:06 +00:00
Plane near ( cam_pos , - _get_camera_normal ( ) ) ;
near . d - = get_znear ( ) ;
frustum . push_back ( near ) ;
2014-02-10 01:10:30 +00:00
2020-04-29 00:14:06 +00:00
Plane far = - near ;
far . d + = get_zfar ( ) ;
frustum . push_back ( far ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
Vector < ObjectID > instances = VisualServer : : get_singleton ( ) - > instances_cull_convex ( frustum , get_tree ( ) - > get_root ( ) - > get_world ( ) - > get_scenario ( ) ) ;
2018-09-02 20:31:03 +00:00
Vector < Node * > selected ;
2017-09-12 13:06:13 +00:00
Node * edited_scene = get_tree ( ) - > get_edited_scene_root ( ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < instances . size ( ) ; i + + ) {
2014-02-10 01:10:30 +00:00
2017-08-24 20:58:51 +00:00
Spatial * sp = Object : : cast_to < Spatial > ( ObjectDB : : get_instance ( instances [ i ] ) ) ;
2019-07-19 15:56:35 +00:00
if ( ! sp | | _is_node_locked ( sp ) )
2014-02-10 01:10:30 +00:00
continue ;
2018-09-02 20:31:03 +00:00
Node * item = Object : : cast_to < Node > ( sp ) ;
while ( item - > get_owner ( ) & & item - > get_owner ( ) ! = edited_scene & & ! edited_scene - > is_editable_instance ( item - > get_owner ( ) ) ) {
item = item - > get_owner ( ) ;
2018-05-06 18:49:22 +00:00
}
2019-04-17 16:24:28 +00:00
// Replace the node by the group if grouped
if ( item - > is_class ( " Spatial " ) ) {
Spatial * sel = Object : : cast_to < Spatial > ( item ) ;
while ( item & & item ! = editor - > get_edited_scene ( ) - > get_parent ( ) ) {
Spatial * selected_tmp = Object : : cast_to < Spatial > ( item ) ;
if ( selected_tmp & & item - > has_meta ( " _edit_group_ " ) ) {
sel = selected_tmp ;
}
item = item - > get_parent ( ) ;
}
item = sel ;
}
2018-09-02 20:31:03 +00:00
if ( selected . find ( item ) ! = - 1 ) continue ;
2018-05-06 18:49:22 +00:00
2019-11-28 10:34:23 +00:00
if ( _is_node_locked ( item ) ) continue ;
2019-07-15 19:50:00 +00:00
2018-07-24 22:08:49 +00:00
Ref < EditorSpatialGizmo > seg = sp - > get_gizmo ( ) ;
2014-02-10 01:10:30 +00:00
if ( ! seg . is_valid ( ) )
continue ;
2018-05-06 18:49:22 +00:00
if ( seg - > intersect_frustum ( camera , frustum ) ) {
2018-09-02 20:31:03 +00:00
selected . push_back ( item ) ;
2017-09-12 13:06:13 +00:00
}
2018-05-06 18:49:22 +00:00
}
2014-02-10 01:10:30 +00:00
2018-05-06 18:49:22 +00:00
bool single = selected . size ( ) = = 1 ;
for ( int i = 0 ; i < selected . size ( ) ; i + + ) {
_select ( selected [ i ] , true , single ) ;
2014-02-10 01:10:30 +00:00
}
}
2015-03-21 20:47:21 +00:00
void SpatialEditorViewport : : _update_name ( ) {
2018-10-01 06:00:49 +00:00
String view_mode = orthogonal ? TTR ( " Orthogonal " ) : TTR ( " Perspective " ) ;
2015-03-21 20:47:21 +00:00
2019-10-23 09:46:26 +00:00
if ( auto_orthogonal ) {
view_mode + = " [auto] " ;
}
2017-03-05 15:44:50 +00:00
if ( name ! = " " )
2018-10-06 20:53:11 +00:00
view_menu - > set_text ( name + " " + view_mode ) ;
2015-03-21 20:47:21 +00:00
else
2018-10-06 20:53:11 +00:00
view_menu - > set_text ( view_mode ) ;
2017-12-19 05:25:00 +00:00
view_menu - > set_size ( Vector2 ( 0 , 0 ) ) ; // resets the button size
2015-03-21 20:47:21 +00:00
}
2017-03-05 15:44:50 +00:00
void SpatialEditorViewport : : _compute_edit ( const Point2 & p_point ) {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
_edit . click_ray = _get_ray ( Vector2 ( p_point . x , p_point . y ) ) ;
_edit . click_ray_pos = _get_ray_pos ( Vector2 ( p_point . x , p_point . y ) ) ;
_edit . plane = TRANSFORM_VIEW ;
2014-02-10 01:10:30 +00:00
spatial_editor - > update_transform_gizmo ( ) ;
2017-03-05 15:44:50 +00:00
_edit . center = spatial_editor - > get_gizmo_transform ( ) . origin ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 01:10:30 +00:00
2017-08-24 20:58:51 +00:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
2014-02-10 01:10:30 +00:00
if ( ! sp )
continue ;
2017-03-05 15:44:50 +00:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
2014-02-10 01:10:30 +00:00
if ( ! se )
continue ;
2017-10-03 16:49:32 +00:00
se - > original = se - > sp - > get_global_gizmo_transform ( ) ;
se - > original_local = se - > sp - > get_local_gizmo_transform ( ) ;
2014-02-10 01:10:30 +00:00
}
}
2017-07-23 00:02:18 +00:00
static int _get_key_modifier_setting ( const String & p_property ) {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
switch ( EditorSettings : : get_singleton ( ) - > get ( p_property ) . operator int ( ) ) {
2014-02-10 01:10:30 +00:00
case 0 : return 0 ;
case 1 : return KEY_SHIFT ;
case 2 : return KEY_ALT ;
case 3 : return KEY_META ;
case 4 : return KEY_CONTROL ;
}
return 0 ;
}
2017-07-23 00:02:18 +00:00
static int _get_key_modifier ( Ref < InputEventWithModifiers > e ) {
if ( e - > get_shift ( ) )
return KEY_SHIFT ;
if ( e - > get_alt ( ) )
return KEY_ALT ;
if ( e - > get_control ( ) )
return KEY_CONTROL ;
if ( e - > get_metakey ( ) )
return KEY_META ;
return 0 ;
}
2017-05-02 20:13:12 +00:00
bool SpatialEditorViewport : : _gizmo_select ( const Vector2 & p_screenpos , bool p_highlight_only ) {
2014-02-10 01:10:30 +00:00
if ( ! spatial_editor - > is_gizmo_visible ( ) )
return false ;
2017-03-05 15:44:50 +00:00
if ( get_selected_count ( ) = = 0 ) {
2017-05-02 20:13:12 +00:00
if ( p_highlight_only )
2017-04-06 15:35:08 +00:00
spatial_editor - > select_gizmo_highlight_axis ( - 1 ) ;
2014-02-10 01:10:30 +00:00
return false ;
}
2017-03-05 15:44:50 +00:00
Vector3 ray_pos = _get_ray_pos ( Vector2 ( p_screenpos . x , p_screenpos . y ) ) ;
Vector3 ray = _get_ray ( Vector2 ( p_screenpos . x , p_screenpos . y ) ) ;
2014-02-10 01:10:30 +00:00
Transform gt = spatial_editor - > get_gizmo_transform ( ) ;
2017-03-05 15:44:50 +00:00
float gs = gizmo_scale ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
if ( spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_SELECT | | spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_MOVE ) {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
int col_axis = - 1 ;
float col_d = 1e20 ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < 3 ; i + + ) {
2014-02-10 01:10:30 +00:00
2017-09-21 21:11:56 +00:00
Vector3 grabber_pos = gt . origin + gt . basis . get_axis ( i ) * gs * ( GIZMO_ARROW_OFFSET + ( GIZMO_ARROW_SIZE * 0.5 ) ) ;
2017-03-05 15:44:50 +00:00
float grabber_radius = gs * GIZMO_ARROW_SIZE ;
2014-02-10 01:10:30 +00:00
Vector3 r ;
2017-08-29 01:39:45 +00:00
2019-07-23 09:42:41 +00:00
if ( Geometry : : segment_intersects_sphere ( ray_pos , ray_pos + ray * MAX_Z , grabber_pos , grabber_radius , & r ) ) {
2014-02-10 01:10:30 +00:00
float d = r . distance_to ( ray_pos ) ;
2017-03-05 15:44:50 +00:00
if ( d < col_d ) {
col_d = d ;
col_axis = i ;
2014-02-10 01:10:30 +00:00
}
}
}
2017-08-29 01:39:45 +00:00
bool is_plane_translate = false ;
2017-09-21 21:11:56 +00:00
// plane select
2017-08-29 01:39:45 +00:00
if ( col_axis = = - 1 ) {
col_d = 1e20 ;
for ( int i = 0 ; i < 3 ; i + + ) {
Vector3 ivec2 = gt . basis . get_axis ( ( i + 1 ) % 3 ) . normalized ( ) ;
Vector3 ivec3 = gt . basis . get_axis ( ( i + 2 ) % 3 ) . normalized ( ) ;
Vector3 grabber_pos = gt . origin + ( ivec2 + ivec3 ) * gs * ( GIZMO_PLANE_SIZE + GIZMO_PLANE_DST ) ;
Vector3 r ;
Plane plane ( gt . origin , gt . basis . get_axis ( i ) . normalized ( ) ) ;
if ( plane . intersects_ray ( ray_pos , ray , & r ) ) {
float dist = r . distance_to ( grabber_pos ) ;
if ( dist < ( gs * GIZMO_PLANE_SIZE ) ) {
float d = ray_pos . distance_to ( r ) ;
if ( d < col_d ) {
col_d = d ;
col_axis = i ;
is_plane_translate = true ;
}
}
}
}
}
2017-03-05 15:44:50 +00:00
if ( col_axis ! = - 1 ) {
2014-02-10 01:10:30 +00:00
2017-05-02 20:13:12 +00:00
if ( p_highlight_only ) {
2014-02-10 01:10:30 +00:00
2017-08-29 01:39:45 +00:00
spatial_editor - > select_gizmo_highlight_axis ( col_axis + ( is_plane_translate ? 6 : 0 ) ) ;
2014-02-10 01:10:30 +00:00
} else {
2017-08-29 01:39:45 +00:00
//handle plane translate
2017-03-05 15:44:50 +00:00
_edit . mode = TRANSFORM_TRANSLATE ;
_compute_edit ( Point2 ( p_screenpos . x , p_screenpos . y ) ) ;
2017-08-29 01:39:45 +00:00
_edit . plane = TransformPlane ( TRANSFORM_X_AXIS + col_axis + ( is_plane_translate ? 3 : 0 ) ) ;
2014-02-10 01:10:30 +00:00
}
return true ;
}
}
2017-03-05 15:44:50 +00:00
if ( spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_SELECT | | spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_ROTATE ) {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
int col_axis = - 1 ;
float col_d = 1e20 ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < 3 ; i + + ) {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
Plane plane ( gt . origin , gt . basis . get_axis ( i ) . normalized ( ) ) ;
2014-02-10 01:10:30 +00:00
Vector3 r ;
2017-03-05 15:44:50 +00:00
if ( ! plane . intersects_ray ( ray_pos , ray , & r ) )
2014-02-10 01:10:30 +00:00
continue ;
float dist = r . distance_to ( gt . origin ) ;
2017-08-29 01:39:45 +00:00
if ( dist > gs * ( GIZMO_CIRCLE_SIZE - GIZMO_RING_HALF_WIDTH ) & & dist < gs * ( GIZMO_CIRCLE_SIZE + GIZMO_RING_HALF_WIDTH ) ) {
2014-02-10 01:10:30 +00:00
float d = ray_pos . distance_to ( r ) ;
2017-03-05 15:44:50 +00:00
if ( d < col_d ) {
col_d = d ;
col_axis = i ;
2014-02-10 01:10:30 +00:00
}
}
}
2017-03-05 15:44:50 +00:00
if ( col_axis ! = - 1 ) {
2014-02-10 01:10:30 +00:00
2017-05-02 20:13:12 +00:00
if ( p_highlight_only ) {
2014-02-10 01:10:30 +00:00
2017-04-06 15:35:08 +00:00
spatial_editor - > select_gizmo_highlight_axis ( col_axis + 3 ) ;
2014-02-10 01:10:30 +00:00
} else {
//handle rotate
2017-03-05 15:44:50 +00:00
_edit . mode = TRANSFORM_ROTATE ;
_compute_edit ( Point2 ( p_screenpos . x , p_screenpos . y ) ) ;
_edit . plane = TransformPlane ( TRANSFORM_X_AXIS + col_axis ) ;
2014-02-10 01:10:30 +00:00
}
return true ;
}
}
2017-09-21 21:11:56 +00:00
if ( spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_SCALE ) {
int col_axis = - 1 ;
float col_d = 1e20 ;
for ( int i = 0 ; i < 3 ; i + + ) {
Vector3 grabber_pos = gt . origin + gt . basis . get_axis ( i ) * gs * GIZMO_SCALE_OFFSET ;
float grabber_radius = gs * GIZMO_ARROW_SIZE ;
Vector3 r ;
2019-07-23 09:42:41 +00:00
if ( Geometry : : segment_intersects_sphere ( ray_pos , ray_pos + ray * MAX_Z , grabber_pos , grabber_radius , & r ) ) {
2017-09-21 21:11:56 +00:00
float d = r . distance_to ( ray_pos ) ;
if ( d < col_d ) {
col_d = d ;
col_axis = i ;
}
}
}
2017-11-14 22:50:19 +00:00
bool is_plane_scale = false ;
// plane select
if ( col_axis = = - 1 ) {
col_d = 1e20 ;
for ( int i = 0 ; i < 3 ; i + + ) {
Vector3 ivec2 = gt . basis . get_axis ( ( i + 1 ) % 3 ) . normalized ( ) ;
Vector3 ivec3 = gt . basis . get_axis ( ( i + 2 ) % 3 ) . normalized ( ) ;
Vector3 grabber_pos = gt . origin + ( ivec2 + ivec3 ) * gs * ( GIZMO_PLANE_SIZE + GIZMO_PLANE_DST ) ;
Vector3 r ;
Plane plane ( gt . origin , gt . basis . get_axis ( i ) . normalized ( ) ) ;
if ( plane . intersects_ray ( ray_pos , ray , & r ) ) {
float dist = r . distance_to ( grabber_pos ) ;
if ( dist < ( gs * GIZMO_PLANE_SIZE ) ) {
float d = ray_pos . distance_to ( r ) ;
if ( d < col_d ) {
col_d = d ;
col_axis = i ;
is_plane_scale = true ;
}
}
}
}
}
2017-09-21 21:11:56 +00:00
if ( col_axis ! = - 1 ) {
if ( p_highlight_only ) {
2017-11-14 22:50:19 +00:00
spatial_editor - > select_gizmo_highlight_axis ( col_axis + ( is_plane_scale ? 12 : 9 ) ) ;
2017-09-21 21:11:56 +00:00
} else {
//handle scale
_edit . mode = TRANSFORM_SCALE ;
_compute_edit ( Point2 ( p_screenpos . x , p_screenpos . y ) ) ;
2017-11-14 22:50:19 +00:00
_edit . plane = TransformPlane ( TRANSFORM_X_AXIS + col_axis + ( is_plane_scale ? 3 : 0 ) ) ;
2017-09-21 21:11:56 +00:00
}
return true ;
}
}
2017-05-02 20:13:12 +00:00
if ( p_highlight_only )
2017-04-06 15:35:08 +00:00
spatial_editor - > select_gizmo_highlight_axis ( - 1 ) ;
2014-02-10 01:10:30 +00:00
return false ;
}
2017-12-19 14:29:55 +00:00
void SpatialEditorViewport : : _surface_mouse_enter ( ) {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
if ( ! surface - > has_focus ( ) & & ( ! get_focus_owner ( ) | | ! get_focus_owner ( ) - > is_text_field ( ) ) )
surface - > grab_focus ( ) ;
2014-02-10 01:10:30 +00:00
}
2017-12-19 14:29:55 +00:00
void SpatialEditorViewport : : _surface_mouse_exit ( ) {
2017-09-02 19:47:16 +00:00
_remove_preview ( ) ;
}
2017-12-19 14:29:55 +00:00
void SpatialEditorViewport : : _surface_focus_enter ( ) {
view_menu - > set_disable_shortcuts ( false ) ;
}
void SpatialEditorViewport : : _surface_focus_exit ( ) {
view_menu - > set_disable_shortcuts ( true ) ;
}
2019-07-15 19:50:00 +00:00
bool SpatialEditorViewport : : _is_node_locked ( const Node * p_node ) {
return p_node - > has_meta ( " _edit_lock_ " ) & & p_node - > get_meta ( " _edit_lock_ " ) ;
}
2017-05-20 15:38:03 +00:00
void SpatialEditorViewport : : _list_select ( Ref < InputEventMouseButton > b ) {
2015-12-13 20:16:13 +00:00
2017-06-03 08:54:24 +00:00
_find_items_at_pos ( b - > get_position ( ) , clicked_includes_current , selection_results , b - > get_shift ( ) ) ;
2015-12-13 20:16:13 +00:00
2017-03-05 15:44:50 +00:00
Node * scene = editor - > get_edited_scene ( ) ;
2015-12-13 20:16:13 +00:00
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < selection_results . size ( ) ; i + + ) {
Spatial * item = selection_results [ i ] . item ;
if ( item ! = scene & & item - > get_owner ( ) ! = scene & & ! scene - > is_editable_instance ( item - > get_owner ( ) ) ) {
2015-12-13 20:16:13 +00:00
//invalid result
selection_results . remove ( i ) ;
i - - ;
}
}
2017-05-20 15:38:03 +00:00
clicked_wants_append = b - > get_shift ( ) ;
2015-12-13 20:16:13 +00:00
if ( selection_results . size ( ) = = 1 ) {
2017-08-07 10:17:31 +00:00
clicked = selection_results [ 0 ] . item - > get_instance_id ( ) ;
2015-12-13 20:16:13 +00:00
selection_results . clear ( ) ;
if ( clicked ) {
2017-03-05 15:44:50 +00:00
_select_clicked ( clicked_wants_append , true ) ;
clicked = 0 ;
2015-12-13 20:16:13 +00:00
}
} else if ( ! selection_results . empty ( ) ) {
NodePath root_path = get_tree ( ) - > get_edited_scene_root ( ) - > get_path ( ) ;
2017-03-05 15:44:50 +00:00
StringName root_name = root_path . get_name ( root_path . get_name_count ( ) - 1 ) ;
2015-12-13 20:16:13 +00:00
for ( int i = 0 ; i < selection_results . size ( ) ; i + + ) {
2017-03-05 15:44:50 +00:00
Spatial * spat = selection_results [ i ] . item ;
2015-12-13 20:16:13 +00:00
2018-09-02 21:40:51 +00:00
Ref < Texture > icon = EditorNode : : get_singleton ( ) - > get_object_icon ( spat , " Node " ) ;
2015-12-13 20:16:13 +00:00
2017-03-05 15:44:50 +00:00
String node_path = " / " + root_name + " / " + root_path . rel_path_to ( spat - > get_path ( ) ) ;
2015-12-13 20:16:13 +00:00
selection_menu - > add_item ( spat - > get_name ( ) ) ;
2017-03-05 15:44:50 +00:00
selection_menu - > set_item_icon ( i , icon ) ;
2015-12-13 20:16:13 +00:00
selection_menu - > set_item_metadata ( i , node_path ) ;
2017-05-01 18:57:35 +00:00
selection_menu - > set_item_tooltip ( i , String ( spat - > get_name ( ) ) + " \n Type: " + spat - > get_class ( ) + " \n Path: " + node_path ) ;
2015-12-13 20:16:13 +00:00
}
2017-06-03 08:54:24 +00:00
selection_menu - > set_global_position ( b - > get_global_position ( ) ) ;
2015-12-13 20:16:13 +00:00
selection_menu - > popup ( ) ;
}
}
2017-10-30 00:22:48 +00:00
2017-05-20 15:38:03 +00:00
void SpatialEditorViewport : : _sinput ( const Ref < InputEvent > & p_event ) {
2014-02-10 01:10:30 +00:00
if ( previewing )
return ; //do NONE
{
2017-06-08 17:57:35 +00:00
EditorNode * en = editor ;
EditorPluginList * force_input_forwarding_list = en - > get_editor_plugins_force_input_forwarding ( ) ;
if ( ! force_input_forwarding_list - > empty ( ) ) {
bool discard = force_input_forwarding_list - > forward_spatial_gui_input ( camera , p_event , true ) ;
if ( discard )
return ;
}
}
{
2014-02-10 01:10:30 +00:00
EditorNode * en = editor ;
2016-03-29 23:02:53 +00:00
EditorPluginList * over_plugin_list = en - > get_editor_plugins_over ( ) ;
if ( ! over_plugin_list - > empty ( ) ) {
2017-06-08 17:57:35 +00:00
bool discard = over_plugin_list - > forward_spatial_gui_input ( camera , p_event , false ) ;
2014-02-10 01:10:30 +00:00
if ( discard )
return ;
}
}
2017-05-20 15:38:03 +00:00
Ref < InputEventMouseButton > b = p_event ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( b . is_valid ( ) ) {
2019-04-06 20:55:01 +00:00
emit_signal ( " clicked " , this ) ;
2017-09-18 23:30:46 +00:00
float zoom_factor = 1 + ( ZOOM_MULTIPLIER - 1 ) * b - > get_factor ( ) ;
2017-05-20 15:38:03 +00:00
switch ( b - > get_button_index ( ) ) {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
case BUTTON_WHEEL_UP : {
2017-10-08 00:43:57 +00:00
if ( is_freelook_active ( ) )
scale_freelook_speed ( zoom_factor ) ;
else
scale_cursor_distance ( 1.0 / zoom_factor ) ;
2017-05-20 15:38:03 +00:00
} break ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
case BUTTON_WHEEL_DOWN : {
2017-10-08 00:43:57 +00:00
if ( is_freelook_active ( ) )
scale_freelook_speed ( 1.0 / zoom_factor ) ;
else
scale_cursor_distance ( zoom_factor ) ;
2017-05-20 15:38:03 +00:00
} break ;
2017-05-07 20:59:05 +00:00
2017-05-20 15:38:03 +00:00
case BUTTON_RIGHT : {
2014-02-10 01:10:30 +00:00
2017-09-19 00:30:48 +00:00
NavigationScheme nav_scheme = ( NavigationScheme ) EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation/navigation_scheme " ) . operator int ( ) ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( b - > is_pressed ( ) & & _edit . gizmo . is_valid ( ) ) {
//restore
_edit . gizmo - > commit_handle ( _edit . gizmo_handle , _edit . gizmo_initial_value , true ) ;
2018-07-24 22:08:49 +00:00
_edit . gizmo = Ref < EditorSpatialGizmo > ( ) ;
2017-05-20 15:38:03 +00:00
}
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( _edit . mode = = TRANSFORM_NONE & & b - > is_pressed ( ) ) {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( b - > get_alt ( ) ) {
2015-11-19 14:47:04 +00:00
2017-05-20 15:38:03 +00:00
if ( nav_scheme = = NAVIGATION_MAYA )
break ;
2015-11-19 14:47:04 +00:00
2017-05-20 15:38:03 +00:00
_list_select ( b ) ;
return ;
2014-02-10 01:10:30 +00:00
}
2017-05-20 15:38:03 +00:00
}
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( _edit . mode ! = TRANSFORM_NONE & & b - > is_pressed ( ) ) {
//cancel motion
_edit . mode = TRANSFORM_NONE ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 01:10:30 +00:00
2017-08-24 20:58:51 +00:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
2017-05-20 15:38:03 +00:00
if ( ! sp )
continue ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
if ( ! se )
continue ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
sp - > set_global_transform ( se - > original ) ;
2014-02-10 01:10:30 +00:00
}
2017-05-20 15:38:03 +00:00
surface - > update ( ) ;
set_message ( TTR ( " Transform Aborted. " ) , 3 ) ;
}
2017-05-07 20:59:05 +00:00
2017-07-23 00:02:18 +00:00
if ( b - > is_pressed ( ) ) {
2019-11-13 20:54:44 +00:00
const int mod = _get_key_modifier ( b ) ;
2018-10-20 10:49:33 +00:00
if ( ! orthogonal ) {
if ( mod = = _get_key_modifier_setting ( " editors/3d/freelook/freelook_activation_modifier " ) ) {
set_freelook_active ( true ) ;
}
2017-07-23 00:02:18 +00:00
}
} else {
2017-10-08 00:43:57 +00:00
set_freelook_active ( false ) ;
2017-07-23 00:02:18 +00:00
}
2017-06-20 00:24:35 +00:00
if ( freelook_active & & ! surface - > has_focus ( ) ) {
// Focus usually doesn't trigger on right-click, but in case of freelook it should,
// otherwise using keyboard navigation would misbehave
surface - > grab_focus ( ) ;
}
2017-05-07 20:59:05 +00:00
2017-05-20 15:38:03 +00:00
} break ;
case BUTTON_MIDDLE : {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( b - > is_pressed ( ) & & _edit . mode ! = TRANSFORM_NONE ) {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
switch ( _edit . plane ) {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
case TRANSFORM_VIEW : {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
_edit . plane = TRANSFORM_X_AXIS ;
set_message ( TTR ( " X-Axis Transform. " ) , 2 ) ;
name = " " ;
_update_name ( ) ;
} break ;
case TRANSFORM_X_AXIS : {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
_edit . plane = TRANSFORM_Y_AXIS ;
set_message ( TTR ( " Y-Axis Transform. " ) , 2 ) ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
} break ;
case TRANSFORM_Y_AXIS : {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
_edit . plane = TRANSFORM_Z_AXIS ;
set_message ( TTR ( " Z-Axis Transform. " ) , 2 ) ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
} break ;
case TRANSFORM_Z_AXIS : {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
_edit . plane = TRANSFORM_VIEW ;
set_message ( TTR ( " View Plane Transform. " ) , 2 ) ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
} break ;
2018-09-26 11:13:56 +00:00
case TRANSFORM_YZ :
case TRANSFORM_XZ :
case TRANSFORM_XY : {
} break ;
2014-02-10 01:10:30 +00:00
}
2017-05-20 15:38:03 +00:00
}
} break ;
case BUTTON_LEFT : {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( b - > is_pressed ( ) ) {
2014-02-10 01:10:30 +00:00
2017-09-19 00:30:48 +00:00
NavigationScheme nav_scheme = ( NavigationScheme ) EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation/navigation_scheme " ) . operator int ( ) ;
2017-05-20 15:38:03 +00:00
if ( ( nav_scheme = = NAVIGATION_MAYA | | nav_scheme = = NAVIGATION_MODO ) & & b - > get_alt ( ) ) {
break ;
}
2014-03-31 08:27:41 +00:00
2017-05-20 15:38:03 +00:00
if ( spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_LIST_SELECT ) {
_list_select ( b ) ;
break ;
}
2015-12-13 20:16:13 +00:00
2017-06-03 08:54:24 +00:00
_edit . mouse_pos = b - > get_position ( ) ;
2019-03-16 08:15:39 +00:00
_edit . snap = spatial_editor - > is_snap_enabled ( ) ;
2017-05-20 15:38:03 +00:00
_edit . mode = TRANSFORM_NONE ;
2014-10-12 05:13:22 +00:00
2017-05-20 15:38:03 +00:00
//gizmo has priority over everything
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
bool can_select_gizmos = true ;
2014-10-12 05:13:22 +00:00
2017-05-20 15:38:03 +00:00
{
int idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_GIZMOS ) ;
can_select_gizmos = view_menu - > get_popup ( ) - > is_item_checked ( idx ) ;
}
2014-10-12 05:13:22 +00:00
2017-05-20 15:38:03 +00:00
if ( can_select_gizmos & & spatial_editor - > get_selected ( ) ) {
2014-05-05 01:50:23 +00:00
2018-07-24 22:08:49 +00:00
Ref < EditorSpatialGizmo > seg = spatial_editor - > get_selected ( ) - > get_gizmo ( ) ;
2017-05-20 15:38:03 +00:00
if ( seg . is_valid ( ) ) {
int handle = - 1 ;
Vector3 point ;
Vector3 normal ;
bool inters = seg - > intersect_ray ( camera , _edit . mouse_pos , point , normal , & handle , b - > get_shift ( ) ) ;
if ( inters & & handle ! = - 1 ) {
2014-05-05 01:50:23 +00:00
2017-05-20 15:38:03 +00:00
_edit . gizmo = seg ;
_edit . gizmo_handle = handle ;
_edit . gizmo_initial_value = seg - > get_handle_value ( handle ) ;
break ;
2014-05-05 01:50:23 +00:00
}
}
2017-05-20 15:38:03 +00:00
}
2014-05-05 01:50:23 +00:00
2017-05-20 15:38:03 +00:00
if ( _gizmo_select ( _edit . mouse_pos ) )
break ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
clicked = 0 ;
clicked_includes_current = false ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( ( spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_SELECT & & b - > get_control ( ) ) | | spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_ROTATE ) {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
/* HANDLE ROTATION */
if ( get_selected_count ( ) = = 0 )
break ; //bye
//handle rotate
_edit . mode = TRANSFORM_ROTATE ;
2017-06-03 08:54:24 +00:00
_compute_edit ( b - > get_position ( ) ) ;
2017-05-20 15:38:03 +00:00
break ;
}
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_MOVE ) {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( get_selected_count ( ) = = 0 )
break ; //bye
2017-08-29 01:39:45 +00:00
//handle translate
2017-05-20 15:38:03 +00:00
_edit . mode = TRANSFORM_TRANSLATE ;
2017-06-03 08:54:24 +00:00
_compute_edit ( b - > get_position ( ) ) ;
2017-05-20 15:38:03 +00:00
break ;
}
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_SCALE ) {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( get_selected_count ( ) = = 0 )
break ; //bye
2017-10-23 19:21:15 +00:00
//handle scale
2017-05-20 15:38:03 +00:00
_edit . mode = TRANSFORM_SCALE ;
2017-06-03 08:54:24 +00:00
_compute_edit ( b - > get_position ( ) ) ;
2017-05-20 15:38:03 +00:00
break ;
}
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
// todo scale
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
int gizmo_handle = - 1 ;
2014-02-10 01:10:30 +00:00
2017-06-03 08:54:24 +00:00
clicked = _select_ray ( b - > get_position ( ) , b - > get_shift ( ) , clicked_includes_current , & gizmo_handle , b - > get_shift ( ) ) ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
//clicking is always deferred to either move or release
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
clicked_wants_append = b - > get_shift ( ) ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( ! clicked ) {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( ! clicked_wants_append )
_clear_selected ( ) ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
//default to regionselect
cursor . region_select = true ;
2017-06-03 08:54:24 +00:00
cursor . region_begin = b - > get_position ( ) ;
cursor . region_end = b - > get_position ( ) ;
2017-05-20 15:38:03 +00:00
}
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( clicked & & gizmo_handle > = 0 ) {
2014-02-10 01:10:30 +00:00
2017-08-24 20:58:51 +00:00
Spatial * spa = Object : : cast_to < Spatial > ( ObjectDB : : get_instance ( clicked ) ) ;
if ( spa ) {
2014-02-10 01:10:30 +00:00
2018-07-24 22:08:49 +00:00
Ref < EditorSpatialGizmo > seg = spa - > get_gizmo ( ) ;
2017-08-24 20:58:51 +00:00
if ( seg . is_valid ( ) ) {
2014-02-10 01:10:30 +00:00
2017-08-24 20:58:51 +00:00
_edit . gizmo = seg ;
_edit . gizmo_handle = gizmo_handle ;
_edit . gizmo_initial_value = seg - > get_handle_value ( gizmo_handle ) ;
break ;
2014-02-10 01:10:30 +00:00
}
}
2017-05-20 15:38:03 +00:00
}
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
surface - > update ( ) ;
} else {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( _edit . gizmo . is_valid ( ) ) {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
_edit . gizmo - > commit_handle ( _edit . gizmo_handle , _edit . gizmo_initial_value , false ) ;
2018-07-24 22:08:49 +00:00
_edit . gizmo = Ref < EditorSpatialGizmo > ( ) ;
2017-05-20 15:38:03 +00:00
break ;
}
if ( clicked ) {
_select_clicked ( clicked_wants_append , true ) ;
2018-10-20 10:49:33 +00:00
// Processing was deferred.
2017-05-20 15:38:03 +00:00
clicked = 0 ;
}
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( cursor . region_select ) {
2018-05-06 18:49:22 +00:00
if ( ! clicked_wants_append ) _clear_selected ( ) ;
2017-05-20 15:38:03 +00:00
_select_region ( ) ;
cursor . region_select = false ;
surface - > update ( ) ;
}
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( _edit . mode ! = TRANSFORM_NONE ) {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
static const char * _transform_name [ 4 ] = { " None " , " Rotate " , " Translate " , " Scale " } ;
undo_redo - > create_action ( _transform_name [ _edit . mode ] ) ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 01:10:30 +00:00
2017-08-24 20:58:51 +00:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
2017-05-20 15:38:03 +00:00
if ( ! sp )
continue ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
if ( ! se )
continue ;
2014-02-10 01:10:30 +00:00
2017-10-03 16:49:32 +00:00
undo_redo - > add_do_method ( sp , " set_global_transform " , sp - > get_global_gizmo_transform ( ) ) ;
2017-05-20 15:38:03 +00:00
undo_redo - > add_undo_method ( sp , " set_global_transform " , se - > original ) ;
2014-02-10 01:10:30 +00:00
}
2017-05-20 15:38:03 +00:00
undo_redo - > commit_action ( ) ;
_edit . mode = TRANSFORM_NONE ;
set_message ( " " ) ;
2014-02-10 01:10:30 +00:00
}
2017-05-07 20:59:05 +00:00
2017-05-20 15:38:03 +00:00
surface - > update ( ) ;
}
2016-05-21 13:29:25 +00:00
2017-05-20 15:38:03 +00:00
} break ;
}
}
2014-05-05 01:50:23 +00:00
2017-05-20 15:38:03 +00:00
Ref < InputEventMouseMotion > m = p_event ;
2014-05-05 01:50:23 +00:00
2017-05-20 15:38:03 +00:00
if ( m . is_valid ( ) ) {
2014-05-05 01:50:23 +00:00
2017-06-03 08:54:24 +00:00
_edit . mouse_pos = m - > get_position ( ) ;
2014-05-05 01:50:23 +00:00
2017-05-20 15:38:03 +00:00
if ( spatial_editor - > get_selected ( ) ) {
2014-05-05 01:50:23 +00:00
2018-07-24 22:08:49 +00:00
Ref < EditorSpatialGizmo > seg = spatial_editor - > get_selected ( ) - > get_gizmo ( ) ;
2017-05-20 15:38:03 +00:00
if ( seg . is_valid ( ) ) {
int selected_handle = - 1 ;
int handle = - 1 ;
Vector3 point ;
Vector3 normal ;
bool inters = seg - > intersect_ray ( camera , _edit . mouse_pos , point , normal , & handle , false ) ;
if ( inters & & handle ! = - 1 ) {
2014-05-05 01:50:23 +00:00
2017-05-20 15:38:03 +00:00
selected_handle = handle ;
}
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( selected_handle ! = spatial_editor - > get_over_gizmo_handle ( ) ) {
spatial_editor - > set_over_gizmo_handle ( selected_handle ) ;
spatial_editor - > get_selected ( ) - > update_gizmo ( ) ;
if ( selected_handle ! = - 1 )
spatial_editor - > select_gizmo_highlight_axis ( - 1 ) ;
}
2014-02-10 01:10:30 +00:00
}
2017-05-20 15:38:03 +00:00
}
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( spatial_editor - > get_over_gizmo_handle ( ) = = - 1 & & ! ( m - > get_button_mask ( ) & 1 ) & & ! _edit . gizmo . is_valid ( ) ) {
2016-05-21 13:29:25 +00:00
2017-05-20 15:38:03 +00:00
_gizmo_select ( _edit . mouse_pos , true ) ;
}
2014-02-10 01:10:30 +00:00
2017-09-19 00:30:48 +00:00
NavigationScheme nav_scheme = ( NavigationScheme ) EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation/navigation_scheme " ) . operator int ( ) ;
2017-05-20 15:38:03 +00:00
NavigationMode nav_mode = NAVIGATION_NONE ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( _edit . gizmo . is_valid ( ) ) {
2014-02-10 01:10:30 +00:00
2017-06-03 08:54:24 +00:00
_edit . gizmo - > set_handle ( _edit . gizmo_handle , camera , m - > get_position ( ) ) ;
2017-05-20 15:38:03 +00:00
Variant v = _edit . gizmo - > get_handle_value ( _edit . gizmo_handle ) ;
String n = _edit . gizmo - > get_handle_name ( _edit . gizmo_handle ) ;
set_message ( n + " : " + String ( v ) ) ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
} else if ( m - > get_button_mask ( ) & BUTTON_MASK_LEFT ) {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( nav_scheme = = NAVIGATION_MAYA & & m - > get_alt ( ) ) {
nav_mode = NAVIGATION_ORBIT ;
} else if ( nav_scheme = = NAVIGATION_MODO & & m - > get_alt ( ) & & m - > get_shift ( ) ) {
nav_mode = NAVIGATION_PAN ;
} else if ( nav_scheme = = NAVIGATION_MODO & & m - > get_alt ( ) & & m - > get_control ( ) ) {
nav_mode = NAVIGATION_ZOOM ;
} else if ( nav_scheme = = NAVIGATION_MODO & & m - > get_alt ( ) ) {
nav_mode = NAVIGATION_ORBIT ;
} else {
if ( clicked ) {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( ! clicked_includes_current ) {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
_select_clicked ( clicked_wants_append , true ) ;
2018-10-20 10:49:33 +00:00
// Processing was deferred.
2014-03-31 03:59:42 +00:00
}
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
_compute_edit ( _edit . mouse_pos ) ;
clicked = 0 ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
_edit . mode = TRANSFORM_TRANSLATE ;
}
2014-02-10 01:10:30 +00:00
2019-06-20 14:59:48 +00:00
if ( cursor . region_select ) {
2017-06-03 08:54:24 +00:00
cursor . region_end = m - > get_position ( ) ;
2017-05-20 15:38:03 +00:00
surface - > update ( ) ;
return ;
}
2014-02-10 01:10:30 +00:00
2019-06-20 14:59:48 +00:00
if ( _edit . mode = = TRANSFORM_NONE )
2017-05-20 15:38:03 +00:00
return ;
2014-02-10 01:10:30 +00:00
2017-06-03 08:54:24 +00:00
Vector3 ray_pos = _get_ray_pos ( m - > get_position ( ) ) ;
Vector3 ray = _get_ray ( m - > get_position ( ) ) ;
2019-07-24 12:41:09 +00:00
float snap = EDITOR_GET ( " interface/inspector/default_float_step " ) ;
int snap_step_decimals = Math : : range_step_decimals ( snap ) ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
switch ( _edit . mode ) {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
case TRANSFORM_SCALE : {
2014-02-10 01:10:30 +00:00
2017-09-21 21:11:56 +00:00
Vector3 motion_mask ;
Plane plane ;
2017-11-14 22:50:19 +00:00
bool plane_mv = false ;
2017-09-21 21:11:56 +00:00
switch ( _edit . plane ) {
case TRANSFORM_VIEW :
motion_mask = Vector3 ( 0 , 0 , 0 ) ;
plane = Plane ( _edit . center , _get_camera_normal ( ) ) ;
break ;
case TRANSFORM_X_AXIS :
motion_mask = spatial_editor - > get_gizmo_transform ( ) . basis . get_axis ( 0 ) ;
plane = Plane ( _edit . center , motion_mask . cross ( motion_mask . cross ( _get_camera_normal ( ) ) ) . normalized ( ) ) ;
break ;
case TRANSFORM_Y_AXIS :
motion_mask = spatial_editor - > get_gizmo_transform ( ) . basis . get_axis ( 1 ) ;
plane = Plane ( _edit . center , motion_mask . cross ( motion_mask . cross ( _get_camera_normal ( ) ) ) . normalized ( ) ) ;
break ;
case TRANSFORM_Z_AXIS :
motion_mask = spatial_editor - > get_gizmo_transform ( ) . basis . get_axis ( 2 ) ;
plane = Plane ( _edit . center , motion_mask . cross ( motion_mask . cross ( _get_camera_normal ( ) ) ) . normalized ( ) ) ;
break ;
2017-11-14 22:50:19 +00:00
case TRANSFORM_YZ :
motion_mask = spatial_editor - > get_gizmo_transform ( ) . basis . get_axis ( 2 ) + spatial_editor - > get_gizmo_transform ( ) . basis . get_axis ( 1 ) ;
plane = Plane ( _edit . center , spatial_editor - > get_gizmo_transform ( ) . basis . get_axis ( 0 ) ) ;
plane_mv = true ;
break ;
case TRANSFORM_XZ :
motion_mask = spatial_editor - > get_gizmo_transform ( ) . basis . get_axis ( 2 ) + spatial_editor - > get_gizmo_transform ( ) . basis . get_axis ( 0 ) ;
plane = Plane ( _edit . center , spatial_editor - > get_gizmo_transform ( ) . basis . get_axis ( 1 ) ) ;
plane_mv = true ;
break ;
case TRANSFORM_XY :
motion_mask = spatial_editor - > get_gizmo_transform ( ) . basis . get_axis ( 0 ) + spatial_editor - > get_gizmo_transform ( ) . basis . get_axis ( 1 ) ;
plane = Plane ( _edit . center , spatial_editor - > get_gizmo_transform ( ) . basis . get_axis ( 2 ) ) ;
plane_mv = true ;
break ;
2017-09-21 21:11:56 +00:00
}
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
Vector3 intersection ;
if ( ! plane . intersects_ray ( ray_pos , ray , & intersection ) )
break ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
Vector3 click ;
if ( ! plane . intersects_ray ( _edit . click_ray_pos , _edit . click_ray , & click ) )
break ;
2014-02-10 01:10:30 +00:00
2017-09-21 21:11:56 +00:00
Vector3 motion = intersection - click ;
2017-11-14 22:50:19 +00:00
if ( _edit . plane ! = TRANSFORM_VIEW ) {
if ( ! plane_mv ) {
motion = motion_mask . dot ( motion ) * motion_mask ;
} else {
// Alternative planar scaling mode
if ( _get_key_modifier ( m ) ! = KEY_SHIFT ) {
motion = motion_mask . dot ( motion ) * motion_mask ;
}
}
2014-02-10 01:10:30 +00:00
2017-11-08 15:07:30 +00:00
} else {
2017-09-21 21:11:56 +00:00
float center_click_dist = click . distance_to ( _edit . center ) ;
float center_inters_dist = intersection . distance_to ( _edit . center ) ;
if ( center_click_dist = = 0 )
break ;
2014-02-10 01:10:30 +00:00
2017-09-21 21:11:56 +00:00
float scale = center_inters_dist - center_click_dist ;
motion = Vector3 ( scale , scale , scale ) ;
2017-05-20 15:38:03 +00:00
}
2014-02-10 01:10:30 +00:00
2017-09-21 21:11:56 +00:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
2014-02-10 01:10:30 +00:00
2018-10-20 10:49:33 +00:00
// Disable local transformation for TRANSFORM_VIEW
bool local_coords = ( spatial_editor - > are_local_coords_enabled ( ) & & _edit . plane ! = TRANSFORM_VIEW ) ;
2014-02-10 01:10:30 +00:00
2017-09-21 21:11:56 +00:00
if ( _edit . snap | | spatial_editor - > is_snap_enabled ( ) ) {
snap = spatial_editor - > get_scale_snap ( ) / 100 ;
}
2019-07-24 12:41:09 +00:00
Vector3 motion_snapped = motion ;
motion_snapped . snap ( Vector3 ( snap , snap , snap ) ) ;
// This might not be necessary anymore after issue #288 is solved (in 4.0?).
set_message ( TTR ( " Scaling: " ) + " ( " + String : : num ( motion_snapped . x , snap_step_decimals ) + " , " +
String : : num ( motion_snapped . y , snap_step_decimals ) + " , " + String : : num ( motion_snapped . z , snap_step_decimals ) + " ) " ) ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 01:10:30 +00:00
2017-08-24 20:58:51 +00:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
2017-09-21 21:11:56 +00:00
if ( ! sp ) {
2017-05-20 15:38:03 +00:00
continue ;
2017-09-21 21:11:56 +00:00
}
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
2017-09-21 21:11:56 +00:00
if ( ! se ) {
2017-05-20 15:38:03 +00:00
continue ;
2017-09-21 21:11:56 +00:00
}
2014-02-10 01:10:30 +00:00
2017-10-23 19:21:15 +00:00
if ( sp - > has_meta ( " _edit_lock_ " ) ) {
continue ;
}
2017-05-20 15:38:03 +00:00
Transform original = se - > original ;
2017-09-21 21:11:56 +00:00
Transform original_local = se - > original_local ;
2017-05-20 15:38:03 +00:00
Transform base = Transform ( Basis ( ) , _edit . center ) ;
2017-09-21 21:11:56 +00:00
Transform t ;
Vector3 local_scale ;
2014-02-10 01:10:30 +00:00
2017-09-21 21:11:56 +00:00
if ( local_coords ) {
Basis g = original . basis . orthonormalized ( ) ;
Vector3 local_motion = g . inverse ( ) . xform ( motion ) ;
if ( _edit . snap | | spatial_editor - > is_snap_enabled ( ) ) {
local_motion . snap ( Vector3 ( snap , snap , snap ) ) ;
}
local_scale = original_local . basis . get_scale ( ) * ( local_motion + Vector3 ( 1 , 1 , 1 ) ) ;
2017-11-08 15:07:30 +00:00
// Prevent scaling to 0 it would break the gizmo
Basis check = original_local . basis ;
check . scale ( local_scale ) ;
if ( check . determinant ( ) ! = 0 ) {
// Apply scale
sp - > set_scale ( local_scale ) ;
}
2017-09-21 21:11:56 +00:00
} else {
if ( _edit . snap | | spatial_editor - > is_snap_enabled ( ) ) {
motion . snap ( Vector3 ( snap , snap , snap ) ) ;
}
Transform r ;
r . basis . scale ( motion + Vector3 ( 1 , 1 , 1 ) ) ;
t = base * ( r * ( base . inverse ( ) * original ) ) ;
2017-11-08 15:07:30 +00:00
// Apply scale
2017-09-21 21:11:56 +00:00
sp - > set_global_transform ( t ) ;
}
2017-05-20 15:38:03 +00:00
}
2014-03-31 03:59:42 +00:00
2017-05-20 15:38:03 +00:00
surface - > update ( ) ;
2014-03-31 03:59:42 +00:00
2017-05-20 15:38:03 +00:00
} break ;
2014-03-31 03:59:42 +00:00
2017-05-20 15:38:03 +00:00
case TRANSFORM_TRANSLATE : {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
Vector3 motion_mask ;
Plane plane ;
2017-11-13 21:54:33 +00:00
bool plane_mv = false ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
switch ( _edit . plane ) {
case TRANSFORM_VIEW :
plane = Plane ( _edit . center , _get_camera_normal ( ) ) ;
break ;
case TRANSFORM_X_AXIS :
motion_mask = spatial_editor - > get_gizmo_transform ( ) . basis . get_axis ( 0 ) ;
plane = Plane ( _edit . center , motion_mask . cross ( motion_mask . cross ( _get_camera_normal ( ) ) ) . normalized ( ) ) ;
break ;
case TRANSFORM_Y_AXIS :
motion_mask = spatial_editor - > get_gizmo_transform ( ) . basis . get_axis ( 1 ) ;
plane = Plane ( _edit . center , motion_mask . cross ( motion_mask . cross ( _get_camera_normal ( ) ) ) . normalized ( ) ) ;
2014-03-31 03:59:42 +00:00
break ;
2017-05-20 15:38:03 +00:00
case TRANSFORM_Z_AXIS :
motion_mask = spatial_editor - > get_gizmo_transform ( ) . basis . get_axis ( 2 ) ;
plane = Plane ( _edit . center , motion_mask . cross ( motion_mask . cross ( _get_camera_normal ( ) ) ) . normalized ( ) ) ;
break ;
2017-08-29 01:39:45 +00:00
case TRANSFORM_YZ :
plane = Plane ( _edit . center , spatial_editor - > get_gizmo_transform ( ) . basis . get_axis ( 0 ) ) ;
plane_mv = true ;
break ;
case TRANSFORM_XZ :
plane = Plane ( _edit . center , spatial_editor - > get_gizmo_transform ( ) . basis . get_axis ( 1 ) ) ;
plane_mv = true ;
break ;
case TRANSFORM_XY :
plane = Plane ( _edit . center , spatial_editor - > get_gizmo_transform ( ) . basis . get_axis ( 2 ) ) ;
plane_mv = true ;
break ;
2017-05-20 15:38:03 +00:00
}
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
Vector3 intersection ;
if ( ! plane . intersects_ray ( ray_pos , ray , & intersection ) )
break ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
Vector3 click ;
if ( ! plane . intersects_ray ( _edit . click_ray_pos , _edit . click_ray , & click ) )
break ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
Vector3 motion = intersection - click ;
2017-11-14 22:50:19 +00:00
if ( _edit . plane ! = TRANSFORM_VIEW ) {
2017-11-08 15:07:30 +00:00
if ( ! plane_mv ) {
2017-08-29 01:39:45 +00:00
motion = motion_mask . dot ( motion ) * motion_mask ;
2017-11-08 15:07:30 +00:00
}
2017-05-20 15:38:03 +00:00
}
2014-02-10 01:10:30 +00:00
2017-08-08 10:55:21 +00:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
2018-10-20 10:49:33 +00:00
// Disable local transformation for TRANSFORM_VIEW
bool local_coords = ( spatial_editor - > are_local_coords_enabled ( ) & & _edit . plane ! = TRANSFORM_VIEW ) ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( _edit . snap | | spatial_editor - > is_snap_enabled ( ) ) {
snap = spatial_editor - > get_translate_snap ( ) ;
2017-08-08 10:55:21 +00:00
}
2019-07-24 12:41:09 +00:00
Vector3 motion_snapped = motion ;
motion_snapped . snap ( Vector3 ( snap , snap , snap ) ) ;
set_message ( TTR ( " Translating: " ) + " ( " + String : : num ( motion_snapped . x , snap_step_decimals ) + " , " +
String : : num ( motion_snapped . y , snap_step_decimals ) + " , " + String : : num ( motion_snapped . z , snap_step_decimals ) + " ) " ) ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 01:10:30 +00:00
2017-08-24 20:58:51 +00:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
2017-05-20 15:38:03 +00:00
if ( ! sp ) {
continue ;
2014-02-10 01:10:30 +00:00
}
2014-03-31 03:59:42 +00:00
2017-05-20 15:38:03 +00:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
if ( ! se ) {
continue ;
}
2014-03-31 03:59:42 +00:00
2017-10-23 19:21:15 +00:00
if ( sp - > has_meta ( " _edit_lock_ " ) ) {
continue ;
}
2017-11-08 15:07:30 +00:00
Transform original = se - > original ;
Transform t ;
if ( local_coords ) {
if ( _edit . snap | | spatial_editor - > is_snap_enabled ( ) ) {
Basis g = original . basis . orthonormalized ( ) ;
Vector3 local_motion = g . inverse ( ) . xform ( motion ) ;
local_motion . snap ( Vector3 ( snap , snap , snap ) ) ;
motion = g . xform ( local_motion ) ;
}
} else {
if ( _edit . snap | | spatial_editor - > is_snap_enabled ( ) ) {
motion . snap ( Vector3 ( snap , snap , snap ) ) ;
}
}
// Apply translation
t = original ;
2017-05-20 15:38:03 +00:00
t . origin + = motion ;
sp - > set_global_transform ( t ) ;
}
2017-11-08 15:07:30 +00:00
surface - > update ( ) ;
2017-05-20 15:38:03 +00:00
} break ;
2014-03-31 03:59:42 +00:00
2017-05-20 15:38:03 +00:00
case TRANSFORM_ROTATE : {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
Plane plane ;
2017-10-04 07:34:58 +00:00
Vector3 axis ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
switch ( _edit . plane ) {
case TRANSFORM_VIEW :
plane = Plane ( _edit . center , _get_camera_normal ( ) ) ;
break ;
case TRANSFORM_X_AXIS :
plane = Plane ( _edit . center , spatial_editor - > get_gizmo_transform ( ) . basis . get_axis ( 0 ) ) ;
2017-10-04 07:34:58 +00:00
axis = Vector3 ( 1 , 0 , 0 ) ;
2014-03-31 03:59:42 +00:00
break ;
2017-05-20 15:38:03 +00:00
case TRANSFORM_Y_AXIS :
plane = Plane ( _edit . center , spatial_editor - > get_gizmo_transform ( ) . basis . get_axis ( 1 ) ) ;
2017-10-04 07:34:58 +00:00
axis = Vector3 ( 0 , 1 , 0 ) ;
2017-05-20 15:38:03 +00:00
break ;
case TRANSFORM_Z_AXIS :
plane = Plane ( _edit . center , spatial_editor - > get_gizmo_transform ( ) . basis . get_axis ( 2 ) ) ;
2017-10-04 07:34:58 +00:00
axis = Vector3 ( 0 , 0 , 1 ) ;
2017-05-20 15:38:03 +00:00
break ;
2018-09-26 11:13:56 +00:00
case TRANSFORM_YZ :
case TRANSFORM_XZ :
case TRANSFORM_XY :
break ;
2017-05-20 15:38:03 +00:00
}
Vector3 intersection ;
if ( ! plane . intersects_ray ( ray_pos , ray , & intersection ) )
break ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
Vector3 click ;
if ( ! plane . intersects_ray ( _edit . click_ray_pos , _edit . click_ray , & click ) )
break ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
Vector3 y_axis = ( click - _edit . center ) . normalized ( ) ;
Vector3 x_axis = plane . normal . cross ( y_axis ) . normalized ( ) ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
float angle = Math : : atan2 ( x_axis . dot ( intersection - _edit . center ) , y_axis . dot ( intersection - _edit . center ) ) ;
2017-10-04 07:34:58 +00:00
2017-05-20 15:38:03 +00:00
if ( _edit . snap | | spatial_editor - > is_snap_enabled ( ) ) {
2019-07-24 12:41:09 +00:00
snap = spatial_editor - > get_rotate_snap ( ) ;
2017-05-20 15:38:03 +00:00
}
2019-07-24 12:41:09 +00:00
angle = Math : : rad2deg ( angle ) + snap * 0.5 ; //else it won't reach +180
angle - = Math : : fmod ( angle , snap ) ;
set_message ( vformat ( TTR ( " Rotating %s degrees. " ) , String : : num ( angle , snap_step_decimals ) ) ) ;
angle = Math : : deg2rad ( angle ) ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
2014-02-10 01:10:30 +00:00
2017-11-13 08:15:41 +00:00
bool local_coords = ( spatial_editor - > are_local_coords_enabled ( ) & & _edit . plane ! = TRANSFORM_VIEW ) ; // Disable local transformation for TRANSFORM_VIEW
2017-10-04 07:34:58 +00:00
2017-05-20 15:38:03 +00:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 01:10:30 +00:00
2017-08-24 20:58:51 +00:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
2017-05-20 15:38:03 +00:00
if ( ! sp )
continue ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
if ( ! se )
continue ;
2014-02-10 01:10:30 +00:00
2017-10-23 19:21:15 +00:00
if ( sp - > has_meta ( " _edit_lock_ " ) ) {
continue ;
}
2017-10-04 07:34:58 +00:00
Transform t ;
2014-02-10 01:10:30 +00:00
2017-10-04 07:34:58 +00:00
if ( local_coords ) {
2014-02-10 01:10:30 +00:00
2017-10-04 07:34:58 +00:00
Transform original_local = se - > original_local ;
Basis rot = Basis ( axis , angle ) ;
2017-11-08 15:07:30 +00:00
t . basis = original_local . get_basis ( ) . orthonormalized ( ) * rot ;
2017-10-04 07:34:58 +00:00
t . origin = original_local . origin ;
2017-11-08 15:07:30 +00:00
// Apply rotation
2017-10-04 07:34:58 +00:00
sp - > set_transform ( t ) ;
2017-11-08 15:07:30 +00:00
sp - > set_scale ( original_local . basis . get_scale ( ) ) ; // re-apply original scale
2017-10-04 07:34:58 +00:00
} else {
Transform original = se - > original ;
Transform r ;
Transform base = Transform ( Basis ( ) , _edit . center ) ;
r . basis . rotate ( plane . normal , angle ) ;
t = base * r * base . inverse ( ) * original ;
2017-11-08 15:07:30 +00:00
// Apply rotation
2017-10-04 07:34:58 +00:00
sp - > set_global_transform ( t ) ;
}
2017-05-20 15:38:03 +00:00
}
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
surface - > update ( ) ;
2017-10-04 07:34:58 +00:00
2017-05-20 15:38:03 +00:00
} break ;
2019-04-09 15:08:36 +00:00
default : {
}
2014-02-10 01:10:30 +00:00
}
2017-05-20 15:38:03 +00:00
}
2014-02-10 01:10:30 +00:00
2017-10-30 00:22:48 +00:00
} else if ( ( m - > get_button_mask ( ) & BUTTON_MASK_RIGHT ) | | freelook_active ) {
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( nav_scheme = = NAVIGATION_MAYA & & m - > get_alt ( ) ) {
nav_mode = NAVIGATION_ZOOM ;
2017-07-23 00:02:18 +00:00
} else if ( freelook_active ) {
2017-05-20 15:38:03 +00:00
nav_mode = NAVIGATION_LOOK ;
2018-10-20 10:49:33 +00:00
} else if ( orthogonal ) {
nav_mode = NAVIGATION_PAN ;
2017-05-20 15:38:03 +00:00
}
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
} else if ( m - > get_button_mask ( ) & BUTTON_MASK_MIDDLE ) {
if ( nav_scheme = = NAVIGATION_GODOT ) {
2016-04-12 01:37:35 +00:00
2019-11-13 20:54:44 +00:00
const int mod = _get_key_modifier ( m ) ;
2016-05-21 13:29:25 +00:00
2019-11-13 20:54:44 +00:00
if ( mod = = _get_key_modifier_setting ( " editors/3d/navigation/pan_modifier " ) ) {
2017-05-20 15:38:03 +00:00
nav_mode = NAVIGATION_PAN ;
2019-11-13 20:54:44 +00:00
} else if ( mod = = _get_key_modifier_setting ( " editors/3d/navigation/zoom_modifier " ) ) {
2017-05-20 15:38:03 +00:00
nav_mode = NAVIGATION_ZOOM ;
2019-11-13 20:54:44 +00:00
} else if ( mod = = KEY_ALT | | mod = = _get_key_modifier_setting ( " editors/3d/navigation/orbit_modifier " ) ) {
// Always allow Alt as a modifier to better support graphic tablets.
2017-05-20 15:38:03 +00:00
nav_mode = NAVIGATION_ORBIT ;
2019-11-13 20:54:44 +00:00
}
2017-05-20 15:38:03 +00:00
} else if ( nav_scheme = = NAVIGATION_MAYA ) {
if ( m - > get_alt ( ) )
nav_mode = NAVIGATION_PAN ;
2014-03-31 03:07:21 +00:00
}
2014-02-10 01:10:30 +00:00
2017-09-19 00:30:48 +00:00
} else if ( EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation/emulate_3_button_mouse " ) ) {
2017-05-20 15:38:03 +00:00
// Handle trackpad (no external mouse) use case
2019-11-13 20:54:44 +00:00
const int mod = _get_key_modifier ( m ) ;
2017-05-20 15:38:03 +00:00
if ( mod ) {
2019-11-13 20:54:44 +00:00
if ( mod = = _get_key_modifier_setting ( " editors/3d/navigation/pan_modifier " ) ) {
2017-05-20 15:38:03 +00:00
nav_mode = NAVIGATION_PAN ;
2019-11-13 20:54:44 +00:00
} else if ( mod = = _get_key_modifier_setting ( " editors/3d/navigation/zoom_modifier " ) ) {
2017-05-20 15:38:03 +00:00
nav_mode = NAVIGATION_ZOOM ;
2019-11-13 20:54:44 +00:00
} else if ( mod = = KEY_ALT | | mod = = _get_key_modifier_setting ( " editors/3d/navigation/orbit_modifier " ) ) {
// Always allow Alt as a modifier to better support graphic tablets.
2017-05-20 15:38:03 +00:00
nav_mode = NAVIGATION_ORBIT ;
2019-11-13 20:54:44 +00:00
}
2017-05-20 15:38:03 +00:00
}
}
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
switch ( nav_mode ) {
case NAVIGATION_PAN : {
2017-11-01 20:49:39 +00:00
_nav_pan ( m , _get_warped_mouse_motion ( m ) ) ;
2014-02-10 01:10:30 +00:00
2017-11-01 20:49:39 +00:00
} break ;
case NAVIGATION_ZOOM : {
_nav_zoom ( m , m - > get_relative ( ) ) ;
} break ;
case NAVIGATION_ORBIT : {
_nav_orbit ( m , _get_warped_mouse_motion ( m ) ) ;
} break ;
case NAVIGATION_LOOK : {
_nav_look ( m , _get_warped_mouse_motion ( m ) ) ;
} break ;
2019-04-09 15:08:36 +00:00
default : {
}
2017-11-01 20:49:39 +00:00
}
}
2017-03-22 20:18:47 +00:00
2017-11-01 20:49:39 +00:00
Ref < InputEventMagnifyGesture > magnify_gesture = p_event ;
if ( magnify_gesture . is_valid ( ) ) {
2017-05-20 15:38:03 +00:00
2017-11-01 20:49:39 +00:00
if ( is_freelook_active ( ) )
scale_freelook_speed ( magnify_gesture - > get_factor ( ) ) ;
else
scale_cursor_distance ( 1.0 / magnify_gesture - > get_factor ( ) ) ;
}
Ref < InputEventPanGesture > pan_gesture = p_event ;
if ( pan_gesture . is_valid ( ) ) {
NavigationScheme nav_scheme = ( NavigationScheme ) EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation/navigation_scheme " ) . operator int ( ) ;
NavigationMode nav_mode = NAVIGATION_NONE ;
2017-05-20 15:38:03 +00:00
2017-11-01 20:49:39 +00:00
if ( nav_scheme = = NAVIGATION_GODOT ) {
2019-11-13 20:54:44 +00:00
const int mod = _get_key_modifier ( pan_gesture ) ;
2017-11-01 20:49:39 +00:00
2019-11-13 20:54:44 +00:00
if ( mod = = _get_key_modifier_setting ( " editors/3d/navigation/pan_modifier " ) ) {
2017-11-01 20:49:39 +00:00
nav_mode = NAVIGATION_PAN ;
2019-11-13 20:54:44 +00:00
} else if ( mod = = _get_key_modifier_setting ( " editors/3d/navigation/zoom_modifier " ) ) {
2017-11-01 20:49:39 +00:00
nav_mode = NAVIGATION_ZOOM ;
2019-11-13 20:54:44 +00:00
} else if ( mod = = KEY_ALT | | mod = = _get_key_modifier_setting ( " editors/3d/navigation/orbit_modifier " ) ) {
// Always allow Alt as a modifier to better support graphic tablets.
2017-11-01 20:49:39 +00:00
nav_mode = NAVIGATION_ORBIT ;
2019-11-13 20:54:44 +00:00
}
2017-11-01 20:49:39 +00:00
} else if ( nav_scheme = = NAVIGATION_MAYA ) {
if ( pan_gesture - > get_alt ( ) )
nav_mode = NAVIGATION_PAN ;
}
switch ( nav_mode ) {
case NAVIGATION_PAN : {
2020-07-23 14:38:31 +00:00
_nav_pan ( pan_gesture , pan_gesture - > get_delta ( ) ) ;
2017-05-20 15:38:03 +00:00
} break ;
case NAVIGATION_ZOOM : {
2020-07-23 14:38:31 +00:00
_nav_zoom ( pan_gesture , pan_gesture - > get_delta ( ) ) ;
2017-05-20 15:38:03 +00:00
} break ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
case NAVIGATION_ORBIT : {
2020-07-23 14:38:31 +00:00
_nav_orbit ( pan_gesture , pan_gesture - > get_delta ( ) ) ;
2017-11-01 20:49:39 +00:00
2017-05-20 15:38:03 +00:00
} break ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
case NAVIGATION_LOOK : {
2020-07-23 14:38:31 +00:00
_nav_look ( pan_gesture , pan_gesture - > get_delta ( ) ) ;
2017-05-01 18:57:35 +00:00
2017-05-20 15:38:03 +00:00
} break ;
2017-05-01 18:57:35 +00:00
2019-04-09 15:08:36 +00:00
default : {
}
2017-05-20 15:38:03 +00:00
}
}
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
Ref < InputEventKey > k = p_event ;
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
if ( k . is_valid ( ) ) {
if ( ! k - > is_pressed ( ) )
return ;
if ( ED_IS_SHORTCUT ( " spatial_editor/snap " , p_event ) ) {
if ( _edit . mode ! = TRANSFORM_NONE ) {
2019-03-16 08:15:39 +00:00
_edit . snap = ! _edit . snap ;
2017-05-20 15:38:03 +00:00
}
}
if ( ED_IS_SHORTCUT ( " spatial_editor/bottom_view " , p_event ) ) {
2017-12-19 14:29:55 +00:00
_menu_option ( VIEW_BOTTOM ) ;
2017-05-20 15:38:03 +00:00
}
if ( ED_IS_SHORTCUT ( " spatial_editor/top_view " , p_event ) ) {
2017-12-19 14:29:55 +00:00
_menu_option ( VIEW_TOP ) ;
2017-05-20 15:38:03 +00:00
}
if ( ED_IS_SHORTCUT ( " spatial_editor/rear_view " , p_event ) ) {
2017-12-19 14:29:55 +00:00
_menu_option ( VIEW_REAR ) ;
2017-05-20 15:38:03 +00:00
}
if ( ED_IS_SHORTCUT ( " spatial_editor/front_view " , p_event ) ) {
2017-12-19 14:29:55 +00:00
_menu_option ( VIEW_FRONT ) ;
2017-05-20 15:38:03 +00:00
}
if ( ED_IS_SHORTCUT ( " spatial_editor/left_view " , p_event ) ) {
2017-12-19 14:29:55 +00:00
_menu_option ( VIEW_LEFT ) ;
2017-05-20 15:38:03 +00:00
}
if ( ED_IS_SHORTCUT ( " spatial_editor/right_view " , p_event ) ) {
2017-12-19 14:29:55 +00:00
_menu_option ( VIEW_RIGHT ) ;
}
if ( ED_IS_SHORTCUT ( " spatial_editor/focus_origin " , p_event ) ) {
_menu_option ( VIEW_CENTER_TO_ORIGIN ) ;
}
if ( ED_IS_SHORTCUT ( " spatial_editor/focus_selection " , p_event ) ) {
_menu_option ( VIEW_CENTER_TO_SELECTION ) ;
2017-05-20 15:38:03 +00:00
}
2018-10-20 10:49:33 +00:00
// Orthgonal mode doesn't work in freelook.
if ( ! freelook_active & & ED_IS_SHORTCUT ( " spatial_editor/switch_perspective_orthogonal " , p_event ) ) {
2017-05-20 15:38:03 +00:00
_menu_option ( orthogonal ? VIEW_PERSPECTIVE : VIEW_ORTHOGONAL ) ;
}
2018-10-27 21:43:19 +00:00
if ( ED_IS_SHORTCUT ( " spatial_editor/align_transform_with_view " , p_event ) ) {
_menu_option ( VIEW_ALIGN_TRANSFORM_WITH_VIEW ) ;
}
if ( ED_IS_SHORTCUT ( " spatial_editor/align_rotation_with_view " , p_event ) ) {
_menu_option ( VIEW_ALIGN_ROTATION_WITH_VIEW ) ;
2017-12-19 14:29:55 +00:00
}
2017-05-20 15:38:03 +00:00
if ( ED_IS_SHORTCUT ( " spatial_editor/insert_anim_key " , p_event ) ) {
if ( ! get_selected_count ( ) | | _edit . mode ! = TRANSFORM_NONE )
return ;
2014-02-10 01:10:30 +00:00
2018-06-07 15:46:14 +00:00
if ( ! AnimationPlayerEditor : : singleton - > get_track_editor ( ) - > has_keying ( ) ) {
2017-05-20 15:38:03 +00:00
set_message ( TTR ( " Keying is disabled (no key inserted). " ) ) ;
return ;
}
2014-02-10 01:10:30 +00:00
2017-05-20 15:38:03 +00:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
2014-03-31 15:06:36 +00:00
2017-05-20 15:38:03 +00:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-03-31 15:06:36 +00:00
2017-08-24 20:58:51 +00:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
2017-05-20 15:38:03 +00:00
if ( ! sp )
continue ;
2014-04-01 10:45:48 +00:00
2019-04-14 20:27:59 +00:00
spatial_editor - > emit_signal ( " transform_key_request " , sp , " " , sp - > get_transform ( ) ) ;
2014-02-10 01:10:30 +00:00
}
2017-05-20 15:38:03 +00:00
set_message ( TTR ( " Animation Key Inserted. " ) ) ;
}
2014-02-10 01:10:30 +00:00
2018-10-20 10:49:33 +00:00
// Freelook doesn't work in orthogonal mode.
if ( ! orthogonal & & ED_IS_SHORTCUT ( " spatial_editor/freelook_toggle " , p_event ) ) {
2017-10-30 00:22:48 +00:00
set_freelook_active ( ! is_freelook_active ( ) ) ;
} else if ( k - > get_scancode ( ) = = KEY_ESCAPE ) {
set_freelook_active ( false ) ;
}
2017-05-20 15:38:03 +00:00
if ( k - > get_scancode ( ) = = KEY_SPACE ) {
if ( ! k - > is_pressed ( ) ) emit_signal ( " toggle_maximize_view " , this ) ;
}
2014-02-10 01:10:30 +00:00
}
2017-10-29 20:31:38 +00:00
// freelook uses most of the useful shortcuts, like save, so its ok
// to consider freelook active as end of the line for future events.
if ( freelook_active )
accept_event ( ) ;
2014-02-10 01:10:30 +00:00
}
2017-11-01 20:49:39 +00:00
void SpatialEditorViewport : : _nav_pan ( Ref < InputEventWithModifiers > p_event , const Vector2 & p_relative ) {
const NavigationScheme nav_scheme = ( NavigationScheme ) EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation/navigation_scheme " ) . operator int ( ) ;
real_t pan_speed = 1 / 150.0 ;
int pan_speed_modifier = 10 ;
if ( nav_scheme = = NAVIGATION_MAYA & & p_event - > get_shift ( ) )
pan_speed * = pan_speed_modifier ;
Transform camera_transform ;
camera_transform . translate ( cursor . pos ) ;
camera_transform . basis . rotate ( Vector3 ( 1 , 0 , 0 ) , - cursor . x_rot ) ;
camera_transform . basis . rotate ( Vector3 ( 0 , 1 , 0 ) , - cursor . y_rot ) ;
2020-08-15 11:18:01 +00:00
const bool invert_x_axis = EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation/invert_x_axis " ) ;
const bool invert_y_axis = EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation/invert_y_axis " ) ;
Vector3 translation (
( invert_x_axis ? - 1 : 1 ) * - p_relative . x * pan_speed ,
( invert_y_axis ? - 1 : 1 ) * p_relative . y * pan_speed ,
0 ) ;
2017-11-01 20:49:39 +00:00
translation * = cursor . distance / DISTANCE_DEFAULT ;
camera_transform . translate ( translation ) ;
cursor . pos = camera_transform . origin ;
}
void SpatialEditorViewport : : _nav_zoom ( Ref < InputEventWithModifiers > p_event , const Vector2 & p_relative ) {
const NavigationScheme nav_scheme = ( NavigationScheme ) EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation/navigation_scheme " ) . operator int ( ) ;
real_t zoom_speed = 1 / 80.0 ;
int zoom_speed_modifier = 10 ;
if ( nav_scheme = = NAVIGATION_MAYA & & p_event - > get_shift ( ) )
zoom_speed * = zoom_speed_modifier ;
NavigationZoomStyle zoom_style = ( NavigationZoomStyle ) EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation/zoom_style " ) . operator int ( ) ;
if ( zoom_style = = NAVIGATION_ZOOM_HORIZONTAL ) {
if ( p_relative . x > 0 )
scale_cursor_distance ( 1 - p_relative . x * zoom_speed ) ;
else if ( p_relative . x < 0 )
scale_cursor_distance ( 1.0 / ( 1 + p_relative . x * zoom_speed ) ) ;
} else {
if ( p_relative . y > 0 )
scale_cursor_distance ( 1 + p_relative . y * zoom_speed ) ;
else if ( p_relative . y < 0 )
scale_cursor_distance ( 1.0 / ( 1 - p_relative . y * zoom_speed ) ) ;
}
}
void SpatialEditorViewport : : _nav_orbit ( Ref < InputEventWithModifiers > p_event , const Vector2 & p_relative ) {
2018-06-25 01:24:31 +00:00
if ( lock_rotation ) {
_nav_pan ( p_event , p_relative ) ;
return ;
}
2019-10-23 09:46:26 +00:00
if ( orthogonal & & auto_orthogonal ) {
_menu_option ( VIEW_PERSPECTIVE ) ;
}
2020-08-15 11:18:01 +00:00
const real_t degrees_per_pixel = EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation_feel/orbit_sensitivity " ) ;
const real_t radians_per_pixel = Math : : deg2rad ( degrees_per_pixel ) ;
const bool invert_y_axis = EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation/invert_y_axis " ) ;
const bool invert_x_axis = EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation/invert_x_axis " ) ;
2017-11-01 20:49:39 +00:00
2018-03-14 13:32:29 +00:00
if ( invert_y_axis ) {
cursor . x_rot - = p_relative . y * radians_per_pixel ;
} else {
cursor . x_rot + = p_relative . y * radians_per_pixel ;
}
2020-08-15 11:18:01 +00:00
// Clamp the Y rotation to roughly -90..90 degrees so the user can't look upside-down and end up disoriented.
2020-06-20 09:05:43 +00:00
cursor . x_rot = CLAMP ( cursor . x_rot , - 1.57 , 1.57 ) ;
2020-08-15 11:18:01 +00:00
if ( invert_x_axis ) {
cursor . y_rot - = p_relative . x * radians_per_pixel ;
} else {
cursor . y_rot + = p_relative . x * radians_per_pixel ;
}
2017-11-01 20:49:39 +00:00
name = " " ;
_update_name ( ) ;
}
void SpatialEditorViewport : : _nav_look ( Ref < InputEventWithModifiers > p_event , const Vector2 & p_relative ) {
2018-10-20 10:49:33 +00:00
if ( orthogonal ) {
_nav_pan ( p_event , p_relative ) ;
return ;
}
2017-11-01 20:49:39 +00:00
2019-10-23 09:46:26 +00:00
if ( orthogonal & & auto_orthogonal ) {
_menu_option ( VIEW_PERSPECTIVE ) ;
}
2020-08-15 11:18:01 +00:00
const real_t degrees_per_pixel = EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation_feel/orbit_sensitivity " ) ;
const real_t radians_per_pixel = Math : : deg2rad ( degrees_per_pixel ) ;
const bool invert_y_axis = EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation/invert_y_axis " ) ;
2017-11-01 20:49:39 +00:00
2018-10-20 10:49:33 +00:00
// Note: do NOT assume the camera has the "current" transform, because it is interpolated and may have "lag".
2020-08-15 11:18:01 +00:00
const Transform prev_camera_transform = to_camera_transform ( cursor ) ;
2018-10-20 10:49:33 +00:00
if ( invert_y_axis ) {
cursor . x_rot - = p_relative . y * radians_per_pixel ;
} else {
cursor . x_rot + = p_relative . y * radians_per_pixel ;
2017-11-01 20:49:39 +00:00
}
2020-08-15 11:18:01 +00:00
// Clamp the Y rotation to roughly -90..90 degrees so the user can't look upside-down and end up disoriented.
2020-06-20 09:05:43 +00:00
cursor . x_rot = CLAMP ( cursor . x_rot , - 1.57 , 1.57 ) ;
2018-10-20 10:49:33 +00:00
2020-08-15 11:18:01 +00:00
cursor . y_rot + = p_relative . x * radians_per_pixel ;
2018-10-20 10:49:33 +00:00
// Look is like the opposite of Orbit: the focus point rotates around the camera
Transform camera_transform = to_camera_transform ( cursor ) ;
Vector3 pos = camera_transform . xform ( Vector3 ( 0 , 0 , 0 ) ) ;
Vector3 prev_pos = prev_camera_transform . xform ( Vector3 ( 0 , 0 , 0 ) ) ;
Vector3 diff = prev_pos - pos ;
cursor . pos + = diff ;
name = " " ;
_update_name ( ) ;
2017-11-01 20:49:39 +00:00
}
2017-10-08 00:43:57 +00:00
void SpatialEditorViewport : : set_freelook_active ( bool active_now ) {
if ( ! freelook_active & & active_now ) {
// Sync camera cursor to cursor to "cut" interpolation jumps due to changing referential
cursor = camera_cursor ;
// Make sure eye_pos is synced, because freelook referential is eye pos rather than orbit pos
Vector3 forward = to_camera_transform ( cursor ) . basis . xform ( Vector3 ( 0 , 0 , - 1 ) ) ;
cursor . eye_pos = cursor . pos - cursor . distance * forward ;
// Also sync the camera cursor, otherwise switching to freelook will be trippy if inertia is active
camera_cursor . eye_pos = cursor . eye_pos ;
if ( EditorSettings : : get_singleton ( ) - > get ( " editors/3d/freelook/freelook_speed_zoom_link " ) ) {
// Re-adjust freelook speed from the current zoom level
real_t base_speed = EditorSettings : : get_singleton ( ) - > get ( " editors/3d/freelook/freelook_base_speed " ) ;
freelook_speed = base_speed * cursor . distance ;
}
2020-06-17 18:02:46 +00:00
previous_mouse_position = get_local_mouse_position ( ) ;
2017-10-30 00:22:48 +00:00
// Hide mouse like in an FPS (warping doesn't work)
2020-04-28 14:41:01 +00:00
Input : : get_singleton ( ) - > set_mouse_mode ( Input : : MOUSE_MODE_CAPTURED ) ;
2017-10-30 00:22:48 +00:00
2017-10-08 00:43:57 +00:00
} else if ( freelook_active & & ! active_now ) {
// Sync camera cursor to cursor to "cut" interpolation jumps due to changing referential
cursor = camera_cursor ;
2017-10-30 00:22:48 +00:00
// Restore mouse
2020-04-28 14:41:01 +00:00
Input : : get_singleton ( ) - > set_mouse_mode ( Input : : MOUSE_MODE_VISIBLE ) ;
2020-06-17 18:02:46 +00:00
// Restore the previous mouse position when leaving freelook mode.
// This is done because leaving `Input.MOUSE_MODE_CAPTURED` will center the cursor
// due to OS limitations.
warp_mouse ( previous_mouse_position ) ;
2017-10-08 00:43:57 +00:00
}
freelook_active = active_now ;
}
2017-05-07 20:59:05 +00:00
void SpatialEditorViewport : : scale_cursor_distance ( real_t scale ) {
// Prevents zero distance which would short-circuit any scaling
if ( cursor . distance < ZOOM_MIN_DISTANCE )
cursor . distance = ZOOM_MIN_DISTANCE ;
cursor . distance * = scale ;
if ( cursor . distance < ZOOM_MIN_DISTANCE )
cursor . distance = ZOOM_MIN_DISTANCE ;
2017-10-08 00:43:57 +00:00
zoom_indicator_delay = ZOOM_INDICATOR_DELAY_S ;
surface - > update ( ) ;
}
void SpatialEditorViewport : : scale_freelook_speed ( real_t scale ) {
// Prevents zero distance which would short-circuit any scaling
if ( freelook_speed < FREELOOK_MIN_SPEED )
freelook_speed = FREELOOK_MIN_SPEED ;
freelook_speed * = scale ;
if ( freelook_speed < FREELOOK_MIN_SPEED )
freelook_speed = FREELOOK_MIN_SPEED ;
2017-05-07 20:59:05 +00:00
zoom_indicator_delay = ZOOM_INDICATOR_DELAY_S ;
surface - > update ( ) ;
}
2017-05-20 15:38:03 +00:00
Point2i SpatialEditorViewport : : _get_warped_mouse_motion ( const Ref < InputEventMouseMotion > & p_ev_mouse_motion ) const {
2017-05-05 21:42:48 +00:00
Point2i relative ;
2017-09-19 00:30:48 +00:00
if ( bool ( EDITOR_DEF ( " editors/3d/navigation/warped_mouse_panning " , false ) ) ) {
2017-05-05 21:42:48 +00:00
relative = Input : : get_singleton ( ) - > warp_mouse_motion ( p_ev_mouse_motion , surface - > get_global_rect ( ) ) ;
} else {
2017-05-20 15:38:03 +00:00
relative = p_ev_mouse_motion - > get_relative ( ) ;
2017-05-05 21:42:48 +00:00
}
return relative ;
}
2018-01-14 23:32:27 +00:00
static bool is_shortcut_pressed ( const String & p_path ) {
Ref < ShortCut > shortcut = ED_GET_SHORTCUT ( p_path ) ;
if ( shortcut . is_null ( ) ) {
return false ;
}
InputEventKey * k = Object : : cast_to < InputEventKey > ( shortcut - > get_shortcut ( ) . ptr ( ) ) ;
if ( k = = NULL ) {
return false ;
}
const Input & input = * Input : : get_singleton ( ) ;
int scancode = k - > get_scancode ( ) ;
return input . is_key_pressed ( scancode ) ;
}
2017-05-01 18:57:35 +00:00
void SpatialEditorViewport : : _update_freelook ( real_t delta ) {
2017-08-26 19:55:09 +00:00
if ( ! is_freelook_active ( ) ) {
2017-05-01 18:57:35 +00:00
return ;
2017-08-26 19:55:09 +00:00
}
2017-05-01 18:57:35 +00:00
2020-04-18 14:20:35 +00:00
const FreelookNavigationScheme navigation_scheme = ( FreelookNavigationScheme ) EditorSettings : : get_singleton ( ) - > get ( " editors/3d/freelook/freelook_navigation_scheme " ) . operator int ( ) ;
Vector3 forward ;
if ( navigation_scheme = = FREELOOK_FULLY_AXIS_LOCKED ) {
// Forward/backward keys will always go straight forward/backward, never moving on the Y axis.
forward = Vector3 ( 0 , 0 , - 1 ) . rotated ( Vector3 ( 0 , 1 , 0 ) , camera - > get_rotation ( ) . y ) ;
} else {
// Forward/backward keys will be relative to the camera pitch.
forward = camera - > get_transform ( ) . basis . xform ( Vector3 ( 0 , 0 , - 1 ) ) ;
}
2019-10-14 20:47:47 +00:00
const Vector3 right = camera - > get_transform ( ) . basis . xform ( Vector3 ( 1 , 0 , 0 ) ) ;
2020-04-18 14:20:35 +00:00
Vector3 up ;
if ( navigation_scheme = = FREELOOK_PARTIALLY_AXIS_LOCKED | | navigation_scheme = = FREELOOK_FULLY_AXIS_LOCKED ) {
// Up/down keys will always go up/down regardless of camera pitch.
up = Vector3 ( 0 , 1 , 0 ) ;
} else {
// Up/down keys will be relative to the camera pitch.
up = camera - > get_transform ( ) . basis . xform ( Vector3 ( 0 , 1 , 0 ) ) ;
}
2017-05-01 18:57:35 +00:00
2017-08-26 19:55:09 +00:00
Vector3 direction ;
2017-05-01 18:57:35 +00:00
2018-01-14 23:32:27 +00:00
if ( is_shortcut_pressed ( " spatial_editor/freelook_left " ) ) {
2017-08-26 19:55:09 +00:00
direction - = right ;
2017-05-01 18:57:35 +00:00
}
2018-01-14 23:32:27 +00:00
if ( is_shortcut_pressed ( " spatial_editor/freelook_right " ) ) {
2017-08-26 19:55:09 +00:00
direction + = right ;
2017-05-01 18:57:35 +00:00
}
2018-01-14 23:32:27 +00:00
if ( is_shortcut_pressed ( " spatial_editor/freelook_forward " ) ) {
2017-08-26 19:55:09 +00:00
direction + = forward ;
2017-05-01 18:57:35 +00:00
}
2018-01-14 23:32:27 +00:00
if ( is_shortcut_pressed ( " spatial_editor/freelook_backwards " ) ) {
2017-08-26 19:55:09 +00:00
direction - = forward ;
2017-05-01 18:57:35 +00:00
}
2018-01-14 23:32:27 +00:00
if ( is_shortcut_pressed ( " spatial_editor/freelook_up " ) ) {
2017-08-26 19:55:09 +00:00
direction + = up ;
2017-05-01 18:57:35 +00:00
}
2018-01-14 23:32:27 +00:00
if ( is_shortcut_pressed ( " spatial_editor/freelook_down " ) ) {
2017-08-26 19:55:09 +00:00
direction - = up ;
2017-05-01 18:57:35 +00:00
}
2017-10-08 00:43:57 +00:00
real_t speed = freelook_speed ;
2019-10-14 20:47:47 +00:00
if ( is_shortcut_pressed ( " spatial_editor/freelook_speed_modifier " ) ) {
speed * = 3.0 ;
}
if ( is_shortcut_pressed ( " spatial_editor/freelook_slow_modifier " ) ) {
speed * = 0.333333 ;
2017-10-08 00:43:57 +00:00
}
2017-05-07 20:59:05 +00:00
2019-10-14 20:47:47 +00:00
const Vector3 motion = direction * speed * delta ;
2017-10-08 00:43:57 +00:00
cursor . pos + = motion ;
cursor . eye_pos + = motion ;
2017-05-01 18:57:35 +00:00
}
2017-03-05 15:44:50 +00:00
void SpatialEditorViewport : : set_message ( String p_message , float p_time ) {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
message = p_message ;
message_time = p_time ;
2014-02-10 01:10:30 +00:00
}
2018-08-14 21:13:48 +00:00
void SpatialEditorPlugin : : edited_scene_changed ( ) {
2018-09-26 15:38:02 +00:00
for ( uint32_t i = 0 ; i < SpatialEditor : : VIEWPORTS_COUNT ; i + + ) {
2018-08-14 21:13:48 +00:00
SpatialEditorViewport * viewport = SpatialEditor : : get_singleton ( ) - > get_editor_viewport ( i ) ;
if ( viewport - > is_visible ( ) ) {
viewport - > notification ( Control : : NOTIFICATION_VISIBILITY_CHANGED ) ;
}
}
}
2014-02-10 01:10:30 +00:00
void SpatialEditorViewport : : _notification ( int p_what ) {
2017-03-05 15:44:50 +00:00
if ( p_what = = NOTIFICATION_VISIBILITY_CHANGED ) {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
bool visible = is_visible_in_tree ( ) ;
2014-02-10 01:10:30 +00:00
set_process ( visible ) ;
2016-04-06 06:34:34 +00:00
2019-01-30 13:46:44 +00:00
if ( visible ) {
2020-02-19 07:22:31 +00:00
orthogonal = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_ORTHOGONAL ) ) ;
_update_name ( ) ;
2017-08-26 03:40:45 +00:00
_update_camera ( 0 ) ;
2019-01-30 13:46:44 +00:00
} else {
set_freelook_active ( false ) ;
}
2014-05-05 01:50:23 +00:00
call_deferred ( " update_transform_gizmo_view " ) ;
2019-10-23 09:46:26 +00:00
rotation_control - > set_visible ( EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation/show_viewport_rotation_gizmo " ) ) ;
2014-05-05 01:50:23 +00:00
}
2017-03-05 15:44:50 +00:00
if ( p_what = = NOTIFICATION_RESIZED ) {
2014-05-05 01:50:23 +00:00
call_deferred ( " update_transform_gizmo_view " ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-05 15:44:50 +00:00
if ( p_what = = NOTIFICATION_PROCESS ) {
2014-02-10 01:10:30 +00:00
2017-10-08 00:43:57 +00:00
real_t delta = get_process_delta_time ( ) ;
2017-05-07 20:59:05 +00:00
if ( zoom_indicator_delay > 0 ) {
zoom_indicator_delay - = delta ;
if ( zoom_indicator_delay < = 0 ) {
surface - > update ( ) ;
}
}
_update_freelook ( delta ) ;
2017-05-01 18:57:35 +00:00
2018-07-26 22:36:05 +00:00
Node * scene_root = editor - > get_scene_tree_dock ( ) - > get_editor_data ( ) - > get_edited_scene_root ( ) ;
2018-10-03 17:40:37 +00:00
if ( previewing_cinema & & scene_root ! = NULL ) {
2018-07-26 22:36:05 +00:00
Camera * cam = scene_root - > get_viewport ( ) - > get_camera ( ) ;
if ( cam ! = NULL & & cam ! = previewing ) {
//then switch the viewport's camera to the scene's viewport camera
if ( previewing ! = NULL ) {
previewing - > disconnect ( " tree_exited " , this , " _preview_exited_scene " ) ;
}
previewing = cam ;
previewing - > connect ( " tree_exited " , this , " _preview_exited_scene " ) ;
VS : : get_singleton ( ) - > viewport_attach_camera ( viewport - > get_viewport_rid ( ) , cam - > get_camera ( ) ) ;
surface - > update ( ) ;
}
}
2017-10-08 00:43:57 +00:00
_update_camera ( delta ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
Map < Node * , Object * > & selection = editor_selection - > get_selection ( ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
bool changed = false ;
bool exist = false ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
for ( Map < Node * , Object * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 01:10:30 +00:00
2017-08-24 20:58:51 +00:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > key ( ) ) ;
2014-02-10 01:10:30 +00:00
if ( ! sp )
continue ;
2017-03-05 15:44:50 +00:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
2014-02-10 01:10:30 +00:00
if ( ! se )
continue ;
2020-03-10 15:23:22 +00:00
Transform t = sp - > get_global_gizmo_transform ( ) ;
exist = true ;
2020-03-19 06:43:25 +00:00
if ( se - > last_xform = = t & & ! se - > last_xform_dirty )
2020-03-10 15:23:22 +00:00
continue ;
changed = true ;
2020-03-19 06:43:25 +00:00
se - > last_xform_dirty = false ;
2020-03-10 15:23:22 +00:00
se - > last_xform = t ;
2017-08-24 20:58:51 +00:00
VisualInstance * vi = Object : : cast_to < VisualInstance > ( sp ) ;
2014-02-10 01:10:30 +00:00
2019-10-04 13:28:30 +00:00
se - > aabb = vi ? vi - > get_aabb ( ) : _calculate_spatial_bounds ( sp ) ;
2014-02-10 01:10:30 +00:00
2017-06-06 18:33:51 +00:00
t . translate ( se - > aabb . position ) ;
2017-08-23 00:05:41 +00:00
// apply AABB scaling before item's global transform
Basis aabb_s ;
aabb_s . scale ( se - > aabb . size ) ;
t . basis = t . basis * aabb_s ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
VisualServer : : get_singleton ( ) - > instance_set_transform ( se - > sbox_instance , t ) ;
2014-02-10 01:10:30 +00:00
}
if ( changed | | ( spatial_editor - > is_gizmo_visible ( ) & & ! exist ) ) {
spatial_editor - > update_transform_gizmo ( ) ;
}
2017-03-05 15:44:50 +00:00
if ( message_time > 0 ) {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
if ( message ! = last_message ) {
2014-02-10 01:10:30 +00:00
surface - > update ( ) ;
2017-03-05 15:44:50 +00:00
last_message = message ;
2014-02-10 01:10:30 +00:00
}
2017-09-30 14:19:07 +00:00
message_time - = get_physics_process_delta_time ( ) ;
2017-03-05 15:44:50 +00:00
if ( message_time < 0 )
2014-02-10 01:10:30 +00:00
surface - > update ( ) ;
}
2017-01-02 01:16:52 +00:00
//update shadow atlas if changed
2016-11-10 02:55:06 +00:00
2017-07-19 20:00:46 +00:00
int shadowmap_size = ProjectSettings : : get_singleton ( ) - > get ( " rendering/quality/shadow_atlas/size " ) ;
int atlas_q0 = ProjectSettings : : get_singleton ( ) - > get ( " rendering/quality/shadow_atlas/quadrant_0_subdiv " ) ;
int atlas_q1 = ProjectSettings : : get_singleton ( ) - > get ( " rendering/quality/shadow_atlas/quadrant_1_subdiv " ) ;
int atlas_q2 = ProjectSettings : : get_singleton ( ) - > get ( " rendering/quality/shadow_atlas/quadrant_2_subdiv " ) ;
int atlas_q3 = ProjectSettings : : get_singleton ( ) - > get ( " rendering/quality/shadow_atlas/quadrant_3_subdiv " ) ;
2016-11-10 02:55:06 +00:00
viewport - > set_shadow_atlas_size ( shadowmap_size ) ;
2017-03-05 15:44:50 +00:00
viewport - > set_shadow_atlas_quadrant_subdiv ( 0 , Viewport : : ShadowAtlasQuadrantSubdiv ( atlas_q0 ) ) ;
viewport - > set_shadow_atlas_quadrant_subdiv ( 1 , Viewport : : ShadowAtlasQuadrantSubdiv ( atlas_q1 ) ) ;
viewport - > set_shadow_atlas_quadrant_subdiv ( 2 , Viewport : : ShadowAtlasQuadrantSubdiv ( atlas_q2 ) ) ;
viewport - > set_shadow_atlas_quadrant_subdiv ( 3 , Viewport : : ShadowAtlasQuadrantSubdiv ( atlas_q3 ) ) ;
2016-11-10 02:55:06 +00:00
2017-10-31 17:23:25 +00:00
bool shrink = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_HALF_RESOLUTION ) ) ;
2018-09-26 14:35:32 +00:00
if ( shrink ! = ( viewport_container - > get_stretch_shrink ( ) > 1 ) ) {
2017-10-31 17:23:25 +00:00
viewport_container - > set_stretch_shrink ( shrink ? 2 : 1 ) ;
}
2017-01-02 01:16:52 +00:00
//update msaa if changed
2017-07-19 20:00:46 +00:00
int msaa_mode = ProjectSettings : : get_singleton ( ) - > get ( " rendering/quality/filters/msaa " ) ;
2017-01-02 01:16:52 +00:00
viewport - > set_msaa ( Viewport : : MSAA ( msaa_mode ) ) ;
2017-07-19 20:00:46 +00:00
bool hdr = ProjectSettings : : get_singleton ( ) - > get ( " rendering/quality/depth/hdr " ) ;
2017-01-02 01:16:52 +00:00
viewport - > set_hdr ( hdr ) ;
2017-06-11 21:13:04 +00:00
bool show_info = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_INFORMATION ) ) ;
2017-12-17 12:06:21 +00:00
info_label - > set_visible ( show_info ) ;
2017-06-11 21:13:04 +00:00
2018-08-29 22:44:47 +00:00
Camera * current_camera ;
if ( previewing ) {
current_camera = previewing ;
} else {
current_camera = camera ;
}
2017-06-11 21:13:04 +00:00
if ( show_info ) {
String text ;
2018-08-29 22:44:47 +00:00
text + = " X: " + rtos ( current_camera - > get_translation ( ) . x ) . pad_decimals ( 1 ) + " \n " ;
text + = " Y: " + rtos ( current_camera - > get_translation ( ) . y ) . pad_decimals ( 1 ) + " \n " ;
text + = " Z: " + rtos ( current_camera - > get_translation ( ) . z ) . pad_decimals ( 1 ) + " \n " ;
text + = TTR ( " Pitch " ) + " : " + itos ( Math : : round ( current_camera - > get_rotation_degrees ( ) . x ) ) + " \n " ;
text + = TTR ( " Yaw " ) + " : " + itos ( Math : : round ( current_camera - > get_rotation_degrees ( ) . y ) ) + " \n \n " ;
2017-06-11 21:13:04 +00:00
text + = TTR ( " Objects Drawn " ) + " : " + itos ( viewport - > get_render_info ( Viewport : : RENDER_INFO_OBJECTS_IN_FRAME ) ) + " \n " ;
text + = TTR ( " Material Changes " ) + " : " + itos ( viewport - > get_render_info ( Viewport : : RENDER_INFO_MATERIAL_CHANGES_IN_FRAME ) ) + " \n " ;
text + = TTR ( " Shader Changes " ) + " : " + itos ( viewport - > get_render_info ( Viewport : : RENDER_INFO_SHADER_CHANGES_IN_FRAME ) ) + " \n " ;
text + = TTR ( " Surface Changes " ) + " : " + itos ( viewport - > get_render_info ( Viewport : : RENDER_INFO_SURFACE_CHANGES_IN_FRAME ) ) + " \n " ;
text + = TTR ( " Draw Calls " ) + " : " + itos ( viewport - > get_render_info ( Viewport : : RENDER_INFO_DRAW_CALLS_IN_FRAME ) ) + " \n " ;
text + = TTR ( " Vertices " ) + " : " + itos ( viewport - > get_render_info ( Viewport : : RENDER_INFO_VERTICES_IN_FRAME ) ) ;
2017-12-17 12:06:21 +00:00
info_label - > set_text ( text ) ;
2017-06-11 21:13:04 +00:00
}
2017-11-19 20:00:16 +00:00
// FPS Counter.
bool show_fps = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_FPS ) ) ;
2017-12-17 12:06:21 +00:00
fps_label - > set_visible ( show_fps ) ;
2017-11-19 20:00:16 +00:00
if ( show_fps ) {
String text ;
const float temp_fps = Engine : : get_singleton ( ) - > get_frames_per_second ( ) ;
2019-02-20 11:07:49 +00:00
text + = TTR ( vformat ( " FPS: %d (%s ms) " , temp_fps , String : : num ( 1000.0f / temp_fps , 2 ) ) ) ;
2017-12-17 12:06:21 +00:00
fps_label - > set_text ( text ) ;
2017-11-19 20:00:16 +00:00
}
2018-07-26 22:36:05 +00:00
bool show_cinema = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_CINEMATIC_PREVIEW ) ) ;
cinema_label - > set_visible ( show_cinema ) ;
if ( show_cinema ) {
float cinema_half_width = cinema_label - > get_size ( ) . width / 2.0f ;
cinema_label - > set_anchor_and_margin ( MARGIN_LEFT , 0.5f , - cinema_half_width ) ;
}
2018-10-10 07:25:59 +00:00
if ( lock_rotation ) {
float locked_half_width = locked_label - > get_size ( ) . width / 2.0f ;
locked_label - > set_anchor_and_margin ( MARGIN_LEFT , 0.5f , - locked_half_width ) ;
}
2014-02-10 01:10:30 +00:00
}
2017-03-05 15:44:50 +00:00
if ( p_what = = NOTIFICATION_ENTER_TREE ) {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
surface - > connect ( " draw " , this , " _draw " ) ;
surface - > connect ( " gui_input " , this , " _sinput " ) ;
2017-12-19 14:29:55 +00:00
surface - > connect ( " mouse_entered " , this , " _surface_mouse_enter " ) ;
surface - > connect ( " mouse_exited " , this , " _surface_mouse_exit " ) ;
surface - > connect ( " focus_entered " , this , " _surface_focus_enter " ) ;
surface - > connect ( " focus_exited " , this , " _surface_focus_exit " ) ;
2018-10-10 07:25:59 +00:00
2014-05-05 01:50:23 +00:00
_init_gizmo_instance ( index ) ;
2015-04-20 22:38:02 +00:00
}
2018-10-10 07:25:59 +00:00
2017-03-05 15:44:50 +00:00
if ( p_what = = NOTIFICATION_EXIT_TREE ) {
2015-04-20 22:38:02 +00:00
_finish_gizmo_instances ( ) ;
2014-02-10 01:10:30 +00:00
}
2018-10-10 07:25:59 +00:00
if ( p_what = = NOTIFICATION_THEME_CHANGED ) {
2020-07-11 15:32:27 +00:00
view_menu - > set_icon ( get_icon ( " GuiTabMenuHl " , " EditorIcons " ) ) ;
2018-10-10 07:25:59 +00:00
preview_camera - > set_icon ( get_icon ( " Camera " , " EditorIcons " ) ) ;
2014-02-10 01:10:30 +00:00
2018-10-10 07:25:59 +00:00
view_menu - > add_style_override ( " normal " , editor - > get_gui_base ( ) - > get_stylebox ( " Information3dViewport " , " EditorStyles " ) ) ;
view_menu - > add_style_override ( " hover " , editor - > get_gui_base ( ) - > get_stylebox ( " Information3dViewport " , " EditorStyles " ) ) ;
view_menu - > add_style_override ( " pressed " , editor - > get_gui_base ( ) - > get_stylebox ( " Information3dViewport " , " EditorStyles " ) ) ;
view_menu - > add_style_override ( " focus " , editor - > get_gui_base ( ) - > get_stylebox ( " Information3dViewport " , " EditorStyles " ) ) ;
view_menu - > add_style_override ( " disabled " , editor - > get_gui_base ( ) - > get_stylebox ( " Information3dViewport " , " EditorStyles " ) ) ;
preview_camera - > add_style_override ( " normal " , editor - > get_gui_base ( ) - > get_stylebox ( " Information3dViewport " , " EditorStyles " ) ) ;
preview_camera - > add_style_override ( " hover " , editor - > get_gui_base ( ) - > get_stylebox ( " Information3dViewport " , " EditorStyles " ) ) ;
preview_camera - > add_style_override ( " pressed " , editor - > get_gui_base ( ) - > get_stylebox ( " Information3dViewport " , " EditorStyles " ) ) ;
preview_camera - > add_style_override ( " focus " , editor - > get_gui_base ( ) - > get_stylebox ( " Information3dViewport " , " EditorStyles " ) ) ;
preview_camera - > add_style_override ( " disabled " , editor - > get_gui_base ( ) - > get_stylebox ( " Information3dViewport " , " EditorStyles " ) ) ;
info_label - > add_style_override ( " normal " , editor - > get_gui_base ( ) - > get_stylebox ( " Information3dViewport " , " EditorStyles " ) ) ;
fps_label - > add_style_override ( " normal " , editor - > get_gui_base ( ) - > get_stylebox ( " Information3dViewport " , " EditorStyles " ) ) ;
cinema_label - > add_style_override ( " normal " , editor - > get_gui_base ( ) - > get_stylebox ( " Information3dViewport " , " EditorStyles " ) ) ;
locked_label - > add_style_override ( " normal " , editor - > get_gui_base ( ) - > get_stylebox ( " Information3dViewport " , " EditorStyles " ) ) ;
2014-02-10 01:10:30 +00:00
}
}
2020-06-13 19:56:03 +00:00
static void draw_indicator_bar ( Control & surface , real_t fill , const Ref < Texture > icon , const Ref < Font > font , const String & text ) {
2017-10-15 19:20:51 +00:00
// Adjust bar size from control height
2020-06-13 19:56:03 +00:00
const Vector2 surface_size = surface . get_size ( ) ;
const real_t h = surface_size . y / 2.0 ;
const real_t y = ( surface_size . y - h ) / 2.0 ;
2017-10-15 19:20:51 +00:00
2020-06-13 19:56:03 +00:00
const Rect2 r ( 10 * EDSCALE , y , 6 * EDSCALE , h ) ;
const real_t sy = r . size . y * fill ;
2017-10-15 19:20:51 +00:00
// Note: because this bar appears over the viewport, it has to stay readable for any background color
// Draw both neutral dark and bright colors to account this
surface . draw_rect ( r , Color ( 1 , 1 , 1 , 0.2 ) ) ;
surface . draw_rect ( Rect2 ( r . position . x , r . position . y + r . size . y - sy , r . size . x , sy ) , Color ( 1 , 1 , 1 , 0.6 ) ) ;
2019-07-09 13:22:01 +00:00
surface . draw_rect ( r . grow ( 1 ) , Color ( 0 , 0 , 0 , 0.7 ) , false , Math : : round ( EDSCALE ) ) ;
2017-10-15 19:20:51 +00:00
2020-06-13 19:56:03 +00:00
const Vector2 icon_size = icon - > get_size ( ) ;
const Vector2 icon_pos = Vector2 ( r . position . x - ( icon_size . x - r . size . x ) / 2 , r . position . y + r . size . y + 2 * EDSCALE ) ;
2017-10-15 19:20:51 +00:00
surface . draw_texture ( icon , icon_pos ) ;
2020-06-13 19:56:03 +00:00
// Draw text below the bar (for speed/zoom information).
surface . draw_string ( font , Vector2 ( icon_pos . x , icon_pos . y + icon_size . y + 16 * EDSCALE ) , text ) ;
2017-05-07 20:59:05 +00:00
}
2014-02-10 01:10:30 +00:00
void SpatialEditorViewport : : _draw ( ) {
2017-10-29 19:32:09 +00:00
EditorPluginList * over_plugin_list = EditorNode : : get_singleton ( ) - > get_editor_plugins_over ( ) ;
if ( ! over_plugin_list - > empty ( ) ) {
2018-09-18 18:00:07 +00:00
over_plugin_list - > forward_spatial_draw_over_viewport ( surface ) ;
2017-10-29 19:32:09 +00:00
}
EditorPluginList * force_over_plugin_list = editor - > get_editor_plugins_force_over ( ) ;
if ( ! force_over_plugin_list - > empty ( ) ) {
2018-09-18 18:00:07 +00:00
force_over_plugin_list - > forward_spatial_force_draw_over_viewport ( surface ) ;
2017-10-29 19:32:09 +00:00
}
2014-02-10 01:10:30 +00:00
if ( surface - > has_focus ( ) ) {
Size2 size = surface - > get_size ( ) ;
2017-03-05 15:44:50 +00:00
Rect2 r = Rect2 ( Point2 ( ) , size ) ;
2017-05-02 20:13:12 +00:00
get_stylebox ( " Focus " , " EditorStyles " ) - > draw ( surface - > get_canvas_item ( ) , r ) ;
2014-02-10 01:10:30 +00:00
}
if ( cursor . region_select ) {
2019-08-15 20:17:08 +00:00
const Rect2 selection_rect = Rect2 ( cursor . region_begin , cursor . region_end - cursor . region_begin ) ;
surface - > draw_rect (
selection_rect ,
get_color ( " box_selection_fill_color " , " Editor " ) ) ;
2014-02-10 01:10:30 +00:00
2019-08-15 20:17:08 +00:00
surface - > draw_rect (
selection_rect ,
get_color ( " box_selection_stroke_color " , " Editor " ) ,
false ,
Math : : round ( EDSCALE ) ) ;
2014-02-10 01:10:30 +00:00
}
2019-08-15 20:17:08 +00:00
RID ci = surface - > get_canvas_item ( ) ;
2017-03-05 15:44:50 +00:00
if ( message_time > 0 ) {
Ref < Font > font = get_font ( " font " , " Label " ) ;
Point2 msgpos = Point2 ( 5 , get_size ( ) . y - 20 ) ;
font - > draw ( ci , msgpos + Point2 ( 1 , 1 ) , message , Color ( 0 , 0 , 0 , 0.8 ) ) ;
font - > draw ( ci , msgpos + Point2 ( - 1 , - 1 ) , message , Color ( 0 , 0 , 0 , 0.8 ) ) ;
font - > draw ( ci , msgpos , message , Color ( 1 , 1 , 1 , 1 ) ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-05 15:44:50 +00:00
if ( _edit . mode = = TRANSFORM_ROTATE ) {
2014-02-10 01:10:30 +00:00
Point2 center = _point_to_screen ( _edit . center ) ;
2019-03-29 13:19:44 +00:00
VisualServer : : get_singleton ( ) - > canvas_item_add_line (
ci ,
_edit . mouse_pos ,
center ,
get_color ( " accent_color " , " Editor " ) * Color ( 1 , 1 , 1 , 0.6 ) ,
Math : : round ( 2 * EDSCALE ) ,
true ) ;
2014-02-10 01:10:30 +00:00
}
2014-09-15 23:06:37 +00:00
if ( previewing ) {
2017-07-19 20:00:46 +00:00
Size2 ss = Size2 ( ProjectSettings : : get_singleton ( ) - > get ( " display/window/size/width " ) , ProjectSettings : : get_singleton ( ) - > get ( " display/window/size/height " ) ) ;
2017-01-13 23:00:43 +00:00
float aspect = ss . aspect ( ) ;
2014-09-15 23:06:37 +00:00
Size2 s = get_size ( ) ;
Rect2 draw_rect ;
2017-03-05 15:44:50 +00:00
switch ( previewing - > get_keep_aspect_mode ( ) ) {
2014-09-15 23:06:37 +00:00
case Camera : : KEEP_WIDTH : {
2017-03-05 15:44:50 +00:00
draw_rect . size = Size2 ( s . width , s . width / aspect ) ;
2017-06-03 22:25:13 +00:00
draw_rect . position . x = 0 ;
draw_rect . position . y = ( s . height - draw_rect . size . y ) * 0.5 ;
2014-09-15 23:06:37 +00:00
} break ;
case Camera : : KEEP_HEIGHT : {
2017-03-05 15:44:50 +00:00
draw_rect . size = Size2 ( s . height * aspect , s . height ) ;
2017-06-03 22:25:13 +00:00
draw_rect . position . y = 0 ;
draw_rect . position . x = ( s . width - draw_rect . size . x ) * 0.5 ;
2014-09-15 23:06:37 +00:00
} break ;
}
2017-03-05 15:44:50 +00:00
draw_rect = Rect2 ( Vector2 ( ) , s ) . clip ( draw_rect ) ;
2014-09-15 23:06:37 +00:00
2019-07-09 13:22:01 +00:00
surface - > draw_rect ( draw_rect , Color ( 0.6 , 0.6 , 0.1 , 0.5 ) , false , Math : : round ( 2 * EDSCALE ) ) ;
2017-05-07 20:59:05 +00:00
} else {
if ( zoom_indicator_delay > 0.0 ) {
2017-10-15 19:20:51 +00:00
if ( is_freelook_active ( ) ) {
// Show speed
2017-05-07 20:59:05 +00:00
2017-10-15 19:20:51 +00:00
real_t min_speed = FREELOOK_MIN_SPEED ;
real_t max_speed = camera - > get_zfar ( ) ;
real_t scale_length = ( max_speed - min_speed ) ;
2017-05-07 20:59:05 +00:00
2019-01-16 15:42:53 +00:00
if ( ! Math : : is_zero_approx ( scale_length ) ) {
2017-10-15 19:20:51 +00:00
real_t logscale_t = 1.0 - Math : : log ( 1 + freelook_speed - min_speed ) / Math : : log ( 1 + scale_length ) ;
2017-05-07 20:59:05 +00:00
2017-10-15 19:20:51 +00:00
// There is no real maximum speed so that factor can become negative,
// Let's make it look asymptotic instead (will decrease slower and slower).
if ( logscale_t < 0.25 )
logscale_t = 0.25 * Math : : exp ( 4.0 * logscale_t - 1.0 ) ;
2017-05-07 20:59:05 +00:00
2020-06-13 19:56:03 +00:00
// Display the freelook speed to help the user get a better sense of scale.
const int precision = freelook_speed < 1.0 ? 2 : 1 ;
draw_indicator_bar (
* surface ,
1.0 - logscale_t ,
get_icon ( " ViewportSpeed " , " EditorIcons " ) ,
get_font ( " font " , " Label " ) ,
vformat ( " %s u/s " , String : : num ( freelook_speed ) . pad_decimals ( precision ) ) ) ;
2017-10-15 19:20:51 +00:00
}
2017-05-07 20:59:05 +00:00
2017-10-15 19:20:51 +00:00
} else {
// Show zoom
real_t min_distance = ZOOM_MIN_DISTANCE ; // TODO Why not pick znear to limit zoom?
real_t max_distance = camera - > get_zfar ( ) ;
real_t scale_length = ( max_distance - min_distance ) ;
2019-01-16 15:42:53 +00:00
if ( ! Math : : is_zero_approx ( scale_length ) ) {
2017-10-15 19:20:51 +00:00
real_t logscale_t = 1.0 - Math : : log ( 1 + cursor . distance - min_distance ) / Math : : log ( 1 + scale_length ) ;
// There is no real maximum distance so that factor can become negative,
// Let's make it look asymptotic instead (will decrease slower and slower).
if ( logscale_t < 0.25 )
logscale_t = 0.25 * Math : : exp ( 4.0 * logscale_t - 1.0 ) ;
2020-06-13 19:56:03 +00:00
// Display the zoom center distance to help the user get a better sense of scale.
const int precision = cursor . distance < 1.0 ? 2 : 1 ;
draw_indicator_bar (
* surface ,
logscale_t ,
get_icon ( " ViewportZoom " , " EditorIcons " ) ,
get_font ( " font " , " Label " ) ,
vformat ( " %s u " , String : : num ( cursor . distance ) . pad_decimals ( precision ) ) ) ;
2017-10-15 19:20:51 +00:00
}
2017-05-07 20:59:05 +00:00
}
}
2014-09-15 23:06:37 +00:00
}
2014-02-10 01:10:30 +00:00
}
void SpatialEditorViewport : : _menu_option ( int p_option ) {
2017-03-05 15:44:50 +00:00
switch ( p_option ) {
2014-02-10 01:10:30 +00:00
case VIEW_TOP : {
2017-03-05 15:44:50 +00:00
cursor . y_rot = 0 ;
2017-12-19 14:29:55 +00:00
cursor . x_rot = Math_PI / 2.0 ;
set_message ( TTR ( " Top View. " ) , 2 ) ;
2017-03-05 15:44:50 +00:00
name = TTR ( " Top " ) ;
2019-10-23 09:46:26 +00:00
_set_auto_orthogonal ( ) ;
2015-03-21 20:47:21 +00:00
_update_name ( ) ;
2017-12-19 14:29:55 +00:00
2014-02-10 01:10:30 +00:00
} break ;
case VIEW_BOTTOM : {
2017-03-05 15:44:50 +00:00
cursor . y_rot = 0 ;
2017-12-19 14:29:55 +00:00
cursor . x_rot = - Math_PI / 2.0 ;
set_message ( TTR ( " Bottom View. " ) , 2 ) ;
2017-03-05 15:44:50 +00:00
name = TTR ( " Bottom " ) ;
2019-10-23 09:46:26 +00:00
_set_auto_orthogonal ( ) ;
2015-03-21 20:47:21 +00:00
_update_name ( ) ;
2014-02-10 01:10:30 +00:00
} break ;
case VIEW_LEFT : {
2017-03-05 15:44:50 +00:00
cursor . x_rot = 0 ;
2017-12-19 14:29:55 +00:00
cursor . y_rot = Math_PI / 2.0 ;
set_message ( TTR ( " Left View. " ) , 2 ) ;
2017-03-05 15:44:50 +00:00
name = TTR ( " Left " ) ;
2019-10-23 09:46:26 +00:00
_set_auto_orthogonal ( ) ;
2015-03-21 20:47:21 +00:00
_update_name ( ) ;
2014-02-10 01:10:30 +00:00
} break ;
case VIEW_RIGHT : {
2017-03-05 15:44:50 +00:00
cursor . x_rot = 0 ;
2017-12-19 14:29:55 +00:00
cursor . y_rot = - Math_PI / 2.0 ;
set_message ( TTR ( " Right View. " ) , 2 ) ;
2017-03-05 15:44:50 +00:00
name = TTR ( " Right " ) ;
2019-10-23 09:46:26 +00:00
_set_auto_orthogonal ( ) ;
2015-03-21 20:47:21 +00:00
_update_name ( ) ;
2014-02-10 01:10:30 +00:00
} break ;
case VIEW_FRONT : {
2017-03-05 15:44:50 +00:00
cursor . x_rot = 0 ;
2017-12-19 14:29:55 +00:00
cursor . y_rot = 0 ;
set_message ( TTR ( " Front View. " ) , 2 ) ;
2017-03-05 15:44:50 +00:00
name = TTR ( " Front " ) ;
2019-10-23 09:46:26 +00:00
_set_auto_orthogonal ( ) ;
2015-03-21 20:47:21 +00:00
_update_name ( ) ;
2014-02-10 01:10:30 +00:00
} break ;
case VIEW_REAR : {
2017-03-05 15:44:50 +00:00
cursor . x_rot = 0 ;
2017-12-19 14:29:55 +00:00
cursor . y_rot = Math_PI ;
set_message ( TTR ( " Rear View. " ) , 2 ) ;
2017-03-05 15:44:50 +00:00
name = TTR ( " Rear " ) ;
2019-10-23 09:46:26 +00:00
_set_auto_orthogonal ( ) ;
2015-03-21 20:47:21 +00:00
_update_name ( ) ;
2014-02-10 01:10:30 +00:00
2016-10-04 18:39:38 +00:00
} break ;
case VIEW_CENTER_TO_ORIGIN : {
2017-03-05 15:44:50 +00:00
cursor . pos = Vector3 ( 0 , 0 , 0 ) ;
2016-10-04 18:39:38 +00:00
2014-02-10 01:10:30 +00:00
} break ;
case VIEW_CENTER_TO_SELECTION : {
2016-07-28 19:37:52 +00:00
focus_selection ( ) ;
2014-02-10 01:10:30 +00:00
} break ;
2018-10-27 21:43:19 +00:00
case VIEW_ALIGN_TRANSFORM_WITH_VIEW : {
2014-03-31 15:06:36 +00:00
if ( ! get_selected_count ( ) )
break ;
Transform camera_transform = camera - > get_global_transform ( ) ;
2017-03-05 15:44:50 +00:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
2014-03-31 15:06:36 +00:00
2018-10-27 21:43:19 +00:00
undo_redo - > create_action ( TTR ( " Align Transform with View " ) ) ;
2017-03-05 15:44:50 +00:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-03-31 15:06:36 +00:00
2017-08-24 20:58:51 +00:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
2014-03-31 15:06:36 +00:00
if ( ! sp )
continue ;
2017-03-05 15:44:50 +00:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
2014-03-31 15:06:36 +00:00
if ( ! se )
continue ;
2018-10-22 14:52:39 +00:00
Transform xform ;
if ( orthogonal ) {
xform = sp - > get_global_transform ( ) ;
xform . basis . set_euler ( camera_transform . basis . get_euler ( ) ) ;
} else {
xform = camera_transform ;
xform . scale_basis ( sp - > get_scale ( ) ) ;
}
2015-10-29 23:44:12 +00:00
2017-03-05 15:44:50 +00:00
undo_redo - > add_do_method ( sp , " set_global_transform " , xform ) ;
2017-10-03 16:49:32 +00:00
undo_redo - > add_undo_method ( sp , " set_global_transform " , sp - > get_global_gizmo_transform ( ) ) ;
2014-03-31 15:06:36 +00:00
}
undo_redo - > commit_action ( ) ;
2018-10-27 21:43:19 +00:00
} break ;
case VIEW_ALIGN_ROTATION_WITH_VIEW : {
if ( ! get_selected_count ( ) )
break ;
Transform camera_transform = camera - > get_global_transform ( ) ;
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
undo_redo - > create_action ( TTR ( " Align Rotation with View " ) ) ;
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
if ( ! sp )
continue ;
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
if ( ! se )
continue ;
undo_redo - > add_do_method ( sp , " set_rotation " , camera_transform . basis . get_rotation ( ) ) ;
undo_redo - > add_undo_method ( sp , " set_rotation " , sp - > get_rotation ( ) ) ;
}
undo_redo - > commit_action ( ) ;
2014-03-31 15:06:36 +00:00
} break ;
2014-02-10 01:10:30 +00:00
case VIEW_ENVIRONMENT : {
int idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_ENVIRONMENT ) ;
2017-03-05 15:44:50 +00:00
bool current = view_menu - > get_popup ( ) - > is_item_checked ( idx ) ;
current = ! current ;
2014-02-10 01:10:30 +00:00
if ( current ) {
camera - > set_environment ( RES ( ) ) ;
} else {
camera - > set_environment ( SpatialEditor : : get_singleton ( ) - > get_viewport_environment ( ) ) ;
}
2017-03-05 15:44:50 +00:00
view_menu - > get_popup ( ) - > set_item_checked ( idx , current ) ;
2014-02-10 01:10:30 +00:00
} break ;
case VIEW_PERSPECTIVE : {
2017-03-05 15:44:50 +00:00
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_PERSPECTIVE ) , true ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_ORTHOGONAL ) , false ) ;
orthogonal = false ;
2019-10-23 09:46:26 +00:00
auto_orthogonal = false ;
2014-05-05 01:50:23 +00:00
call_deferred ( " update_transform_gizmo_view " ) ;
2015-03-21 20:47:21 +00:00
_update_name ( ) ;
2014-05-05 01:50:23 +00:00
2014-02-10 01:10:30 +00:00
} break ;
case VIEW_ORTHOGONAL : {
2017-03-05 15:44:50 +00:00
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_PERSPECTIVE ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_ORTHOGONAL ) , true ) ;
orthogonal = true ;
2019-10-23 09:46:26 +00:00
auto_orthogonal = false ;
2014-05-05 01:50:23 +00:00
call_deferred ( " update_transform_gizmo_view " ) ;
2015-03-21 20:47:21 +00:00
_update_name ( ) ;
2014-02-10 01:10:30 +00:00
2018-06-25 01:24:31 +00:00
} break ;
2019-10-23 09:46:26 +00:00
case VIEW_AUTO_ORTHOGONAL : {
int idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_AUTO_ORTHOGONAL ) ;
bool current = view_menu - > get_popup ( ) - > is_item_checked ( idx ) ;
current = ! current ;
view_menu - > get_popup ( ) - > set_item_checked ( idx , current ) ;
if ( auto_orthogonal ) {
auto_orthogonal = false ;
_update_name ( ) ;
}
} break ;
2018-06-25 01:24:31 +00:00
case VIEW_LOCK_ROTATION : {
int idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_LOCK_ROTATION ) ;
bool current = view_menu - > get_popup ( ) - > is_item_checked ( idx ) ;
lock_rotation = ! current ;
view_menu - > get_popup ( ) - > set_item_checked ( idx , ! current ) ;
if ( lock_rotation ) {
2018-10-10 07:25:59 +00:00
locked_label - > show ( ) ;
2018-06-25 01:24:31 +00:00
} else {
2018-10-10 07:25:59 +00:00
locked_label - > hide ( ) ;
2018-06-25 01:24:31 +00:00
}
2014-02-10 01:10:30 +00:00
} break ;
2014-10-03 03:10:51 +00:00
case VIEW_AUDIO_LISTENER : {
int idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_AUDIO_LISTENER ) ;
2017-03-05 15:44:50 +00:00
bool current = view_menu - > get_popup ( ) - > is_item_checked ( idx ) ;
current = ! current ;
2014-10-03 03:10:51 +00:00
viewport - > set_as_audio_listener ( current ) ;
2017-03-05 15:44:50 +00:00
view_menu - > get_popup ( ) - > set_item_checked ( idx , current ) ;
2014-10-03 03:10:51 +00:00
2017-07-15 04:23:10 +00:00
} break ;
case VIEW_AUDIO_DOPPLER : {
int idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_AUDIO_DOPPLER ) ;
bool current = view_menu - > get_popup ( ) - > is_item_checked ( idx ) ;
current = ! current ;
camera - > set_doppler_tracking ( current ? Camera : : DOPPLER_TRACKING_IDLE_STEP : Camera : : DOPPLER_TRACKING_DISABLED ) ;
view_menu - > get_popup ( ) - > set_item_checked ( idx , current ) ;
2014-10-03 03:10:51 +00:00
} break ;
2018-07-26 22:36:05 +00:00
case VIEW_CINEMATIC_PREVIEW : {
int idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_CINEMATIC_PREVIEW ) ;
bool current = view_menu - > get_popup ( ) - > is_item_checked ( idx ) ;
current = ! current ;
view_menu - > get_popup ( ) - > set_item_checked ( idx , current ) ;
previewing_cinema = true ;
_toggle_cinema_preview ( current ) ;
if ( current ) {
preview_camera - > hide ( ) ;
} else {
if ( previewing ! = NULL )
preview_camera - > show ( ) ;
}
} break ;
2014-10-12 05:13:22 +00:00
case VIEW_GIZMOS : {
int idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_GIZMOS ) ;
2017-03-05 15:44:50 +00:00
bool current = view_menu - > get_popup ( ) - > is_item_checked ( idx ) ;
current = ! current ;
2014-10-12 05:13:22 +00:00
if ( current )
2017-03-05 15:44:50 +00:00
camera - > set_cull_mask ( ( ( 1 < < 20 ) - 1 ) | ( 1 < < ( GIZMO_BASE_LAYER + index ) ) | ( 1 < < GIZMO_EDIT_LAYER ) | ( 1 < < GIZMO_GRID_LAYER ) ) ;
2014-10-12 05:13:22 +00:00
else
2017-03-05 15:44:50 +00:00
camera - > set_cull_mask ( ( ( 1 < < 20 ) - 1 ) | ( 1 < < ( GIZMO_BASE_LAYER + index ) ) | ( 1 < < GIZMO_GRID_LAYER ) ) ;
view_menu - > get_popup ( ) - > set_item_checked ( idx , current ) ;
2014-10-12 05:13:22 +00:00
2017-06-11 21:13:04 +00:00
} break ;
2017-10-31 17:23:25 +00:00
case VIEW_HALF_RESOLUTION : {
int idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_HALF_RESOLUTION ) ;
bool current = view_menu - > get_popup ( ) - > is_item_checked ( idx ) ;
current = ! current ;
view_menu - > get_popup ( ) - > set_item_checked ( idx , current ) ;
} break ;
2017-06-11 21:13:04 +00:00
case VIEW_INFORMATION : {
int idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_INFORMATION ) ;
bool current = view_menu - > get_popup ( ) - > is_item_checked ( idx ) ;
view_menu - > get_popup ( ) - > set_item_checked ( idx , ! current ) ;
2017-11-19 20:00:16 +00:00
} break ;
case VIEW_FPS : {
int idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_FPS ) ;
bool current = view_menu - > get_popup ( ) - > is_item_checked ( idx ) ;
view_menu - > get_popup ( ) - > set_item_checked ( idx , ! current ) ;
2014-10-12 05:13:22 +00:00
} break ;
2017-06-11 18:52:03 +00:00
case VIEW_DISPLAY_NORMAL : {
viewport - > set_debug_draw ( Viewport : : DEBUG_DRAW_DISABLED ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_NORMAL ) , true ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_WIREFRAME ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_OVERDRAW ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_SHADELESS ) , false ) ;
} break ;
case VIEW_DISPLAY_WIREFRAME : {
viewport - > set_debug_draw ( Viewport : : DEBUG_DRAW_WIREFRAME ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_NORMAL ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_WIREFRAME ) , true ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_OVERDRAW ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_SHADELESS ) , false ) ;
} break ;
case VIEW_DISPLAY_OVERDRAW : {
viewport - > set_debug_draw ( Viewport : : DEBUG_DRAW_OVERDRAW ) ;
VisualServer : : get_singleton ( ) - > scenario_set_debug ( get_tree ( ) - > get_root ( ) - > get_world ( ) - > get_scenario ( ) , VisualServer : : SCENARIO_DEBUG_OVERDRAW ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_NORMAL ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_WIREFRAME ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_OVERDRAW ) , true ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_SHADELESS ) , false ) ;
} break ;
case VIEW_DISPLAY_SHADELESS : {
viewport - > set_debug_draw ( Viewport : : DEBUG_DRAW_UNSHADED ) ;
VisualServer : : get_singleton ( ) - > scenario_set_debug ( get_tree ( ) - > get_root ( ) - > get_world ( ) - > get_scenario ( ) , VisualServer : : SCENARIO_DEBUG_SHADELESS ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_NORMAL ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_WIREFRAME ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_OVERDRAW ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_SHADELESS ) , true ) ;
} break ;
2014-02-10 01:10:30 +00:00
}
}
2019-10-23 09:46:26 +00:00
void SpatialEditorViewport : : _set_auto_orthogonal ( ) {
if ( ! orthogonal & & view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_AUTO_ORTHOGONAL ) ) ) {
_menu_option ( VIEW_ORTHOGONAL ) ;
auto_orthogonal = true ;
}
}
2014-02-10 01:10:30 +00:00
void SpatialEditorViewport : : _preview_exited_scene ( ) {
2019-10-27 12:04:29 +00:00
preview_camera - > disconnect ( " toggled " , this , " _toggle_camera_preview " ) ;
2014-02-10 01:10:30 +00:00
preview_camera - > set_pressed ( false ) ;
_toggle_camera_preview ( false ) ;
2019-11-09 16:24:40 +00:00
preview_camera - > connect ( " toggled " , this , " _toggle_camera_preview " ) ;
2014-02-10 01:10:30 +00:00
view_menu - > show ( ) ;
}
2014-05-05 01:50:23 +00:00
void SpatialEditorViewport : : _init_gizmo_instance ( int p_idx ) {
2017-12-19 05:25:00 +00:00
uint32_t layer = 1 < < ( GIZMO_BASE_LAYER + p_idx ) ;
2014-05-05 01:50:23 +00:00
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < 3 ; i + + ) {
move_gizmo_instance [ i ] = VS : : get_singleton ( ) - > instance_create ( ) ;
VS : : get_singleton ( ) - > instance_set_base ( move_gizmo_instance [ i ] , spatial_editor - > get_move_gizmo ( i ) - > get_rid ( ) ) ;
VS : : get_singleton ( ) - > instance_set_scenario ( move_gizmo_instance [ i ] , get_tree ( ) - > get_root ( ) - > get_world ( ) - > get_scenario ( ) ) ;
VS : : get_singleton ( ) - > instance_set_visible ( move_gizmo_instance [ i ] , false ) ;
2016-03-07 23:00:55 +00:00
VS : : get_singleton ( ) - > instance_geometry_set_cast_shadows_setting ( move_gizmo_instance [ i ] , VS : : SHADOW_CASTING_SETTING_OFF ) ;
2017-03-05 15:44:50 +00:00
VS : : get_singleton ( ) - > instance_set_layer_mask ( move_gizmo_instance [ i ] , layer ) ;
2014-05-05 01:50:23 +00:00
2017-08-29 01:39:45 +00:00
move_plane_gizmo_instance [ i ] = VS : : get_singleton ( ) - > instance_create ( ) ;
VS : : get_singleton ( ) - > instance_set_base ( move_plane_gizmo_instance [ i ] , spatial_editor - > get_move_plane_gizmo ( i ) - > get_rid ( ) ) ;
VS : : get_singleton ( ) - > instance_set_scenario ( move_plane_gizmo_instance [ i ] , get_tree ( ) - > get_root ( ) - > get_world ( ) - > get_scenario ( ) ) ;
VS : : get_singleton ( ) - > instance_set_visible ( move_plane_gizmo_instance [ i ] , false ) ;
VS : : get_singleton ( ) - > instance_geometry_set_cast_shadows_setting ( move_plane_gizmo_instance [ i ] , VS : : SHADOW_CASTING_SETTING_OFF ) ;
VS : : get_singleton ( ) - > instance_set_layer_mask ( move_plane_gizmo_instance [ i ] , layer ) ;
2017-03-05 15:44:50 +00:00
rotate_gizmo_instance [ i ] = VS : : get_singleton ( ) - > instance_create ( ) ;
VS : : get_singleton ( ) - > instance_set_base ( rotate_gizmo_instance [ i ] , spatial_editor - > get_rotate_gizmo ( i ) - > get_rid ( ) ) ;
VS : : get_singleton ( ) - > instance_set_scenario ( rotate_gizmo_instance [ i ] , get_tree ( ) - > get_root ( ) - > get_world ( ) - > get_scenario ( ) ) ;
VS : : get_singleton ( ) - > instance_set_visible ( rotate_gizmo_instance [ i ] , false ) ;
2016-03-07 23:00:55 +00:00
VS : : get_singleton ( ) - > instance_geometry_set_cast_shadows_setting ( rotate_gizmo_instance [ i ] , VS : : SHADOW_CASTING_SETTING_OFF ) ;
2017-03-05 15:44:50 +00:00
VS : : get_singleton ( ) - > instance_set_layer_mask ( rotate_gizmo_instance [ i ] , layer ) ;
2017-09-21 21:11:56 +00:00
scale_gizmo_instance [ i ] = VS : : get_singleton ( ) - > instance_create ( ) ;
VS : : get_singleton ( ) - > instance_set_base ( scale_gizmo_instance [ i ] , spatial_editor - > get_scale_gizmo ( i ) - > get_rid ( ) ) ;
VS : : get_singleton ( ) - > instance_set_scenario ( scale_gizmo_instance [ i ] , get_tree ( ) - > get_root ( ) - > get_world ( ) - > get_scenario ( ) ) ;
VS : : get_singleton ( ) - > instance_set_visible ( scale_gizmo_instance [ i ] , false ) ;
VS : : get_singleton ( ) - > instance_geometry_set_cast_shadows_setting ( scale_gizmo_instance [ i ] , VS : : SHADOW_CASTING_SETTING_OFF ) ;
VS : : get_singleton ( ) - > instance_set_layer_mask ( scale_gizmo_instance [ i ] , layer ) ;
2017-11-14 22:50:19 +00:00
scale_plane_gizmo_instance [ i ] = VS : : get_singleton ( ) - > instance_create ( ) ;
VS : : get_singleton ( ) - > instance_set_base ( scale_plane_gizmo_instance [ i ] , spatial_editor - > get_scale_plane_gizmo ( i ) - > get_rid ( ) ) ;
VS : : get_singleton ( ) - > instance_set_scenario ( scale_plane_gizmo_instance [ i ] , get_tree ( ) - > get_root ( ) - > get_world ( ) - > get_scenario ( ) ) ;
VS : : get_singleton ( ) - > instance_set_visible ( scale_plane_gizmo_instance [ i ] , false ) ;
VS : : get_singleton ( ) - > instance_geometry_set_cast_shadows_setting ( scale_plane_gizmo_instance [ i ] , VS : : SHADOW_CASTING_SETTING_OFF ) ;
VS : : get_singleton ( ) - > instance_set_layer_mask ( scale_plane_gizmo_instance [ i ] , layer ) ;
2014-05-05 01:50:23 +00:00
}
}
2015-04-20 22:38:02 +00:00
void SpatialEditorViewport : : _finish_gizmo_instances ( ) {
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < 3 ; i + + ) {
2015-04-20 22:38:02 +00:00
VS : : get_singleton ( ) - > free ( move_gizmo_instance [ i ] ) ;
2017-08-29 01:39:45 +00:00
VS : : get_singleton ( ) - > free ( move_plane_gizmo_instance [ i ] ) ;
2015-04-20 22:38:02 +00:00
VS : : get_singleton ( ) - > free ( rotate_gizmo_instance [ i ] ) ;
2017-09-21 21:11:56 +00:00
VS : : get_singleton ( ) - > free ( scale_gizmo_instance [ i ] ) ;
2017-11-14 22:50:19 +00:00
VS : : get_singleton ( ) - > free ( scale_plane_gizmo_instance [ i ] ) ;
2015-04-20 22:38:02 +00:00
}
}
2014-02-10 01:10:30 +00:00
void SpatialEditorViewport : : _toggle_camera_preview ( bool p_activate ) {
ERR_FAIL_COND ( p_activate & & ! preview ) ;
ERR_FAIL_COND ( ! p_activate & & ! previewing ) ;
2020-05-08 01:14:24 +00:00
rotation_control - > set_visible ( ! p_activate ) ;
2014-02-10 01:10:30 +00:00
if ( ! p_activate ) {
2018-01-12 11:28:39 +00:00
previewing - > disconnect ( " tree_exiting " , this , " _preview_exited_scene " ) ;
2017-03-05 15:44:50 +00:00
previewing = NULL ;
VS : : get_singleton ( ) - > viewport_attach_camera ( viewport - > get_viewport_rid ( ) , camera - > get_camera ( ) ) ; //restore
2014-02-10 01:10:30 +00:00
if ( ! preview )
preview_camera - > hide ( ) ;
2018-10-10 07:25:59 +00:00
view_menu - > set_disabled ( false ) ;
2014-09-15 23:06:37 +00:00
surface - > update ( ) ;
2014-02-10 01:10:30 +00:00
} else {
2017-03-05 15:44:50 +00:00
previewing = preview ;
2018-01-12 11:28:39 +00:00
previewing - > connect ( " tree_exiting " , this , " _preview_exited_scene " ) ;
2017-03-05 15:44:50 +00:00
VS : : get_singleton ( ) - > viewport_attach_camera ( viewport - > get_viewport_rid ( ) , preview - > get_camera ( ) ) ; //replace
2018-10-10 07:25:59 +00:00
view_menu - > set_disabled ( true ) ;
2014-09-15 23:06:37 +00:00
surface - > update ( ) ;
2014-02-10 01:10:30 +00:00
}
}
2018-07-26 22:36:05 +00:00
void SpatialEditorViewport : : _toggle_cinema_preview ( bool p_activate ) {
previewing_cinema = p_activate ;
if ( ! previewing_cinema ) {
if ( previewing ! = NULL )
previewing - > disconnect ( " tree_exited " , this , " _preview_exited_scene " ) ;
previewing = NULL ;
VS : : get_singleton ( ) - > viewport_attach_camera ( viewport - > get_viewport_rid ( ) , camera - > get_camera ( ) ) ; //restore
preview_camera - > set_pressed ( false ) ;
if ( ! preview ) {
preview_camera - > hide ( ) ;
} else {
preview_camera - > show ( ) ;
}
view_menu - > show ( ) ;
surface - > update ( ) ;
}
}
2015-11-04 21:39:07 +00:00
void SpatialEditorViewport : : _selection_result_pressed ( int p_result ) {
if ( selection_results . size ( ) < = p_result )
return ;
2017-08-07 10:17:31 +00:00
clicked = selection_results [ p_result ] . item - > get_instance_id ( ) ;
2015-11-04 21:39:07 +00:00
if ( clicked ) {
2017-03-05 15:44:50 +00:00
_select_clicked ( clicked_wants_append , true ) ;
clicked = 0 ;
2015-11-04 21:39:07 +00:00
}
}
void SpatialEditorViewport : : _selection_menu_hide ( ) {
selection_results . clear ( ) ;
selection_menu - > clear ( ) ;
selection_menu - > set_size ( Vector2 ( 0 , 0 ) ) ;
}
2017-03-05 15:44:50 +00:00
void SpatialEditorViewport : : set_can_preview ( Camera * p_preview ) {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
preview = p_preview ;
2014-02-10 01:10:30 +00:00
2018-07-26 22:36:05 +00:00
if ( ! preview_camera - > is_pressed ( ) & & ! previewing_cinema )
2017-12-19 05:25:00 +00:00
preview_camera - > set_visible ( p_preview ) ;
2014-02-10 01:10:30 +00:00
}
2014-05-05 01:50:23 +00:00
void SpatialEditorViewport : : update_transform_gizmo_view ( ) {
2017-01-13 13:45:50 +00:00
if ( ! is_visible_in_tree ( ) )
2014-05-05 01:50:23 +00:00
return ;
Transform xform = spatial_editor - > get_gizmo_transform ( ) ;
Transform camera_xform = camera - > get_transform ( ) ;
2019-01-24 23:52:28 +00:00
if ( xform . origin . distance_squared_to ( camera_xform . origin ) < 0.01 ) {
for ( int i = 0 ; i < 3 ; i + + ) {
VisualServer : : get_singleton ( ) - > instance_set_visible ( move_gizmo_instance [ i ] , false ) ;
VisualServer : : get_singleton ( ) - > instance_set_visible ( move_plane_gizmo_instance [ i ] , false ) ;
VisualServer : : get_singleton ( ) - > instance_set_visible ( rotate_gizmo_instance [ i ] , false ) ;
VisualServer : : get_singleton ( ) - > instance_set_visible ( scale_gizmo_instance [ i ] , false ) ;
VisualServer : : get_singleton ( ) - > instance_set_visible ( scale_plane_gizmo_instance [ i ] , false ) ;
}
return ;
}
2014-05-05 01:50:23 +00:00
Vector3 camz = - camera_xform . get_basis ( ) . get_axis ( 2 ) . normalized ( ) ;
Vector3 camy = - camera_xform . get_basis ( ) . get_axis ( 1 ) . normalized ( ) ;
2017-03-05 15:44:50 +00:00
Plane p ( camera_xform . origin , camz ) ;
2020-06-22 08:53:22 +00:00
float gizmo_d = MAX ( Math : : abs ( p . distance_to ( xform . origin ) ) , CMP_EPSILON ) ;
2017-03-05 15:44:50 +00:00
float d0 = camera - > unproject_position ( camera_xform . origin + camz * gizmo_d ) . y ;
float d1 = camera - > unproject_position ( camera_xform . origin + camz * gizmo_d + camy ) . y ;
float dd = Math : : abs ( d0 - d1 ) ;
if ( dd = = 0 )
dd = 0.0001 ;
2014-05-05 01:50:23 +00:00
2019-08-03 01:01:32 +00:00
float gizmo_size = EditorSettings : : get_singleton ( ) - > get ( " editors/3d/manipulator_gizmo_size " ) ;
// At low viewport heights, multiply the gizmo scale based on the viewport height.
// This prevents the gizmo from growing very large and going outside the viewport.
const int viewport_base_height = 400 * MAX ( 1 , EDSCALE ) ;
gizmo_scale =
( gizmo_size / Math : : abs ( dd ) ) * MAX ( 1 , EDSCALE ) *
MIN ( viewport_base_height , viewport_container - > get_size ( ) . height ) / viewport_base_height /
viewport_container - > get_stretch_shrink ( ) ;
2017-03-05 15:44:50 +00:00
Vector3 scale = Vector3 ( 1 , 1 , 1 ) * gizmo_scale ;
2014-05-05 01:50:23 +00:00
xform . basis . scale ( scale ) ;
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < 3 ; i + + ) {
VisualServer : : get_singleton ( ) - > instance_set_transform ( move_gizmo_instance [ i ] , xform ) ;
VisualServer : : get_singleton ( ) - > instance_set_visible ( move_gizmo_instance [ i ] , spatial_editor - > is_gizmo_visible ( ) & & ( spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_SELECT | | spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_MOVE ) ) ;
2017-08-29 01:39:45 +00:00
VisualServer : : get_singleton ( ) - > instance_set_transform ( move_plane_gizmo_instance [ i ] , xform ) ;
VisualServer : : get_singleton ( ) - > instance_set_visible ( move_plane_gizmo_instance [ i ] , spatial_editor - > is_gizmo_visible ( ) & & ( spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_SELECT | | spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_MOVE ) ) ;
2017-03-05 15:44:50 +00:00
VisualServer : : get_singleton ( ) - > instance_set_transform ( rotate_gizmo_instance [ i ] , xform ) ;
VisualServer : : get_singleton ( ) - > instance_set_visible ( rotate_gizmo_instance [ i ] , spatial_editor - > is_gizmo_visible ( ) & & ( spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_SELECT | | spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_ROTATE ) ) ;
2017-09-21 21:11:56 +00:00
VisualServer : : get_singleton ( ) - > instance_set_transform ( scale_gizmo_instance [ i ] , xform ) ;
VisualServer : : get_singleton ( ) - > instance_set_visible ( scale_gizmo_instance [ i ] , spatial_editor - > is_gizmo_visible ( ) & & ( spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_SCALE ) ) ;
2017-11-14 22:50:19 +00:00
VisualServer : : get_singleton ( ) - > instance_set_transform ( scale_plane_gizmo_instance [ i ] , xform ) ;
VisualServer : : get_singleton ( ) - > instance_set_visible ( scale_plane_gizmo_instance [ i ] , spatial_editor - > is_gizmo_visible ( ) & & ( spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_SCALE ) ) ;
2014-05-05 01:50:23 +00:00
}
}
2017-03-05 15:44:50 +00:00
void SpatialEditorViewport : : set_state ( const Dictionary & p_state ) {
2014-02-10 01:10:30 +00:00
2017-12-19 05:25:00 +00:00
if ( p_state . has ( " position " ) )
cursor . pos = p_state [ " position " ] ;
if ( p_state . has ( " x_rotation " ) )
cursor . x_rot = p_state [ " x_rotation " ] ;
if ( p_state . has ( " y_rotation " ) )
cursor . y_rot = p_state [ " y_rotation " ] ;
if ( p_state . has ( " distance " ) )
cursor . distance = p_state [ " distance " ] ;
if ( p_state . has ( " use_orthogonal " ) ) {
bool orth = p_state [ " use_orthogonal " ] ;
if ( orth )
_menu_option ( VIEW_ORTHOGONAL ) ;
else
_menu_option ( VIEW_PERSPECTIVE ) ;
}
2019-10-23 09:46:26 +00:00
if ( p_state . has ( " view_name " ) ) {
name = p_state [ " view_name " ] ;
_update_name ( ) ;
}
if ( p_state . has ( " auto_orthogonal " ) ) {
auto_orthogonal = p_state [ " auto_orthogonal " ] ;
_update_name ( ) ;
}
if ( p_state . has ( " auto_orthogonal_enabled " ) ) {
bool enabled = p_state [ " auto_orthogonal_enabled " ] ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_AUTO_ORTHOGONAL ) , enabled ) ;
}
2017-12-19 05:25:00 +00:00
if ( p_state . has ( " display_mode " ) ) {
int display = p_state [ " display_mode " ] ;
int idx = view_menu - > get_popup ( ) - > get_item_index ( display ) ;
if ( ! view_menu - > get_popup ( ) - > is_item_checked ( idx ) )
_menu_option ( display ) ;
}
2018-06-25 01:24:31 +00:00
if ( p_state . has ( " lock_rotation " ) ) {
lock_rotation = p_state [ " lock_rotation " ] ;
int idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_LOCK_ROTATION ) ;
view_menu - > get_popup ( ) - > set_item_checked ( idx , lock_rotation ) ;
}
2017-12-19 05:25:00 +00:00
if ( p_state . has ( " use_environment " ) ) {
bool env = p_state [ " use_environment " ] ;
if ( env ! = camera - > get_environment ( ) . is_valid ( ) )
_menu_option ( VIEW_ENVIRONMENT ) ;
}
2014-10-03 03:10:51 +00:00
if ( p_state . has ( " listener " ) ) {
bool listener = p_state [ " listener " ] ;
int idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_AUDIO_LISTENER ) ;
viewport - > set_as_audio_listener ( listener ) ;
2017-03-05 15:44:50 +00:00
view_menu - > get_popup ( ) - > set_item_checked ( idx , listener ) ;
2014-10-03 03:10:51 +00:00
}
2017-07-15 04:23:10 +00:00
if ( p_state . has ( " doppler " ) ) {
bool doppler = p_state [ " doppler " ] ;
int idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_AUDIO_DOPPLER ) ;
camera - > set_doppler_tracking ( doppler ? Camera : : DOPPLER_TRACKING_IDLE_STEP : Camera : : DOPPLER_TRACKING_DISABLED ) ;
view_menu - > get_popup ( ) - > set_item_checked ( idx , doppler ) ;
}
2017-11-20 00:45:56 +00:00
if ( p_state . has ( " gizmos " ) ) {
bool gizmos = p_state [ " gizmos " ] ;
int idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_GIZMOS ) ;
if ( view_menu - > get_popup ( ) - > is_item_checked ( idx ) ! = gizmos )
_menu_option ( VIEW_GIZMOS ) ;
}
if ( p_state . has ( " information " ) ) {
bool information = p_state [ " information " ] ;
int idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_INFORMATION ) ;
if ( view_menu - > get_popup ( ) - > is_item_checked ( idx ) ! = information )
_menu_option ( VIEW_INFORMATION ) ;
}
2017-12-19 05:25:00 +00:00
if ( p_state . has ( " fps " ) ) {
bool fps = p_state [ " fps " ] ;
int idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_FPS ) ;
if ( view_menu - > get_popup ( ) - > is_item_checked ( idx ) ! = fps )
_menu_option ( VIEW_FPS ) ;
}
2017-10-31 17:23:25 +00:00
if ( p_state . has ( " half_res " ) ) {
bool half_res = p_state [ " half_res " ] ;
int idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_HALF_RESOLUTION ) ;
view_menu - > get_popup ( ) - > set_item_checked ( idx , half_res ) ;
}
2018-07-26 22:36:05 +00:00
if ( p_state . has ( " cinematic_preview " ) ) {
previewing_cinema = p_state [ " cinematic_preview " ] ;
int idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_CINEMATIC_PREVIEW ) ;
view_menu - > get_popup ( ) - > set_item_checked ( idx , previewing_cinema ) ;
}
2014-02-10 01:10:30 +00:00
2019-10-27 12:04:29 +00:00
if ( preview_camera - > is_connected ( " toggled " , this , " _toggle_camera_preview " ) ) {
preview_camera - > disconnect ( " toggled " , this , " _toggle_camera_preview " ) ;
}
2015-08-30 01:59:25 +00:00
if ( p_state . has ( " previewing " ) ) {
Node * pv = EditorNode : : get_singleton ( ) - > get_edited_scene ( ) - > get_node ( p_state [ " previewing " ] ) ;
2017-08-24 20:58:51 +00:00
if ( Object : : cast_to < Camera > ( pv ) ) {
previewing = Object : : cast_to < Camera > ( pv ) ;
2018-01-12 11:28:39 +00:00
previewing - > connect ( " tree_exiting " , this , " _preview_exited_scene " ) ;
2017-03-05 15:44:50 +00:00
VS : : get_singleton ( ) - > viewport_attach_camera ( viewport - > get_viewport_rid ( ) , previewing - > get_camera ( ) ) ; //replace
2019-03-11 17:10:00 +00:00
view_menu - > set_disabled ( true ) ;
2015-08-30 01:59:25 +00:00
surface - > update ( ) ;
preview_camera - > set_pressed ( true ) ;
preview_camera - > show ( ) ;
}
}
2019-10-27 12:04:29 +00:00
preview_camera - > connect ( " toggled " , this , " _toggle_camera_preview " ) ;
2014-02-10 01:10:30 +00:00
}
Dictionary SpatialEditorViewport : : get_state ( ) const {
Dictionary d ;
2017-09-10 13:37:49 +00:00
d [ " position " ] = cursor . pos ;
d [ " x_rotation " ] = cursor . x_rot ;
d [ " y_rotation " ] = cursor . y_rot ;
2017-03-05 15:44:50 +00:00
d [ " distance " ] = cursor . distance ;
d [ " use_environment " ] = camera - > get_environment ( ) . is_valid ( ) ;
d [ " use_orthogonal " ] = camera - > get_projection ( ) = = Camera : : PROJECTION_ORTHOGONAL ;
2019-10-23 09:46:26 +00:00
d [ " view_name " ] = name ;
d [ " auto_orthogonal " ] = auto_orthogonal ;
d [ " auto_orthogonal_enabled " ] = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_AUTO_ORTHOGONAL ) ) ;
2017-12-19 05:25:00 +00:00
if ( view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_NORMAL ) ) )
d [ " display_mode " ] = VIEW_DISPLAY_NORMAL ;
else if ( view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_WIREFRAME ) ) )
d [ " display_mode " ] = VIEW_DISPLAY_WIREFRAME ;
else if ( view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_OVERDRAW ) ) )
d [ " display_mode " ] = VIEW_DISPLAY_OVERDRAW ;
else if ( view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_SHADELESS ) ) )
d [ " display_mode " ] = VIEW_DISPLAY_SHADELESS ;
2017-03-05 15:44:50 +00:00
d [ " listener " ] = viewport - > is_audio_listener ( ) ;
2017-11-20 00:45:56 +00:00
d [ " doppler " ] = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_AUDIO_DOPPLER ) ) ;
d [ " gizmos " ] = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_GIZMOS ) ) ;
d [ " information " ] = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_INFORMATION ) ) ;
2017-12-19 05:25:00 +00:00
d [ " fps " ] = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_FPS ) ) ;
2017-10-31 17:23:25 +00:00
d [ " half_res " ] = viewport_container - > get_stretch_shrink ( ) > 1 ;
2018-07-26 22:36:05 +00:00
d [ " cinematic_preview " ] = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_CINEMATIC_PREVIEW ) ) ;
2017-12-19 05:25:00 +00:00
if ( previewing )
2017-03-05 15:44:50 +00:00
d [ " previewing " ] = EditorNode : : get_singleton ( ) - > get_edited_scene ( ) - > get_path_to ( previewing ) ;
2018-06-25 01:24:31 +00:00
if ( lock_rotation )
d [ " lock_rotation " ] = lock_rotation ;
2015-08-30 01:59:25 +00:00
2014-02-10 01:10:30 +00:00
return d ;
}
2017-03-05 15:44:50 +00:00
void SpatialEditorViewport : : _bind_methods ( ) {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
ClassDB : : bind_method ( D_METHOD ( " _draw " ) , & SpatialEditorViewport : : _draw ) ;
2017-12-19 14:29:55 +00:00
ClassDB : : bind_method ( D_METHOD ( " _surface_mouse_enter " ) , & SpatialEditorViewport : : _surface_mouse_enter ) ;
ClassDB : : bind_method ( D_METHOD ( " _surface_mouse_exit " ) , & SpatialEditorViewport : : _surface_mouse_exit ) ;
ClassDB : : bind_method ( D_METHOD ( " _surface_focus_enter " ) , & SpatialEditorViewport : : _surface_focus_enter ) ;
ClassDB : : bind_method ( D_METHOD ( " _surface_focus_exit " ) , & SpatialEditorViewport : : _surface_focus_exit ) ;
2017-03-05 15:44:50 +00:00
ClassDB : : bind_method ( D_METHOD ( " _sinput " ) , & SpatialEditorViewport : : _sinput ) ;
ClassDB : : bind_method ( D_METHOD ( " _menu_option " ) , & SpatialEditorViewport : : _menu_option ) ;
ClassDB : : bind_method ( D_METHOD ( " _toggle_camera_preview " ) , & SpatialEditorViewport : : _toggle_camera_preview ) ;
ClassDB : : bind_method ( D_METHOD ( " _preview_exited_scene " ) , & SpatialEditorViewport : : _preview_exited_scene ) ;
2020-03-10 16:56:46 +00:00
ClassDB : : bind_method ( D_METHOD ( " _update_camera " ) , & SpatialEditorViewport : : _update_camera ) ;
2017-03-05 15:44:50 +00:00
ClassDB : : bind_method ( D_METHOD ( " update_transform_gizmo_view " ) , & SpatialEditorViewport : : update_transform_gizmo_view ) ;
ClassDB : : bind_method ( D_METHOD ( " _selection_result_pressed " ) , & SpatialEditorViewport : : _selection_result_pressed ) ;
ClassDB : : bind_method ( D_METHOD ( " _selection_menu_hide " ) , & SpatialEditorViewport : : _selection_menu_hide ) ;
2017-09-02 19:47:16 +00:00
ClassDB : : bind_method ( D_METHOD ( " can_drop_data_fw " ) , & SpatialEditorViewport : : can_drop_data_fw ) ;
ClassDB : : bind_method ( D_METHOD ( " drop_data_fw " ) , & SpatialEditorViewport : : drop_data_fw ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
ADD_SIGNAL ( MethodInfo ( " toggle_maximize_view " , PropertyInfo ( Variant : : OBJECT , " viewport " ) ) ) ;
2019-04-06 20:55:01 +00:00
ADD_SIGNAL ( MethodInfo ( " clicked " , PropertyInfo ( Variant : : OBJECT , " viewport " ) ) ) ;
2014-02-10 01:10:30 +00:00
}
2014-09-19 21:39:50 +00:00
void SpatialEditorViewport : : reset ( ) {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
orthogonal = false ;
2019-10-23 09:46:26 +00:00
auto_orthogonal = false ;
2018-06-25 01:24:31 +00:00
lock_rotation = false ;
2017-03-05 15:44:50 +00:00
message_time = 0 ;
message = " " ;
last_message = " " ;
name = " " ;
2014-09-19 21:39:50 +00:00
2020-06-07 17:21:29 +00:00
cursor = Cursor ( ) ;
2015-03-21 20:47:21 +00:00
_update_name ( ) ;
2014-09-19 21:39:50 +00:00
}
2014-02-10 01:10:30 +00:00
2016-07-28 19:37:52 +00:00
void SpatialEditorViewport : : focus_selection ( ) {
if ( ! get_selected_count ( ) )
return ;
Vector3 center ;
2017-03-05 15:44:50 +00:00
int count = 0 ;
2016-07-28 19:37:52 +00:00
2017-03-05 15:44:50 +00:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
2016-07-28 19:37:52 +00:00
2017-03-05 15:44:50 +00:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2016-07-28 19:37:52 +00:00
2017-08-24 20:58:51 +00:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
2016-07-28 19:37:52 +00:00
if ( ! sp )
continue ;
2017-03-05 15:44:50 +00:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
2016-07-28 19:37:52 +00:00
if ( ! se )
continue ;
2017-10-03 16:49:32 +00:00
center + = sp - > get_global_gizmo_transform ( ) . origin ;
2016-07-28 19:37:52 +00:00
count + + ;
}
2017-03-05 15:44:50 +00:00
if ( count ! = 0 ) {
center / = float ( count ) ;
2016-07-28 19:37:52 +00:00
}
2017-03-05 15:44:50 +00:00
cursor . pos = center ;
2016-07-28 19:37:52 +00:00
}
2017-11-17 02:09:00 +00:00
void SpatialEditorViewport : : assign_pending_data_pointers ( Spatial * p_preview_node , AABB * p_preview_bounds , AcceptDialog * p_accept ) {
2017-09-02 19:47:16 +00:00
preview_node = p_preview_node ;
preview_bounds = p_preview_bounds ;
accept = p_accept ;
}
Vector3 SpatialEditorViewport : : _get_instance_position ( const Point2 & p_pos ) const {
const float MAX_DISTANCE = 10 ;
Vector3 world_ray = _get_ray ( p_pos ) ;
Vector3 world_pos = _get_ray_pos ( p_pos ) ;
Vector < ObjectID > instances = VisualServer : : get_singleton ( ) - > instances_cull_ray ( world_pos , world_ray , get_tree ( ) - > get_root ( ) - > get_world ( ) - > get_scenario ( ) ) ;
2018-07-24 22:08:49 +00:00
Set < Ref < EditorSpatialGizmo > > found_gizmos ;
2017-09-02 19:47:16 +00:00
float closest_dist = MAX_DISTANCE ;
Vector3 point = world_pos + world_ray * MAX_DISTANCE ;
Vector3 normal = Vector3 ( 0.0 , 0.0 , 0.0 ) ;
for ( int i = 0 ; i < instances . size ( ) ; i + + ) {
MeshInstance * mesh_instance = Object : : cast_to < MeshInstance > ( ObjectDB : : get_instance ( instances [ i ] ) ) ;
if ( ! mesh_instance )
continue ;
2018-07-24 22:08:49 +00:00
Ref < EditorSpatialGizmo > seg = mesh_instance - > get_gizmo ( ) ;
2017-09-02 19:47:16 +00:00
if ( ( ! seg . is_valid ( ) ) | | found_gizmos . has ( seg ) ) {
continue ;
}
found_gizmos . insert ( seg ) ;
Vector3 hit_point ;
Vector3 hit_normal ;
bool inters = seg - > intersect_ray ( camera , p_pos , hit_point , hit_normal , NULL , false ) ;
if ( ! inters )
continue ;
float dist = world_pos . distance_to ( hit_point ) ;
if ( dist < 0 )
continue ;
if ( dist < closest_dist ) {
closest_dist = dist ;
point = hit_point ;
normal = hit_normal ;
}
}
2017-10-18 04:16:05 +00:00
Vector3 offset = Vector3 ( ) ;
for ( int i = 0 ; i < 3 ; i + + ) {
if ( normal [ i ] > 0.0 )
offset [ i ] = ( preview_bounds - > get_size ( ) [ i ] - ( preview_bounds - > get_size ( ) [ i ] + preview_bounds - > get_position ( ) [ i ] ) ) ;
else if ( normal [ i ] < 0.0 )
offset [ i ] = - ( preview_bounds - > get_size ( ) [ i ] + preview_bounds - > get_position ( ) [ i ] ) ;
}
return point + offset ;
2017-09-02 19:47:16 +00:00
}
2019-10-04 13:28:30 +00:00
AABB SpatialEditorViewport : : _calculate_spatial_bounds ( const Spatial * p_parent , bool p_exclude_toplevel_transform ) {
AABB bounds ;
const MeshInstance * mesh_instance = Object : : cast_to < MeshInstance > ( p_parent ) ;
if ( mesh_instance ) {
bounds = mesh_instance - > get_aabb ( ) ;
}
2017-09-02 19:47:16 +00:00
for ( int i = 0 ; i < p_parent - > get_child_count ( ) ; i + + ) {
Spatial * child = Object : : cast_to < Spatial > ( p_parent - > get_child ( i ) ) ;
if ( child ) {
2019-10-04 13:28:30 +00:00
AABB child_bounds = _calculate_spatial_bounds ( child , false ) ;
if ( bounds . size = = Vector3 ( ) & & p_parent - > get_class_name ( ) = = StringName ( " Spatial " ) ) {
bounds = child_bounds ;
} else {
bounds . merge_with ( child_bounds ) ;
2017-09-02 19:47:16 +00:00
}
}
}
2019-10-04 13:28:30 +00:00
if ( bounds . size = = Vector3 ( ) & & p_parent - > get_class_name ( ) ! = StringName ( " Spatial " ) ) {
bounds = AABB ( Vector3 ( - 0.2 , - 0.2 , - 0.2 ) , Vector3 ( 0.4 , 0.4 , 0.4 ) ) ;
}
if ( ! p_exclude_toplevel_transform ) {
bounds = p_parent - > get_transform ( ) . xform ( bounds ) ;
}
2017-09-02 19:47:16 +00:00
return bounds ;
}
void SpatialEditorViewport : : _create_preview ( const Vector < String > & files ) const {
for ( int i = 0 ; i < files . size ( ) ; i + + ) {
String path = files [ i ] ;
RES res = ResourceLoader : : load ( path ) ;
2019-09-29 12:17:42 +00:00
ERR_CONTINUE ( res . is_null ( ) ) ;
2017-09-02 19:47:16 +00:00
Ref < PackedScene > scene = Ref < PackedScene > ( Object : : cast_to < PackedScene > ( * res ) ) ;
2017-09-16 13:57:17 +00:00
Ref < Mesh > mesh = Ref < Mesh > ( Object : : cast_to < Mesh > ( * res ) ) ;
if ( mesh ! = NULL | | scene ! = NULL ) {
if ( mesh ! = NULL ) {
MeshInstance * mesh_instance = memnew ( MeshInstance ) ;
mesh_instance - > set_mesh ( mesh ) ;
preview_node - > add_child ( mesh_instance ) ;
} else {
if ( scene . is_valid ( ) ) {
Node * instance = scene - > instance ( ) ;
if ( instance ) {
preview_node - > add_child ( instance ) ;
}
2017-09-02 19:47:16 +00:00
}
}
editor - > get_scene_root ( ) - > add_child ( preview_node ) ;
}
}
2019-10-04 13:28:30 +00:00
* preview_bounds = _calculate_spatial_bounds ( preview_node ) ;
2017-09-02 19:47:16 +00:00
}
void SpatialEditorViewport : : _remove_preview ( ) {
if ( preview_node - > get_parent ( ) ) {
for ( int i = preview_node - > get_child_count ( ) - 1 ; i > = 0 ; i - - ) {
Node * node = preview_node - > get_child ( i ) ;
node - > queue_delete ( ) ;
preview_node - > remove_child ( node ) ;
}
editor - > get_scene_root ( ) - > remove_child ( preview_node ) ;
}
}
bool SpatialEditorViewport : : _cyclical_dependency_exists ( const String & p_target_scene_path , Node * p_desired_node ) {
if ( p_desired_node - > get_filename ( ) = = p_target_scene_path ) {
return true ;
}
int childCount = p_desired_node - > get_child_count ( ) ;
for ( int i = 0 ; i < childCount ; i + + ) {
Node * child = p_desired_node - > get_child ( i ) ;
if ( _cyclical_dependency_exists ( p_target_scene_path , child ) ) {
return true ;
}
}
return false ;
}
bool SpatialEditorViewport : : _create_instance ( Node * parent , String & path , const Point2 & p_point ) {
2017-09-16 13:57:17 +00:00
RES res = ResourceLoader : : load ( path ) ;
2019-09-29 12:17:42 +00:00
ERR_FAIL_COND_V ( res . is_null ( ) , false ) ;
2017-09-16 13:57:17 +00:00
Ref < PackedScene > scene = Ref < PackedScene > ( Object : : cast_to < PackedScene > ( * res ) ) ;
Ref < Mesh > mesh = Ref < Mesh > ( Object : : cast_to < Mesh > ( * res ) ) ;
Node * instanced_scene = NULL ;
if ( mesh ! = NULL | | scene ! = NULL ) {
if ( mesh ! = NULL ) {
MeshInstance * mesh_instance = memnew ( MeshInstance ) ;
mesh_instance - > set_mesh ( mesh ) ;
2018-11-29 20:14:53 +00:00
mesh_instance - > set_name ( path . get_file ( ) . get_basename ( ) ) ;
2017-09-16 13:57:17 +00:00
instanced_scene = mesh_instance ;
} else {
if ( ! scene . is_valid ( ) ) { // invalid scene
return false ;
} else {
2018-05-06 17:13:23 +00:00
instanced_scene = scene - > instance ( PackedScene : : GEN_EDIT_STATE_INSTANCE ) ;
2017-09-16 13:57:17 +00:00
}
}
2017-09-02 19:47:16 +00:00
}
2017-09-16 13:57:17 +00:00
if ( instanced_scene = = NULL ) {
2017-09-02 19:47:16 +00:00
return false ;
}
if ( editor - > get_edited_scene ( ) - > get_filename ( ) ! = " " ) { // cyclical instancing
if ( _cyclical_dependency_exists ( editor - > get_edited_scene ( ) - > get_filename ( ) , instanced_scene ) ) {
memdelete ( instanced_scene ) ;
return false ;
}
}
2017-11-10 21:31:53 +00:00
if ( scene ! = NULL ) {
instanced_scene - > set_filename ( ProjectSettings : : get_singleton ( ) - > localize_path ( path ) ) ;
}
2017-09-02 19:47:16 +00:00
editor_data - > get_undo_redo ( ) . add_do_method ( parent , " add_child " , instanced_scene ) ;
editor_data - > get_undo_redo ( ) . add_do_method ( instanced_scene , " set_owner " , editor - > get_edited_scene ( ) ) ;
editor_data - > get_undo_redo ( ) . add_do_reference ( instanced_scene ) ;
editor_data - > get_undo_redo ( ) . add_undo_method ( parent , " remove_child " , instanced_scene ) ;
String new_name = parent - > validate_child_name ( instanced_scene ) ;
ScriptEditorDebugger * sed = ScriptEditor : : get_singleton ( ) - > get_debugger ( ) ;
editor_data - > get_undo_redo ( ) . add_do_method ( sed , " live_debug_instance_node " , editor - > get_edited_scene ( ) - > get_path_to ( parent ) , path , new_name ) ;
editor_data - > get_undo_redo ( ) . add_undo_method ( sed , " live_debug_remove_node " , NodePath ( String ( editor - > get_edited_scene ( ) - > get_path_to ( parent ) ) + " / " + new_name ) ) ;
2020-06-07 17:18:37 +00:00
Spatial * spatial = Object : : cast_to < Spatial > ( instanced_scene ) ;
if ( spatial ) {
Transform global_transform ;
Spatial * parent_spatial = Object : : cast_to < Spatial > ( parent ) ;
if ( parent_spatial ) {
global_transform = parent_spatial - > get_global_gizmo_transform ( ) ;
}
2017-09-02 19:47:16 +00:00
2020-06-07 17:18:37 +00:00
global_transform . origin = spatial_editor - > snap_point ( _get_instance_position ( p_point ) ) ;
global_transform . basis * = spatial - > get_transform ( ) . basis ;
2017-09-02 19:47:16 +00:00
2020-06-07 17:18:37 +00:00
editor_data - > get_undo_redo ( ) . add_do_method ( instanced_scene , " set_global_transform " , global_transform ) ;
}
2017-09-02 19:47:16 +00:00
return true ;
}
void SpatialEditorViewport : : _perform_drop_data ( ) {
_remove_preview ( ) ;
Vector < String > error_files ;
editor_data - > get_undo_redo ( ) . create_action ( TTR ( " Create Node " ) ) ;
for ( int i = 0 ; i < selected_files . size ( ) ; i + + ) {
String path = selected_files [ i ] ;
RES res = ResourceLoader : : load ( path ) ;
if ( res . is_null ( ) ) {
continue ;
}
Ref < PackedScene > scene = Ref < PackedScene > ( Object : : cast_to < PackedScene > ( * res ) ) ;
2017-09-16 13:57:17 +00:00
Ref < Mesh > mesh = Ref < Mesh > ( Object : : cast_to < Mesh > ( * res ) ) ;
if ( mesh ! = NULL | | scene ! = NULL ) {
2017-09-02 19:47:16 +00:00
bool success = _create_instance ( target_node , path , drop_pos ) ;
if ( ! success ) {
error_files . push_back ( path ) ;
}
}
}
editor_data - > get_undo_redo ( ) . commit_action ( ) ;
if ( error_files . size ( ) > 0 ) {
String files_str ;
for ( int i = 0 ; i < error_files . size ( ) ; i + + ) {
files_str + = error_files [ i ] . get_file ( ) . get_basename ( ) + " , " ;
}
files_str = files_str . substr ( 0 , files_str . length ( ) - 1 ) ;
accept - > set_text ( vformat ( TTR ( " Error instancing scene from %s " ) , files_str . c_str ( ) ) ) ;
accept - > popup_centered_minsize ( ) ;
}
}
bool SpatialEditorViewport : : can_drop_data_fw ( const Point2 & p_point , const Variant & p_data , Control * p_from ) const {
bool can_instance = false ;
if ( ! preview_node - > is_inside_tree ( ) ) {
Dictionary d = p_data ;
if ( d . has ( " type " ) & & ( String ( d [ " type " ] ) = = " files " ) ) {
Vector < String > files = d [ " files " ] ;
List < String > scene_extensions ;
ResourceLoader : : get_recognized_extensions_for_type ( " PackedScene " , & scene_extensions ) ;
2017-09-16 13:57:17 +00:00
List < String > mesh_extensions ;
ResourceLoader : : get_recognized_extensions_for_type ( " Mesh " , & mesh_extensions ) ;
2017-09-02 19:47:16 +00:00
for ( int i = 0 ; i < files . size ( ) ; i + + ) {
2017-09-16 13:57:17 +00:00
if ( mesh_extensions . find ( files [ i ] . get_extension ( ) ) | | scene_extensions . find ( files [ i ] . get_extension ( ) ) ) {
2017-09-02 19:47:16 +00:00
RES res = ResourceLoader : : load ( files [ i ] ) ;
if ( res . is_null ( ) ) {
continue ;
}
String type = res - > get_class ( ) ;
if ( type = = " PackedScene " ) {
Ref < PackedScene > sdata = ResourceLoader : : load ( files [ i ] ) ;
Node * instanced_scene = sdata - > instance ( PackedScene : : GEN_EDIT_STATE_INSTANCE ) ;
if ( ! instanced_scene ) {
continue ;
}
memdelete ( instanced_scene ) ;
2017-12-31 04:22:16 +00:00
} else if ( type = = " Mesh " | | type = = " ArrayMesh " | | type = = " PrimitiveMesh " ) {
2017-09-16 13:57:17 +00:00
Ref < Mesh > mesh = ResourceLoader : : load ( files [ i ] ) ;
if ( ! mesh . is_valid ( ) ) {
continue ;
}
} else {
continue ;
2017-09-02 19:47:16 +00:00
}
can_instance = true ;
break ;
}
}
if ( can_instance ) {
_create_preview ( files ) ;
}
}
} else {
can_instance = true ;
}
if ( can_instance ) {
Transform global_transform = Transform ( Basis ( ) , _get_instance_position ( p_point ) ) ;
preview_node - > set_global_transform ( global_transform ) ;
}
return can_instance ;
}
void SpatialEditorViewport : : drop_data_fw ( const Point2 & p_point , const Variant & p_data , Control * p_from ) {
if ( ! can_drop_data_fw ( p_point , p_data , p_from ) )
return ;
bool is_shift = Input : : get_singleton ( ) - > is_key_pressed ( KEY_SHIFT ) ;
selected_files . clear ( ) ;
Dictionary d = p_data ;
if ( d . has ( " type " ) & & String ( d [ " type " ] ) = = " files " ) {
selected_files = d [ " files " ] ;
}
List < Node * > list = editor - > get_editor_selection ( ) - > get_selected_node_list ( ) ;
if ( list . size ( ) = = 0 ) {
Node * root_node = editor - > get_edited_scene ( ) ;
if ( root_node ) {
list . push_back ( root_node ) ;
} else {
accept - > set_text ( TTR ( " No parent to instance a child at. " ) ) ;
accept - > popup_centered_minsize ( ) ;
_remove_preview ( ) ;
return ;
}
}
if ( list . size ( ) ! = 1 ) {
accept - > set_text ( TTR ( " This operation requires a single selected node. " ) ) ;
accept - > popup_centered_minsize ( ) ;
_remove_preview ( ) ;
return ;
}
target_node = list [ 0 ] ;
if ( is_shift & & target_node ! = editor - > get_edited_scene ( ) ) {
target_node = target_node - > get_parent ( ) ;
}
drop_pos = p_point ;
_perform_drop_data ( ) ;
}
2014-05-05 01:50:23 +00:00
SpatialEditorViewport : : SpatialEditorViewport ( SpatialEditor * p_spatial_editor , EditorNode * p_editor , int p_index ) {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
_edit . mode = TRANSFORM_NONE ;
_edit . plane = TRANSFORM_VIEW ;
_edit . edited_gizmo = 0 ;
_edit . snap = 1 ;
_edit . gizmo_handle = 0 ;
index = p_index ;
editor = p_editor ;
2017-09-02 19:47:16 +00:00
editor_data = editor - > get_scene_tree_dock ( ) - > get_editor_data ( ) ;
2017-03-05 15:44:50 +00:00
editor_selection = editor - > get_editor_selection ( ) ;
undo_redo = editor - > get_undo_redo ( ) ;
clicked = 0 ;
clicked_includes_current = false ;
orthogonal = false ;
2019-10-23 09:46:26 +00:00
auto_orthogonal = false ;
2018-08-05 18:24:11 +00:00
lock_rotation = false ;
2017-03-05 15:44:50 +00:00
message_time = 0 ;
2017-05-07 20:59:05 +00:00
zoom_indicator_delay = 0.0 ;
2017-03-05 15:44:50 +00:00
spatial_editor = p_spatial_editor ;
ViewportContainer * c = memnew ( ViewportContainer ) ;
2017-10-31 17:23:25 +00:00
viewport_container = c ;
2016-10-19 14:14:41 +00:00
c - > set_stretch ( true ) ;
2014-02-10 01:10:30 +00:00
add_child ( c ) ;
2017-09-21 22:12:33 +00:00
c - > set_anchors_and_margins_preset ( Control : : PRESET_WIDE ) ;
2017-03-05 15:44:50 +00:00
viewport = memnew ( Viewport ) ;
2016-01-18 22:49:11 +00:00
viewport - > set_disable_input ( true ) ;
2016-11-10 02:55:06 +00:00
2014-02-10 01:10:30 +00:00
c - > add_child ( viewport ) ;
2017-03-05 15:44:50 +00:00
surface = memnew ( Control ) ;
2017-09-02 19:47:16 +00:00
surface - > set_drag_forwarding ( this ) ;
2014-02-10 01:10:30 +00:00
add_child ( surface ) ;
2017-09-21 22:12:33 +00:00
surface - > set_anchors_and_margins_preset ( Control : : PRESET_WIDE ) ;
2017-06-11 21:13:04 +00:00
surface - > set_clip_contents ( true ) ;
2014-02-10 01:10:30 +00:00
camera = memnew ( Camera ) ;
camera - > set_disable_gizmo ( true ) ;
2017-03-05 15:44:50 +00:00
camera - > set_cull_mask ( ( ( 1 < < 20 ) - 1 ) | ( 1 < < ( GIZMO_BASE_LAYER + p_index ) ) | ( 1 < < GIZMO_EDIT_LAYER ) | ( 1 < < GIZMO_GRID_LAYER ) ) ;
2014-02-10 01:10:30 +00:00
viewport - > add_child ( camera ) ;
camera - > make_current ( ) ;
surface - > set_focus_mode ( FOCUS_ALL ) ;
2019-05-24 19:21:07 +00:00
VBoxContainer * vbox = memnew ( VBoxContainer ) ;
surface - > add_child ( vbox ) ;
vbox - > set_position ( Point2 ( 10 , 10 ) * EDSCALE ) ;
2017-03-05 15:44:50 +00:00
view_menu = memnew ( MenuButton ) ;
2018-10-10 07:25:59 +00:00
view_menu - > set_flat ( false ) ;
2019-05-24 19:21:07 +00:00
vbox - > add_child ( view_menu ) ;
view_menu - > set_h_size_flags ( 0 ) ;
2018-10-10 07:25:59 +00:00
2016-06-30 20:54:34 +00:00
view_menu - > get_popup ( ) - > add_shortcut ( ED_GET_SHORTCUT ( " spatial_editor/top_view " ) , VIEW_TOP ) ;
view_menu - > get_popup ( ) - > add_shortcut ( ED_GET_SHORTCUT ( " spatial_editor/bottom_view " ) , VIEW_BOTTOM ) ;
view_menu - > get_popup ( ) - > add_shortcut ( ED_GET_SHORTCUT ( " spatial_editor/left_view " ) , VIEW_LEFT ) ;
view_menu - > get_popup ( ) - > add_shortcut ( ED_GET_SHORTCUT ( " spatial_editor/right_view " ) , VIEW_RIGHT ) ;
view_menu - > get_popup ( ) - > add_shortcut ( ED_GET_SHORTCUT ( " spatial_editor/front_view " ) , VIEW_FRONT ) ;
view_menu - > get_popup ( ) - > add_shortcut ( ED_GET_SHORTCUT ( " spatial_editor/rear_view " ) , VIEW_REAR ) ;
2014-02-10 01:10:30 +00:00
view_menu - > get_popup ( ) - > add_separator ( ) ;
2018-03-24 02:05:20 +00:00
view_menu - > get_popup ( ) - > add_radio_check_item ( TTR ( " Perspective " ) + " ( " + ED_GET_SHORTCUT ( " spatial_editor/switch_perspective_orthogonal " ) - > get_as_text ( ) + " ) " , VIEW_PERSPECTIVE ) ;
view_menu - > get_popup ( ) - > add_radio_check_item ( TTR ( " Orthogonal " ) + " ( " + ED_GET_SHORTCUT ( " spatial_editor/switch_perspective_orthogonal " ) - > get_as_text ( ) + " ) " , VIEW_ORTHOGONAL ) ;
2017-03-05 15:44:50 +00:00
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_PERSPECTIVE ) , true ) ;
2019-10-23 09:46:26 +00:00
view_menu - > get_popup ( ) - > add_check_item ( TTR ( " Auto Orthogonal Enabled " ) , VIEW_AUTO_ORTHOGONAL ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_AUTO_ORTHOGONAL ) , true ) ;
2014-02-10 01:10:30 +00:00
view_menu - > get_popup ( ) - > add_separator ( ) ;
2018-06-25 01:24:31 +00:00
view_menu - > get_popup ( ) - > add_check_shortcut ( ED_SHORTCUT ( " spatial_editor/view_lock_rotation " , TTR ( " Lock View Rotation " ) ) , VIEW_LOCK_ROTATION ) ;
view_menu - > get_popup ( ) - > add_separator ( ) ;
2018-03-24 02:05:20 +00:00
view_menu - > get_popup ( ) - > add_radio_check_shortcut ( ED_SHORTCUT ( " spatial_editor/view_display_normal " , TTR ( " Display Normal " ) ) , VIEW_DISPLAY_NORMAL ) ;
view_menu - > get_popup ( ) - > add_radio_check_shortcut ( ED_SHORTCUT ( " spatial_editor/view_display_wireframe " , TTR ( " Display Wireframe " ) ) , VIEW_DISPLAY_WIREFRAME ) ;
view_menu - > get_popup ( ) - > add_radio_check_shortcut ( ED_SHORTCUT ( " spatial_editor/view_display_overdraw " , TTR ( " Display Overdraw " ) ) , VIEW_DISPLAY_OVERDRAW ) ;
view_menu - > get_popup ( ) - > add_radio_check_shortcut ( ED_SHORTCUT ( " spatial_editor/view_display_unshaded " , TTR ( " Display Unshaded " ) ) , VIEW_DISPLAY_SHADELESS ) ;
2017-06-11 18:52:03 +00:00
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_NORMAL ) , true ) ;
view_menu - > get_popup ( ) - > add_separator ( ) ;
view_menu - > get_popup ( ) - > add_check_shortcut ( ED_SHORTCUT ( " spatial_editor/view_environment " , TTR ( " View Environment " ) ) , VIEW_ENVIRONMENT ) ;
view_menu - > get_popup ( ) - > add_check_shortcut ( ED_SHORTCUT ( " spatial_editor/view_gizmos " , TTR ( " View Gizmos " ) ) , VIEW_GIZMOS ) ;
view_menu - > get_popup ( ) - > add_check_shortcut ( ED_SHORTCUT ( " spatial_editor/view_information " , TTR ( " View Information " ) ) , VIEW_INFORMATION ) ;
2017-11-19 20:00:16 +00:00
view_menu - > get_popup ( ) - > add_check_shortcut ( ED_SHORTCUT ( " spatial_editor/view_fps " , TTR ( " View FPS " ) ) , VIEW_FPS ) ;
2017-03-05 15:44:50 +00:00
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_ENVIRONMENT ) , true ) ;
2014-10-03 03:10:51 +00:00
view_menu - > get_popup ( ) - > add_separator ( ) ;
2017-10-31 17:23:25 +00:00
view_menu - > get_popup ( ) - > add_check_shortcut ( ED_SHORTCUT ( " spatial_editor/view_half_resolution " , TTR ( " Half Resolution " ) ) , VIEW_HALF_RESOLUTION ) ;
view_menu - > get_popup ( ) - > add_separator ( ) ;
2016-06-30 20:54:34 +00:00
view_menu - > get_popup ( ) - > add_check_shortcut ( ED_SHORTCUT ( " spatial_editor/view_audio_listener " , TTR ( " Audio Listener " ) ) , VIEW_AUDIO_LISTENER ) ;
2019-08-12 20:23:00 +00:00
view_menu - > get_popup ( ) - > add_check_shortcut ( ED_SHORTCUT ( " spatial_editor/view_audio_doppler " , TTR ( " Enable Doppler " ) ) , VIEW_AUDIO_DOPPLER ) ;
2017-03-05 15:44:50 +00:00
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_GIZMOS ) , true ) ;
2014-10-03 03:10:51 +00:00
2018-07-26 22:36:05 +00:00
view_menu - > get_popup ( ) - > add_separator ( ) ;
view_menu - > get_popup ( ) - > add_check_shortcut ( ED_SHORTCUT ( " spatial_editor/view_cinematic_preview " , TTR ( " Cinematic Preview " ) ) , VIEW_CINEMATIC_PREVIEW ) ;
2014-02-10 01:10:30 +00:00
view_menu - > get_popup ( ) - > add_separator ( ) ;
2016-10-04 18:39:38 +00:00
view_menu - > get_popup ( ) - > add_shortcut ( ED_GET_SHORTCUT ( " spatial_editor/focus_origin " ) , VIEW_CENTER_TO_ORIGIN ) ;
2016-06-30 20:54:34 +00:00
view_menu - > get_popup ( ) - > add_shortcut ( ED_GET_SHORTCUT ( " spatial_editor/focus_selection " ) , VIEW_CENTER_TO_SELECTION ) ;
2018-10-27 21:43:19 +00:00
view_menu - > get_popup ( ) - > add_shortcut ( ED_GET_SHORTCUT ( " spatial_editor/align_transform_with_view " ) , VIEW_ALIGN_TRANSFORM_WITH_VIEW ) ;
view_menu - > get_popup ( ) - > add_shortcut ( ED_GET_SHORTCUT ( " spatial_editor/align_rotation_with_view " ) , VIEW_ALIGN_ROTATION_WITH_VIEW ) ;
2017-03-05 15:44:50 +00:00
view_menu - > get_popup ( ) - > connect ( " id_pressed " , this , " _menu_option " ) ;
2014-02-10 01:10:30 +00:00
2017-12-19 14:29:55 +00:00
view_menu - > set_disable_shortcuts ( true ) ;
2020-01-17 15:06:47 +00:00
if ( OS : : get_singleton ( ) - > get_current_video_driver ( ) = = OS : : VIDEO_DRIVER_GLES2 ) {
// Alternate display modes only work when using the GLES3 renderer; make this explicit.
const int normal_idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_NORMAL ) ;
const int wireframe_idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_WIREFRAME ) ;
const int overdraw_idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_OVERDRAW ) ;
const int shadeless_idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_DISPLAY_SHADELESS ) ;
const String unsupported_tooltip = TTR ( " Not available when using the GLES2 renderer. " ) ;
view_menu - > get_popup ( ) - > set_item_disabled ( normal_idx , true ) ;
view_menu - > get_popup ( ) - > set_item_tooltip ( normal_idx , unsupported_tooltip ) ;
view_menu - > get_popup ( ) - > set_item_disabled ( wireframe_idx , true ) ;
view_menu - > get_popup ( ) - > set_item_tooltip ( wireframe_idx , unsupported_tooltip ) ;
view_menu - > get_popup ( ) - > set_item_disabled ( overdraw_idx , true ) ;
view_menu - > get_popup ( ) - > set_item_tooltip ( overdraw_idx , unsupported_tooltip ) ;
view_menu - > get_popup ( ) - > set_item_disabled ( shadeless_idx , true ) ;
view_menu - > get_popup ( ) - > set_item_tooltip ( shadeless_idx , unsupported_tooltip ) ;
}
2017-07-27 02:00:23 +00:00
ED_SHORTCUT ( " spatial_editor/freelook_left " , TTR ( " Freelook Left " ) , KEY_A ) ;
ED_SHORTCUT ( " spatial_editor/freelook_right " , TTR ( " Freelook Right " ) , KEY_D ) ;
ED_SHORTCUT ( " spatial_editor/freelook_forward " , TTR ( " Freelook Forward " ) , KEY_W ) ;
ED_SHORTCUT ( " spatial_editor/freelook_backwards " , TTR ( " Freelook Backwards " ) , KEY_S ) ;
2017-09-13 23:36:42 +00:00
ED_SHORTCUT ( " spatial_editor/freelook_up " , TTR ( " Freelook Up " ) , KEY_E ) ;
ED_SHORTCUT ( " spatial_editor/freelook_down " , TTR ( " Freelook Down " ) , KEY_Q ) ;
2017-07-27 02:00:23 +00:00
ED_SHORTCUT ( " spatial_editor/freelook_speed_modifier " , TTR ( " Freelook Speed Modifier " ) , KEY_SHIFT ) ;
2019-10-14 20:47:47 +00:00
ED_SHORTCUT ( " spatial_editor/freelook_slow_modifier " , TTR ( " Freelook Slow Modifier " ) , KEY_ALT ) ;
2017-07-27 02:00:23 +00:00
2018-10-10 07:25:59 +00:00
preview_camera = memnew ( CheckBox ) ;
2017-12-19 05:25:00 +00:00
preview_camera - > set_text ( TTR ( " Preview " ) ) ;
2019-05-24 19:21:07 +00:00
vbox - > add_child ( preview_camera ) ;
preview_camera - > set_h_size_flags ( 0 ) ;
2014-02-10 01:10:30 +00:00
preview_camera - > hide ( ) ;
2019-11-09 16:24:40 +00:00
preview_camera - > connect ( " toggled " , this , " _toggle_camera_preview " ) ;
2017-03-05 15:44:50 +00:00
previewing = NULL ;
gizmo_scale = 1.0 ;
2017-05-07 20:59:05 +00:00
2017-09-02 19:47:16 +00:00
preview_node = NULL ;
2017-06-11 21:13:04 +00:00
info_label = memnew ( Label ) ;
2017-12-17 12:06:21 +00:00
info_label - > set_anchor_and_margin ( MARGIN_LEFT , ANCHOR_END , - 90 * EDSCALE ) ;
info_label - > set_anchor_and_margin ( MARGIN_TOP , ANCHOR_END , - 90 * EDSCALE ) ;
info_label - > set_anchor_and_margin ( MARGIN_RIGHT , ANCHOR_END , - 10 * EDSCALE ) ;
info_label - > set_anchor_and_margin ( MARGIN_BOTTOM , ANCHOR_END , - 10 * EDSCALE ) ;
info_label - > set_h_grow_direction ( GROW_DIRECTION_BEGIN ) ;
info_label - > set_v_grow_direction ( GROW_DIRECTION_BEGIN ) ;
surface - > add_child ( info_label ) ;
info_label - > hide ( ) ;
2017-06-11 21:13:04 +00:00
2018-07-26 22:36:05 +00:00
cinema_label = memnew ( Label ) ;
cinema_label - > set_anchor_and_margin ( MARGIN_TOP , ANCHOR_BEGIN , 10 * EDSCALE ) ;
cinema_label - > set_h_grow_direction ( GROW_DIRECTION_END ) ;
cinema_label - > set_align ( Label : : ALIGN_CENTER ) ;
surface - > add_child ( cinema_label ) ;
cinema_label - > set_text ( TTR ( " Cinematic Preview " ) ) ;
cinema_label - > hide ( ) ;
previewing_cinema = false ;
2018-10-10 07:25:59 +00:00
locked_label = memnew ( Label ) ;
locked_label - > set_anchor_and_margin ( MARGIN_TOP , ANCHOR_END , - 20 * EDSCALE ) ;
locked_label - > set_anchor_and_margin ( MARGIN_BOTTOM , ANCHOR_END , - 10 * EDSCALE ) ;
locked_label - > set_h_grow_direction ( GROW_DIRECTION_END ) ;
locked_label - > set_v_grow_direction ( GROW_DIRECTION_BEGIN ) ;
locked_label - > set_align ( Label : : ALIGN_CENTER ) ;
surface - > add_child ( locked_label ) ;
locked_label - > set_text ( TTR ( " View Rotation Locked " ) ) ;
locked_label - > hide ( ) ;
2019-10-23 09:46:26 +00:00
top_right_vbox = memnew ( VBoxContainer ) ;
top_right_vbox - > set_anchors_and_margins_preset ( PRESET_TOP_RIGHT , PRESET_MODE_MINSIZE , 2.0 * EDSCALE ) ;
top_right_vbox - > set_h_grow_direction ( GROW_DIRECTION_BEGIN ) ;
rotation_control = memnew ( ViewportRotationControl ) ;
rotation_control - > set_custom_minimum_size ( Size2 ( 80 , 80 ) * EDSCALE ) ;
rotation_control - > set_h_size_flags ( SIZE_SHRINK_END ) ;
rotation_control - > set_viewport ( this ) ;
top_right_vbox - > add_child ( rotation_control ) ;
fps_label = memnew ( Label ) ;
fps_label - > set_anchor_and_margin ( MARGIN_LEFT , ANCHOR_END , - 90 * EDSCALE ) ;
fps_label - > set_anchor_and_margin ( MARGIN_TOP , ANCHOR_BEGIN , 10 * EDSCALE ) ;
fps_label - > set_anchor_and_margin ( MARGIN_RIGHT , ANCHOR_END , - 10 * EDSCALE ) ;
fps_label - > set_h_grow_direction ( GROW_DIRECTION_BEGIN ) ;
fps_label - > set_tooltip ( TTR ( " Note: The FPS value displayed is the editor's framerate. \n It cannot be used as a reliable indication of in-game performance. " ) ) ;
fps_label - > set_mouse_filter ( MOUSE_FILTER_PASS ) ; // Otherwise tooltip doesn't show.
top_right_vbox - > add_child ( fps_label ) ;
fps_label - > hide ( ) ;
surface - > add_child ( top_right_vbox ) ;
2017-09-02 19:47:16 +00:00
accept = NULL ;
2017-05-07 20:59:05 +00:00
freelook_active = false ;
2017-10-08 00:43:57 +00:00
freelook_speed = EditorSettings : : get_singleton ( ) - > get ( " editors/3d/freelook/freelook_base_speed " ) ;
2014-10-03 03:10:51 +00:00
2017-03-05 15:44:50 +00:00
selection_menu = memnew ( PopupMenu ) ;
2015-11-04 21:39:07 +00:00
add_child ( selection_menu ) ;
2017-08-04 13:46:22 +00:00
selection_menu - > set_custom_minimum_size ( Size2 ( 100 , 0 ) * EDSCALE ) ;
2017-01-08 21:18:54 +00:00
selection_menu - > connect ( " id_pressed " , this , " _selection_result_pressed " ) ;
2015-11-04 21:39:07 +00:00
selection_menu - > connect ( " popup_hide " , this , " _selection_menu_hide " ) ;
2017-03-05 15:44:50 +00:00
if ( p_index = = 0 ) {
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_AUDIO_LISTENER ) , true ) ;
2014-10-03 03:10:51 +00:00
viewport - > set_as_audio_listener ( true ) ;
}
2017-08-04 13:46:22 +00:00
name = " " ;
2015-03-21 20:47:21 +00:00
_update_name ( ) ;
2017-03-05 15:44:50 +00:00
EditorSettings : : get_singleton ( ) - > connect ( " settings_changed " , this , " update_transform_gizmo_view " ) ;
2014-02-10 01:10:30 +00:00
}
2017-06-11 14:29:27 +00:00
//////////////////////////////////////////////////////////////
void SpatialEditorViewportContainer : : _gui_input ( const Ref < InputEvent > & p_event ) {
Ref < InputEventMouseButton > mb = p_event ;
2018-08-25 06:47:04 +00:00
if ( mb . is_valid ( ) & & mb - > get_button_index ( ) = = BUTTON_LEFT ) {
2017-06-11 14:29:27 +00:00
2018-08-25 06:47:04 +00:00
if ( mb - > is_pressed ( ) ) {
Vector2 size = get_size ( ) ;
2017-06-11 14:29:27 +00:00
2018-08-25 06:47:04 +00:00
int h_sep = get_constant ( " separation " , " HSplitContainer " ) ;
int v_sep = get_constant ( " separation " , " VSplitContainer " ) ;
2017-06-11 14:29:27 +00:00
2018-08-25 06:47:04 +00:00
int mid_w = size . width * ratio_h ;
int mid_h = size . height * ratio_v ;
2017-06-11 14:29:27 +00:00
2018-08-25 06:47:04 +00:00
dragging_h = mb - > get_position ( ) . x > ( mid_w - h_sep / 2 ) & & mb - > get_position ( ) . x < ( mid_w + h_sep / 2 ) ;
dragging_v = mb - > get_position ( ) . y > ( mid_h - v_sep / 2 ) & & mb - > get_position ( ) . y < ( mid_h + v_sep / 2 ) ;
2017-06-11 14:29:27 +00:00
2018-08-25 06:47:04 +00:00
drag_begin_pos = mb - > get_position ( ) ;
drag_begin_ratio . x = ratio_h ;
drag_begin_ratio . y = ratio_v ;
2017-06-11 14:29:27 +00:00
2018-08-25 06:47:04 +00:00
switch ( view ) {
case VIEW_USE_1_VIEWPORT : {
2017-06-11 14:29:27 +00:00
2018-08-25 06:47:04 +00:00
dragging_h = false ;
dragging_v = false ;
2017-06-11 14:29:27 +00:00
2018-08-25 06:47:04 +00:00
} break ;
case VIEW_USE_2_VIEWPORTS : {
2017-06-11 14:29:27 +00:00
2018-08-25 06:47:04 +00:00
dragging_h = false ;
2017-06-11 14:29:27 +00:00
2018-08-25 06:47:04 +00:00
} break ;
case VIEW_USE_2_VIEWPORTS_ALT : {
2017-06-11 14:29:27 +00:00
dragging_v = false ;
2018-08-25 06:47:04 +00:00
} break ;
case VIEW_USE_3_VIEWPORTS :
case VIEW_USE_3_VIEWPORTS_ALT :
case VIEW_USE_4_VIEWPORTS : {
2017-06-11 14:29:27 +00:00
2018-08-25 06:47:04 +00:00
// Do nothing.
2017-06-11 14:29:27 +00:00
2018-08-25 06:47:04 +00:00
} break ;
}
} else {
dragging_h = false ;
dragging_v = false ;
2017-06-11 14:29:27 +00:00
}
}
Ref < InputEventMouseMotion > mm = p_event ;
2018-08-25 06:47:04 +00:00
if ( mm . is_valid ( ) ) {
if ( view = = VIEW_USE_3_VIEWPORTS | | view = = VIEW_USE_3_VIEWPORTS_ALT | | view = = VIEW_USE_4_VIEWPORTS ) {
Vector2 size = get_size ( ) ;
int h_sep = get_constant ( " separation " , " HSplitContainer " ) ;
int v_sep = get_constant ( " separation " , " VSplitContainer " ) ;
int mid_w = size . width * ratio_h ;
int mid_h = size . height * ratio_v ;
bool was_hovering_h = hovering_h ;
bool was_hovering_v = hovering_v ;
hovering_h = mm - > get_position ( ) . x > ( mid_w - h_sep / 2 ) & & mm - > get_position ( ) . x < ( mid_w + h_sep / 2 ) ;
hovering_v = mm - > get_position ( ) . y > ( mid_h - v_sep / 2 ) & & mm - > get_position ( ) . y < ( mid_h + v_sep / 2 ) ;
if ( was_hovering_h ! = hovering_h | | was_hovering_v ! = hovering_v ) {
update ( ) ;
}
}
2017-06-11 14:29:27 +00:00
if ( dragging_h ) {
float new_ratio = drag_begin_ratio . x + ( mm - > get_position ( ) . x - drag_begin_pos . x ) / get_size ( ) . width ;
new_ratio = CLAMP ( new_ratio , 40 / get_size ( ) . width , ( get_size ( ) . width - 40 ) / get_size ( ) . width ) ;
ratio_h = new_ratio ;
queue_sort ( ) ;
update ( ) ;
}
if ( dragging_v ) {
float new_ratio = drag_begin_ratio . y + ( mm - > get_position ( ) . y - drag_begin_pos . y ) / get_size ( ) . height ;
new_ratio = CLAMP ( new_ratio , 40 / get_size ( ) . height , ( get_size ( ) . height - 40 ) / get_size ( ) . height ) ;
ratio_v = new_ratio ;
queue_sort ( ) ;
update ( ) ;
}
}
}
void SpatialEditorViewportContainer : : _notification ( int p_what ) {
if ( p_what = = NOTIFICATION_MOUSE_ENTER | | p_what = = NOTIFICATION_MOUSE_EXIT ) {
mouseover = ( p_what = = NOTIFICATION_MOUSE_ENTER ) ;
update ( ) ;
}
if ( p_what = = NOTIFICATION_DRAW & & mouseover ) {
Ref < Texture > h_grabber = get_icon ( " grabber " , " HSplitContainer " ) ;
Ref < Texture > v_grabber = get_icon ( " grabber " , " VSplitContainer " ) ;
2018-08-25 06:47:04 +00:00
Ref < Texture > hdiag_grabber = get_icon ( " GuiViewportHdiagsplitter " , " EditorIcons " ) ;
Ref < Texture > vdiag_grabber = get_icon ( " GuiViewportVdiagsplitter " , " EditorIcons " ) ;
Ref < Texture > vh_grabber = get_icon ( " GuiViewportVhsplitter " , " EditorIcons " ) ;
2017-06-11 14:29:27 +00:00
Vector2 size = get_size ( ) ;
int h_sep = get_constant ( " separation " , " HSplitContainer " ) ;
int v_sep = get_constant ( " separation " , " VSplitContainer " ) ;
int mid_w = size . width * ratio_h ;
int mid_h = size . height * ratio_v ;
int size_left = mid_w - h_sep / 2 ;
int size_bottom = size . height - mid_h - v_sep / 2 ;
switch ( view ) {
case VIEW_USE_1_VIEWPORT : {
2018-08-25 06:47:04 +00:00
// Nothing to show.
2017-06-11 14:29:27 +00:00
} break ;
case VIEW_USE_2_VIEWPORTS : {
draw_texture ( v_grabber , Vector2 ( ( size . width - v_grabber - > get_width ( ) ) / 2 , mid_h - v_grabber - > get_height ( ) / 2 ) ) ;
2018-08-25 06:47:04 +00:00
set_default_cursor_shape ( CURSOR_VSPLIT ) ;
2017-06-11 14:29:27 +00:00
} break ;
case VIEW_USE_2_VIEWPORTS_ALT : {
draw_texture ( h_grabber , Vector2 ( mid_w - h_grabber - > get_width ( ) / 2 , ( size . height - h_grabber - > get_height ( ) ) / 2 ) ) ;
2018-08-25 06:47:04 +00:00
set_default_cursor_shape ( CURSOR_HSPLIT ) ;
2017-06-11 14:29:27 +00:00
} break ;
case VIEW_USE_3_VIEWPORTS : {
2018-08-25 06:47:04 +00:00
if ( ( hovering_v & & hovering_h & & ! dragging_v & & ! dragging_h ) | | ( dragging_v & & dragging_h ) ) {
draw_texture ( hdiag_grabber , Vector2 ( mid_w - hdiag_grabber - > get_width ( ) / 2 , mid_h - v_grabber - > get_height ( ) / 4 ) ) ;
set_default_cursor_shape ( CURSOR_DRAG ) ;
} else if ( ( hovering_v & & ! dragging_h ) | | dragging_v ) {
draw_texture ( v_grabber , Vector2 ( ( size . width - v_grabber - > get_width ( ) ) / 2 , mid_h - v_grabber - > get_height ( ) / 2 ) ) ;
set_default_cursor_shape ( CURSOR_VSPLIT ) ;
} else if ( hovering_h | | dragging_h ) {
draw_texture ( h_grabber , Vector2 ( mid_w - h_grabber - > get_width ( ) / 2 , mid_h + v_grabber - > get_height ( ) / 2 + ( size_bottom - h_grabber - > get_height ( ) ) / 2 ) ) ;
set_default_cursor_shape ( CURSOR_HSPLIT ) ;
}
2017-06-11 14:29:27 +00:00
} break ;
case VIEW_USE_3_VIEWPORTS_ALT : {
2018-08-25 06:47:04 +00:00
if ( ( hovering_v & & hovering_h & & ! dragging_v & & ! dragging_h ) | | ( dragging_v & & dragging_h ) ) {
draw_texture ( vdiag_grabber , Vector2 ( mid_w - vdiag_grabber - > get_width ( ) + v_grabber - > get_height ( ) / 4 , mid_h - vdiag_grabber - > get_height ( ) / 2 ) ) ;
set_default_cursor_shape ( CURSOR_DRAG ) ;
} else if ( ( hovering_v & & ! dragging_h ) | | dragging_v ) {
draw_texture ( v_grabber , Vector2 ( ( size_left - v_grabber - > get_width ( ) ) / 2 , mid_h - v_grabber - > get_height ( ) / 2 ) ) ;
set_default_cursor_shape ( CURSOR_VSPLIT ) ;
} else if ( hovering_h | | dragging_h ) {
draw_texture ( h_grabber , Vector2 ( mid_w - h_grabber - > get_width ( ) / 2 , ( size . height - h_grabber - > get_height ( ) ) / 2 ) ) ;
set_default_cursor_shape ( CURSOR_HSPLIT ) ;
}
2017-06-11 14:29:27 +00:00
} break ;
case VIEW_USE_4_VIEWPORTS : {
Vector2 half ( mid_w , mid_h ) ;
2018-08-25 06:47:04 +00:00
if ( ( hovering_v & & hovering_h & & ! dragging_v & & ! dragging_h ) | | ( dragging_v & & dragging_h ) ) {
draw_texture ( vh_grabber , half - vh_grabber - > get_size ( ) / 2.0 ) ;
set_default_cursor_shape ( CURSOR_DRAG ) ;
} else if ( ( hovering_v & & ! dragging_h ) | | dragging_v ) {
draw_texture ( v_grabber , half - v_grabber - > get_size ( ) / 2.0 ) ;
set_default_cursor_shape ( CURSOR_VSPLIT ) ;
} else if ( hovering_h | | dragging_h ) {
draw_texture ( h_grabber , half - h_grabber - > get_size ( ) / 2.0 ) ;
set_default_cursor_shape ( CURSOR_HSPLIT ) ;
}
2017-06-11 14:29:27 +00:00
} break ;
}
}
if ( p_what = = NOTIFICATION_SORT_CHILDREN ) {
SpatialEditorViewport * viewports [ 4 ] ;
int vc = 0 ;
for ( int i = 0 ; i < get_child_count ( ) ; i + + ) {
2017-08-24 20:58:51 +00:00
viewports [ vc ] = Object : : cast_to < SpatialEditorViewport > ( get_child ( i ) ) ;
2017-06-11 14:29:27 +00:00
if ( viewports [ vc ] ) {
vc + + ;
}
}
ERR_FAIL_COND ( vc ! = 4 ) ;
Size2 size = get_size ( ) ;
if ( size . x < 10 | | size . y < 10 ) {
for ( int i = 0 ; i < 4 ; i + + ) {
viewports [ i ] - > hide ( ) ;
}
return ;
}
int h_sep = get_constant ( " separation " , " HSplitContainer " ) ;
int v_sep = get_constant ( " separation " , " VSplitContainer " ) ;
int mid_w = size . width * ratio_h ;
int mid_h = size . height * ratio_v ;
int size_left = mid_w - h_sep / 2 ;
int size_right = size . width - mid_w - h_sep / 2 ;
int size_top = mid_h - v_sep / 2 ;
int size_bottom = size . height - mid_h - v_sep / 2 ;
switch ( view ) {
case VIEW_USE_1_VIEWPORT : {
2018-09-30 17:09:31 +00:00
viewports [ 0 ] - > show ( ) ;
2017-06-11 14:29:27 +00:00
for ( int i = 1 ; i < 4 ; i + + ) {
viewports [ i ] - > hide ( ) ;
}
fit_child_in_rect ( viewports [ 0 ] , Rect2 ( Vector2 ( ) , size ) ) ;
} break ;
case VIEW_USE_2_VIEWPORTS : {
2018-09-30 17:09:31 +00:00
for ( int i = 0 ; i < 4 ; i + + ) {
2017-06-11 14:29:27 +00:00
if ( i = = 1 | | i = = 3 )
viewports [ i ] - > hide ( ) ;
else
viewports [ i ] - > show ( ) ;
}
fit_child_in_rect ( viewports [ 0 ] , Rect2 ( Vector2 ( ) , Vector2 ( size . width , size_top ) ) ) ;
fit_child_in_rect ( viewports [ 2 ] , Rect2 ( Vector2 ( 0 , mid_h + v_sep / 2 ) , Vector2 ( size . width , size_bottom ) ) ) ;
} break ;
case VIEW_USE_2_VIEWPORTS_ALT : {
2018-09-30 17:09:31 +00:00
for ( int i = 0 ; i < 4 ; i + + ) {
2017-06-11 14:29:27 +00:00
if ( i = = 1 | | i = = 3 )
viewports [ i ] - > hide ( ) ;
else
viewports [ i ] - > show ( ) ;
}
fit_child_in_rect ( viewports [ 0 ] , Rect2 ( Vector2 ( ) , Vector2 ( size_left , size . height ) ) ) ;
fit_child_in_rect ( viewports [ 2 ] , Rect2 ( Vector2 ( mid_w + h_sep / 2 , 0 ) , Vector2 ( size_right , size . height ) ) ) ;
} break ;
case VIEW_USE_3_VIEWPORTS : {
2018-09-30 17:09:31 +00:00
for ( int i = 0 ; i < 4 ; i + + ) {
2017-06-11 14:29:27 +00:00
if ( i = = 1 )
viewports [ i ] - > hide ( ) ;
else
viewports [ i ] - > show ( ) ;
}
fit_child_in_rect ( viewports [ 0 ] , Rect2 ( Vector2 ( ) , Vector2 ( size . width , size_top ) ) ) ;
fit_child_in_rect ( viewports [ 2 ] , Rect2 ( Vector2 ( 0 , mid_h + v_sep / 2 ) , Vector2 ( size_left , size_bottom ) ) ) ;
fit_child_in_rect ( viewports [ 3 ] , Rect2 ( Vector2 ( mid_w + h_sep / 2 , mid_h + v_sep / 2 ) , Vector2 ( size_right , size_bottom ) ) ) ;
} break ;
case VIEW_USE_3_VIEWPORTS_ALT : {
2018-09-30 17:09:31 +00:00
for ( int i = 0 ; i < 4 ; i + + ) {
2017-06-11 14:29:27 +00:00
if ( i = = 1 )
viewports [ i ] - > hide ( ) ;
else
viewports [ i ] - > show ( ) ;
}
fit_child_in_rect ( viewports [ 0 ] , Rect2 ( Vector2 ( ) , Vector2 ( size_left , size_top ) ) ) ;
fit_child_in_rect ( viewports [ 2 ] , Rect2 ( Vector2 ( 0 , mid_h + v_sep / 2 ) , Vector2 ( size_left , size_bottom ) ) ) ;
fit_child_in_rect ( viewports [ 3 ] , Rect2 ( Vector2 ( mid_w + h_sep / 2 , 0 ) , Vector2 ( size_right , size . height ) ) ) ;
} break ;
case VIEW_USE_4_VIEWPORTS : {
2018-09-30 17:09:31 +00:00
for ( int i = 0 ; i < 4 ; i + + ) {
2017-06-11 14:29:27 +00:00
viewports [ i ] - > show ( ) ;
}
fit_child_in_rect ( viewports [ 0 ] , Rect2 ( Vector2 ( ) , Vector2 ( size_left , size_top ) ) ) ;
fit_child_in_rect ( viewports [ 1 ] , Rect2 ( Vector2 ( mid_w + h_sep / 2 , 0 ) , Vector2 ( size_right , size_top ) ) ) ;
fit_child_in_rect ( viewports [ 2 ] , Rect2 ( Vector2 ( 0 , mid_h + v_sep / 2 ) , Vector2 ( size_left , size_bottom ) ) ) ;
fit_child_in_rect ( viewports [ 3 ] , Rect2 ( Vector2 ( mid_w + h_sep / 2 , mid_h + v_sep / 2 ) , Vector2 ( size_right , size_bottom ) ) ) ;
} break ;
}
}
}
void SpatialEditorViewportContainer : : set_view ( View p_view ) {
view = p_view ;
queue_sort ( ) ;
}
SpatialEditorViewportContainer : : View SpatialEditorViewportContainer : : get_view ( ) {
return view ;
}
void SpatialEditorViewportContainer : : _bind_methods ( ) {
ClassDB : : bind_method ( " _gui_input " , & SpatialEditorViewportContainer : : _gui_input ) ;
}
SpatialEditorViewportContainer : : SpatialEditorViewportContainer ( ) {
2018-08-25 06:47:04 +00:00
set_clip_contents ( true ) ;
2017-06-11 14:29:27 +00:00
view = VIEW_USE_1_VIEWPORT ;
mouseover = false ;
ratio_h = 0.5 ;
ratio_v = 0.5 ;
2018-08-25 06:47:04 +00:00
hovering_v = false ;
hovering_h = false ;
2017-06-11 14:29:27 +00:00
dragging_v = false ;
dragging_h = false ;
}
///////////////////////////////////////////////////////////////////
2017-03-05 15:44:50 +00:00
SpatialEditor * SpatialEditor : : singleton = NULL ;
2014-02-10 01:10:30 +00:00
SpatialEditorSelectedItem : : ~ SpatialEditorSelectedItem ( ) {
if ( sbox_instance . is_valid ( ) )
VisualServer : : get_singleton ( ) - > free ( sbox_instance ) ;
}
2017-04-06 15:35:08 +00:00
void SpatialEditor : : select_gizmo_highlight_axis ( int p_axis ) {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < 3 ; i + + ) {
2014-02-10 01:10:30 +00:00
2019-08-01 12:23:29 +00:00
move_gizmo [ i ] - > surface_set_material ( 0 , i = = p_axis ? gizmo_color_hl [ i ] : gizmo_color [ i ] ) ;
move_plane_gizmo [ i ] - > surface_set_material ( 0 , ( i + 6 ) = = p_axis ? plane_gizmo_color_hl [ i ] : plane_gizmo_color [ i ] ) ;
rotate_gizmo [ i ] - > surface_set_material ( 0 , ( i + 3 ) = = p_axis ? gizmo_color_hl [ i ] : gizmo_color [ i ] ) ;
scale_gizmo [ i ] - > surface_set_material ( 0 , ( i + 9 ) = = p_axis ? gizmo_color_hl [ i ] : gizmo_color [ i ] ) ;
scale_plane_gizmo [ i ] - > surface_set_material ( 0 , ( i + 12 ) = = p_axis ? plane_gizmo_color_hl [ i ] : plane_gizmo_color [ i ] ) ;
2014-02-10 01:10:30 +00:00
}
}
void SpatialEditor : : update_transform_gizmo ( ) {
2017-03-05 15:44:50 +00:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
2017-11-17 02:09:00 +00:00
AABB center ;
2017-03-05 15:44:50 +00:00
bool first = true ;
2014-02-10 01:10:30 +00:00
2017-01-11 03:52:51 +00:00
Basis gizmo_basis ;
2017-09-21 21:11:56 +00:00
bool local_gizmo_coords = are_local_coords_enabled ( ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 01:10:30 +00:00
2017-08-24 20:58:51 +00:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
2014-02-10 01:10:30 +00:00
if ( ! sp )
continue ;
2017-03-05 15:44:50 +00:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
2014-02-10 01:10:30 +00:00
if ( ! se )
continue ;
2017-10-03 16:49:32 +00:00
Transform xf = se - > sp - > get_global_gizmo_transform ( ) ;
2014-02-10 01:10:30 +00:00
if ( first ) {
2017-06-06 18:33:51 +00:00
center . position = xf . origin ;
2017-03-05 15:44:50 +00:00
first = false ;
2014-02-10 01:10:30 +00:00
if ( local_gizmo_coords ) {
2017-03-05 15:44:50 +00:00
gizmo_basis = xf . basis ;
2014-02-10 01:10:30 +00:00
gizmo_basis . orthonormalize ( ) ;
}
} else {
center . expand_to ( xf . origin ) ;
2017-03-05 15:44:50 +00:00
gizmo_basis = Basis ( ) ;
2014-02-10 01:10:30 +00:00
}
}
2017-06-06 18:33:51 +00:00
Vector3 pcenter = center . position + center . size * 0.5 ;
2017-03-05 15:44:50 +00:00
gizmo . visible = ! first ;
gizmo . transform . origin = pcenter ;
gizmo . transform . basis = gizmo_basis ;
2014-02-10 01:10:30 +00:00
2017-08-31 21:30:35 +00:00
for ( uint32_t i = 0 ; i < VIEWPORTS_COUNT ; i + + ) {
2014-05-05 01:50:23 +00:00
viewports [ i ] - > update_transform_gizmo_view ( ) ;
}
2014-02-10 01:10:30 +00:00
}
2017-11-22 21:29:27 +00:00
void _update_all_gizmos ( Node * p_node ) {
for ( int i = p_node - > get_child_count ( ) - 1 ; 0 < = i ; - - i ) {
Spatial * spatial_node = Object : : cast_to < Spatial > ( p_node - > get_child ( i ) ) ;
if ( spatial_node ) {
spatial_node - > update_gizmo ( ) ;
}
_update_all_gizmos ( p_node - > get_child ( i ) ) ;
}
}
2018-09-02 20:31:03 +00:00
void SpatialEditor : : update_all_gizmos ( Node * p_node ) {
2019-09-03 10:42:34 +00:00
if ( ! p_node ) {
p_node = SceneTree : : get_singleton ( ) - > get_root ( ) ;
}
2018-09-02 20:31:03 +00:00
_update_all_gizmos ( p_node ) ;
2017-11-22 21:29:27 +00:00
}
2014-02-10 01:10:30 +00:00
Object * SpatialEditor : : _get_editor_data ( Object * p_what ) {
2017-08-24 20:58:51 +00:00
Spatial * sp = Object : : cast_to < Spatial > ( p_what ) ;
2014-02-10 01:10:30 +00:00
if ( ! sp )
return NULL ;
2017-03-05 15:44:50 +00:00
SpatialEditorSelectedItem * si = memnew ( SpatialEditorSelectedItem ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
si - > sp = sp ;
si - > sbox_instance = VisualServer : : get_singleton ( ) - > instance_create2 ( selection_box - > get_rid ( ) , sp - > get_world ( ) - > get_scenario ( ) ) ;
2016-03-07 23:00:55 +00:00
VS : : get_singleton ( ) - > instance_geometry_set_cast_shadows_setting ( si - > sbox_instance , VS : : SHADOW_CASTING_SETTING_OFF ) ;
2014-02-10 01:10:30 +00:00
return si ;
}
void SpatialEditor : : _generate_selection_box ( ) {
2017-11-17 02:09:00 +00:00
AABB aabb ( Vector3 ( ) , Vector3 ( 1 , 1 , 1 ) ) ;
2017-03-05 15:44:50 +00:00
aabb . grow_by ( aabb . get_longest_axis_size ( ) / 20.0 ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
Ref < SurfaceTool > st = memnew ( SurfaceTool ) ;
2016-03-08 23:00:52 +00:00
2014-02-10 01:10:30 +00:00
st - > begin ( Mesh : : PRIMITIVE_LINES ) ;
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < 12 ; i + + ) {
2016-03-08 23:00:52 +00:00
2017-03-05 15:44:50 +00:00
Vector3 a , b ;
aabb . get_edge ( i , a , b ) ;
2016-03-08 23:00:52 +00:00
2017-03-05 15:44:50 +00:00
st - > add_color ( Color ( 1.0 , 1.0 , 0.8 , 0.8 ) ) ;
2014-02-10 01:10:30 +00:00
st - > add_vertex ( a ) ;
2017-03-05 15:44:50 +00:00
st - > add_color ( Color ( 1.0 , 1.0 , 0.8 , 0.4 ) ) ;
st - > add_vertex ( a . linear_interpolate ( b , 0.2 ) ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
st - > add_color ( Color ( 1.0 , 1.0 , 0.8 , 0.4 ) ) ;
st - > add_vertex ( a . linear_interpolate ( b , 0.8 ) ) ;
st - > add_color ( Color ( 1.0 , 1.0 , 0.8 , 0.8 ) ) ;
2014-02-10 01:10:30 +00:00
st - > add_vertex ( b ) ;
}
2017-04-07 02:36:37 +00:00
Ref < SpatialMaterial > mat = memnew ( SpatialMaterial ) ;
mat - > set_flag ( SpatialMaterial : : FLAG_UNSHADED , true ) ;
2017-03-05 15:44:50 +00:00
mat - > set_albedo ( Color ( 1 , 1 , 1 ) ) ;
2017-04-07 02:36:37 +00:00
mat - > set_feature ( SpatialMaterial : : FEATURE_TRANSPARENT , true ) ;
mat - > set_flag ( SpatialMaterial : : FLAG_ALBEDO_FROM_VERTEX_COLOR , true ) ;
mat - > set_flag ( SpatialMaterial : : FLAG_SRGB_VERTEX_COLOR , true ) ;
2014-02-10 01:10:30 +00:00
st - > set_material ( mat ) ;
selection_box = st - > commit ( ) ;
}
Dictionary SpatialEditor : : get_state ( ) const {
Dictionary d ;
2017-03-05 15:44:50 +00:00
d [ " snap_enabled " ] = snap_enabled ;
d [ " translate_snap " ] = get_translate_snap ( ) ;
d [ " rotate_snap " ] = get_rotate_snap ( ) ;
d [ " scale_snap " ] = get_scale_snap ( ) ;
2017-11-18 18:51:37 +00:00
d [ " local_coords " ] = tool_option_button [ TOOL_OPT_LOCAL_COORDS ] - > is_pressed ( ) ;
2017-03-05 15:44:50 +00:00
int vc = 0 ;
if ( view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_1_VIEWPORT ) ) )
vc = 1 ;
else if ( view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_2_VIEWPORTS ) ) )
vc = 2 ;
else if ( view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_3_VIEWPORTS ) ) )
vc = 3 ;
else if ( view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_4_VIEWPORTS ) ) )
vc = 4 ;
else if ( view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_2_VIEWPORTS_ALT ) ) )
vc = 5 ;
else if ( view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_3_VIEWPORTS_ALT ) ) )
vc = 6 ;
d [ " viewport_mode " ] = vc ;
2014-02-10 01:10:30 +00:00
Array vpdata ;
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < 4 ; i + + ) {
vpdata . push_back ( viewports [ i ] - > get_state ( ) ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-05 15:44:50 +00:00
d [ " viewports " ] = vpdata ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
d [ " show_grid " ] = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_GRID ) ) ;
d [ " show_origin " ] = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_ORIGIN ) ) ;
d [ " fov " ] = get_fov ( ) ;
d [ " znear " ] = get_znear ( ) ;
d [ " zfar " ] = get_zfar ( ) ;
2014-02-10 01:10:30 +00:00
2018-07-24 22:08:49 +00:00
Dictionary gizmos_status ;
2019-03-11 23:30:50 +00:00
for ( int i = 0 ; i < gizmo_plugins_by_name . size ( ) ; i + + ) {
if ( ! gizmo_plugins_by_name [ i ] - > can_be_hidden ( ) ) continue ;
2018-08-11 21:07:00 +00:00
int state = gizmos_menu - > get_item_state ( gizmos_menu - > get_item_index ( i ) ) ;
2019-03-11 23:30:50 +00:00
String name = gizmo_plugins_by_name [ i ] - > get_name ( ) ;
2018-08-11 21:07:00 +00:00
gizmos_status [ name ] = state ;
2018-07-24 22:08:49 +00:00
}
d [ " gizmos_status " ] = gizmos_status ;
2014-02-10 01:10:30 +00:00
return d ;
}
2017-03-05 15:44:50 +00:00
void SpatialEditor : : set_state ( const Dictionary & p_state ) {
2014-02-10 01:10:30 +00:00
Dictionary d = p_state ;
2016-01-10 20:59:12 +00:00
if ( d . has ( " snap_enabled " ) ) {
2017-03-05 15:44:50 +00:00
snap_enabled = d [ " snap_enabled " ] ;
2018-01-10 20:22:49 +00:00
tool_option_button [ TOOL_OPT_USE_SNAP ] - > set_pressed ( d [ " snap_enabled " ] ) ;
2016-01-10 20:59:12 +00:00
}
if ( d . has ( " translate_snap " ) )
2020-03-08 19:31:11 +00:00
snap_translate_value = d [ " translate_snap " ] ;
2016-01-10 20:59:12 +00:00
if ( d . has ( " rotate_snap " ) )
2020-03-08 19:31:11 +00:00
snap_rotate_value = d [ " rotate_snap " ] ;
2016-01-10 20:59:12 +00:00
if ( d . has ( " scale_snap " ) )
2020-03-08 19:31:11 +00:00
snap_scale_value = d [ " scale_snap " ] ;
_snap_update ( ) ;
2016-01-10 20:59:12 +00:00
if ( d . has ( " local_coords " ) ) {
2017-11-18 18:51:37 +00:00
tool_option_button [ TOOL_OPT_LOCAL_COORDS ] - > set_pressed ( d [ " local_coords " ] ) ;
2016-01-10 20:59:12 +00:00
update_transform_gizmo ( ) ;
}
2016-01-11 13:35:11 +00:00
if ( d . has ( " viewport_mode " ) ) {
int vc = d [ " viewport_mode " ] ;
2017-03-05 15:44:50 +00:00
if ( vc = = 1 )
2016-01-11 13:35:11 +00:00
_menu_item_pressed ( MENU_VIEW_USE_1_VIEWPORT ) ;
2017-03-05 15:44:50 +00:00
else if ( vc = = 2 )
2016-01-11 13:35:11 +00:00
_menu_item_pressed ( MENU_VIEW_USE_2_VIEWPORTS ) ;
2017-03-05 15:44:50 +00:00
else if ( vc = = 3 )
2016-01-11 13:35:11 +00:00
_menu_item_pressed ( MENU_VIEW_USE_3_VIEWPORTS ) ;
2017-03-05 15:44:50 +00:00
else if ( vc = = 4 )
2016-01-11 13:35:11 +00:00
_menu_item_pressed ( MENU_VIEW_USE_4_VIEWPORTS ) ;
2017-03-05 15:44:50 +00:00
else if ( vc = = 5 )
2016-01-11 13:35:11 +00:00
_menu_item_pressed ( MENU_VIEW_USE_2_VIEWPORTS_ALT ) ;
2017-03-05 15:44:50 +00:00
else if ( vc = = 6 )
2016-01-11 13:35:11 +00:00
_menu_item_pressed ( MENU_VIEW_USE_3_VIEWPORTS_ALT ) ;
}
2014-02-10 01:10:30 +00:00
2016-01-11 13:35:11 +00:00
if ( d . has ( " viewports " ) ) {
Array vp = d [ " viewports " ] ;
2019-03-12 02:17:30 +00:00
uint32_t vp_size = static_cast < uint32_t > ( vp . size ( ) ) ;
if ( vp_size > VIEWPORTS_COUNT ) {
2019-06-11 12:49:34 +00:00
WARN_PRINT ( " Ignoring superfluous viewport settings from spatial editor state. " ) ;
2019-03-12 02:17:30 +00:00
vp_size = VIEWPORTS_COUNT ;
}
2014-02-10 01:10:30 +00:00
2019-03-12 02:17:30 +00:00
for ( uint32_t i = 0 ; i < vp_size ; i + + ) {
2016-01-11 13:35:11 +00:00
viewports [ i ] - > set_state ( vp [ i ] ) ;
}
2014-02-10 01:10:30 +00:00
}
if ( d . has ( " zfar " ) )
2017-01-04 04:16:14 +00:00
settings_zfar - > set_value ( float ( d [ " zfar " ] ) ) ;
2014-02-10 01:10:30 +00:00
if ( d . has ( " znear " ) )
2017-01-04 04:16:14 +00:00
settings_znear - > set_value ( float ( d [ " znear " ] ) ) ;
2014-02-10 01:10:30 +00:00
if ( d . has ( " fov " ) )
2017-01-04 04:16:14 +00:00
settings_fov - > set_value ( float ( d [ " fov " ] ) ) ;
2014-02-10 01:10:30 +00:00
if ( d . has ( " show_grid " ) ) {
bool use = d [ " show_grid " ] ;
2017-03-05 15:44:50 +00:00
if ( use ! = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_GRID ) ) ) {
2014-07-15 07:06:55 +00:00
_menu_item_pressed ( MENU_VIEW_GRID ) ;
2014-02-10 01:10:30 +00:00
}
}
if ( d . has ( " show_origin " ) ) {
bool use = d [ " show_origin " ] ;
2017-03-05 15:44:50 +00:00
if ( use ! = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_ORIGIN ) ) ) {
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_ORIGIN ) , use ) ;
VisualServer : : get_singleton ( ) - > instance_set_visible ( origin_instance , use ) ;
2014-02-10 01:10:30 +00:00
}
}
2018-07-24 22:08:49 +00:00
if ( d . has ( " gizmos_status " ) ) {
Dictionary gizmos_status = d [ " gizmos_status " ] ;
List < Variant > keys ;
gizmos_status . get_key_list ( & keys ) ;
2019-03-11 23:30:50 +00:00
for ( int j = 0 ; j < gizmo_plugins_by_name . size ( ) ; + + j ) {
if ( ! gizmo_plugins_by_name [ j ] - > can_be_hidden ( ) ) continue ;
int state = EditorSpatialGizmoPlugin : : VISIBLE ;
2018-09-26 15:38:02 +00:00
for ( int i = 0 ; i < keys . size ( ) ; i + + ) {
2019-03-11 23:30:50 +00:00
if ( gizmo_plugins_by_name . write [ j ] - > get_name ( ) = = keys [ i ] ) {
2018-08-11 21:07:00 +00:00
state = gizmos_status [ keys [ i ] ] ;
2019-03-11 23:30:50 +00:00
break ;
2018-07-24 22:08:49 +00:00
}
}
2018-08-11 21:07:00 +00:00
2019-03-11 23:30:50 +00:00
gizmo_plugins_by_name . write [ j ] - > set_state ( state ) ;
2018-07-24 22:08:49 +00:00
}
2019-03-11 23:30:50 +00:00
_update_gizmos_menu ( ) ;
2018-07-24 22:08:49 +00:00
}
2014-02-10 01:10:30 +00:00
}
void SpatialEditor : : edit ( Spatial * p_spatial ) {
2016-03-08 23:00:52 +00:00
2017-03-05 15:44:50 +00:00
if ( p_spatial ! = selected ) {
2014-05-05 01:50:23 +00:00
if ( selected ) {
2018-07-24 22:08:49 +00:00
Ref < EditorSpatialGizmo > seg = selected - > get_gizmo ( ) ;
2014-05-05 01:50:23 +00:00
if ( seg . is_valid ( ) ) {
seg - > set_selected ( false ) ;
selected - > update_gizmo ( ) ;
}
}
2017-03-05 15:44:50 +00:00
selected = p_spatial ;
over_gizmo_handle = - 1 ;
2014-05-05 01:50:23 +00:00
if ( selected ) {
2018-07-24 22:08:49 +00:00
Ref < EditorSpatialGizmo > seg = selected - > get_gizmo ( ) ;
2014-05-05 01:50:23 +00:00
if ( seg . is_valid ( ) ) {
seg - > set_selected ( true ) ;
selected - > update_gizmo ( ) ;
}
}
}
2014-02-10 01:10:30 +00:00
}
2020-03-08 19:31:11 +00:00
void SpatialEditor : : _snap_changed ( ) {
snap_translate_value = snap_translate - > get_text ( ) . to_double ( ) ;
snap_rotate_value = snap_rotate - > get_text ( ) . to_double ( ) ;
snap_scale_value = snap_scale - > get_text ( ) . to_double ( ) ;
}
void SpatialEditor : : _snap_update ( ) {
snap_translate - > set_text ( String : : num ( snap_translate_value ) ) ;
snap_rotate - > set_text ( String : : num ( snap_rotate_value ) ) ;
snap_scale - > set_text ( String : : num ( snap_scale_value ) ) ;
}
2014-02-10 01:10:30 +00:00
void SpatialEditor : : _xform_dialog_action ( ) {
Transform t ;
//translation
Vector3 scale ;
Vector3 rotate ;
Vector3 translate ;
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < 3 ; i + + ) {
translate [ i ] = xform_translate [ i ] - > get_text ( ) . to_double ( ) ;
rotate [ i ] = Math : : deg2rad ( xform_rotate [ i ] - > get_text ( ) . to_double ( ) ) ;
scale [ i ] = xform_scale [ i ] - > get_text ( ) . to_double ( ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-05 15:44:50 +00:00
2017-01-05 17:31:39 +00:00
t . basis . scale ( scale ) ;
t . basis . rotate ( rotate ) ;
2017-03-05 15:44:50 +00:00
t . origin = translate ;
2014-02-10 01:10:30 +00:00
2016-05-04 01:25:37 +00:00
undo_redo - > create_action ( TTR ( " XForm Dialog " ) ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 01:10:30 +00:00
2017-08-24 20:58:51 +00:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
2014-02-10 01:10:30 +00:00
if ( ! sp )
continue ;
2017-03-05 15:44:50 +00:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
2014-02-10 01:10:30 +00:00
if ( ! se )
continue ;
2017-03-05 15:44:50 +00:00
bool post = xform_type - > get_selected ( ) > 0 ;
2014-02-10 01:10:30 +00:00
2017-10-03 16:49:32 +00:00
Transform tr = sp - > get_global_gizmo_transform ( ) ;
2014-02-10 01:10:30 +00:00
if ( post )
tr = tr * t ;
else {
tr . basis = t . basis * tr . basis ;
2017-03-05 15:44:50 +00:00
tr . origin + = t . origin ;
2014-02-10 01:10:30 +00:00
}
2017-03-05 15:44:50 +00:00
undo_redo - > add_do_method ( sp , " set_global_transform " , tr ) ;
2017-10-03 16:49:32 +00:00
undo_redo - > add_undo_method ( sp , " set_global_transform " , sp - > get_global_gizmo_transform ( ) ) ;
2014-02-10 01:10:30 +00:00
}
undo_redo - > commit_action ( ) ;
}
2017-11-18 18:51:37 +00:00
void SpatialEditor : : _menu_item_toggled ( bool pressed , int p_option ) {
switch ( p_option ) {
case MENU_TOOL_LOCAL_COORDS : {
tool_option_button [ TOOL_OPT_LOCAL_COORDS ] - > set_pressed ( pressed ) ;
update_transform_gizmo ( ) ;
} break ;
case MENU_TOOL_USE_SNAP : {
tool_option_button [ TOOL_OPT_USE_SNAP ] - > set_pressed ( pressed ) ;
snap_enabled = pressed ;
} break ;
2019-04-06 20:55:01 +00:00
case MENU_TOOL_OVERRIDE_CAMERA : {
ScriptEditorDebugger * const debugger = ScriptEditor : : get_singleton ( ) - > get_debugger ( ) ;
if ( pressed ) {
using Override = ScriptEditorDebugger : : CameraOverride ;
debugger - > set_camera_override ( ( Override ) ( Override : : OVERRIDE_3D_1 + camera_override_viewport_id ) ) ;
} else {
debugger - > set_camera_override ( ScriptEditorDebugger : : OVERRIDE_NONE ) ;
}
} break ;
2017-11-18 18:51:37 +00:00
}
}
2018-07-24 22:08:49 +00:00
void SpatialEditor : : _menu_gizmo_toggled ( int p_option ) {
2018-08-11 21:07:00 +00:00
const int idx = gizmos_menu - > get_item_index ( p_option ) ;
gizmos_menu - > toggle_item_multistate ( idx ) ;
// Change icon
const int state = gizmos_menu - > get_item_state ( idx ) ;
switch ( state ) {
2018-11-18 21:01:09 +00:00
case EditorSpatialGizmoPlugin : : VISIBLE :
2018-08-11 21:07:00 +00:00
gizmos_menu - > set_item_icon ( idx , view_menu - > get_popup ( ) - > get_icon ( " visibility_visible " ) ) ;
break ;
2018-11-18 21:01:09 +00:00
case EditorSpatialGizmoPlugin : : ON_TOP :
2018-08-11 21:07:00 +00:00
gizmos_menu - > set_item_icon ( idx , view_menu - > get_popup ( ) - > get_icon ( " visibility_xray " ) ) ;
break ;
case EditorSpatialGizmoPlugin : : HIDDEN :
gizmos_menu - > set_item_icon ( idx , view_menu - > get_popup ( ) - > get_icon ( " visibility_hidden " ) ) ;
break ;
}
2019-03-11 23:30:50 +00:00
gizmo_plugins_by_name . write [ p_option ] - > set_state ( state ) ;
2018-07-24 22:08:49 +00:00
2018-08-11 21:07:00 +00:00
update_all_gizmos ( ) ;
2018-07-24 22:08:49 +00:00
}
2019-04-06 20:55:01 +00:00
void SpatialEditor : : _update_camera_override_button ( bool p_game_running ) {
Button * const button = tool_option_button [ TOOL_OPT_OVERRIDE_CAMERA ] ;
if ( p_game_running ) {
button - > set_disabled ( false ) ;
2019-11-11 14:46:23 +00:00
button - > set_tooltip ( TTR ( " Game Camera Override \n No game instance running. " ) ) ;
2019-04-06 20:55:01 +00:00
} else {
button - > set_disabled ( true ) ;
button - > set_pressed ( false ) ;
2019-11-11 14:46:23 +00:00
button - > set_tooltip ( TTR ( " Game Camera Override \n Overrides game camera with editor viewport camera. " ) ) ;
2019-04-06 20:55:01 +00:00
}
}
void SpatialEditor : : _update_camera_override_viewport ( Object * p_viewport ) {
SpatialEditorViewport * current_viewport = Object : : cast_to < SpatialEditorViewport > ( p_viewport ) ;
if ( ! current_viewport )
return ;
ScriptEditorDebugger * const debugger = ScriptEditor : : get_singleton ( ) - > get_debugger ( ) ;
camera_override_viewport_id = current_viewport - > index ;
if ( debugger - > get_camera_override ( ) > = ScriptEditorDebugger : : OVERRIDE_3D_1 ) {
using Override = ScriptEditorDebugger : : CameraOverride ;
debugger - > set_camera_override ( ( Override ) ( Override : : OVERRIDE_3D_1 + camera_override_viewport_id ) ) ;
}
}
2014-02-10 01:10:30 +00:00
void SpatialEditor : : _menu_item_pressed ( int p_option ) {
2017-03-05 15:44:50 +00:00
switch ( p_option ) {
2014-02-10 01:10:30 +00:00
case MENU_TOOL_SELECT :
case MENU_TOOL_MOVE :
case MENU_TOOL_ROTATE :
2015-12-13 20:16:13 +00:00
case MENU_TOOL_SCALE :
case MENU_TOOL_LIST_SELECT : {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < TOOL_MAX ; i + + )
tool_button [ i ] - > set_pressed ( i = = p_option ) ;
tool_mode = ( ToolMode ) p_option ;
2014-02-10 01:10:30 +00:00
update_transform_gizmo ( ) ;
} break ;
case MENU_TRANSFORM_CONFIGURE_SNAP : {
2017-03-05 15:44:50 +00:00
snap_dialog - > popup_centered ( Size2 ( 200 , 180 ) ) ;
2014-02-10 01:10:30 +00:00
} break ;
case MENU_TRANSFORM_DIALOG : {
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < 3 ; i + + ) {
2014-02-10 01:10:30 +00:00
xform_translate [ i ] - > set_text ( " 0 " ) ;
xform_rotate [ i ] - > set_text ( " 0 " ) ;
xform_scale [ i ] - > set_text ( " 1 " ) ;
}
2017-07-31 13:00:02 +00:00
xform_dialog - > popup_centered ( Size2 ( 320 , 240 ) * EDSCALE ) ;
2014-02-10 01:10:30 +00:00
} break ;
case MENU_VIEW_USE_1_VIEWPORT : {
2017-06-11 14:29:27 +00:00
viewport_base - > set_view ( SpatialEditorViewportContainer : : VIEW_USE_1_VIEWPORT ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_1_VIEWPORT ) , true ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_2_VIEWPORTS ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_3_VIEWPORTS ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_4_VIEWPORTS ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_2_VIEWPORTS_ALT ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_3_VIEWPORTS_ALT ) , false ) ;
2014-02-10 01:10:30 +00:00
} break ;
case MENU_VIEW_USE_2_VIEWPORTS : {
2017-06-11 14:29:27 +00:00
viewport_base - > set_view ( SpatialEditorViewportContainer : : VIEW_USE_2_VIEWPORTS ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_1_VIEWPORT ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_2_VIEWPORTS ) , true ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_3_VIEWPORTS ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_4_VIEWPORTS ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_2_VIEWPORTS_ALT ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_3_VIEWPORTS_ALT ) , false ) ;
2014-10-09 03:06:51 +00:00
} break ;
case MENU_VIEW_USE_2_VIEWPORTS_ALT : {
2017-06-11 14:29:27 +00:00
viewport_base - > set_view ( SpatialEditorViewportContainer : : VIEW_USE_2_VIEWPORTS_ALT ) ;
2014-10-09 03:06:51 +00:00
2017-03-05 15:44:50 +00:00
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_1_VIEWPORT ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_2_VIEWPORTS ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_3_VIEWPORTS ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_4_VIEWPORTS ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_2_VIEWPORTS_ALT ) , true ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_3_VIEWPORTS_ALT ) , false ) ;
2014-02-10 01:10:30 +00:00
} break ;
case MENU_VIEW_USE_3_VIEWPORTS : {
2017-06-11 14:29:27 +00:00
viewport_base - > set_view ( SpatialEditorViewportContainer : : VIEW_USE_3_VIEWPORTS ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_1_VIEWPORT ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_2_VIEWPORTS ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_3_VIEWPORTS ) , true ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_4_VIEWPORTS ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_2_VIEWPORTS_ALT ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_3_VIEWPORTS_ALT ) , false ) ;
2014-10-09 03:06:51 +00:00
} break ;
case MENU_VIEW_USE_3_VIEWPORTS_ALT : {
2017-06-11 14:29:27 +00:00
viewport_base - > set_view ( SpatialEditorViewportContainer : : VIEW_USE_3_VIEWPORTS_ALT ) ;
2014-10-09 03:06:51 +00:00
2017-03-05 15:44:50 +00:00
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_1_VIEWPORT ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_2_VIEWPORTS ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_3_VIEWPORTS ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_4_VIEWPORTS ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_2_VIEWPORTS_ALT ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_3_VIEWPORTS_ALT ) , true ) ;
2014-02-10 01:10:30 +00:00
} break ;
case MENU_VIEW_USE_4_VIEWPORTS : {
2017-06-11 14:29:27 +00:00
viewport_base - > set_view ( SpatialEditorViewportContainer : : VIEW_USE_4_VIEWPORTS ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_1_VIEWPORT ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_2_VIEWPORTS ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_3_VIEWPORTS ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_4_VIEWPORTS ) , true ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_2_VIEWPORTS_ALT ) , false ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_3_VIEWPORTS_ALT ) , false ) ;
2014-02-10 01:10:30 +00:00
} break ;
case MENU_VIEW_ORIGIN : {
2017-03-05 15:44:50 +00:00
bool is_checked = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( p_option ) ) ;
2014-02-10 01:10:30 +00:00
2018-08-17 21:21:08 +00:00
origin_enabled = ! is_checked ;
VisualServer : : get_singleton ( ) - > instance_set_visible ( origin_instance , origin_enabled ) ;
// Update the grid since its appearance depends on whether the origin is enabled
_finish_grid ( ) ;
_init_grid ( ) ;
2014-02-10 01:10:30 +00:00
2018-08-17 21:21:08 +00:00
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( p_option ) , origin_enabled ) ;
2014-02-10 01:10:30 +00:00
} break ;
case MENU_VIEW_GRID : {
2017-03-05 15:44:50 +00:00
bool is_checked = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( p_option ) ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
grid_enabled = ! is_checked ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < 3 ; + + i ) {
2014-07-15 05:29:03 +00:00
if ( grid_enable [ i ] ) {
2017-03-05 15:44:50 +00:00
VisualServer : : get_singleton ( ) - > instance_set_visible ( grid_instance [ i ] , grid_enabled ) ;
grid_visible [ i ] = grid_enabled ;
2014-07-15 05:29:03 +00:00
}
}
2017-03-05 15:44:50 +00:00
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( p_option ) , grid_enabled ) ;
2014-02-10 01:10:30 +00:00
} break ;
case MENU_VIEW_CAMERA_SETTINGS : {
2017-03-05 15:44:50 +00:00
settings_dialog - > popup_centered ( settings_vbc - > get_combined_minimum_size ( ) + Size2 ( 50 , 50 ) ) ;
2014-02-10 01:10:30 +00:00
} break ;
2018-07-26 06:34:40 +00:00
case MENU_SNAP_TO_FLOOR : {
snap_selected_nodes_to_floor ( ) ;
} break ;
2017-10-23 19:21:15 +00:00
case MENU_LOCK_SELECTED : {
2019-04-26 17:23:50 +00:00
undo_redo - > create_action ( TTR ( " Lock Selected " ) ) ;
2017-10-23 19:21:15 +00:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
Spatial * spatial = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
if ( ! spatial | | ! spatial - > is_visible_in_tree ( ) )
continue ;
if ( spatial - > get_viewport ( ) ! = EditorNode : : get_singleton ( ) - > get_scene_root ( ) )
continue ;
2019-04-26 17:23:50 +00:00
undo_redo - > add_do_method ( spatial , " set_meta " , " _edit_lock_ " , true ) ;
undo_redo - > add_undo_method ( spatial , " remove_meta " , " _edit_lock_ " ) ;
undo_redo - > add_do_method ( this , " emit_signal " , " item_lock_status_changed " ) ;
undo_redo - > add_undo_method ( this , " emit_signal " , " item_lock_status_changed " ) ;
2017-10-23 19:21:15 +00:00
}
2019-04-26 17:23:50 +00:00
undo_redo - > add_do_method ( this , " _refresh_menu_icons " , Variant ( ) ) ;
undo_redo - > add_undo_method ( this , " _refresh_menu_icons " , Variant ( ) ) ;
undo_redo - > commit_action ( ) ;
2017-10-23 19:21:15 +00:00
} break ;
case MENU_UNLOCK_SELECTED : {
2019-04-26 17:23:50 +00:00
undo_redo - > create_action ( TTR ( " Unlock Selected " ) ) ;
2017-10-23 19:21:15 +00:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
Spatial * spatial = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
if ( ! spatial | | ! spatial - > is_visible_in_tree ( ) )
continue ;
if ( spatial - > get_viewport ( ) ! = EditorNode : : get_singleton ( ) - > get_scene_root ( ) )
continue ;
2019-04-26 17:23:50 +00:00
undo_redo - > add_do_method ( spatial , " remove_meta " , " _edit_lock_ " ) ;
undo_redo - > add_undo_method ( spatial , " set_meta " , " _edit_lock_ " , true ) ;
undo_redo - > add_do_method ( this , " emit_signal " , " item_lock_status_changed " ) ;
undo_redo - > add_undo_method ( this , " emit_signal " , " item_lock_status_changed " ) ;
2017-10-23 19:21:15 +00:00
}
2019-04-26 17:23:50 +00:00
undo_redo - > add_do_method ( this , " _refresh_menu_icons " , Variant ( ) ) ;
undo_redo - > add_undo_method ( this , " _refresh_menu_icons " , Variant ( ) ) ;
undo_redo - > commit_action ( ) ;
2019-04-17 16:24:28 +00:00
} break ;
case MENU_GROUP_SELECTED : {
2019-04-26 17:23:50 +00:00
undo_redo - > create_action ( TTR ( " Group Selected " ) ) ;
2019-04-17 16:24:28 +00:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
Spatial * spatial = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
if ( ! spatial | | ! spatial - > is_visible_in_tree ( ) )
continue ;
if ( spatial - > get_viewport ( ) ! = EditorNode : : get_singleton ( ) - > get_scene_root ( ) )
continue ;
2019-04-26 17:23:50 +00:00
undo_redo - > add_do_method ( spatial , " set_meta " , " _edit_group_ " , true ) ;
undo_redo - > add_undo_method ( spatial , " remove_meta " , " _edit_group_ " ) ;
undo_redo - > add_do_method ( this , " emit_signal " , " item_group_status_changed " ) ;
undo_redo - > add_undo_method ( this , " emit_signal " , " item_group_status_changed " ) ;
2019-04-17 16:24:28 +00:00
}
2019-04-26 17:23:50 +00:00
undo_redo - > add_do_method ( this , " _refresh_menu_icons " , Variant ( ) ) ;
undo_redo - > add_undo_method ( this , " _refresh_menu_icons " , Variant ( ) ) ;
undo_redo - > commit_action ( ) ;
2019-04-17 16:24:28 +00:00
} break ;
case MENU_UNGROUP_SELECTED : {
2019-04-26 17:23:50 +00:00
undo_redo - > create_action ( TTR ( " Ungroup Selected " ) ) ;
2019-04-17 16:24:28 +00:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
Spatial * spatial = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
if ( ! spatial | | ! spatial - > is_visible_in_tree ( ) )
continue ;
if ( spatial - > get_viewport ( ) ! = EditorNode : : get_singleton ( ) - > get_scene_root ( ) )
continue ;
2019-04-26 17:23:50 +00:00
undo_redo - > add_do_method ( spatial , " remove_meta " , " _edit_group_ " ) ;
undo_redo - > add_undo_method ( spatial , " set_meta " , " _edit_group_ " , true ) ;
undo_redo - > add_do_method ( this , " emit_signal " , " item_group_status_changed " ) ;
undo_redo - > add_undo_method ( this , " emit_signal " , " item_group_status_changed " ) ;
2019-04-17 16:24:28 +00:00
}
2019-04-26 17:23:50 +00:00
undo_redo - > add_do_method ( this , " _refresh_menu_icons " , Variant ( ) ) ;
undo_redo - > add_undo_method ( this , " _refresh_menu_icons " , Variant ( ) ) ;
undo_redo - > commit_action ( ) ;
2017-10-23 19:21:15 +00:00
} break ;
2014-02-10 01:10:30 +00:00
}
}
void SpatialEditor : : _init_indicators ( ) {
{
2018-09-20 11:27:32 +00:00
origin_enabled = true ;
grid_enabled = true ;
2014-02-10 01:10:30 +00:00
2017-01-14 17:03:38 +00:00
indicator_mat . instance ( ) ;
2017-04-07 02:36:37 +00:00
indicator_mat - > set_flag ( SpatialMaterial : : FLAG_UNSHADED , true ) ;
indicator_mat - > set_flag ( SpatialMaterial : : FLAG_ALBEDO_FROM_VERTEX_COLOR , true ) ;
indicator_mat - > set_flag ( SpatialMaterial : : FLAG_SRGB_VERTEX_COLOR , true ) ;
2016-10-29 23:48:09 +00:00
2014-02-10 01:10:30 +00:00
Vector < Color > origin_colors ;
Vector < Vector3 > origin_points ;
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < 3 ; i + + ) {
2014-02-10 01:10:30 +00:00
Vector3 axis ;
2017-03-05 15:44:50 +00:00
axis [ i ] = 1 ;
2019-08-23 16:14:47 +00:00
Color origin_color ;
switch ( i ) {
case 0 :
origin_color = get_color ( " axis_x_color " , " Editor " ) ;
break ;
case 1 :
origin_color = get_color ( " axis_y_color " , " Editor " ) ;
break ;
case 2 :
origin_color = get_color ( " axis_z_color " , " Editor " ) ;
break ;
default :
origin_color = Color ( ) ;
break ;
}
2017-12-08 22:45:33 +00:00
grid_enable [ i ] = false ;
grid_visible [ i ] = false ;
2014-02-10 01:10:30 +00:00
2019-08-01 12:23:29 +00:00
origin_colors . push_back ( origin_color ) ;
origin_colors . push_back ( origin_color ) ;
2017-03-05 15:44:50 +00:00
origin_points . push_back ( axis * 4096 ) ;
origin_points . push_back ( axis * - 4096 ) ;
2017-12-08 22:45:33 +00:00
}
2014-02-10 01:10:30 +00:00
2017-12-08 22:45:33 +00:00
grid_enable [ 1 ] = true ;
grid_visible [ 1 ] = true ;
2017-03-05 15:44:50 +00:00
2017-12-08 22:45:33 +00:00
_init_grid ( ) ;
2014-02-10 01:10:30 +00:00
origin = VisualServer : : get_singleton ( ) - > mesh_create ( ) ;
Array d ;
d . resize ( VS : : ARRAY_MAX ) ;
2017-03-05 15:44:50 +00:00
d [ VisualServer : : ARRAY_VERTEX ] = origin_points ;
d [ VisualServer : : ARRAY_COLOR ] = origin_colors ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
VisualServer : : get_singleton ( ) - > mesh_add_surface_from_arrays ( origin , VisualServer : : PRIMITIVE_LINES , d ) ;
VisualServer : : get_singleton ( ) - > mesh_surface_set_material ( origin , 0 , indicator_mat - > get_rid ( ) ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
origin_instance = VisualServer : : get_singleton ( ) - > instance_create2 ( origin , get_tree ( ) - > get_root ( ) - > get_world ( ) - > get_scenario ( ) ) ;
VS : : get_singleton ( ) - > instance_set_layer_mask ( origin_instance , 1 < < SpatialEditorViewport : : GIZMO_GRID_LAYER ) ;
2014-10-16 03:06:34 +00:00
2016-03-07 23:00:55 +00:00
VisualServer : : get_singleton ( ) - > instance_geometry_set_cast_shadows_setting ( origin_instance , VS : : SHADOW_CASTING_SETTING_OFF ) ;
2014-02-10 01:10:30 +00:00
}
{
//move gizmo
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < 3 ; i + + ) {
2014-02-10 01:10:30 +00:00
2019-08-23 16:14:47 +00:00
Color col ;
switch ( i ) {
case 0 :
col = get_color ( " axis_x_color " , " Editor " ) ;
break ;
case 1 :
col = get_color ( " axis_y_color " , " Editor " ) ;
break ;
case 2 :
col = get_color ( " axis_z_color " , " Editor " ) ;
break ;
default :
col = Color ( ) ;
break ;
}
2019-08-01 12:23:29 +00:00
col . a = EditorSettings : : get_singleton ( ) - > get ( " editors/3d/manipulator_gizmo_opacity " ) ;
2017-06-07 21:18:55 +00:00
move_gizmo [ i ] = Ref < ArrayMesh > ( memnew ( ArrayMesh ) ) ;
2017-08-29 01:39:45 +00:00
move_plane_gizmo [ i ] = Ref < ArrayMesh > ( memnew ( ArrayMesh ) ) ;
2017-06-07 21:18:55 +00:00
rotate_gizmo [ i ] = Ref < ArrayMesh > ( memnew ( ArrayMesh ) ) ;
2017-09-21 21:11:56 +00:00
scale_gizmo [ i ] = Ref < ArrayMesh > ( memnew ( ArrayMesh ) ) ;
2017-11-14 22:50:19 +00:00
scale_plane_gizmo [ i ] = Ref < ArrayMesh > ( memnew ( ArrayMesh ) ) ;
2014-02-10 01:10:30 +00:00
2017-04-07 02:36:37 +00:00
Ref < SpatialMaterial > mat = memnew ( SpatialMaterial ) ;
mat - > set_flag ( SpatialMaterial : : FLAG_UNSHADED , true ) ;
2017-09-01 15:56:52 +00:00
mat - > set_on_top_of_alpha ( ) ;
2017-04-07 02:36:37 +00:00
mat - > set_feature ( SpatialMaterial : : FEATURE_TRANSPARENT , true ) ;
2016-10-27 14:50:26 +00:00
mat - > set_albedo ( col ) ;
2017-03-05 15:44:50 +00:00
gizmo_color [ i ] = mat ;
2014-02-10 01:10:30 +00:00
2019-08-01 12:23:29 +00:00
Ref < SpatialMaterial > mat_hl = mat - > duplicate ( ) ;
mat_hl - > set_albedo ( Color ( col . r , col . g , col . b , 1.0 ) ) ;
gizmo_color_hl [ i ] = mat_hl ;
2014-02-10 01:10:30 +00:00
Vector3 ivec ;
2017-03-05 15:44:50 +00:00
ivec [ i ] = 1 ;
2014-02-10 01:10:30 +00:00
Vector3 nivec ;
2017-03-05 15:44:50 +00:00
nivec [ ( i + 1 ) % 3 ] = 1 ;
nivec [ ( i + 2 ) % 3 ] = 1 ;
2014-02-10 01:10:30 +00:00
Vector3 ivec2 ;
2017-03-05 15:44:50 +00:00
ivec2 [ ( i + 1 ) % 3 ] = 1 ;
2014-02-10 01:10:30 +00:00
Vector3 ivec3 ;
2017-03-05 15:44:50 +00:00
ivec3 [ ( i + 2 ) % 3 ] = 1 ;
2014-02-10 01:10:30 +00:00
2017-09-21 21:11:56 +00:00
//translate
2014-02-10 01:10:30 +00:00
{
2017-03-05 15:44:50 +00:00
Ref < SurfaceTool > surftool = memnew ( SurfaceTool ) ;
2014-02-10 01:10:30 +00:00
surftool - > begin ( Mesh : : PRIMITIVE_TRIANGLES ) ;
2017-09-21 21:11:56 +00:00
// Arrow profile
2017-03-05 15:44:50 +00:00
const int arrow_points = 5 ;
Vector3 arrow [ 5 ] = {
nivec * 0.0 + ivec * 0.0 ,
nivec * 0.01 + ivec * 0.0 ,
2017-09-21 21:11:56 +00:00
nivec * 0.01 + ivec * GIZMO_ARROW_OFFSET ,
nivec * 0.065 + ivec * GIZMO_ARROW_OFFSET ,
nivec * 0.0 + ivec * ( GIZMO_ARROW_OFFSET + GIZMO_ARROW_SIZE ) ,
2014-02-10 01:10:30 +00:00
} ;
2018-08-09 14:34:18 +00:00
int arrow_sides = 16 ;
2014-02-10 01:10:30 +00:00
2018-08-09 14:34:18 +00:00
for ( int k = 0 ; k < arrow_sides ; k + + ) {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
Basis ma ( ivec , Math_PI * 2 * float ( k ) / arrow_sides ) ;
Basis mb ( ivec , Math_PI * 2 * float ( k + 1 ) / arrow_sides ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
for ( int j = 0 ; j < arrow_points - 1 ; j + + ) {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
Vector3 points [ 4 ] = {
2014-02-10 01:10:30 +00:00
ma . xform ( arrow [ j ] ) ,
mb . xform ( arrow [ j ] ) ,
2017-03-05 15:44:50 +00:00
mb . xform ( arrow [ j + 1 ] ) ,
ma . xform ( arrow [ j + 1 ] ) ,
2014-02-10 01:10:30 +00:00
} ;
surftool - > add_vertex ( points [ 0 ] ) ;
surftool - > add_vertex ( points [ 1 ] ) ;
surftool - > add_vertex ( points [ 2 ] ) ;
surftool - > add_vertex ( points [ 0 ] ) ;
surftool - > add_vertex ( points [ 2 ] ) ;
surftool - > add_vertex ( points [ 3 ] ) ;
}
}
surftool - > set_material ( mat ) ;
surftool - > commit ( move_gizmo [ i ] ) ;
}
2017-09-21 21:11:56 +00:00
// Plane Translation
2017-08-29 01:39:45 +00:00
{
Ref < SurfaceTool > surftool = memnew ( SurfaceTool ) ;
surftool - > begin ( Mesh : : PRIMITIVE_TRIANGLES ) ;
Vector3 vec = ivec2 - ivec3 ;
Vector3 plane [ 4 ] = {
vec * GIZMO_PLANE_DST ,
vec * GIZMO_PLANE_DST + ivec2 * GIZMO_PLANE_SIZE ,
vec * ( GIZMO_PLANE_DST + GIZMO_PLANE_SIZE ) ,
vec * GIZMO_PLANE_DST - ivec3 * GIZMO_PLANE_SIZE
} ;
Basis ma ( ivec , Math_PI / 2 ) ;
Vector3 points [ 4 ] = {
ma . xform ( plane [ 0 ] ) ,
ma . xform ( plane [ 1 ] ) ,
ma . xform ( plane [ 2 ] ) ,
ma . xform ( plane [ 3 ] ) ,
} ;
surftool - > add_vertex ( points [ 0 ] ) ;
surftool - > add_vertex ( points [ 1 ] ) ;
surftool - > add_vertex ( points [ 2 ] ) ;
surftool - > add_vertex ( points [ 0 ] ) ;
surftool - > add_vertex ( points [ 2 ] ) ;
surftool - > add_vertex ( points [ 3 ] ) ;
Ref < SpatialMaterial > plane_mat = memnew ( SpatialMaterial ) ;
plane_mat - > set_flag ( SpatialMaterial : : FLAG_UNSHADED , true ) ;
2017-09-01 15:56:52 +00:00
plane_mat - > set_on_top_of_alpha ( ) ;
2017-08-29 01:39:45 +00:00
plane_mat - > set_feature ( SpatialMaterial : : FEATURE_TRANSPARENT , true ) ;
plane_mat - > set_cull_mode ( SpatialMaterial : : CULL_DISABLED ) ;
2019-08-01 12:23:29 +00:00
plane_mat - > set_albedo ( col ) ;
2017-08-29 01:39:45 +00:00
plane_gizmo_color [ i ] = plane_mat ; // needed, so we can draw planes from both sides
surftool - > set_material ( plane_mat ) ;
surftool - > commit ( move_plane_gizmo [ i ] ) ;
2019-08-01 12:23:29 +00:00
Ref < SpatialMaterial > plane_mat_hl = plane_mat - > duplicate ( ) ;
plane_mat_hl - > set_albedo ( Color ( col . r , col . g , col . b , 1.0 ) ) ;
plane_gizmo_color_hl [ i ] = plane_mat_hl ; // needed, so we can draw planes from both sides
2017-08-29 01:39:45 +00:00
}
2017-09-21 21:11:56 +00:00
// Rotate
2014-02-10 01:10:30 +00:00
{
2017-03-05 15:44:50 +00:00
Ref < SurfaceTool > surftool = memnew ( SurfaceTool ) ;
2014-02-10 01:10:30 +00:00
surftool - > begin ( Mesh : : PRIMITIVE_TRIANGLES ) ;
2017-03-05 15:44:50 +00:00
Vector3 circle [ 5 ] = {
2017-08-29 01:39:45 +00:00
ivec * 0.02 + ivec2 * 0.02 + ivec2 * GIZMO_CIRCLE_SIZE ,
ivec * - 0.02 + ivec2 * 0.02 + ivec2 * GIZMO_CIRCLE_SIZE ,
ivec * - 0.02 + ivec2 * - 0.02 + ivec2 * GIZMO_CIRCLE_SIZE ,
ivec * 0.02 + ivec2 * - 0.02 + ivec2 * GIZMO_CIRCLE_SIZE ,
ivec * 0.02 + ivec2 * 0.02 + ivec2 * GIZMO_CIRCLE_SIZE ,
2014-02-10 01:10:30 +00:00
} ;
2018-08-09 14:34:18 +00:00
for ( int k = 0 ; k < 64 ; k + + ) {
2014-02-10 01:10:30 +00:00
2018-08-09 14:34:18 +00:00
Basis ma ( ivec , Math_PI * 2 * float ( k ) / 64 ) ;
Basis mb ( ivec , Math_PI * 2 * float ( k + 1 ) / 64 ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
for ( int j = 0 ; j < 4 ; j + + ) {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
Vector3 points [ 4 ] = {
2014-02-10 01:10:30 +00:00
ma . xform ( circle [ j ] ) ,
mb . xform ( circle [ j ] ) ,
2017-03-05 15:44:50 +00:00
mb . xform ( circle [ j + 1 ] ) ,
ma . xform ( circle [ j + 1 ] ) ,
2014-02-10 01:10:30 +00:00
} ;
surftool - > add_vertex ( points [ 0 ] ) ;
surftool - > add_vertex ( points [ 1 ] ) ;
surftool - > add_vertex ( points [ 2 ] ) ;
surftool - > add_vertex ( points [ 0 ] ) ;
surftool - > add_vertex ( points [ 2 ] ) ;
surftool - > add_vertex ( points [ 3 ] ) ;
}
}
surftool - > set_material ( mat ) ;
surftool - > commit ( rotate_gizmo [ i ] ) ;
}
2017-09-21 21:11:56 +00:00
// Scale
{
Ref < SurfaceTool > surftool = memnew ( SurfaceTool ) ;
surftool - > begin ( Mesh : : PRIMITIVE_TRIANGLES ) ;
2014-05-05 01:50:23 +00:00
2017-09-21 21:11:56 +00:00
// Cube arrow profile
const int arrow_points = 6 ;
Vector3 arrow [ 6 ] = {
nivec * 0.0 + ivec * 0.0 ,
nivec * 0.01 + ivec * 0.0 ,
nivec * 0.01 + ivec * 1.0 * GIZMO_SCALE_OFFSET ,
nivec * 0.07 + ivec * 1.0 * GIZMO_SCALE_OFFSET ,
nivec * 0.07 + ivec * 1.11 * GIZMO_SCALE_OFFSET ,
nivec * 0.0 + ivec * 1.11 * GIZMO_SCALE_OFFSET ,
} ;
2014-02-10 01:10:30 +00:00
2017-09-21 21:11:56 +00:00
int arrow_sides = 4 ;
for ( int k = 0 ; k < 4 ; k + + ) {
2014-02-10 01:10:30 +00:00
2017-09-21 21:11:56 +00:00
Basis ma ( ivec , Math_PI * 2 * float ( k ) / arrow_sides ) ;
Basis mb ( ivec , Math_PI * 2 * float ( k + 1 ) / arrow_sides ) ;
2014-02-10 01:10:30 +00:00
2017-09-21 21:11:56 +00:00
for ( int j = 0 ; j < arrow_points - 1 ; j + + ) {
Vector3 points [ 4 ] = {
ma . xform ( arrow [ j ] ) ,
mb . xform ( arrow [ j ] ) ,
mb . xform ( arrow [ j + 1 ] ) ,
ma . xform ( arrow [ j + 1 ] ) ,
} ;
surftool - > add_vertex ( points [ 0 ] ) ;
surftool - > add_vertex ( points [ 1 ] ) ;
surftool - > add_vertex ( points [ 2 ] ) ;
surftool - > add_vertex ( points [ 0 ] ) ;
surftool - > add_vertex ( points [ 2 ] ) ;
surftool - > add_vertex ( points [ 3 ] ) ;
}
}
surftool - > set_material ( mat ) ;
surftool - > commit ( scale_gizmo [ i ] ) ;
}
2017-11-14 22:50:19 +00:00
// Plane Scale
{
Ref < SurfaceTool > surftool = memnew ( SurfaceTool ) ;
surftool - > begin ( Mesh : : PRIMITIVE_TRIANGLES ) ;
Vector3 vec = ivec2 - ivec3 ;
Vector3 plane [ 4 ] = {
vec * GIZMO_PLANE_DST ,
vec * GIZMO_PLANE_DST + ivec2 * GIZMO_PLANE_SIZE ,
vec * ( GIZMO_PLANE_DST + GIZMO_PLANE_SIZE ) ,
vec * GIZMO_PLANE_DST - ivec3 * GIZMO_PLANE_SIZE
} ;
Basis ma ( ivec , Math_PI / 2 ) ;
Vector3 points [ 4 ] = {
ma . xform ( plane [ 0 ] ) ,
ma . xform ( plane [ 1 ] ) ,
ma . xform ( plane [ 2 ] ) ,
ma . xform ( plane [ 3 ] ) ,
} ;
surftool - > add_vertex ( points [ 0 ] ) ;
surftool - > add_vertex ( points [ 1 ] ) ;
surftool - > add_vertex ( points [ 2 ] ) ;
surftool - > add_vertex ( points [ 0 ] ) ;
surftool - > add_vertex ( points [ 2 ] ) ;
surftool - > add_vertex ( points [ 3 ] ) ;
Ref < SpatialMaterial > plane_mat = memnew ( SpatialMaterial ) ;
plane_mat - > set_flag ( SpatialMaterial : : FLAG_UNSHADED , true ) ;
plane_mat - > set_on_top_of_alpha ( ) ;
plane_mat - > set_feature ( SpatialMaterial : : FEATURE_TRANSPARENT , true ) ;
plane_mat - > set_cull_mode ( SpatialMaterial : : CULL_DISABLED ) ;
2019-08-01 12:23:29 +00:00
plane_mat - > set_albedo ( col ) ;
2017-11-14 22:50:19 +00:00
plane_gizmo_color [ i ] = plane_mat ; // needed, so we can draw planes from both sides
surftool - > set_material ( plane_mat ) ;
surftool - > commit ( scale_plane_gizmo [ i ] ) ;
2019-08-01 12:23:29 +00:00
Ref < SpatialMaterial > plane_mat_hl = plane_mat - > duplicate ( ) ;
plane_mat_hl - > set_albedo ( Color ( col . r , col . g , col . b , 1.0 ) ) ;
plane_gizmo_color_hl [ i ] = plane_mat_hl ; // needed, so we can draw planes from both sides
2017-11-14 22:50:19 +00:00
}
2017-09-21 21:11:56 +00:00
}
}
_generate_selection_box ( ) ;
2014-02-10 01:10:30 +00:00
}
2018-10-29 10:30:28 +00:00
void SpatialEditor : : _update_gizmos_menu ( ) {
2018-07-24 22:08:49 +00:00
2018-10-29 10:30:28 +00:00
gizmos_menu - > clear ( ) ;
2018-07-24 22:08:49 +00:00
2019-03-11 23:30:50 +00:00
for ( int i = 0 ; i < gizmo_plugins_by_name . size ( ) ; + + i ) {
if ( ! gizmo_plugins_by_name [ i ] - > can_be_hidden ( ) ) continue ;
String plugin_name = gizmo_plugins_by_name [ i ] - > get_name ( ) ;
const int plugin_state = gizmo_plugins_by_name [ i ] - > get_state ( ) ;
gizmos_menu - > add_multistate_item ( TTR ( plugin_name ) , 3 , plugin_state , i ) ;
const int idx = gizmos_menu - > get_item_index ( i ) ;
2020-06-07 13:34:01 +00:00
gizmos_menu - > set_item_tooltip (
idx ,
TTR ( " Click to toggle between visibility states. \n \n Open eye: Gizmo is visible. \n Closed eye: Gizmo is hidden. \n Half-open eye: Gizmo is also visible through opaque surfaces ( \" x-ray \" ). " ) ) ;
2019-03-11 23:30:50 +00:00
switch ( plugin_state ) {
case EditorSpatialGizmoPlugin : : VISIBLE :
gizmos_menu - > set_item_icon ( idx , gizmos_menu - > get_icon ( " visibility_visible " ) ) ;
break ;
case EditorSpatialGizmoPlugin : : ON_TOP :
gizmos_menu - > set_item_icon ( idx , gizmos_menu - > get_icon ( " visibility_xray " ) ) ;
break ;
case EditorSpatialGizmoPlugin : : HIDDEN :
gizmos_menu - > set_item_icon ( idx , gizmos_menu - > get_icon ( " visibility_hidden " ) ) ;
break ;
}
2018-07-24 22:08:49 +00:00
}
}
2019-02-15 17:32:38 +00:00
void SpatialEditor : : _update_gizmos_menu_theme ( ) {
2019-03-11 23:30:50 +00:00
for ( int i = 0 ; i < gizmo_plugins_by_name . size ( ) ; + + i ) {
if ( ! gizmo_plugins_by_name [ i ] - > can_be_hidden ( ) ) continue ;
const int plugin_state = gizmo_plugins_by_name [ i ] - > get_state ( ) ;
const int idx = gizmos_menu - > get_item_index ( i ) ;
switch ( plugin_state ) {
case EditorSpatialGizmoPlugin : : VISIBLE :
gizmos_menu - > set_item_icon ( idx , gizmos_menu - > get_icon ( " visibility_visible " ) ) ;
break ;
case EditorSpatialGizmoPlugin : : ON_TOP :
gizmos_menu - > set_item_icon ( idx , gizmos_menu - > get_icon ( " visibility_xray " ) ) ;
break ;
case EditorSpatialGizmoPlugin : : HIDDEN :
gizmos_menu - > set_item_icon ( idx , gizmos_menu - > get_icon ( " visibility_hidden " ) ) ;
break ;
}
2019-02-15 17:32:38 +00:00
}
}
2017-12-08 22:45:33 +00:00
void SpatialEditor : : _init_grid ( ) {
PoolVector < Color > grid_colors [ 3 ] ;
PoolVector < Vector3 > grid_points [ 3 ] ;
2018-04-29 23:43:20 +00:00
Color primary_grid_color = EditorSettings : : get_singleton ( ) - > get ( " editors/3d/primary_grid_color " ) ;
Color secondary_grid_color = EditorSettings : : get_singleton ( ) - > get ( " editors/3d/secondary_grid_color " ) ;
int grid_size = EditorSettings : : get_singleton ( ) - > get ( " editors/3d/grid_size " ) ;
int primary_grid_steps = EditorSettings : : get_singleton ( ) - > get ( " editors/3d/primary_grid_steps " ) ;
2017-12-08 22:45:33 +00:00
for ( int i = 0 ; i < 3 ; i + + ) {
Vector3 axis ;
axis [ i ] = 1 ;
Vector3 axis_n1 ;
axis_n1 [ ( i + 1 ) % 3 ] = 1 ;
Vector3 axis_n2 ;
axis_n2 [ ( i + 2 ) % 3 ] = 1 ;
2018-04-29 23:43:20 +00:00
for ( int j = - grid_size ; j < = grid_size ; j + + ) {
Vector3 p1 = axis_n1 * j + axis_n2 * - grid_size ;
2017-12-08 22:45:33 +00:00
Vector3 p1_dest = p1 * ( - axis_n2 + axis_n1 ) ;
2018-04-29 23:43:20 +00:00
Vector3 p2 = axis_n2 * j + axis_n1 * - grid_size ;
2017-12-08 22:45:33 +00:00
Vector3 p2_dest = p2 * ( - axis_n1 + axis_n2 ) ;
2018-04-29 23:43:20 +00:00
Color line_color = secondary_grid_color ;
2018-08-17 21:21:08 +00:00
if ( origin_enabled & & j = = 0 ) {
// Don't draw the center lines of the grid if the origin is enabled
// The origin would overlap the grid lines in this case, causing flickering
continue ;
} else if ( j % primary_grid_steps = = 0 ) {
2018-04-29 23:43:20 +00:00
line_color = primary_grid_color ;
2017-12-08 22:45:33 +00:00
}
grid_points [ i ] . push_back ( p1 ) ;
grid_points [ i ] . push_back ( p1_dest ) ;
grid_colors [ i ] . push_back ( line_color ) ;
grid_colors [ i ] . push_back ( line_color ) ;
grid_points [ i ] . push_back ( p2 ) ;
grid_points [ i ] . push_back ( p2_dest ) ;
grid_colors [ i ] . push_back ( line_color ) ;
grid_colors [ i ] . push_back ( line_color ) ;
}
grid [ i ] = VisualServer : : get_singleton ( ) - > mesh_create ( ) ;
Array d ;
d . resize ( VS : : ARRAY_MAX ) ;
d [ VisualServer : : ARRAY_VERTEX ] = grid_points [ i ] ;
d [ VisualServer : : ARRAY_COLOR ] = grid_colors [ i ] ;
VisualServer : : get_singleton ( ) - > mesh_add_surface_from_arrays ( grid [ i ] , VisualServer : : PRIMITIVE_LINES , d ) ;
VisualServer : : get_singleton ( ) - > mesh_surface_set_material ( grid [ i ] , 0 , indicator_mat - > get_rid ( ) ) ;
grid_instance [ i ] = VisualServer : : get_singleton ( ) - > instance_create2 ( grid [ i ] , get_tree ( ) - > get_root ( ) - > get_world ( ) - > get_scenario ( ) ) ;
VisualServer : : get_singleton ( ) - > instance_set_visible ( grid_instance [ i ] , grid_visible [ i ] ) ;
VisualServer : : get_singleton ( ) - > instance_geometry_set_cast_shadows_setting ( grid_instance [ i ] , VS : : SHADOW_CASTING_SETTING_OFF ) ;
VS : : get_singleton ( ) - > instance_set_layer_mask ( grid_instance [ i ] , 1 < < SpatialEditorViewport : : GIZMO_GRID_LAYER ) ;
}
}
2014-02-10 01:10:30 +00:00
void SpatialEditor : : _finish_indicators ( ) {
VisualServer : : get_singleton ( ) - > free ( origin_instance ) ;
VisualServer : : get_singleton ( ) - > free ( origin ) ;
2017-12-08 22:45:33 +00:00
_finish_grid ( ) ;
}
void SpatialEditor : : _finish_grid ( ) {
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < 3 ; i + + ) {
2014-02-10 01:10:30 +00:00
VisualServer : : get_singleton ( ) - > free ( grid_instance [ i ] ) ;
VisualServer : : get_singleton ( ) - > free ( grid [ i ] ) ;
}
}
2017-05-07 20:59:05 +00:00
bool SpatialEditor : : is_any_freelook_active ( ) const {
for ( unsigned int i = 0 ; i < VIEWPORTS_COUNT ; + + i ) {
if ( viewports [ i ] - > is_freelook_active ( ) )
return true ;
}
return false ;
}
2017-10-23 19:21:15 +00:00
void SpatialEditor : : _refresh_menu_icons ( ) {
bool all_locked = true ;
2019-04-17 16:24:28 +00:00
bool all_grouped = true ;
2017-10-23 19:21:15 +00:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
if ( selection . empty ( ) ) {
all_locked = false ;
2019-04-17 16:24:28 +00:00
all_grouped = false ;
2017-10-23 19:21:15 +00:00
} else {
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
if ( Object : : cast_to < Spatial > ( E - > get ( ) ) & & ! Object : : cast_to < Spatial > ( E - > get ( ) ) - > has_meta ( " _edit_lock_ " ) ) {
all_locked = false ;
break ;
}
}
2019-04-17 16:24:28 +00:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
if ( Object : : cast_to < Spatial > ( E - > get ( ) ) & & ! Object : : cast_to < Spatial > ( E - > get ( ) ) - > has_meta ( " _edit_group_ " ) ) {
all_grouped = false ;
break ;
}
}
2017-10-23 19:21:15 +00:00
}
tool_button [ TOOL_LOCK_SELECTED ] - > set_visible ( ! all_locked ) ;
tool_button [ TOOL_LOCK_SELECTED ] - > set_disabled ( selection . empty ( ) ) ;
tool_button [ TOOL_UNLOCK_SELECTED ] - > set_visible ( all_locked ) ;
2019-04-17 16:24:28 +00:00
tool_button [ TOOL_GROUP_SELECTED ] - > set_visible ( ! all_grouped ) ;
tool_button [ TOOL_GROUP_SELECTED ] - > set_disabled ( selection . empty ( ) ) ;
tool_button [ TOOL_UNGROUP_SELECTED ] - > set_visible ( all_grouped ) ;
2017-10-23 19:21:15 +00:00
}
2018-07-26 06:34:40 +00:00
template < typename T >
Set < T * > _get_child_nodes ( Node * parent_node ) {
Set < T * > nodes = Set < T * > ( ) ;
T * node = Node : : cast_to < T > ( parent_node ) ;
if ( node ) {
nodes . insert ( node ) ;
}
for ( int i = 0 ; i < parent_node - > get_child_count ( ) ; i + + ) {
Node * child_node = parent_node - > get_child ( i ) ;
Set < T * > child_nodes = _get_child_nodes < T > ( child_node ) ;
for ( typename Set < T * > : : Element * I = child_nodes . front ( ) ; I ; I = I - > next ( ) ) {
nodes . insert ( I - > get ( ) ) ;
}
}
return nodes ;
}
Set < RID > _get_physics_bodies_rid ( Node * node ) {
Set < RID > rids = Set < RID > ( ) ;
PhysicsBody * pb = Node : : cast_to < PhysicsBody > ( node ) ;
if ( pb ) {
rids . insert ( pb - > get_rid ( ) ) ;
}
Set < PhysicsBody * > child_nodes = _get_child_nodes < PhysicsBody > ( node ) ;
for ( Set < PhysicsBody * > : : Element * I = child_nodes . front ( ) ; I ; I = I - > next ( ) ) {
rids . insert ( I - > get ( ) - > get_rid ( ) ) ;
}
return rids ;
}
void SpatialEditor : : snap_selected_nodes_to_floor ( ) {
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
Dictionary snap_data ;
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
if ( sp ) {
Vector3 from = Vector3 ( ) ;
Vector3 position_offset = Vector3 ( ) ;
// Priorities for snapping to floor are CollisionShapes, VisualInstances and then origin
Set < VisualInstance * > vi = _get_child_nodes < VisualInstance > ( sp ) ;
Set < CollisionShape * > cs = _get_child_nodes < CollisionShape > ( sp ) ;
if ( cs . size ( ) ) {
AABB aabb = sp - > get_global_transform ( ) . xform ( cs . front ( ) - > get ( ) - > get_shape ( ) - > get_debug_mesh ( ) - > get_aabb ( ) ) ;
for ( Set < CollisionShape * > : : Element * I = cs . front ( ) ; I ; I = I - > next ( ) ) {
aabb . merge_with ( sp - > get_global_transform ( ) . xform ( I - > get ( ) - > get_shape ( ) - > get_debug_mesh ( ) - > get_aabb ( ) ) ) ;
}
Vector3 size = aabb . size * Vector3 ( 0.5 , 0.0 , 0.5 ) ;
from = aabb . position + size ;
position_offset . y = from . y - sp - > get_global_transform ( ) . origin . y ;
} else if ( vi . size ( ) ) {
AABB aabb = vi . front ( ) - > get ( ) - > get_transformed_aabb ( ) ;
for ( Set < VisualInstance * > : : Element * I = vi . front ( ) ; I ; I = I - > next ( ) ) {
aabb . merge_with ( I - > get ( ) - > get_transformed_aabb ( ) ) ;
}
Vector3 size = aabb . size * Vector3 ( 0.5 , 0.0 , 0.5 ) ;
from = aabb . position + size ;
position_offset . y = from . y - sp - > get_global_transform ( ) . origin . y ;
} else {
from = sp - > get_global_transform ( ) . origin ;
}
// We add a bit of margin to the from position to avoid it from snapping
// when the spatial is already on a floor and there's another floor under
// it
2019-08-17 23:42:42 +00:00
from = from + Vector3 ( 0.0 , 0.2 , 0.0 ) ;
2018-07-26 06:34:40 +00:00
Dictionary d ;
d [ " from " ] = from ;
d [ " position_offset " ] = position_offset ;
snap_data [ sp ] = d ;
}
}
PhysicsDirectSpaceState * ss = get_tree ( ) - > get_root ( ) - > get_world ( ) - > get_direct_space_state ( ) ;
PhysicsDirectSpaceState : : RayResult result ;
Array keys = snap_data . keys ( ) ;
2019-08-17 23:42:42 +00:00
// The maximum height an object can travel to be snapped
const float max_snap_height = 20.0 ;
Fix misc. source comment typos
Found using `codespell -q 3 -S ./thirdparty,*.po -L ang,ba,cas,dof,doubleclick,fave,hist,leapyear,lod,nd,numer,ois,paket,seeked,sinc,switchs,te,uint -D ~/Projects/codespell/codespell_lib/data/dictionary.txt `
2019-09-19 18:36:39 +00:00
// Will be set to `true` if at least one node from the selection was successfully snapped
2019-08-17 23:42:42 +00:00
bool snapped_to_floor = false ;
2018-07-26 06:34:40 +00:00
2019-08-17 23:42:42 +00:00
if ( keys . size ( ) ) {
// For snapping to be performed, there must be solid geometry under at least one of the selected nodes.
// We need to check this before snapping to register the undo/redo action only if needed.
2018-07-26 06:34:40 +00:00
for ( int i = 0 ; i < keys . size ( ) ; i + + ) {
Node * node = keys [ i ] ;
Spatial * sp = Object : : cast_to < Spatial > ( node ) ;
Dictionary d = snap_data [ node ] ;
Vector3 from = d [ " from " ] ;
2019-08-17 23:42:42 +00:00
Vector3 to = from - Vector3 ( 0.0 , max_snap_height , 0.0 ) ;
2018-07-26 06:34:40 +00:00
Set < RID > excluded = _get_physics_bodies_rid ( sp ) ;
if ( ss - > intersect_ray ( from , to , result , excluded ) ) {
2019-08-17 23:42:42 +00:00
snapped_to_floor = true ;
2018-07-26 06:34:40 +00:00
}
}
2019-08-17 23:42:42 +00:00
if ( snapped_to_floor ) {
undo_redo - > create_action ( TTR ( " Snap Nodes To Floor " ) ) ;
// Perform snapping if at least one node can be snapped
for ( int i = 0 ; i < keys . size ( ) ; i + + ) {
Node * node = keys [ i ] ;
Spatial * sp = Object : : cast_to < Spatial > ( node ) ;
Dictionary d = snap_data [ node ] ;
Vector3 from = d [ " from " ] ;
Vector3 to = from - Vector3 ( 0.0 , max_snap_height , 0.0 ) ;
Set < RID > excluded = _get_physics_bodies_rid ( sp ) ;
if ( ss - > intersect_ray ( from , to , result , excluded ) ) {
Vector3 position_offset = d [ " position_offset " ] ;
Transform new_transform = sp - > get_global_transform ( ) ;
new_transform . origin . y = result . position . y ;
new_transform . origin = new_transform . origin - position_offset ;
undo_redo - > add_do_method ( sp , " set_global_transform " , new_transform ) ;
undo_redo - > add_undo_method ( sp , " set_global_transform " , sp - > get_global_transform ( ) ) ;
}
}
undo_redo - > commit_action ( ) ;
} else {
EditorNode : : get_singleton ( ) - > show_warning ( TTR ( " Couldn't find a solid floor to snap the selection to. " ) ) ;
}
2018-07-26 06:34:40 +00:00
}
}
2017-05-20 15:38:03 +00:00
void SpatialEditor : : _unhandled_key_input ( Ref < InputEvent > p_event ) {
2014-02-10 01:10:30 +00:00
2017-01-13 13:45:50 +00:00
if ( ! is_visible_in_tree ( ) | | get_viewport ( ) - > gui_has_modal_stack ( ) )
2014-02-10 01:10:30 +00:00
return ;
2018-02-21 14:14:26 +00:00
snap_key_enabled = Input : : get_singleton ( ) - > is_key_pressed ( KEY_CONTROL ) ;
2014-02-10 01:10:30 +00:00
}
void SpatialEditor : : _notification ( int p_what ) {
2017-03-05 15:44:50 +00:00
if ( p_what = = NOTIFICATION_READY ) {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
tool_button [ SpatialEditor : : TOOL_MODE_SELECT ] - > set_icon ( get_icon ( " ToolSelect " , " EditorIcons " ) ) ;
tool_button [ SpatialEditor : : TOOL_MODE_MOVE ] - > set_icon ( get_icon ( " ToolMove " , " EditorIcons " ) ) ;
tool_button [ SpatialEditor : : TOOL_MODE_ROTATE ] - > set_icon ( get_icon ( " ToolRotate " , " EditorIcons " ) ) ;
tool_button [ SpatialEditor : : TOOL_MODE_SCALE ] - > set_icon ( get_icon ( " ToolScale " , " EditorIcons " ) ) ;
tool_button [ SpatialEditor : : TOOL_MODE_LIST_SELECT ] - > set_icon ( get_icon ( " ListSelect " , " EditorIcons " ) ) ;
2017-10-23 19:21:15 +00:00
tool_button [ SpatialEditor : : TOOL_LOCK_SELECTED ] - > set_icon ( get_icon ( " Lock " , " EditorIcons " ) ) ;
tool_button [ SpatialEditor : : TOOL_UNLOCK_SELECTED ] - > set_icon ( get_icon ( " Unlock " , " EditorIcons " ) ) ;
2019-04-17 16:24:28 +00:00
tool_button [ SpatialEditor : : TOOL_GROUP_SELECTED ] - > set_icon ( get_icon ( " Group " , " EditorIcons " ) ) ;
tool_button [ SpatialEditor : : TOOL_UNGROUP_SELECTED ] - > set_icon ( get_icon ( " Ungroup " , " EditorIcons " ) ) ;
2014-02-10 01:10:30 +00:00
2017-11-18 18:51:37 +00:00
tool_option_button [ SpatialEditor : : TOOL_OPT_LOCAL_COORDS ] - > set_icon ( get_icon ( " Object " , " EditorIcons " ) ) ;
tool_option_button [ SpatialEditor : : TOOL_OPT_USE_SNAP ] - > set_icon ( get_icon ( " Snap " , " EditorIcons " ) ) ;
2019-04-06 20:55:01 +00:00
tool_option_button [ SpatialEditor : : TOOL_OPT_OVERRIDE_CAMERA ] - > set_icon ( get_icon ( " Camera " , " EditorIcons " ) ) ;
2017-11-18 18:51:37 +00:00
2017-03-05 15:44:50 +00:00
view_menu - > get_popup ( ) - > set_item_icon ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_1_VIEWPORT ) , get_icon ( " Panels1 " , " EditorIcons " ) ) ;
view_menu - > get_popup ( ) - > set_item_icon ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_2_VIEWPORTS ) , get_icon ( " Panels2 " , " EditorIcons " ) ) ;
view_menu - > get_popup ( ) - > set_item_icon ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_2_VIEWPORTS_ALT ) , get_icon ( " Panels2Alt " , " EditorIcons " ) ) ;
view_menu - > get_popup ( ) - > set_item_icon ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_3_VIEWPORTS ) , get_icon ( " Panels3 " , " EditorIcons " ) ) ;
view_menu - > get_popup ( ) - > set_item_icon ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_3_VIEWPORTS_ALT ) , get_icon ( " Panels3Alt " , " EditorIcons " ) ) ;
view_menu - > get_popup ( ) - > set_item_icon ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_4_VIEWPORTS ) , get_icon ( " Panels4 " , " EditorIcons " ) ) ;
2014-02-10 01:10:30 +00:00
_menu_item_pressed ( MENU_VIEW_USE_1_VIEWPORT ) ;
2017-10-23 19:21:15 +00:00
_refresh_menu_icons ( ) ;
2017-03-05 15:44:50 +00:00
get_tree ( ) - > connect ( " node_removed " , this , " _node_removed " ) ;
2017-10-23 19:21:15 +00:00
EditorNode : : get_singleton ( ) - > get_scene_tree_dock ( ) - > get_tree_editor ( ) - > connect ( " node_changed " , this , " _refresh_menu_icons " ) ;
editor_selection - > connect ( " selection_changed " , this , " _refresh_menu_icons " ) ;
2019-04-06 20:55:01 +00:00
editor - > connect ( " stop_pressed " , this , " _update_camera_override_button " , make_binds ( false ) ) ;
editor - > connect ( " play_pressed " , this , " _update_camera_override_button " , make_binds ( true ) ) ;
2019-02-15 17:32:38 +00:00
} else if ( p_what = = NOTIFICATION_ENTER_TREE ) {
2014-02-10 01:10:30 +00:00
2018-10-29 10:30:28 +00:00
_register_all_gizmos ( ) ;
_update_gizmos_menu ( ) ;
2014-02-10 01:10:30 +00:00
_init_indicators ( ) ;
2019-02-15 17:32:38 +00:00
} else if ( p_what = = NOTIFICATION_THEME_CHANGED ) {
_update_gizmos_menu_theme ( ) ;
} else if ( p_what = = NOTIFICATION_EXIT_TREE ) {
2014-02-10 01:10:30 +00:00
_finish_indicators ( ) ;
2019-02-15 17:32:38 +00:00
} else if ( p_what = = EditorSettings : : NOTIFICATION_EDITOR_SETTINGS_CHANGED ) {
2017-08-29 23:03:13 +00:00
tool_button [ SpatialEditor : : TOOL_MODE_SELECT ] - > set_icon ( get_icon ( " ToolSelect " , " EditorIcons " ) ) ;
tool_button [ SpatialEditor : : TOOL_MODE_MOVE ] - > set_icon ( get_icon ( " ToolMove " , " EditorIcons " ) ) ;
tool_button [ SpatialEditor : : TOOL_MODE_ROTATE ] - > set_icon ( get_icon ( " ToolRotate " , " EditorIcons " ) ) ;
tool_button [ SpatialEditor : : TOOL_MODE_SCALE ] - > set_icon ( get_icon ( " ToolScale " , " EditorIcons " ) ) ;
tool_button [ SpatialEditor : : TOOL_MODE_LIST_SELECT ] - > set_icon ( get_icon ( " ListSelect " , " EditorIcons " ) ) ;
2019-08-30 08:19:31 +00:00
tool_button [ SpatialEditor : : TOOL_LOCK_SELECTED ] - > set_icon ( get_icon ( " Lock " , " EditorIcons " ) ) ;
tool_button [ SpatialEditor : : TOOL_UNLOCK_SELECTED ] - > set_icon ( get_icon ( " Unlock " , " EditorIcons " ) ) ;
tool_button [ SpatialEditor : : TOOL_GROUP_SELECTED ] - > set_icon ( get_icon ( " Group " , " EditorIcons " ) ) ;
tool_button [ SpatialEditor : : TOOL_UNGROUP_SELECTED ] - > set_icon ( get_icon ( " Ungroup " , " EditorIcons " ) ) ;
2017-08-29 23:03:13 +00:00
2017-11-18 18:51:37 +00:00
tool_option_button [ SpatialEditor : : TOOL_OPT_LOCAL_COORDS ] - > set_icon ( get_icon ( " Object " , " EditorIcons " ) ) ;
tool_option_button [ SpatialEditor : : TOOL_OPT_USE_SNAP ] - > set_icon ( get_icon ( " Snap " , " EditorIcons " ) ) ;
2017-08-29 23:03:13 +00:00
view_menu - > get_popup ( ) - > set_item_icon ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_1_VIEWPORT ) , get_icon ( " Panels1 " , " EditorIcons " ) ) ;
view_menu - > get_popup ( ) - > set_item_icon ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_2_VIEWPORTS ) , get_icon ( " Panels2 " , " EditorIcons " ) ) ;
view_menu - > get_popup ( ) - > set_item_icon ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_2_VIEWPORTS_ALT ) , get_icon ( " Panels2Alt " , " EditorIcons " ) ) ;
view_menu - > get_popup ( ) - > set_item_icon ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_3_VIEWPORTS ) , get_icon ( " Panels3 " , " EditorIcons " ) ) ;
view_menu - > get_popup ( ) - > set_item_icon ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_3_VIEWPORTS_ALT ) , get_icon ( " Panels3Alt " , " EditorIcons " ) ) ;
view_menu - > get_popup ( ) - > set_item_icon ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_4_VIEWPORTS ) , get_icon ( " Panels4 " , " EditorIcons " ) ) ;
2017-12-08 22:45:33 +00:00
// Update grid color by rebuilding grid.
_finish_grid ( ) ;
_init_grid ( ) ;
2019-04-06 20:55:01 +00:00
} else if ( p_what = = NOTIFICATION_VISIBILITY_CHANGED ) {
if ( ! is_visible ( ) & & tool_option_button [ TOOL_OPT_OVERRIDE_CAMERA ] - > is_pressed ( ) ) {
ScriptEditorDebugger * debugger = ScriptEditor : : get_singleton ( ) - > get_debugger ( ) ;
debugger - > set_camera_override ( ScriptEditorDebugger : : OVERRIDE_NONE ) ;
tool_option_button [ TOOL_OPT_OVERRIDE_CAMERA ] - > set_pressed ( false ) ;
}
2017-08-29 23:03:13 +00:00
}
2014-02-10 01:10:30 +00:00
}
void SpatialEditor : : add_control_to_menu_panel ( Control * p_control ) {
hbc_menu - > add_child ( p_control ) ;
}
2018-02-13 21:21:19 +00:00
void SpatialEditor : : remove_control_from_menu_panel ( Control * p_control ) {
hbc_menu - > remove_child ( p_control ) ;
}
2017-03-05 15:44:50 +00:00
void SpatialEditor : : set_can_preview ( Camera * p_preview ) {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < 4 ; i + + ) {
2014-02-10 01:10:30 +00:00
viewports [ i ] - > set_can_preview ( p_preview ) ;
}
}
VSplitContainer * SpatialEditor : : get_shader_split ( ) {
return shader_split ;
}
2017-12-01 00:50:09 +00:00
HSplitContainer * SpatialEditor : : get_palette_split ( ) {
2014-02-10 01:10:30 +00:00
2017-12-01 00:50:09 +00:00
return palette_split ;
2014-02-10 01:10:30 +00:00
}
2017-03-05 15:44:50 +00:00
void SpatialEditor : : _request_gizmo ( Object * p_obj ) {
2014-02-10 01:10:30 +00:00
2017-08-24 20:58:51 +00:00
Spatial * sp = Object : : cast_to < Spatial > ( p_obj ) ;
2014-02-10 01:10:30 +00:00
if ( ! sp )
return ;
2017-08-26 03:40:45 +00:00
if ( editor - > get_edited_scene ( ) & & ( sp = = editor - > get_edited_scene ( ) | | ( sp - > get_owner ( ) & & editor - > get_edited_scene ( ) - > is_a_parent_of ( sp ) ) ) ) {
2014-02-10 01:10:30 +00:00
2018-07-24 22:08:49 +00:00
Ref < EditorSpatialGizmo > seg ;
2014-02-10 01:10:30 +00:00
2019-03-11 23:30:50 +00:00
for ( int i = 0 ; i < gizmo_plugins_by_priority . size ( ) ; + + i ) {
seg = gizmo_plugins_by_priority . write [ i ] - > get_gizmo ( sp ) ;
2014-02-10 01:10:30 +00:00
2018-07-24 22:08:49 +00:00
if ( seg . is_valid ( ) ) {
sp - > set_gizmo ( seg ) ;
2014-05-05 01:50:23 +00:00
2018-07-24 22:08:49 +00:00
if ( sp = = selected ) {
seg - > set_selected ( true ) ;
selected - > update_gizmo ( ) ;
}
2014-05-05 01:50:23 +00:00
2018-07-24 22:08:49 +00:00
break ;
}
2014-05-05 01:50:23 +00:00
}
2014-02-10 01:10:30 +00:00
}
}
2017-03-05 15:44:50 +00:00
void SpatialEditor : : _toggle_maximize_view ( Object * p_viewport ) {
2014-04-01 10:45:48 +00:00
if ( ! p_viewport ) return ;
2017-08-24 20:58:51 +00:00
SpatialEditorViewport * current_viewport = Object : : cast_to < SpatialEditorViewport > ( p_viewport ) ;
2014-04-01 10:45:48 +00:00
if ( ! current_viewport ) return ;
2017-03-05 15:44:50 +00:00
int index = - 1 ;
2014-04-01 10:45:48 +00:00
bool maximized = false ;
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < 4 ; i + + ) {
if ( viewports [ i ] = = current_viewport ) {
index = i ;
if ( current_viewport - > get_global_rect ( ) = = viewport_base - > get_global_rect ( ) )
maximized = true ;
2014-04-01 10:45:48 +00:00
break ;
}
}
2017-03-05 15:44:50 +00:00
if ( index = = - 1 ) return ;
2014-04-01 10:45:48 +00:00
if ( ! maximized ) {
2017-08-31 21:30:35 +00:00
for ( uint32_t i = 0 ; i < VIEWPORTS_COUNT ; i + + ) {
if ( i = = ( uint32_t ) index )
2017-09-21 22:12:33 +00:00
viewports [ i ] - > set_anchors_and_margins_preset ( Control : : PRESET_WIDE ) ;
2014-04-01 10:45:48 +00:00
else
viewports [ i ] - > hide ( ) ;
}
} else {
2017-08-31 21:30:35 +00:00
for ( uint32_t i = 0 ; i < VIEWPORTS_COUNT ; i + + )
2014-04-01 10:45:48 +00:00
viewports [ i ] - > show ( ) ;
2017-03-05 15:44:50 +00:00
if ( view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_1_VIEWPORT ) ) )
2014-04-01 10:45:48 +00:00
_menu_item_pressed ( MENU_VIEW_USE_1_VIEWPORT ) ;
2017-03-05 15:44:50 +00:00
else if ( view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_2_VIEWPORTS ) ) )
2014-04-01 10:45:48 +00:00
_menu_item_pressed ( MENU_VIEW_USE_2_VIEWPORTS ) ;
2017-03-05 15:44:50 +00:00
else if ( view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_2_VIEWPORTS_ALT ) ) )
2014-10-09 03:06:51 +00:00
_menu_item_pressed ( MENU_VIEW_USE_2_VIEWPORTS_ALT ) ;
2017-03-05 15:44:50 +00:00
else if ( view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_3_VIEWPORTS ) ) )
2014-04-01 10:45:48 +00:00
_menu_item_pressed ( MENU_VIEW_USE_3_VIEWPORTS ) ;
2017-03-05 15:44:50 +00:00
else if ( view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_3_VIEWPORTS_ALT ) ) )
2014-10-09 03:06:51 +00:00
_menu_item_pressed ( MENU_VIEW_USE_3_VIEWPORTS_ALT ) ;
2017-03-05 15:44:50 +00:00
else if ( view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_4_VIEWPORTS ) ) )
2014-04-01 10:45:48 +00:00
_menu_item_pressed ( MENU_VIEW_USE_4_VIEWPORTS ) ;
}
}
2017-03-05 15:44:50 +00:00
void SpatialEditor : : _node_removed ( Node * p_node ) {
2014-05-05 01:50:23 +00:00
2017-03-05 15:44:50 +00:00
if ( p_node = = selected )
selected = NULL ;
2014-05-05 01:50:23 +00:00
}
2018-07-24 22:08:49 +00:00
void SpatialEditor : : _register_all_gizmos ( ) {
2018-10-29 10:30:28 +00:00
add_gizmo_plugin ( Ref < CameraSpatialGizmoPlugin > ( memnew ( CameraSpatialGizmoPlugin ) ) ) ;
add_gizmo_plugin ( Ref < LightSpatialGizmoPlugin > ( memnew ( LightSpatialGizmoPlugin ) ) ) ;
add_gizmo_plugin ( Ref < AudioStreamPlayer3DSpatialGizmoPlugin > ( memnew ( AudioStreamPlayer3DSpatialGizmoPlugin ) ) ) ;
add_gizmo_plugin ( Ref < MeshInstanceSpatialGizmoPlugin > ( memnew ( MeshInstanceSpatialGizmoPlugin ) ) ) ;
add_gizmo_plugin ( Ref < SoftBodySpatialGizmoPlugin > ( memnew ( SoftBodySpatialGizmoPlugin ) ) ) ;
add_gizmo_plugin ( Ref < Sprite3DSpatialGizmoPlugin > ( memnew ( Sprite3DSpatialGizmoPlugin ) ) ) ;
add_gizmo_plugin ( Ref < SkeletonSpatialGizmoPlugin > ( memnew ( SkeletonSpatialGizmoPlugin ) ) ) ;
add_gizmo_plugin ( Ref < Position3DSpatialGizmoPlugin > ( memnew ( Position3DSpatialGizmoPlugin ) ) ) ;
add_gizmo_plugin ( Ref < RayCastSpatialGizmoPlugin > ( memnew ( RayCastSpatialGizmoPlugin ) ) ) ;
add_gizmo_plugin ( Ref < SpringArmSpatialGizmoPlugin > ( memnew ( SpringArmSpatialGizmoPlugin ) ) ) ;
add_gizmo_plugin ( Ref < VehicleWheelSpatialGizmoPlugin > ( memnew ( VehicleWheelSpatialGizmoPlugin ) ) ) ;
add_gizmo_plugin ( Ref < VisibilityNotifierGizmoPlugin > ( memnew ( VisibilityNotifierGizmoPlugin ) ) ) ;
add_gizmo_plugin ( Ref < ParticlesGizmoPlugin > ( memnew ( ParticlesGizmoPlugin ) ) ) ;
2019-08-08 06:18:09 +00:00
add_gizmo_plugin ( Ref < CPUParticlesGizmoPlugin > ( memnew ( CPUParticlesGizmoPlugin ) ) ) ;
2018-10-29 10:30:28 +00:00
add_gizmo_plugin ( Ref < ReflectionProbeGizmoPlugin > ( memnew ( ReflectionProbeGizmoPlugin ) ) ) ;
add_gizmo_plugin ( Ref < GIProbeGizmoPlugin > ( memnew ( GIProbeGizmoPlugin ) ) ) ;
add_gizmo_plugin ( Ref < BakedIndirectLightGizmoPlugin > ( memnew ( BakedIndirectLightGizmoPlugin ) ) ) ;
add_gizmo_plugin ( Ref < CollisionShapeSpatialGizmoPlugin > ( memnew ( CollisionShapeSpatialGizmoPlugin ) ) ) ;
add_gizmo_plugin ( Ref < CollisionPolygonSpatialGizmoPlugin > ( memnew ( CollisionPolygonSpatialGizmoPlugin ) ) ) ;
add_gizmo_plugin ( Ref < NavigationMeshSpatialGizmoPlugin > ( memnew ( NavigationMeshSpatialGizmoPlugin ) ) ) ;
add_gizmo_plugin ( Ref < JointSpatialGizmoPlugin > ( memnew ( JointSpatialGizmoPlugin ) ) ) ;
add_gizmo_plugin ( Ref < PhysicalBoneSpatialGizmoPlugin > ( memnew ( PhysicalBoneSpatialGizmoPlugin ) ) ) ;
2018-07-24 22:08:49 +00:00
}
2014-02-10 01:10:30 +00:00
void SpatialEditor : : _bind_methods ( ) {
2017-03-05 15:44:50 +00:00
ClassDB : : bind_method ( " _unhandled_key_input " , & SpatialEditor : : _unhandled_key_input ) ;
ClassDB : : bind_method ( " _node_removed " , & SpatialEditor : : _node_removed ) ;
ClassDB : : bind_method ( " _menu_item_pressed " , & SpatialEditor : : _menu_item_pressed ) ;
2018-07-24 22:08:49 +00:00
ClassDB : : bind_method ( " _menu_gizmo_toggled " , & SpatialEditor : : _menu_gizmo_toggled ) ;
2017-11-18 18:51:37 +00:00
ClassDB : : bind_method ( " _menu_item_toggled " , & SpatialEditor : : _menu_item_toggled ) ;
2017-03-05 15:44:50 +00:00
ClassDB : : bind_method ( " _xform_dialog_action " , & SpatialEditor : : _xform_dialog_action ) ;
ClassDB : : bind_method ( " _get_editor_data " , & SpatialEditor : : _get_editor_data ) ;
ClassDB : : bind_method ( " _request_gizmo " , & SpatialEditor : : _request_gizmo ) ;
ClassDB : : bind_method ( " _toggle_maximize_view " , & SpatialEditor : : _toggle_maximize_view ) ;
2017-10-23 19:21:15 +00:00
ClassDB : : bind_method ( " _refresh_menu_icons " , & SpatialEditor : : _refresh_menu_icons ) ;
2019-04-06 20:55:01 +00:00
ClassDB : : bind_method ( " _update_camera_override_button " , & SpatialEditor : : _update_camera_override_button ) ;
ClassDB : : bind_method ( " _update_camera_override_viewport " , & SpatialEditor : : _update_camera_override_viewport ) ;
2020-03-08 19:31:11 +00:00
ClassDB : : bind_method ( " _snap_changed " , & SpatialEditor : : _snap_changed ) ;
ClassDB : : bind_method ( " _snap_update " , & SpatialEditor : : _snap_update ) ;
2014-04-01 10:45:48 +00:00
2017-03-05 15:44:50 +00:00
ADD_SIGNAL ( MethodInfo ( " transform_key_request " ) ) ;
2017-10-23 19:21:15 +00:00
ADD_SIGNAL ( MethodInfo ( " item_lock_status_changed " ) ) ;
2019-04-17 16:24:28 +00:00
ADD_SIGNAL ( MethodInfo ( " item_group_status_changed " ) ) ;
2014-09-19 21:39:50 +00:00
}
void SpatialEditor : : clear ( ) {
2017-11-25 22:03:26 +00:00
settings_fov - > set_value ( EDITOR_DEF ( " editors/3d/default_fov " , 70.0 ) ) ;
settings_znear - > set_value ( EDITOR_DEF ( " editors/3d/default_z_near " , 0.05 ) ) ;
2017-03-05 15:44:50 +00:00
settings_zfar - > set_value ( EDITOR_DEF ( " editors/3d/default_z_far " , 1500.0 ) ) ;
2014-09-19 21:39:50 +00:00
2017-08-31 21:30:35 +00:00
for ( uint32_t i = 0 ; i < VIEWPORTS_COUNT ; i + + ) {
2014-09-19 21:39:50 +00:00
viewports [ i ] - > reset ( ) ;
}
2017-03-05 15:44:50 +00:00
VisualServer : : get_singleton ( ) - > instance_set_visible ( origin_instance , true ) ;
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_ORIGIN ) , true ) ;
for ( int i = 0 ; i < 3 ; + + i ) {
2014-09-19 21:39:50 +00:00
if ( grid_enable [ i ] ) {
2017-03-05 15:44:50 +00:00
VisualServer : : get_singleton ( ) - > instance_set_visible ( grid_instance [ i ] , true ) ;
grid_visible [ i ] = true ;
2014-09-19 21:39:50 +00:00
}
}
2017-08-31 21:30:35 +00:00
for ( uint32_t i = 0 ; i < VIEWPORTS_COUNT ; i + + ) {
2014-10-03 03:10:51 +00:00
2017-03-05 15:44:50 +00:00
viewports [ i ] - > view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( SpatialEditorViewport : : VIEW_AUDIO_LISTENER ) , i = = 0 ) ;
viewports [ i ] - > viewport - > set_as_audio_listener ( i = = 0 ) ;
2014-10-03 03:10:51 +00:00
}
2014-10-12 05:13:22 +00:00
2017-03-05 15:44:50 +00:00
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_GRID ) , true ) ;
2014-02-10 01:10:30 +00:00
}
SpatialEditor : : SpatialEditor ( EditorNode * p_editor ) {
2017-03-05 15:44:50 +00:00
gizmo . visible = true ;
gizmo . scale = 1.0 ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
viewport_environment = Ref < Environment > ( memnew ( Environment ) ) ;
undo_redo = p_editor - > get_undo_redo ( ) ;
2014-02-10 01:10:30 +00:00
VBoxContainer * vbc = this ;
2017-03-05 15:44:50 +00:00
custom_camera = NULL ;
singleton = this ;
editor = p_editor ;
editor_selection = editor - > get_editor_selection ( ) ;
2014-02-10 01:10:30 +00:00
editor_selection - > add_editor_plugin ( this ) ;
2017-03-05 15:44:50 +00:00
snap_enabled = false ;
2018-02-21 14:14:26 +00:00
snap_key_enabled = false ;
2014-02-10 01:10:30 +00:00
tool_mode = TOOL_MODE_SELECT ;
2019-04-06 20:55:01 +00:00
camera_override_viewport_id = 0 ;
2017-03-05 15:44:50 +00:00
hbc_menu = memnew ( HBoxContainer ) ;
2014-02-10 01:10:30 +00:00
vbc - > add_child ( hbc_menu ) ;
Vector < Variant > button_binds ;
button_binds . resize ( 1 ) ;
2017-11-18 18:51:37 +00:00
String sct ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
tool_button [ TOOL_MODE_SELECT ] = memnew ( ToolButton ) ;
hbc_menu - > add_child ( tool_button [ TOOL_MODE_SELECT ] ) ;
2014-02-10 01:10:30 +00:00
tool_button [ TOOL_MODE_SELECT ] - > set_toggle_mode ( true ) ;
tool_button [ TOOL_MODE_SELECT ] - > set_flat ( true ) ;
tool_button [ TOOL_MODE_SELECT ] - > set_pressed ( true ) ;
2018-07-25 01:11:03 +00:00
button_binds . write [ 0 ] = MENU_TOOL_SELECT ;
2017-03-05 15:44:50 +00:00
tool_button [ TOOL_MODE_SELECT ] - > connect ( " pressed " , this , " _menu_item_pressed " , button_binds ) ;
2019-08-17 21:37:13 +00:00
tool_button [ TOOL_MODE_SELECT ] - > set_shortcut ( ED_SHORTCUT ( " spatial_editor/tool_select " , TTR ( " Select Mode " ) , KEY_Q ) ) ;
tool_button [ TOOL_MODE_SELECT ] - > set_tooltip ( keycode_get_string ( KEY_MASK_CMD ) + TTR ( " Drag: Rotate \n Alt+Drag: Move \n Alt+RMB: Depth list selection " ) ) ;
2014-02-10 01:10:30 +00:00
2018-09-15 15:44:26 +00:00
hbc_menu - > add_child ( memnew ( VSeparator ) ) ;
2017-03-05 15:44:50 +00:00
tool_button [ TOOL_MODE_MOVE ] = memnew ( ToolButton ) ;
hbc_menu - > add_child ( tool_button [ TOOL_MODE_MOVE ] ) ;
2014-02-10 01:10:30 +00:00
tool_button [ TOOL_MODE_MOVE ] - > set_toggle_mode ( true ) ;
tool_button [ TOOL_MODE_MOVE ] - > set_flat ( true ) ;
2018-07-25 01:11:03 +00:00
button_binds . write [ 0 ] = MENU_TOOL_MOVE ;
2017-03-05 15:44:50 +00:00
tool_button [ TOOL_MODE_MOVE ] - > connect ( " pressed " , this , " _menu_item_pressed " , button_binds ) ;
2019-08-17 21:37:13 +00:00
tool_button [ TOOL_MODE_MOVE ] - > set_shortcut ( ED_SHORTCUT ( " spatial_editor/tool_move " , TTR ( " Move Mode " ) , KEY_W ) ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
tool_button [ TOOL_MODE_ROTATE ] = memnew ( ToolButton ) ;
hbc_menu - > add_child ( tool_button [ TOOL_MODE_ROTATE ] ) ;
2014-02-10 01:10:30 +00:00
tool_button [ TOOL_MODE_ROTATE ] - > set_toggle_mode ( true ) ;
tool_button [ TOOL_MODE_ROTATE ] - > set_flat ( true ) ;
2018-07-25 01:11:03 +00:00
button_binds . write [ 0 ] = MENU_TOOL_ROTATE ;
2017-03-05 15:44:50 +00:00
tool_button [ TOOL_MODE_ROTATE ] - > connect ( " pressed " , this , " _menu_item_pressed " , button_binds ) ;
2019-08-17 21:37:13 +00:00
tool_button [ TOOL_MODE_ROTATE ] - > set_shortcut ( ED_SHORTCUT ( " spatial_editor/tool_rotate " , TTR ( " Rotate Mode " ) , KEY_E ) ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
tool_button [ TOOL_MODE_SCALE ] = memnew ( ToolButton ) ;
hbc_menu - > add_child ( tool_button [ TOOL_MODE_SCALE ] ) ;
2014-02-10 01:10:30 +00:00
tool_button [ TOOL_MODE_SCALE ] - > set_toggle_mode ( true ) ;
tool_button [ TOOL_MODE_SCALE ] - > set_flat ( true ) ;
2018-07-25 01:11:03 +00:00
button_binds . write [ 0 ] = MENU_TOOL_SCALE ;
2017-03-05 15:44:50 +00:00
tool_button [ TOOL_MODE_SCALE ] - > connect ( " pressed " , this , " _menu_item_pressed " , button_binds ) ;
2019-08-17 21:37:13 +00:00
tool_button [ TOOL_MODE_SCALE ] - > set_shortcut ( ED_SHORTCUT ( " spatial_editor/tool_scale " , TTR ( " Scale Mode " ) , KEY_R ) ) ;
2014-02-10 01:10:30 +00:00
2018-09-15 15:44:26 +00:00
hbc_menu - > add_child ( memnew ( VSeparator ) ) ;
2017-03-05 15:44:50 +00:00
tool_button [ TOOL_MODE_LIST_SELECT ] = memnew ( ToolButton ) ;
hbc_menu - > add_child ( tool_button [ TOOL_MODE_LIST_SELECT ] ) ;
2015-12-13 20:16:13 +00:00
tool_button [ TOOL_MODE_LIST_SELECT ] - > set_toggle_mode ( true ) ;
tool_button [ TOOL_MODE_LIST_SELECT ] - > set_flat ( true ) ;
2018-07-25 01:11:03 +00:00
button_binds . write [ 0 ] = MENU_TOOL_LIST_SELECT ;
2017-03-05 15:44:50 +00:00
tool_button [ TOOL_MODE_LIST_SELECT ] - > connect ( " pressed " , this , " _menu_item_pressed " , button_binds ) ;
2016-06-01 11:32:20 +00:00
tool_button [ TOOL_MODE_LIST_SELECT ] - > set_tooltip ( TTR ( " Show a list of all objects at the position clicked \n (same as Alt+RMB in select mode). " ) ) ;
2015-12-13 20:16:13 +00:00
2017-10-23 19:21:15 +00:00
tool_button [ TOOL_LOCK_SELECTED ] = memnew ( ToolButton ) ;
hbc_menu - > add_child ( tool_button [ TOOL_LOCK_SELECTED ] ) ;
2018-07-25 01:11:03 +00:00
button_binds . write [ 0 ] = MENU_LOCK_SELECTED ;
2017-10-23 19:21:15 +00:00
tool_button [ TOOL_LOCK_SELECTED ] - > connect ( " pressed " , this , " _menu_item_pressed " , button_binds ) ;
tool_button [ TOOL_LOCK_SELECTED ] - > set_tooltip ( TTR ( " Lock the selected object in place (can't be moved). " ) ) ;
tool_button [ TOOL_UNLOCK_SELECTED ] = memnew ( ToolButton ) ;
hbc_menu - > add_child ( tool_button [ TOOL_UNLOCK_SELECTED ] ) ;
2018-07-25 01:11:03 +00:00
button_binds . write [ 0 ] = MENU_UNLOCK_SELECTED ;
2017-10-23 19:21:15 +00:00
tool_button [ TOOL_UNLOCK_SELECTED ] - > connect ( " pressed " , this , " _menu_item_pressed " , button_binds ) ;
tool_button [ TOOL_UNLOCK_SELECTED ] - > set_tooltip ( TTR ( " Unlock the selected object (can be moved). " ) ) ;
2019-04-17 16:24:28 +00:00
tool_button [ TOOL_GROUP_SELECTED ] = memnew ( ToolButton ) ;
hbc_menu - > add_child ( tool_button [ TOOL_GROUP_SELECTED ] ) ;
button_binds . write [ 0 ] = MENU_GROUP_SELECTED ;
tool_button [ TOOL_GROUP_SELECTED ] - > connect ( " pressed " , this , " _menu_item_pressed " , button_binds ) ;
tool_button [ TOOL_GROUP_SELECTED ] - > set_tooltip ( TTR ( " Makes sure the object's children are not selectable. " ) ) ;
tool_button [ TOOL_UNGROUP_SELECTED ] = memnew ( ToolButton ) ;
hbc_menu - > add_child ( tool_button [ TOOL_UNGROUP_SELECTED ] ) ;
button_binds . write [ 0 ] = MENU_UNGROUP_SELECTED ;
tool_button [ TOOL_UNGROUP_SELECTED ] - > connect ( " pressed " , this , " _menu_item_pressed " , button_binds ) ;
tool_button [ TOOL_UNGROUP_SELECTED ] - > set_tooltip ( TTR ( " Restores the object's children's ability to be selected. " ) ) ;
2018-09-15 15:44:26 +00:00
hbc_menu - > add_child ( memnew ( VSeparator ) ) ;
2017-11-18 18:51:37 +00:00
tool_option_button [ TOOL_OPT_LOCAL_COORDS ] = memnew ( ToolButton ) ;
hbc_menu - > add_child ( tool_option_button [ TOOL_OPT_LOCAL_COORDS ] ) ;
tool_option_button [ TOOL_OPT_LOCAL_COORDS ] - > set_toggle_mode ( true ) ;
tool_option_button [ TOOL_OPT_LOCAL_COORDS ] - > set_flat ( true ) ;
2018-07-25 01:11:03 +00:00
button_binds . write [ 0 ] = MENU_TOOL_LOCAL_COORDS ;
2017-11-18 18:51:37 +00:00
tool_option_button [ TOOL_OPT_LOCAL_COORDS ] - > connect ( " toggled " , this , " _menu_item_toggled " , button_binds ) ;
2019-08-17 21:37:13 +00:00
tool_option_button [ TOOL_OPT_LOCAL_COORDS ] - > set_shortcut ( ED_SHORTCUT ( " spatial_editor/local_coords " , TTR ( " Use Local Space " ) , KEY_T ) ) ;
2017-11-18 18:51:37 +00:00
tool_option_button [ TOOL_OPT_USE_SNAP ] = memnew ( ToolButton ) ;
hbc_menu - > add_child ( tool_option_button [ TOOL_OPT_USE_SNAP ] ) ;
tool_option_button [ TOOL_OPT_USE_SNAP ] - > set_toggle_mode ( true ) ;
tool_option_button [ TOOL_OPT_USE_SNAP ] - > set_flat ( true ) ;
2018-07-25 01:11:03 +00:00
button_binds . write [ 0 ] = MENU_TOOL_USE_SNAP ;
2017-11-18 18:51:37 +00:00
tool_option_button [ TOOL_OPT_USE_SNAP ] - > connect ( " toggled " , this , " _menu_item_toggled " , button_binds ) ;
2019-08-17 21:37:13 +00:00
tool_option_button [ TOOL_OPT_USE_SNAP ] - > set_shortcut ( ED_SHORTCUT ( " spatial_editor/snap " , TTR ( " Use Snap " ) , KEY_Y ) ) ;
2017-11-18 18:51:37 +00:00
2018-09-15 15:44:26 +00:00
hbc_menu - > add_child ( memnew ( VSeparator ) ) ;
2015-12-13 20:16:13 +00:00
2019-04-06 20:55:01 +00:00
tool_option_button [ TOOL_OPT_OVERRIDE_CAMERA ] = memnew ( ToolButton ) ;
hbc_menu - > add_child ( tool_option_button [ TOOL_OPT_OVERRIDE_CAMERA ] ) ;
tool_option_button [ TOOL_OPT_OVERRIDE_CAMERA ] - > set_toggle_mode ( true ) ;
tool_option_button [ TOOL_OPT_OVERRIDE_CAMERA ] - > set_flat ( true ) ;
tool_option_button [ TOOL_OPT_OVERRIDE_CAMERA ] - > set_disabled ( true ) ;
button_binds . write [ 0 ] = MENU_TOOL_OVERRIDE_CAMERA ;
tool_option_button [ TOOL_OPT_OVERRIDE_CAMERA ] - > connect ( " toggled " , this , " _menu_item_toggled " , button_binds ) ;
_update_camera_override_button ( false ) ;
hbc_menu - > add_child ( memnew ( VSeparator ) ) ;
2017-09-02 19:47:16 +00:00
// Drag and drop support;
preview_node = memnew ( Spatial ) ;
2017-11-17 02:09:00 +00:00
preview_bounds = AABB ( ) ;
2017-09-02 19:47:16 +00:00
2017-03-05 15:44:50 +00:00
ED_SHORTCUT ( " spatial_editor/bottom_view " , TTR ( " Bottom View " ) , KEY_MASK_ALT + KEY_KP_7 ) ;
2016-06-30 20:54:34 +00:00
ED_SHORTCUT ( " spatial_editor/top_view " , TTR ( " Top View " ) , KEY_KP_7 ) ;
2017-03-05 15:44:50 +00:00
ED_SHORTCUT ( " spatial_editor/rear_view " , TTR ( " Rear View " ) , KEY_MASK_ALT + KEY_KP_1 ) ;
2016-06-30 20:54:34 +00:00
ED_SHORTCUT ( " spatial_editor/front_view " , TTR ( " Front View " ) , KEY_KP_1 ) ;
2017-03-05 15:44:50 +00:00
ED_SHORTCUT ( " spatial_editor/left_view " , TTR ( " Left View " ) , KEY_MASK_ALT + KEY_KP_3 ) ;
2016-06-30 20:54:34 +00:00
ED_SHORTCUT ( " spatial_editor/right_view " , TTR ( " Right View " ) , KEY_KP_3 ) ;
2019-05-19 21:08:07 +00:00
ED_SHORTCUT ( " spatial_editor/switch_perspective_orthogonal " , TTR ( " Switch Perspective/Orthogonal View " ) , KEY_KP_5 ) ;
2016-06-30 20:54:34 +00:00
ED_SHORTCUT ( " spatial_editor/insert_anim_key " , TTR ( " Insert Animation Key " ) , KEY_K ) ;
2016-10-04 18:39:38 +00:00
ED_SHORTCUT ( " spatial_editor/focus_origin " , TTR ( " Focus Origin " ) , KEY_O ) ;
2016-06-30 20:54:34 +00:00
ED_SHORTCUT ( " spatial_editor/focus_selection " , TTR ( " Focus Selection " ) , KEY_F ) ;
2018-10-27 21:43:19 +00:00
ED_SHORTCUT ( " spatial_editor/align_transform_with_view " , TTR ( " Align Transform with View " ) , KEY_MASK_ALT + KEY_MASK_CMD + KEY_M ) ;
ED_SHORTCUT ( " spatial_editor/align_rotation_with_view " , TTR ( " Align Rotation with View " ) , KEY_MASK_ALT + KEY_MASK_CMD + KEY_F ) ;
2017-10-30 00:22:48 +00:00
ED_SHORTCUT ( " spatial_editor/freelook_toggle " , TTR ( " Toggle Freelook " ) , KEY_MASK_SHIFT + KEY_F ) ;
2014-02-10 01:10:30 +00:00
PopupMenu * p ;
2017-03-05 15:44:50 +00:00
transform_menu = memnew ( MenuButton ) ;
2016-05-30 18:47:53 +00:00
transform_menu - > set_text ( TTR ( " Transform " ) ) ;
2018-07-29 22:26:43 +00:00
transform_menu - > set_switch_on_hover ( true ) ;
2017-03-05 15:44:50 +00:00
hbc_menu - > add_child ( transform_menu ) ;
2014-02-10 01:10:30 +00:00
p = transform_menu - > get_popup ( ) ;
2019-05-19 21:08:07 +00:00
p - > add_shortcut ( ED_SHORTCUT ( " spatial_editor/snap_to_floor " , TTR ( " Snap Object to Floor " ) , KEY_PAGEDOWN ) , MENU_SNAP_TO_FLOOR ) ;
2018-04-22 17:36:01 +00:00
p - > add_shortcut ( ED_SHORTCUT ( " spatial_editor/transform_dialog " , TTR ( " Transform Dialog... " ) ) , MENU_TRANSFORM_DIALOG ) ;
2014-02-10 01:10:30 +00:00
2019-08-12 20:23:00 +00:00
p - > add_separator ( ) ;
p - > add_shortcut ( ED_SHORTCUT ( " spatial_editor/configure_snap " , TTR ( " Configure Snap... " ) ) , MENU_TRANSFORM_CONFIGURE_SNAP ) ;
2017-03-05 15:44:50 +00:00
p - > connect ( " id_pressed " , this , " _menu_item_pressed " ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
view_menu = memnew ( MenuButton ) ;
2016-05-04 01:25:37 +00:00
view_menu - > set_text ( TTR ( " View " ) ) ;
2018-07-29 22:26:43 +00:00
view_menu - > set_switch_on_hover ( true ) ;
2017-03-05 15:44:50 +00:00
hbc_menu - > add_child ( view_menu ) ;
2014-02-10 01:10:30 +00:00
p = view_menu - > get_popup ( ) ;
2017-09-02 19:47:16 +00:00
accept = memnew ( AcceptDialog ) ;
editor - > get_gui_base ( ) - > add_child ( accept ) ;
2018-03-24 02:05:20 +00:00
p - > add_radio_check_shortcut ( ED_SHORTCUT ( " spatial_editor/1_viewport " , TTR ( " 1 Viewport " ) , KEY_MASK_CMD + KEY_1 ) , MENU_VIEW_USE_1_VIEWPORT ) ;
p - > add_radio_check_shortcut ( ED_SHORTCUT ( " spatial_editor/2_viewports " , TTR ( " 2 Viewports " ) , KEY_MASK_CMD + KEY_2 ) , MENU_VIEW_USE_2_VIEWPORTS ) ;
p - > add_radio_check_shortcut ( ED_SHORTCUT ( " spatial_editor/2_viewports_alt " , TTR ( " 2 Viewports (Alt) " ) , KEY_MASK_ALT + KEY_MASK_CMD + KEY_2 ) , MENU_VIEW_USE_2_VIEWPORTS_ALT ) ;
p - > add_radio_check_shortcut ( ED_SHORTCUT ( " spatial_editor/3_viewports " , TTR ( " 3 Viewports " ) , KEY_MASK_CMD + KEY_3 ) , MENU_VIEW_USE_3_VIEWPORTS ) ;
p - > add_radio_check_shortcut ( ED_SHORTCUT ( " spatial_editor/3_viewports_alt " , TTR ( " 3 Viewports (Alt) " ) , KEY_MASK_ALT + KEY_MASK_CMD + KEY_3 ) , MENU_VIEW_USE_3_VIEWPORTS_ALT ) ;
p - > add_radio_check_shortcut ( ED_SHORTCUT ( " spatial_editor/4_viewports " , TTR ( " 4 Viewports " ) , KEY_MASK_CMD + KEY_4 ) , MENU_VIEW_USE_4_VIEWPORTS ) ;
2014-02-10 01:10:30 +00:00
p - > add_separator ( ) ;
2018-08-11 21:07:00 +00:00
p - > add_submenu_item ( TTR ( " Gizmos " ) , " GizmosMenu " ) ;
2018-08-12 13:20:20 +00:00
p - > add_separator ( ) ;
2016-06-30 20:54:34 +00:00
p - > add_check_shortcut ( ED_SHORTCUT ( " spatial_editor/view_origin " , TTR ( " View Origin " ) ) , MENU_VIEW_ORIGIN ) ;
p - > add_check_shortcut ( ED_SHORTCUT ( " spatial_editor/view_grid " , TTR ( " View Grid " ) ) , MENU_VIEW_GRID ) ;
2019-08-12 20:23:00 +00:00
2014-02-10 01:10:30 +00:00
p - > add_separator ( ) ;
2019-08-12 20:23:00 +00:00
p - > add_shortcut ( ED_SHORTCUT ( " spatial_editor/settings " , TTR ( " Settings... " ) ) , MENU_VIEW_CAMERA_SETTINGS ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
p - > set_item_checked ( p - > get_item_index ( MENU_VIEW_ORIGIN ) , true ) ;
p - > set_item_checked ( p - > get_item_index ( MENU_VIEW_GRID ) , true ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
p - > connect ( " id_pressed " , this , " _menu_item_pressed " ) ;
2014-02-10 01:10:30 +00:00
2018-08-11 21:07:00 +00:00
gizmos_menu = memnew ( PopupMenu ) ;
p - > add_child ( gizmos_menu ) ;
gizmos_menu - > set_name ( " GizmosMenu " ) ;
gizmos_menu - > set_hide_on_checkable_item_selection ( false ) ;
gizmos_menu - > connect ( " id_pressed " , this , " _menu_gizmo_toggled " ) ;
2018-07-24 22:08:49 +00:00
2014-02-10 01:10:30 +00:00
/* REST OF MENU */
2017-03-05 15:44:50 +00:00
palette_split = memnew ( HSplitContainer ) ;
2014-02-10 01:10:30 +00:00
palette_split - > set_v_size_flags ( SIZE_EXPAND_FILL ) ;
vbc - > add_child ( palette_split ) ;
2017-03-05 15:44:50 +00:00
shader_split = memnew ( VSplitContainer ) ;
2014-02-10 01:10:30 +00:00
shader_split - > set_h_size_flags ( SIZE_EXPAND_FILL ) ;
palette_split - > add_child ( shader_split ) ;
2017-06-11 14:29:27 +00:00
viewport_base = memnew ( SpatialEditorViewportContainer ) ;
2014-02-10 01:10:30 +00:00
shader_split - > add_child ( viewport_base ) ;
viewport_base - > set_v_size_flags ( SIZE_EXPAND_FILL ) ;
2017-08-31 21:30:35 +00:00
for ( uint32_t i = 0 ; i < VIEWPORTS_COUNT ; i + + ) {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
viewports [ i ] = memnew ( SpatialEditorViewport ( this , editor , i ) ) ;
viewports [ i ] - > connect ( " toggle_maximize_view " , this , " _toggle_maximize_view " ) ;
2019-04-06 20:55:01 +00:00
viewports [ i ] - > connect ( " clicked " , this , " _update_camera_override_viewport " ) ;
2017-09-02 19:47:16 +00:00
viewports [ i ] - > assign_pending_data_pointers ( preview_node , & preview_bounds , accept ) ;
2014-02-10 01:10:30 +00:00
viewport_base - > add_child ( viewports [ i ] ) ;
}
/* SNAP DIALOG */
2020-03-08 19:31:11 +00:00
snap_translate_value = 1 ;
snap_rotate_value = 15 ;
snap_scale_value = 10 ;
2017-03-05 15:44:50 +00:00
snap_dialog = memnew ( ConfirmationDialog ) ;
2016-05-04 01:25:37 +00:00
snap_dialog - > set_title ( TTR ( " Snap Settings " ) ) ;
2014-02-10 01:10:30 +00:00
add_child ( snap_dialog ) ;
2020-03-08 19:31:11 +00:00
snap_dialog - > connect ( " confirmed " , this , " _snap_changed " ) ;
snap_dialog - > get_cancel ( ) - > connect ( " pressed " , this , " _snap_update " ) ;
2015-10-18 16:31:44 +00:00
2017-03-05 15:44:50 +00:00
VBoxContainer * snap_dialog_vbc = memnew ( VBoxContainer ) ;
2015-10-18 16:31:44 +00:00
snap_dialog - > add_child ( snap_dialog_vbc ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
snap_translate = memnew ( LineEdit ) ;
snap_dialog_vbc - > add_margin_child ( TTR ( " Translate Snap: " ) , snap_translate ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
snap_rotate = memnew ( LineEdit ) ;
snap_dialog_vbc - > add_margin_child ( TTR ( " Rotate Snap (deg.): " ) , snap_rotate ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
snap_scale = memnew ( LineEdit ) ;
snap_dialog_vbc - > add_margin_child ( TTR ( " Scale Snap (%): " ) , snap_scale ) ;
2014-02-10 01:10:30 +00:00
2020-03-08 19:31:11 +00:00
_snap_update ( ) ;
2015-10-18 16:31:44 +00:00
/* SETTINGS DIALOG */
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
settings_dialog = memnew ( ConfirmationDialog ) ;
2016-05-04 01:25:37 +00:00
settings_dialog - > set_title ( TTR ( " Viewport Settings " ) ) ;
2014-02-10 01:10:30 +00:00
add_child ( settings_dialog ) ;
2017-03-05 15:44:50 +00:00
settings_vbc = memnew ( VBoxContainer ) ;
2017-08-04 11:23:10 +00:00
settings_vbc - > set_custom_minimum_size ( Size2 ( 200 , 0 ) * EDSCALE ) ;
2014-10-12 05:13:22 +00:00
settings_dialog - > add_child ( settings_vbc ) ;
2017-03-05 15:44:50 +00:00
settings_fov = memnew ( SpinBox ) ;
2017-08-04 11:23:10 +00:00
settings_fov - > set_max ( MAX_FOV ) ;
settings_fov - > set_min ( MIN_FOV ) ;
2014-10-12 05:13:22 +00:00
settings_fov - > set_step ( 0.01 ) ;
2017-11-25 22:03:26 +00:00
settings_fov - > set_value ( EDITOR_DEF ( " editors/3d/default_fov " , 70.0 ) ) ;
2017-03-05 15:44:50 +00:00
settings_vbc - > add_margin_child ( TTR ( " Perspective FOV (deg.): " ) , settings_fov ) ;
2014-10-12 05:13:22 +00:00
2017-03-05 15:44:50 +00:00
settings_znear = memnew ( SpinBox ) ;
2017-08-04 11:23:10 +00:00
settings_znear - > set_max ( MAX_Z ) ;
settings_znear - > set_min ( MIN_Z ) ;
2014-10-12 05:13:22 +00:00
settings_znear - > set_step ( 0.01 ) ;
2017-11-25 22:03:26 +00:00
settings_znear - > set_value ( EDITOR_DEF ( " editors/3d/default_z_near " , 0.05 ) ) ;
2017-03-05 15:44:50 +00:00
settings_vbc - > add_margin_child ( TTR ( " View Z-Near: " ) , settings_znear ) ;
2014-10-12 05:13:22 +00:00
2017-03-05 15:44:50 +00:00
settings_zfar = memnew ( SpinBox ) ;
2017-08-04 11:23:10 +00:00
settings_zfar - > set_max ( MAX_Z ) ;
settings_zfar - > set_min ( MIN_Z ) ;
2014-10-12 05:13:22 +00:00
settings_zfar - > set_step ( 0.01 ) ;
2017-03-05 15:44:50 +00:00
settings_zfar - > set_value ( EDITOR_DEF ( " editors/3d/default_z_far " , 1500 ) ) ;
settings_vbc - > add_margin_child ( TTR ( " View Z-Far: " ) , settings_zfar ) ;
2014-02-10 01:10:30 +00:00
2020-03-10 16:56:46 +00:00
for ( uint32_t i = 0 ; i < VIEWPORTS_COUNT ; + + i ) {
settings_dialog - > connect ( " confirmed " , viewports [ i ] , " _update_camera " , varray ( 0.0 ) ) ;
}
2014-02-10 01:10:30 +00:00
/* XFORM DIALOG */
2017-03-05 15:44:50 +00:00
xform_dialog = memnew ( ConfirmationDialog ) ;
2016-05-04 01:25:37 +00:00
xform_dialog - > set_title ( TTR ( " Transform Change " ) ) ;
2014-02-10 01:10:30 +00:00
add_child ( xform_dialog ) ;
2017-07-31 13:00:02 +00:00
VBoxContainer * xform_vbc = memnew ( VBoxContainer ) ;
xform_dialog - > add_child ( xform_vbc ) ;
2015-10-18 16:31:44 +00:00
Label * l = memnew ( Label ) ;
2016-05-04 01:25:37 +00:00
l - > set_text ( TTR ( " Translate: " ) ) ;
2017-07-31 13:00:02 +00:00
xform_vbc - > add_child ( l ) ;
HBoxContainer * xform_hbc = memnew ( HBoxContainer ) ;
xform_vbc - > add_child ( xform_hbc ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < 3 ; i + + ) {
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
xform_translate [ i ] = memnew ( LineEdit ) ;
2017-07-31 13:00:02 +00:00
xform_translate [ i ] - > set_h_size_flags ( SIZE_EXPAND_FILL ) ;
xform_hbc - > add_child ( xform_translate [ i ] ) ;
2014-02-10 01:10:30 +00:00
}
l = memnew ( Label ) ;
2016-05-04 01:25:37 +00:00
l - > set_text ( TTR ( " Rotate (deg.): " ) ) ;
2017-07-31 13:00:02 +00:00
xform_vbc - > add_child ( l ) ;
xform_hbc = memnew ( HBoxContainer ) ;
xform_vbc - > add_child ( xform_hbc ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < 3 ; i + + ) {
xform_rotate [ i ] = memnew ( LineEdit ) ;
2017-07-31 13:00:02 +00:00
xform_rotate [ i ] - > set_h_size_flags ( SIZE_EXPAND_FILL ) ;
xform_hbc - > add_child ( xform_rotate [ i ] ) ;
2014-02-10 01:10:30 +00:00
}
l = memnew ( Label ) ;
2016-05-04 01:25:37 +00:00
l - > set_text ( TTR ( " Scale (ratio): " ) ) ;
2017-07-31 13:00:02 +00:00
xform_vbc - > add_child ( l ) ;
xform_hbc = memnew ( HBoxContainer ) ;
xform_vbc - > add_child ( xform_hbc ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < 3 ; i + + ) {
xform_scale [ i ] = memnew ( LineEdit ) ;
2017-07-31 13:00:02 +00:00
xform_scale [ i ] - > set_h_size_flags ( SIZE_EXPAND_FILL ) ;
xform_hbc - > add_child ( xform_scale [ i ] ) ;
2014-02-10 01:10:30 +00:00
}
l = memnew ( Label ) ;
2016-05-04 01:25:37 +00:00
l - > set_text ( TTR ( " Transform Type " ) ) ;
2017-07-31 13:00:02 +00:00
xform_vbc - > add_child ( l ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
xform_type = memnew ( OptionButton ) ;
2017-07-31 13:00:02 +00:00
xform_type - > set_h_size_flags ( SIZE_EXPAND_FILL ) ;
2016-05-04 01:25:37 +00:00
xform_type - > add_item ( TTR ( " Pre " ) ) ;
xform_type - > add_item ( TTR ( " Post " ) ) ;
2017-07-31 13:00:02 +00:00
xform_vbc - > add_child ( xform_type ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
xform_dialog - > connect ( " confirmed " , this , " _xform_dialog_action " ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
scenario_debug = VisualServer : : SCENARIO_DEBUG_DISABLED ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
selected = NULL ;
2014-02-10 01:10:30 +00:00
2014-04-10 03:18:27 +00:00
set_process_unhandled_key_input ( true ) ;
2014-02-10 01:10:30 +00:00
add_to_group ( " _spatial_editor_group " ) ;
2014-05-05 01:50:23 +00:00
2017-03-05 15:44:50 +00:00
EDITOR_DEF ( " editors/3d/manipulator_gizmo_size " , 80 ) ;
EditorSettings : : get_singleton ( ) - > add_property_hint ( PropertyInfo ( Variant : : INT , " editors/3d/manipulator_gizmo_size " , PROPERTY_HINT_RANGE , " 16,1024,1 " ) ) ;
2019-08-01 12:23:29 +00:00
EDITOR_DEF ( " editors/3d/manipulator_gizmo_opacity " , 0.4 ) ;
EditorSettings : : get_singleton ( ) - > add_property_hint ( PropertyInfo ( Variant : : REAL , " editors/3d/manipulator_gizmo_opacity " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) ) ;
2019-10-23 09:46:26 +00:00
EDITOR_DEF ( " editors/3d/navigation/show_viewport_rotation_gizmo " , true ) ;
2014-05-05 01:50:23 +00:00
2017-03-05 15:44:50 +00:00
over_gizmo_handle = - 1 ;
2014-02-10 01:10:30 +00:00
}
SpatialEditor : : ~ SpatialEditor ( ) {
2017-09-02 19:47:16 +00:00
memdelete ( preview_node ) ;
2014-02-10 01:10:30 +00:00
}
void SpatialEditorPlugin : : make_visible ( bool p_visible ) {
if ( p_visible ) {
2016-03-08 23:00:52 +00:00
2014-02-10 01:10:30 +00:00
spatial_editor - > show ( ) ;
spatial_editor - > set_process ( true ) ;
} else {
2016-03-08 23:00:52 +00:00
2014-02-10 01:10:30 +00:00
spatial_editor - > hide ( ) ;
spatial_editor - > set_process ( false ) ;
}
}
void SpatialEditorPlugin : : edit ( Object * p_object ) {
2014-05-05 01:50:23 +00:00
2017-08-24 20:58:51 +00:00
spatial_editor - > edit ( Object : : cast_to < Spatial > ( p_object ) ) ;
2014-02-10 01:10:30 +00:00
}
bool SpatialEditorPlugin : : handles ( Object * p_object ) const {
2016-03-08 23:00:52 +00:00
2017-01-03 02:03:46 +00:00
return p_object - > is_class ( " Spatial " ) ;
2014-02-10 01:10:30 +00:00
}
Dictionary SpatialEditorPlugin : : get_state ( ) const {
return spatial_editor - > get_state ( ) ;
}
2017-03-05 15:44:50 +00:00
void SpatialEditorPlugin : : set_state ( const Dictionary & p_state ) {
2014-02-10 01:10:30 +00:00
spatial_editor - > set_state ( p_state ) ;
}
2017-03-05 15:44:50 +00:00
void SpatialEditor : : snap_cursor_to_plane ( const Plane & p_plane ) {
2014-02-10 01:10:30 +00:00
2017-01-14 11:26:56 +00:00
//cursor.pos=p_plane.project(cursor.pos);
2014-02-10 01:10:30 +00:00
}
2017-09-18 21:44:04 +00:00
Vector3 SpatialEditor : : snap_point ( Vector3 p_target , Vector3 p_start ) const {
if ( is_snap_enabled ( ) ) {
p_target . x = Math : : snap_scalar ( 0.0 , get_translate_snap ( ) , p_target . x ) ;
p_target . y = Math : : snap_scalar ( 0.0 , get_translate_snap ( ) , p_target . y ) ;
p_target . z = Math : : snap_scalar ( 0.0 , get_translate_snap ( ) , p_target . z ) ;
}
return p_target ;
}
2019-04-09 15:55:44 +00:00
float SpatialEditor : : get_translate_snap ( ) const {
float snap_value ;
if ( Input : : get_singleton ( ) - > is_key_pressed ( KEY_SHIFT ) ) {
snap_value = snap_translate - > get_text ( ) . to_double ( ) / 10.0 ;
} else {
snap_value = snap_translate - > get_text ( ) . to_double ( ) ;
}
return snap_value ;
}
float SpatialEditor : : get_rotate_snap ( ) const {
float snap_value ;
if ( Input : : get_singleton ( ) - > is_key_pressed ( KEY_SHIFT ) ) {
snap_value = snap_rotate - > get_text ( ) . to_double ( ) / 3.0 ;
} else {
snap_value = snap_rotate - > get_text ( ) . to_double ( ) ;
}
return snap_value ;
}
float SpatialEditor : : get_scale_snap ( ) const {
float snap_value ;
if ( Input : : get_singleton ( ) - > is_key_pressed ( KEY_SHIFT ) ) {
snap_value = snap_scale - > get_text ( ) . to_double ( ) / 2.0 ;
} else {
snap_value = snap_scale - > get_text ( ) . to_double ( ) ;
}
return snap_value ;
}
2014-02-10 01:10:30 +00:00
void SpatialEditorPlugin : : _bind_methods ( ) {
2017-03-05 15:44:50 +00:00
ClassDB : : bind_method ( " snap_cursor_to_plane " , & SpatialEditorPlugin : : snap_cursor_to_plane ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-05 15:44:50 +00:00
void SpatialEditorPlugin : : snap_cursor_to_plane ( const Plane & p_plane ) {
2014-02-10 01:10:30 +00:00
spatial_editor - > snap_cursor_to_plane ( p_plane ) ;
}
2019-03-11 23:30:50 +00:00
struct _GizmoPluginPriorityComparator {
bool operator ( ) ( const Ref < EditorSpatialGizmoPlugin > & p_a , const Ref < EditorSpatialGizmoPlugin > & p_b ) const {
if ( p_a - > get_priority ( ) = = p_b - > get_priority ( ) ) {
return p_a - > get_name ( ) < p_b - > get_name ( ) ;
}
return p_a - > get_priority ( ) > p_b - > get_priority ( ) ;
}
} ;
struct _GizmoPluginNameComparator {
bool operator ( ) ( const Ref < EditorSpatialGizmoPlugin > & p_a , const Ref < EditorSpatialGizmoPlugin > & p_b ) const {
return p_a - > get_name ( ) < p_b - > get_name ( ) ;
}
} ;
2018-10-29 10:30:28 +00:00
void SpatialEditor : : add_gizmo_plugin ( Ref < EditorSpatialGizmoPlugin > p_plugin ) {
2019-01-25 11:57:32 +00:00
ERR_FAIL_NULL ( p_plugin . ptr ( ) ) ;
2019-03-11 23:30:50 +00:00
gizmo_plugins_by_priority . push_back ( p_plugin ) ;
gizmo_plugins_by_priority . sort_custom < _GizmoPluginPriorityComparator > ( ) ;
gizmo_plugins_by_name . push_back ( p_plugin ) ;
gizmo_plugins_by_name . sort_custom < _GizmoPluginNameComparator > ( ) ;
2018-10-29 10:30:28 +00:00
_update_gizmos_menu ( ) ;
SpatialEditor : : get_singleton ( ) - > update_all_gizmos ( ) ;
}
void SpatialEditor : : remove_gizmo_plugin ( Ref < EditorSpatialGizmoPlugin > p_plugin ) {
2019-03-11 23:30:50 +00:00
gizmo_plugins_by_priority . erase ( p_plugin ) ;
gizmo_plugins_by_name . erase ( p_plugin ) ;
2018-10-29 10:30:28 +00:00
_update_gizmos_menu ( ) ;
2018-07-24 22:08:49 +00:00
}
2014-02-10 01:10:30 +00:00
SpatialEditorPlugin : : SpatialEditorPlugin ( EditorNode * p_node ) {
2016-03-08 23:00:52 +00:00
2017-03-05 15:44:50 +00:00
editor = p_node ;
spatial_editor = memnew ( SpatialEditor ( p_node ) ) ;
2016-02-08 16:01:54 +00:00
spatial_editor - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2014-02-10 01:10:30 +00:00
editor - > get_viewport ( ) - > add_child ( spatial_editor ) ;
2016-02-08 16:01:54 +00:00
2014-02-10 01:10:30 +00:00
spatial_editor - > hide ( ) ;
2019-04-14 20:27:59 +00:00
spatial_editor - > connect ( " transform_key_request " , editor - > get_inspector_dock ( ) , " _transform_keyed " ) ;
2014-02-10 01:10:30 +00:00
}
SpatialEditorPlugin : : ~ SpatialEditorPlugin ( ) {
}
2018-07-24 22:08:49 +00:00
void EditorSpatialGizmoPlugin : : create_material ( const String & p_name , const Color & p_color , bool p_billboard , bool p_on_top , bool p_use_vertex_color ) {
2018-09-02 20:31:03 +00:00
Color instanced_color = EDITOR_DEF ( " editors/3d_gizmos/gizmo_colors/instanced " , Color ( 0.7 , 0.7 , 0.7 , 0.6 ) ) ;
2018-07-24 22:08:49 +00:00
Vector < Ref < SpatialMaterial > > mats ;
for ( int i = 0 ; i < 4 ; i + + ) {
bool selected = i % 2 = = 1 ;
bool instanced = i < 2 ;
Ref < SpatialMaterial > material = Ref < SpatialMaterial > ( memnew ( SpatialMaterial ) ) ;
Color color = instanced ? instanced_color : p_color ;
if ( ! selected ) {
color . a * = 0.3 ;
}
material - > set_albedo ( color ) ;
material - > set_flag ( SpatialMaterial : : FLAG_UNSHADED , true ) ;
material - > set_feature ( SpatialMaterial : : FEATURE_TRANSPARENT , true ) ;
2018-08-11 21:07:00 +00:00
material - > set_render_priority ( SpatialMaterial : : RENDER_PRIORITY_MIN + 1 ) ;
2018-07-24 22:08:49 +00:00
if ( p_use_vertex_color ) {
material - > set_flag ( SpatialMaterial : : FLAG_ALBEDO_FROM_VERTEX_COLOR , true ) ;
material - > set_flag ( SpatialMaterial : : FLAG_SRGB_VERTEX_COLOR , true ) ;
}
if ( p_billboard ) {
material - > set_billboard_mode ( SpatialMaterial : : BILLBOARD_ENABLED ) ;
}
if ( p_on_top & & selected ) {
material - > set_on_top_of_alpha ( ) ;
}
mats . push_back ( material ) ;
}
materials [ p_name ] = mats ;
}
void EditorSpatialGizmoPlugin : : create_icon_material ( const String & p_name , const Ref < Texture > & p_texture , bool p_on_top , const Color & p_albedo ) {
2018-09-02 20:31:03 +00:00
Color instanced_color = EDITOR_DEF ( " editors/3d_gizmos/gizmo_colors/instanced " , Color ( 0.7 , 0.7 , 0.7 , 0.6 ) ) ;
2018-07-24 22:08:49 +00:00
Vector < Ref < SpatialMaterial > > icons ;
for ( int i = 0 ; i < 4 ; i + + ) {
bool selected = i % 2 = = 1 ;
bool instanced = i < 2 ;
Ref < SpatialMaterial > icon = Ref < SpatialMaterial > ( memnew ( SpatialMaterial ) ) ;
Color color = instanced ? instanced_color : p_albedo ;
if ( ! selected ) {
2018-09-02 20:31:03 +00:00
color . a * = 0.85 ;
2018-07-24 22:08:49 +00:00
}
icon - > set_albedo ( color ) ;
icon - > set_flag ( SpatialMaterial : : FLAG_UNSHADED , true ) ;
2019-12-31 23:52:20 +00:00
icon - > set_flag ( SpatialMaterial : : FLAG_ALBEDO_FROM_VERTEX_COLOR , true ) ;
icon - > set_flag ( SpatialMaterial : : FLAG_SRGB_VERTEX_COLOR , true ) ;
2018-07-24 22:08:49 +00:00
icon - > set_cull_mode ( SpatialMaterial : : CULL_DISABLED ) ;
icon - > set_depth_draw_mode ( SpatialMaterial : : DEPTH_DRAW_DISABLED ) ;
icon - > set_feature ( SpatialMaterial : : FEATURE_TRANSPARENT , true ) ;
icon - > set_texture ( SpatialMaterial : : TEXTURE_ALBEDO , p_texture ) ;
icon - > set_flag ( SpatialMaterial : : FLAG_FIXED_SIZE , true ) ;
icon - > set_billboard_mode ( SpatialMaterial : : BILLBOARD_ENABLED ) ;
2018-08-11 21:07:00 +00:00
icon - > set_render_priority ( SpatialMaterial : : RENDER_PRIORITY_MIN ) ;
2018-07-24 22:08:49 +00:00
if ( p_on_top & & selected ) {
icon - > set_on_top_of_alpha ( ) ;
}
icons . push_back ( icon ) ;
}
materials [ p_name ] = icons ;
}
void EditorSpatialGizmoPlugin : : create_handle_material ( const String & p_name , bool p_billboard ) {
Ref < SpatialMaterial > handle_material = Ref < SpatialMaterial > ( memnew ( SpatialMaterial ) ) ;
handle_material - > set_flag ( SpatialMaterial : : FLAG_UNSHADED , true ) ;
handle_material - > set_flag ( SpatialMaterial : : FLAG_USE_POINT_SIZE , true ) ;
Ref < Texture > handle_t = SpatialEditor : : get_singleton ( ) - > get_icon ( " Editor3DHandle " , " EditorIcons " ) ;
handle_material - > set_point_size ( handle_t - > get_width ( ) ) ;
handle_material - > set_texture ( SpatialMaterial : : TEXTURE_ALBEDO , handle_t ) ;
handle_material - > set_albedo ( Color ( 1 , 1 , 1 ) ) ;
handle_material - > set_feature ( SpatialMaterial : : FEATURE_TRANSPARENT , true ) ;
handle_material - > set_flag ( SpatialMaterial : : FLAG_ALBEDO_FROM_VERTEX_COLOR , true ) ;
handle_material - > set_flag ( SpatialMaterial : : FLAG_SRGB_VERTEX_COLOR , true ) ;
handle_material - > set_on_top_of_alpha ( ) ;
if ( p_billboard ) {
handle_material - > set_billboard_mode ( SpatialMaterial : : BILLBOARD_ENABLED ) ;
handle_material - > set_on_top_of_alpha ( ) ;
}
materials [ p_name ] = Vector < Ref < SpatialMaterial > > ( ) ;
materials [ p_name ] . push_back ( handle_material ) ;
}
void EditorSpatialGizmoPlugin : : add_material ( const String & p_name , Ref < SpatialMaterial > p_material ) {
materials [ p_name ] = Vector < Ref < SpatialMaterial > > ( ) ;
materials [ p_name ] . push_back ( p_material ) ;
}
2018-10-29 10:30:28 +00:00
Ref < SpatialMaterial > EditorSpatialGizmoPlugin : : get_material ( const String & p_name , const Ref < EditorSpatialGizmo > & p_gizmo ) {
2018-07-24 22:08:49 +00:00
ERR_FAIL_COND_V ( ! materials . has ( p_name ) , Ref < SpatialMaterial > ( ) ) ;
ERR_FAIL_COND_V ( materials [ p_name ] . size ( ) = = 0 , Ref < SpatialMaterial > ( ) ) ;
2019-01-25 11:57:32 +00:00
if ( p_gizmo . is_null ( ) | | materials [ p_name ] . size ( ) = = 1 ) return materials [ p_name ] [ 0 ] ;
2018-07-24 22:08:49 +00:00
int index = ( p_gizmo - > is_selected ( ) ? 1 : 0 ) + ( p_gizmo - > is_editable ( ) ? 2 : 0 ) ;
2018-08-11 21:07:00 +00:00
Ref < SpatialMaterial > mat = materials [ p_name ] [ index ] ;
if ( current_state = = ON_TOP & & p_gizmo - > is_selected ( ) ) {
mat - > set_flag ( SpatialMaterial : : FLAG_DISABLE_DEPTH_TEST , true ) ;
} else {
mat - > set_flag ( SpatialMaterial : : FLAG_DISABLE_DEPTH_TEST , false ) ;
}
return mat ;
2018-07-24 22:08:49 +00:00
}
2018-10-29 10:30:28 +00:00
String EditorSpatialGizmoPlugin : : get_name ( ) const {
if ( get_script_instance ( ) & & get_script_instance ( ) - > has_method ( " get_name " ) ) {
return get_script_instance ( ) - > call ( " get_name " ) ;
}
2019-01-25 11:57:32 +00:00
return TTR ( " Nameless gizmo " ) ;
2018-10-29 10:30:28 +00:00
}
2019-03-11 23:30:50 +00:00
int EditorSpatialGizmoPlugin : : get_priority ( ) const {
if ( get_script_instance ( ) & & get_script_instance ( ) - > has_method ( " get_priority " ) ) {
return get_script_instance ( ) - > call ( " get_priority " ) ;
}
return 0 ;
}
2018-07-24 22:08:49 +00:00
Ref < EditorSpatialGizmo > EditorSpatialGizmoPlugin : : get_gizmo ( Spatial * p_spatial ) {
2018-10-29 10:30:28 +00:00
if ( get_script_instance ( ) & & get_script_instance ( ) - > has_method ( " get_gizmo " ) ) {
return get_script_instance ( ) - > call ( " get_gizmo " , p_spatial ) ;
}
2018-07-24 22:08:49 +00:00
Ref < EditorSpatialGizmo > ref = create_gizmo ( p_spatial ) ;
if ( ref . is_null ( ) ) return ref ;
ref - > set_plugin ( this ) ;
ref - > set_spatial_node ( p_spatial ) ;
2018-08-11 21:07:00 +00:00
ref - > set_hidden ( current_state = = HIDDEN ) ;
2018-07-24 22:08:49 +00:00
current_gizmos . push_back ( ref . ptr ( ) ) ;
return ref ;
}
2018-10-29 10:30:28 +00:00
void EditorSpatialGizmoPlugin : : _bind_methods ( ) {
# define GIZMO_REF PropertyInfo(Variant::OBJECT, "gizmo", PROPERTY_HINT_RESOURCE_TYPE, "EditorSpatialGizmo")
BIND_VMETHOD ( MethodInfo ( Variant : : BOOL , " has_gizmo " , PropertyInfo ( Variant : : OBJECT , " spatial " , PROPERTY_HINT_RESOURCE_TYPE , " Spatial " ) ) ) ;
BIND_VMETHOD ( MethodInfo ( GIZMO_REF , " create_gizmo " , PropertyInfo ( Variant : : OBJECT , " spatial " , PROPERTY_HINT_RESOURCE_TYPE , " Spatial " ) ) ) ;
ClassDB : : bind_method ( D_METHOD ( " create_material " , " name " , " color " , " billboard " , " on_top " , " use_vertex_color " ) , & EditorSpatialGizmoPlugin : : create_material , DEFVAL ( false ) , DEFVAL ( false ) , DEFVAL ( false ) ) ;
ClassDB : : bind_method ( D_METHOD ( " create_icon_material " , " name " , " texture " , " on_top " , " color " ) , & EditorSpatialGizmoPlugin : : create_icon_material , DEFVAL ( false ) , DEFVAL ( Color ( 1 , 1 , 1 , 1 ) ) ) ;
ClassDB : : bind_method ( D_METHOD ( " create_handle_material " , " name " , " billboard " ) , & EditorSpatialGizmoPlugin : : create_handle_material , DEFVAL ( false ) ) ;
ClassDB : : bind_method ( D_METHOD ( " add_material " , " name " , " material " ) , & EditorSpatialGizmoPlugin : : add_material ) ;
ClassDB : : bind_method ( D_METHOD ( " get_material " , " name " , " gizmo " ) , & EditorSpatialGizmoPlugin : : get_material ) ; //, DEFVAL(Ref<EditorSpatialGizmo>()));
BIND_VMETHOD ( MethodInfo ( Variant : : STRING , " get_name " ) ) ;
2019-03-11 23:30:50 +00:00
BIND_VMETHOD ( MethodInfo ( Variant : : STRING , " get_priority " ) ) ;
2018-10-29 10:30:28 +00:00
BIND_VMETHOD ( MethodInfo ( Variant : : BOOL , " can_be_hidden " ) ) ;
BIND_VMETHOD ( MethodInfo ( Variant : : BOOL , " is_selectable_when_hidden " ) ) ;
BIND_VMETHOD ( MethodInfo ( " redraw " , GIZMO_REF ) ) ;
BIND_VMETHOD ( MethodInfo ( Variant : : STRING , " get_handle_name " , GIZMO_REF , PropertyInfo ( Variant : : INT , " index " ) ) ) ;
MethodInfo hvget ( Variant : : NIL , " get_handle_value " , GIZMO_REF , PropertyInfo ( Variant : : INT , " index " ) ) ;
hvget . return_val . usage | = PROPERTY_USAGE_NIL_IS_VARIANT ;
BIND_VMETHOD ( hvget ) ;
BIND_VMETHOD ( MethodInfo ( " set_handle " , GIZMO_REF , PropertyInfo ( Variant : : INT , " index " ) , PropertyInfo ( Variant : : OBJECT , " camera " , PROPERTY_HINT_RESOURCE_TYPE , " Camera " ) , PropertyInfo ( Variant : : VECTOR2 , " point " ) ) ) ;
MethodInfo cm = MethodInfo ( " commit_handle " , GIZMO_REF , PropertyInfo ( Variant : : INT , " index " ) , PropertyInfo ( Variant : : NIL , " restore " ) , PropertyInfo ( Variant : : BOOL , " cancel " ) ) ;
cm . default_arguments . push_back ( false ) ;
BIND_VMETHOD ( cm ) ;
2019-01-25 11:57:32 +00:00
BIND_VMETHOD ( MethodInfo ( Variant : : BOOL , " is_handle_highlighted " , GIZMO_REF , PropertyInfo ( Variant : : INT , " index " ) ) ) ;
2018-10-29 10:30:28 +00:00
# undef GIZMO_REF
}
2018-07-24 22:08:49 +00:00
bool EditorSpatialGizmoPlugin : : has_gizmo ( Spatial * p_spatial ) {
2018-10-29 10:30:28 +00:00
if ( get_script_instance ( ) & & get_script_instance ( ) - > has_method ( " has_gizmo " ) ) {
return get_script_instance ( ) - > call ( " has_gizmo " , p_spatial ) ;
}
2018-07-24 22:08:49 +00:00
return false ;
}
Ref < EditorSpatialGizmo > EditorSpatialGizmoPlugin : : create_gizmo ( Spatial * p_spatial ) {
2018-10-29 10:30:28 +00:00
if ( get_script_instance ( ) & & get_script_instance ( ) - > has_method ( " create_gizmo " ) ) {
return get_script_instance ( ) - > call ( " create_gizmo " , p_spatial ) ;
}
2018-07-24 22:08:49 +00:00
Ref < EditorSpatialGizmo > ref ;
if ( has_gizmo ( p_spatial ) ) ref . instance ( ) ;
return ref ;
}
bool EditorSpatialGizmoPlugin : : can_be_hidden ( ) const {
2018-10-29 10:30:28 +00:00
if ( get_script_instance ( ) & & get_script_instance ( ) - > has_method ( " can_be_hidden " ) ) {
return get_script_instance ( ) - > call ( " can_be_hidden " ) ;
}
2018-07-24 22:08:49 +00:00
return true ;
}
bool EditorSpatialGizmoPlugin : : is_selectable_when_hidden ( ) const {
2018-10-29 10:30:28 +00:00
if ( get_script_instance ( ) & & get_script_instance ( ) - > has_method ( " is_selectable_when_hidden " ) ) {
return get_script_instance ( ) - > call ( " is_selectable_when_hidden " ) ;
}
return false ;
}
void EditorSpatialGizmoPlugin : : redraw ( EditorSpatialGizmo * p_gizmo ) {
if ( get_script_instance ( ) & & get_script_instance ( ) - > has_method ( " redraw " ) ) {
Ref < EditorSpatialGizmo > ref ( p_gizmo ) ;
get_script_instance ( ) - > call ( " redraw " , ref ) ;
}
}
String EditorSpatialGizmoPlugin : : get_handle_name ( const EditorSpatialGizmo * p_gizmo , int p_idx ) const {
if ( get_script_instance ( ) & & get_script_instance ( ) - > has_method ( " get_handle_name " ) ) {
return get_script_instance ( ) - > call ( " get_handle_name " , p_gizmo , p_idx ) ;
}
return " " ;
}
Variant EditorSpatialGizmoPlugin : : get_handle_value ( EditorSpatialGizmo * p_gizmo , int p_idx ) const {
if ( get_script_instance ( ) & & get_script_instance ( ) - > has_method ( " get_handle_value " ) ) {
return get_script_instance ( ) - > call ( " get_handle_value " , p_gizmo , p_idx ) ;
}
return Variant ( ) ;
}
void EditorSpatialGizmoPlugin : : set_handle ( EditorSpatialGizmo * p_gizmo , int p_idx , Camera * p_camera , const Point2 & p_point ) {
if ( get_script_instance ( ) & & get_script_instance ( ) - > has_method ( " set_handle " ) ) {
get_script_instance ( ) - > call ( " set_handle " , p_gizmo , p_idx , p_camera , p_point ) ;
}
}
void EditorSpatialGizmoPlugin : : commit_handle ( EditorSpatialGizmo * p_gizmo , int p_idx , const Variant & p_restore , bool p_cancel ) {
if ( get_script_instance ( ) & & get_script_instance ( ) - > has_method ( " commit_handle " ) ) {
get_script_instance ( ) - > call ( " commit_handle " , p_gizmo , p_idx , p_restore , p_cancel ) ;
}
}
2019-01-25 11:57:32 +00:00
bool EditorSpatialGizmoPlugin : : is_handle_highlighted ( const EditorSpatialGizmo * p_gizmo , int p_idx ) const {
if ( get_script_instance ( ) & & get_script_instance ( ) - > has_method ( " is_handle_highlighted " ) ) {
return get_script_instance ( ) - > call ( " is_handle_highlighted " , p_gizmo , p_idx ) ;
2018-10-29 10:30:28 +00:00
}
2018-07-24 22:08:49 +00:00
return false ;
}
2018-08-11 21:07:00 +00:00
void EditorSpatialGizmoPlugin : : set_state ( int p_state ) {
current_state = p_state ;
2018-07-24 22:08:49 +00:00
for ( int i = 0 ; i < current_gizmos . size ( ) ; + + i ) {
2018-08-11 21:07:00 +00:00
current_gizmos [ i ] - > set_hidden ( current_state = = HIDDEN ) ;
2018-07-24 22:08:49 +00:00
}
}
2019-03-11 23:30:50 +00:00
int EditorSpatialGizmoPlugin : : get_state ( ) const {
return current_state ;
}
2018-07-24 22:08:49 +00:00
void EditorSpatialGizmoPlugin : : unregister_gizmo ( EditorSpatialGizmo * p_gizmo ) {
current_gizmos . erase ( p_gizmo ) ;
}
EditorSpatialGizmoPlugin : : EditorSpatialGizmoPlugin ( ) {
2018-11-18 21:01:09 +00:00
current_state = VISIBLE ;
2018-07-24 22:08:49 +00:00
}
EditorSpatialGizmoPlugin : : ~ EditorSpatialGizmoPlugin ( ) {
2018-10-29 10:30:28 +00:00
for ( int i = 0 ; i < current_gizmos . size ( ) ; + + i ) {
current_gizmos [ i ] - > set_plugin ( NULL ) ;
current_gizmos [ i ] - > get_spatial_node ( ) - > set_gizmo ( NULL ) ;
}
2019-09-28 09:04:50 +00:00
if ( SpatialEditor : : get_singleton ( ) ) {
SpatialEditor : : get_singleton ( ) - > update_all_gizmos ( ) ;
}
2018-07-24 22:08:49 +00:00
}