2014-02-10 02:10:30 +01:00
/*************************************************************************/
/* spatial_editor_plugin.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 14:16:55 +02:00
/* https://godotengine.org */
2014-02-10 02:10:30 +01:00
/*************************************************************************/
2019-01-01 12:53:14 +01:00
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
2014-02-10 02:10:30 +01: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-05 00:50:27 +01:00
2014-02-10 02:10:30 +01:00
# include "spatial_editor_plugin.h"
2018-09-04 11:30:04 +02:00
# include "core/math/camera_matrix.h"
2017-03-22 21:18:47 +01:00
# include "core/os/input.h"
2018-09-04 11:30:04 +02:00
# include "core/os/keyboard.h"
# include "core/print_string.h"
# include "core/project_settings.h"
2019-02-12 13:30:56 +01:00
# include "core/sort_array.h"
2017-03-05 14:21:25 +01:00
# include "editor/editor_node.h"
# include "editor/editor_settings.h"
2017-03-05 16:44:50 +01:00
# include "editor/plugins/animation_player_editor_plugin.h"
2017-09-02 21:47:16 +02:00
# include "editor/plugins/script_editor_plugin.h"
# include "editor/script_editor_debugger.h"
2017-03-05 14:21:25 +01:00
# include "editor/spatial_editor_gizmos.h"
2017-03-05 16:44:50 +01:00
# include "scene/3d/camera.h"
2018-09-04 11:30:04 +02:00
# include "scene/3d/collision_shape.h"
# include "scene/3d/mesh_instance.h"
# include "scene/3d/physics_body.h"
2017-03-05 16:44:50 +01:00
# include "scene/3d/visual_instance.h"
2017-09-02 21:47:16 +02:00
# include "scene/resources/packed_scene.h"
2017-03-05 16:44:50 +01:00
# include "scene/resources/surface_tool.h"
2016-01-18 00:03:57 +01:00
2014-02-10 02:10:30 +01:00
# define DISTANCE_DEFAULT 4
2017-09-21 23:11:56 +02:00
# define GIZMO_ARROW_SIZE 0.35
2014-02-10 02:10:30 +01:00
# define GIZMO_RING_HALF_WIDTH 0.1
# define GIZMO_SCALE_DEFAULT 0.15
2017-08-29 03:39:45 +02:00
# define GIZMO_PLANE_SIZE 0.2
# define GIZMO_PLANE_DST 0.3
2017-09-21 23:11:56 +02: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 02:10:30 +01:00
2017-05-07 22:59:05 +02:00
# define ZOOM_MIN_DISTANCE 0.001
# define ZOOM_MULTIPLIER 1.08
# define ZOOM_INDICATOR_DELAY_S 1.5
2017-10-08 02:43:57 +02:00
# define FREELOOK_MIN_SPEED 0.01
# define FREELOOK_SPEED_MULTIPLIER 1.08
2017-05-07 22:59:05 +02:00
2017-08-04 13:23:10 +02:00
# define MIN_Z 0.01
2019-07-23 11:42:41 +02:00
# define MAX_Z 1000000.0
2017-08-04 13:23:10 +02:00
# define MIN_FOV 0.01
# define MAX_FOV 179
2017-10-03 18:49:32 +02:00
# ifdef TOOLS_ENABLED
# define get_global_gizmo_transform get_global_gizmo_transform
# define get_local_gizmo_transform get_local_gizmo_transform
# else
# define get_global_gizmo_transform get_global_transform
# define get_local_gizmo_transform get_transform
# endif
2017-08-26 05:40:45 +02:00
void SpatialEditorViewport : : _update_camera ( float p_interp_delta ) {
2017-09-23 22:27:29 +02:00
bool is_orthogonal = camera - > get_projection ( ) = = Camera : : PROJECTION_ORTHOGONAL ;
2016-04-06 08:34:34 +02:00
2017-10-08 02:43:57 +02:00
Cursor old_camera_cursor = camera_cursor ;
camera_cursor = cursor ;
2017-09-16 17:12:11 +02:00
2017-10-08 02:43:57 +02:00
if ( p_interp_delta > 0 ) {
2017-09-16 17:12:11 +02:00
2017-10-08 02:43:57 +02:00
//-------
// Perform smoothing
2017-09-16 17:12:11 +02:00
2017-10-08 02:43:57 +02:00
if ( is_freelook_active ( ) ) {
2017-05-01 20:57:35 +02:00
2017-10-08 02:43:57 +02: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 ) ) ) ;
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 14:10:57 +02:00
2017-10-08 02:43:57 +02: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 20:57:35 +02:00
2017-10-08 02:43:57 +02:00
float zoom_inertia = EDITOR_GET ( " editors/3d/navigation_feel/zoom_inertia " ) ;
2017-08-26 14:10:57 +02:00
2017-10-08 02:43:57 +02: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 ) ) ) ;
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 05:40:45 +02:00
}
2017-10-08 02:43:57 +02:00
//-------
// Apply camera transform
2017-09-23 22:27:29 +02:00
float tolerance = 0.001 ;
2017-08-26 05:40:45 +02:00
bool equal = true ;
2017-09-23 22:27:29 +02: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 19:53:00 +02:00
equal = false ;
2017-09-23 22:27:29 +02:00
}
2017-08-26 05:40:45 +02:00
2017-09-23 22:27:29 +02:00
if ( equal & & old_camera_cursor . pos . distance_squared_to ( camera_cursor . pos ) > tolerance * tolerance ) {
2017-08-26 05:40:45 +02:00
equal = false ;
2017-09-23 22:27:29 +02:00
}
2017-08-26 05:40:45 +02:00
2017-09-23 22:27:29 +02:00
if ( equal & & Math : : abs ( old_camera_cursor . distance - camera_cursor . distance ) > tolerance ) {
2017-09-06 19:53:00 +02:00
equal = false ;
2017-09-23 22:27:29 +02:00
}
2017-08-26 05:40:45 +02:00
2017-09-23 22:27:29 +02:00
if ( ! equal | | p_interp_delta = = 0 | | is_freelook_active ( ) | | is_orthogonal ! = orthogonal ) {
2017-08-26 05:40:45 +02:00
2017-09-06 19:53:00 +02:00
camera - > set_global_transform ( to_camera_transform ( camera_cursor ) ) ;
2017-09-23 22:27:29 +02:00
2017-12-19 06:25:00 +01:00
if ( orthogonal )
2017-09-23 22:27:29 +02:00
camera - > set_orthogonal ( 2 * cursor . distance , 0.1 , 8192 ) ;
2017-12-19 06:25:00 +01:00
else
2017-09-23 22:27:29 +02:00
camera - > set_perspective ( get_fov ( ) , get_znear ( ) , get_zfar ( ) ) ;
2017-12-19 23:54:54 +01:00
update_transform_gizmo_view ( ) ;
2017-05-01 20:57:35 +02:00
}
}
Transform SpatialEditorViewport : : to_camera_transform ( const Cursor & p_cursor ) const {
2016-04-06 08:34:34 +02:00
Transform camera_transform ;
2017-05-01 20:57:35 +02: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 08:34:34 +02:00
if ( orthogonal )
camera_transform . translate ( 0 , 0 , 4096 ) ;
else
2017-05-01 20:57:35 +02:00
camera_transform . translate ( 0 , 0 , p_cursor . distance ) ;
2016-04-06 08:34:34 +02:00
2017-05-01 20:57:35 +02:00
return camera_transform ;
2016-04-06 08:34:34 +02:00
}
2014-02-10 02:10:30 +01:00
int SpatialEditorViewport : : get_selected_count ( ) const {
2017-03-05 16:44:50 +01:00
Map < Node * , Object * > & selection = editor_selection - > get_selection ( ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
int count = 0 ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( Map < Node * , Object * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > key ( ) ) ;
2014-02-10 02:10:30 +01:00
if ( ! sp )
continue ;
2017-03-05 16:44:50 +01:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
2014-02-10 02:10:30 +01:00
if ( ! se )
continue ;
count + + ;
}
return count ;
}
float SpatialEditorViewport : : get_znear ( ) const {
2017-08-04 13:23:10 +02:00
return CLAMP ( spatial_editor - > get_znear ( ) , MIN_Z , MAX_Z ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
float SpatialEditorViewport : : get_zfar ( ) const {
2014-02-10 02:10:30 +01:00
2017-08-04 13:23:10 +02:00
return CLAMP ( spatial_editor - > get_zfar ( ) , MIN_Z , MAX_Z ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
float SpatialEditorViewport : : get_fov ( ) const {
2014-02-10 02:10:30 +01:00
2017-08-04 13:23:10 +02:00
return CLAMP ( spatial_editor - > get_fov ( ) , MIN_FOV , MAX_FOV ) ;
2014-02-10 02:10:30 +01:00
}
Transform SpatialEditorViewport : : _get_camera_transform ( ) const {
return camera - > get_global_transform ( ) ;
}
2017-09-10 15:37:49 +02:00
Vector3 SpatialEditorViewport : : _get_camera_position ( ) const {
2014-02-10 02:10:30 +01:00
return _get_camera_transform ( ) . origin ;
}
2017-03-05 16:44:50 +01:00
Point2 SpatialEditorViewport : : _point_to_screen ( const Vector3 & p_point ) {
2014-02-10 02:10:30 +01:00
2017-10-31 18:23:25 +01:00
return camera - > unproject_position ( p_point ) * viewport_container - > get_stretch_shrink ( ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
Vector3 SpatialEditorViewport : : _get_ray_pos ( const Vector2 & p_pos ) const {
2014-02-10 02:10:30 +01:00
2017-10-31 18:23:25 +01:00
return camera - > project_ray_origin ( p_pos / viewport_container - > get_stretch_shrink ( ) ) ;
2014-02-10 02:10:30 +01:00
}
Vector3 SpatialEditorViewport : : _get_camera_normal ( ) const {
return - _get_camera_transform ( ) . basis . get_axis ( 2 ) ;
}
2017-09-02 21:47:16 +02:00
Vector3 SpatialEditorViewport : : _get_ray ( const Vector2 & p_pos ) const {
2014-02-10 02:10:30 +01:00
2017-10-31 18:23:25 +01:00
return camera - > project_ray_normal ( p_pos / viewport_container - > get_stretch_shrink ( ) ) ;
2014-02-10 02:10:30 +01:00
}
void SpatialEditorViewport : : _clear_selected ( ) {
editor_selection - > clear ( ) ;
}
2017-03-05 16:44:50 +01:00
void SpatialEditorViewport : : _select_clicked ( bool p_append , bool p_single ) {
2014-02-10 02:10:30 +01:00
if ( ! clicked )
return ;
2019-04-17 18:24:28 +02:00
Node * node = Object : : cast_to < Node > ( ObjectDB : : get_instance ( clicked ) ) ;
Spatial * selected = Object : : cast_to < Spatial > ( node ) ;
if ( ! selected )
2014-02-10 02:10:30 +01:00
return ;
2019-04-17 18:24:28 +02: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 21:50:00 +02:00
if ( ! _is_node_locked ( selected ) )
_select ( selected , clicked_wants_append , true ) ;
2014-02-10 02:10:30 +01:00
}
2018-09-02 22:31:03 +02:00
void SpatialEditorViewport : : _select ( Node * p_node , bool p_append , bool p_single ) {
2014-02-10 02:10:30 +01:00
if ( ! p_append ) {
2018-05-06 20:49:22 +02:00
editor_selection - > clear ( ) ;
}
2014-02-10 02:10:30 +01:00
2018-05-06 20:49:22 +02:00
if ( editor_selection - > is_selected ( p_node ) ) {
//erase
editor_selection - > remove_node ( p_node ) ;
} else {
2014-02-10 02:10:30 +01:00
editor_selection - > add_node ( p_node ) ;
2018-05-06 20:49:22 +02:00
}
2014-02-10 02:10:30 +01:00
2018-05-06 20:49:22 +02:00
if ( p_single ) {
2018-02-07 07:27:39 +01:00
if ( Engine : : get_singleton ( ) - > is_editor_hint ( ) )
editor - > call ( " edit_node " , p_node ) ;
2014-02-10 02:10:30 +01:00
}
}
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
if ( r_gizmo_handle )
2017-03-05 16:44:50 +01:00
* r_gizmo_handle = - 1 ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Vector3 ray = _get_ray ( p_pos ) ;
Vector3 pos = _get_ray_pos ( p_pos ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Vector < ObjectID > instances = VisualServer : : get_singleton ( ) - > instances_cull_ray ( pos , ray , get_tree ( ) - > get_root ( ) - > get_world ( ) - > get_scenario ( ) ) ;
2018-07-25 00:08:49 +02:00
Set < Ref < EditorSpatialGizmo > > found_gizmos ;
2014-02-10 02:10:30 +01:00
2017-08-26 05:40:45 +02:00
Node * edited_scene = get_tree ( ) - > get_edited_scene_root ( ) ;
2017-03-05 16:44:50 +01:00
ObjectID closest = 0 ;
2018-08-27 16:02:49 +02:00
Node * item = NULL ;
2017-03-05 16:44:50 +01:00
float closest_dist = 1e20 ;
int selected_handle = - 1 ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < instances . size ( ) ; i + + ) {
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
Spatial * spat = Object : : cast_to < Spatial > ( ObjectDB : : get_instance ( instances [ i ] ) ) ;
2014-02-10 02:10:30 +01:00
if ( ! spat )
continue ;
2018-07-25 00:08:49 +02:00
Ref < EditorSpatialGizmo > seg = spat - > get_gizmo ( ) ;
2014-02-10 02:10:30 +01:00
2017-08-09 18:40:02 +02:00
if ( ( ! seg . is_valid ( ) ) | | found_gizmos . has ( seg ) ) {
2014-02-10 02:10:30 +01:00
continue ;
2017-08-09 18:40:02 +02:00
}
2014-02-10 02:10:30 +01:00
found_gizmos . insert ( seg ) ;
Vector3 point ;
Vector3 normal ;
2017-03-05 16:44:50 +01:00
int handle = - 1 ;
2018-05-06 20:49:22 +02:00
bool inters = seg - > intersect_ray ( camera , p_pos , point , normal , & handle , p_alt_select ) ;
2014-02-10 02:10:30 +01:00
if ( ! inters )
continue ;
float dist = pos . distance_to ( point ) ;
2017-03-05 16:44:50 +01:00
if ( dist < 0 )
2014-02-10 02:10:30 +01:00
continue ;
2017-02-06 04:38:39 +01:00
if ( dist < closest_dist ) {
2018-09-02 22:31:03 +02: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 05:40:45 +02:00
}
2018-08-27 16:02:49 +02:00
closest = item - > get_instance_id ( ) ;
closest_dist = dist ;
selected_handle = handle ;
2017-02-06 04:38:39 +01:00
}
2014-02-10 02:10:30 +01:00
}
2017-02-06 04:38:39 +01:00
if ( ! item )
2014-02-10 02:10:30 +01:00
return 0 ;
2017-03-05 16:44:50 +01:00
if ( ! editor_selection - > is_selected ( item ) | | ( r_gizmo_handle & & selected_handle > = 0 ) ) {
2014-02-10 02:10:30 +01:00
if ( r_gizmo_handle )
2017-03-05 16:44:50 +01:00
* r_gizmo_handle = selected_handle ;
2014-02-10 02:10:30 +01:00
}
2017-02-06 04:38:39 +01:00
return closest ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01: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 22:39:07 +01:00
2017-03-05 16:44:50 +01:00
Vector3 ray = _get_ray ( p_pos ) ;
Vector3 pos = _get_ray_pos ( p_pos ) ;
2015-11-04 22:39:07 +01:00
2017-03-05 16:44:50 +01:00
Vector < ObjectID > instances = VisualServer : : get_singleton ( ) - > instances_cull_ray ( pos , ray , get_tree ( ) - > get_root ( ) - > get_world ( ) - > get_scenario ( ) ) ;
2018-07-25 00:08:49 +02:00
Set < Ref < EditorSpatialGizmo > > found_gizmos ;
2015-11-04 22:39:07 +01:00
2017-03-05 16:44:50 +01:00
r_includes_current = false ;
2015-11-04 22:39:07 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < instances . size ( ) ; i + + ) {
2015-11-04 22:39:07 +01:00
2017-08-24 22:58:51 +02:00
Spatial * spat = Object : : cast_to < Spatial > ( ObjectDB : : get_instance ( instances [ i ] ) ) ;
2015-11-04 22:39:07 +01:00
if ( ! spat )
continue ;
2018-07-25 00:08:49 +02:00
Ref < EditorSpatialGizmo > seg = spat - > get_gizmo ( ) ;
2015-11-04 22:39:07 +01:00
if ( ! seg . is_valid ( ) )
continue ;
if ( found_gizmos . has ( seg ) )
continue ;
found_gizmos . insert ( seg ) ;
Vector3 point ;
Vector3 normal ;
2017-03-05 16:44:50 +01:00
int handle = - 1 ;
bool inters = seg - > intersect_ray ( camera , p_pos , point , normal , NULL , p_alt_select ) ;
2015-11-04 22:39:07 +01:00
if ( ! inters )
continue ;
float dist = pos . distance_to ( point ) ;
2017-03-05 16:44:50 +01:00
if ( dist < 0 )
2015-11-04 22:39:07 +01:00
continue ;
if ( editor_selection - > is_selected ( spat ) )
2017-03-05 16:44:50 +01:00
r_includes_current = true ;
2015-11-04 22:39:07 +01:00
_RayResult res ;
2017-03-05 16:44:50 +01:00
res . item = spat ;
res . depth = dist ;
res . handle = handle ;
2015-11-04 22:39:07 +01:00
results . push_back ( res ) ;
}
if ( results . empty ( ) )
return ;
results . sort ( ) ;
}
2017-08-12 18:52:50 +02:00
Vector3 SpatialEditorViewport : : _get_screen_to_space ( const Vector3 & p_vector3 ) {
2014-02-10 02:10:30 +01:00
CameraMatrix cm ;
2018-06-27 16:59:45 +02: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 ( ) ) ;
}
2017-03-05 16:44:50 +01:00
float screen_w , screen_h ;
cm . get_viewport_size ( screen_w , screen_h ) ;
2014-02-10 02:10:30 +01:00
Transform camera_transform ;
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
2018-05-06 20:49:22 +02:00
return camera_transform . xform ( Vector3 ( ( ( p_vector3 . x / get_size ( ) . width ) * 2.0 - 1.0 ) * screen_w , ( ( 1.0 - ( p_vector3 . y / get_size ( ) . height ) ) * 2.0 - 1.0 ) * screen_h , - ( get_znear ( ) + p_vector3 . z ) ) ) ;
2014-02-10 02:10:30 +01:00
}
void SpatialEditorViewport : : _select_region ( ) {
2017-03-05 16:44:50 +01:00
if ( cursor . region_begin = = cursor . region_end )
2014-02-10 02:10:30 +01:00
return ; //nothing really
2018-05-06 20:49:22 +02:00
float z_offset = MAX ( 0.0 , 5.0 - get_znear ( ) ) ;
2017-03-05 16:44:50 +01:00
Vector3 box [ 4 ] = {
2014-02-10 02:10:30 +01:00
Vector3 (
2017-03-05 16:44:50 +01:00
MIN ( cursor . region_begin . x , cursor . region_end . x ) ,
MIN ( cursor . region_begin . y , cursor . region_end . y ) ,
2018-05-06 20:49:22 +02:00
z_offset ) ,
2014-02-10 02:10:30 +01:00
Vector3 (
2017-03-05 16:44:50 +01:00
MAX ( cursor . region_begin . x , cursor . region_end . x ) ,
MIN ( cursor . region_begin . y , cursor . region_end . y ) ,
2018-05-06 20:49:22 +02:00
z_offset ) ,
2014-02-10 02:10:30 +01:00
Vector3 (
2017-03-05 16:44:50 +01:00
MAX ( cursor . region_begin . x , cursor . region_end . x ) ,
MAX ( cursor . region_begin . y , cursor . region_end . y ) ,
2018-05-06 20:49:22 +02:00
z_offset ) ,
2014-02-10 02:10:30 +01:00
Vector3 (
2017-03-05 16:44:50 +01:00
MIN ( cursor . region_begin . x , cursor . region_end . x ) ,
MAX ( cursor . region_begin . y , cursor . region_end . y ) ,
2018-05-06 20:49:22 +02:00
z_offset )
2014-02-10 02:10:30 +01:00
} ;
Vector < Plane > frustum ;
2017-09-10 15:37:49 +02:00
Vector3 cam_pos = _get_camera_position ( ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 4 ; i + + ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Vector3 a = _get_screen_to_space ( box [ i ] ) ;
Vector3 b = _get_screen_to_space ( box [ ( i + 1 ) % 4 ] ) ;
2018-06-27 16:59:45 +02:00
if ( orthogonal ) {
frustum . push_back ( Plane ( a , ( a - b ) . normalized ( ) ) ) ;
} else {
frustum . push_back ( Plane ( a , b , cam_pos ) ) ;
}
2014-02-10 02:10:30 +01:00
}
2018-06-27 16:59:45 +02:00
if ( ! orthogonal ) {
Plane near ( cam_pos , - _get_camera_normal ( ) ) ;
near . d - = get_znear ( ) ;
2014-02-10 02:10:30 +01:00
2018-06-27 16:59:45 +02:00
frustum . push_back ( near ) ;
2014-02-10 02:10:30 +01:00
2018-06-27 16:59:45 +02:00
Plane far = - near ;
far . d + = get_zfar ( ) ;
2014-02-10 02:10:30 +01:00
2018-06-27 16:59:45 +02:00
frustum . push_back ( far ) ;
}
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Vector < ObjectID > instances = VisualServer : : get_singleton ( ) - > instances_cull_convex ( frustum , get_tree ( ) - > get_root ( ) - > get_world ( ) - > get_scenario ( ) ) ;
2018-09-02 22:31:03 +02:00
Vector < Node * > selected ;
2017-09-12 15:06:13 +02:00
Node * edited_scene = get_tree ( ) - > get_edited_scene_root ( ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < instances . size ( ) ; i + + ) {
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
Spatial * sp = Object : : cast_to < Spatial > ( ObjectDB : : get_instance ( instances [ i ] ) ) ;
2019-07-19 17:56:35 +02:00
if ( ! sp | | _is_node_locked ( sp ) )
2014-02-10 02:10:30 +01:00
continue ;
2018-09-02 22:31:03 +02: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 20:49:22 +02:00
}
2019-04-17 18:24:28 +02: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 22:31:03 +02:00
if ( selected . find ( item ) ! = - 1 ) continue ;
2018-05-06 20:49:22 +02:00
2019-07-15 21:50:00 +02:00
if ( _is_node_locked ( Object : : cast_to < Spatial > ( item ) ) ) continue ;
2018-07-25 00:08:49 +02:00
Ref < EditorSpatialGizmo > seg = sp - > get_gizmo ( ) ;
2014-02-10 02:10:30 +01:00
if ( ! seg . is_valid ( ) )
continue ;
2018-05-06 20:49:22 +02:00
if ( seg - > intersect_frustum ( camera , frustum ) ) {
2018-09-02 22:31:03 +02:00
selected . push_back ( item ) ;
2017-09-12 15:06:13 +02:00
}
2018-05-06 20:49:22 +02:00
}
2014-02-10 02:10:30 +01:00
2018-05-06 20:49:22 +02:00
bool single = selected . size ( ) = = 1 ;
for ( int i = 0 ; i < selected . size ( ) ; i + + ) {
_select ( selected [ i ] , true , single ) ;
2014-02-10 02:10:30 +01:00
}
}
2015-03-21 21:47:21 +01:00
void SpatialEditorViewport : : _update_name ( ) {
2018-10-01 08:00:49 +02:00
String view_mode = orthogonal ? TTR ( " Orthogonal " ) : TTR ( " Perspective " ) ;
2015-03-21 21:47:21 +01:00
2017-03-05 16:44:50 +01:00
if ( name ! = " " )
2018-10-06 22:53:11 +02:00
view_menu - > set_text ( name + " " + view_mode ) ;
2015-03-21 21:47:21 +01:00
else
2018-10-06 22:53:11 +02:00
view_menu - > set_text ( view_mode ) ;
2017-12-19 06:25:00 +01:00
view_menu - > set_size ( Vector2 ( 0 , 0 ) ) ; // resets the button size
2015-03-21 21:47:21 +01:00
}
2017-03-05 16:44:50 +01:00
void SpatialEditorViewport : : _compute_edit ( const Point2 & p_point ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
spatial_editor - > update_transform_gizmo ( ) ;
2017-03-05 16:44:50 +01:00
_edit . center = spatial_editor - > get_gizmo_transform ( ) . origin ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
2014-02-10 02:10:30 +01:00
if ( ! sp )
continue ;
2017-03-05 16:44:50 +01:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
2014-02-10 02:10:30 +01:00
if ( ! se )
continue ;
2017-10-03 18:49:32 +02:00
se - > original = se - > sp - > get_global_gizmo_transform ( ) ;
se - > original_local = se - > sp - > get_local_gizmo_transform ( ) ;
2014-02-10 02:10:30 +01:00
}
}
2017-07-23 02:02:18 +02:00
static int _get_key_modifier_setting ( const String & p_property ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
switch ( EditorSettings : : get_singleton ( ) - > get ( p_property ) . operator int ( ) ) {
2014-02-10 02:10:30 +01: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 02:02:18 +02: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 22:13:12 +02:00
bool SpatialEditorViewport : : _gizmo_select ( const Vector2 & p_screenpos , bool p_highlight_only ) {
2014-02-10 02:10:30 +01:00
if ( ! spatial_editor - > is_gizmo_visible ( ) )
return false ;
2017-03-05 16:44:50 +01:00
if ( get_selected_count ( ) = = 0 ) {
2017-05-02 22:13:12 +02:00
if ( p_highlight_only )
2017-04-06 17:35:08 +02:00
spatial_editor - > select_gizmo_highlight_axis ( - 1 ) ;
2014-02-10 02:10:30 +01:00
return false ;
}
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
Transform gt = spatial_editor - > get_gizmo_transform ( ) ;
2017-03-05 16:44:50 +01:00
float gs = gizmo_scale ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_SELECT | | spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_MOVE ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
int col_axis = - 1 ;
float col_d = 1e20 ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 3 ; i + + ) {
2014-02-10 02:10:30 +01:00
2017-09-21 23:11:56 +02:00
Vector3 grabber_pos = gt . origin + gt . basis . get_axis ( i ) * gs * ( GIZMO_ARROW_OFFSET + ( GIZMO_ARROW_SIZE * 0.5 ) ) ;
2017-03-05 16:44:50 +01:00
float grabber_radius = gs * GIZMO_ARROW_SIZE ;
2014-02-10 02:10:30 +01:00
Vector3 r ;
2017-08-29 03:39:45 +02:00
2019-07-23 11:42:41 +02:00
if ( Geometry : : segment_intersects_sphere ( ray_pos , ray_pos + ray * MAX_Z , grabber_pos , grabber_radius , & r ) ) {
2014-02-10 02:10:30 +01:00
float d = r . distance_to ( ray_pos ) ;
2017-03-05 16:44:50 +01:00
if ( d < col_d ) {
col_d = d ;
col_axis = i ;
2014-02-10 02:10:30 +01:00
}
}
}
2017-08-29 03:39:45 +02:00
bool is_plane_translate = false ;
2017-09-21 23:11:56 +02:00
// plane select
2017-08-29 03:39:45 +02: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 16:44:50 +01:00
if ( col_axis ! = - 1 ) {
2014-02-10 02:10:30 +01:00
2017-05-02 22:13:12 +02:00
if ( p_highlight_only ) {
2014-02-10 02:10:30 +01:00
2017-08-29 03:39:45 +02:00
spatial_editor - > select_gizmo_highlight_axis ( col_axis + ( is_plane_translate ? 6 : 0 ) ) ;
2014-02-10 02:10:30 +01:00
} else {
2017-08-29 03:39:45 +02:00
//handle plane translate
2017-03-05 16:44:50 +01:00
_edit . mode = TRANSFORM_TRANSLATE ;
_compute_edit ( Point2 ( p_screenpos . x , p_screenpos . y ) ) ;
2017-08-29 03:39:45 +02:00
_edit . plane = TransformPlane ( TRANSFORM_X_AXIS + col_axis + ( is_plane_translate ? 3 : 0 ) ) ;
2014-02-10 02:10:30 +01:00
}
return true ;
}
}
2017-03-05 16:44:50 +01:00
if ( spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_SELECT | | spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_ROTATE ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
int col_axis = - 1 ;
float col_d = 1e20 ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 3 ; i + + ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Plane plane ( gt . origin , gt . basis . get_axis ( i ) . normalized ( ) ) ;
2014-02-10 02:10:30 +01:00
Vector3 r ;
2017-03-05 16:44:50 +01:00
if ( ! plane . intersects_ray ( ray_pos , ray , & r ) )
2014-02-10 02:10:30 +01:00
continue ;
float dist = r . distance_to ( gt . origin ) ;
2017-08-29 03:39:45 +02:00
if ( dist > gs * ( GIZMO_CIRCLE_SIZE - GIZMO_RING_HALF_WIDTH ) & & dist < gs * ( GIZMO_CIRCLE_SIZE + GIZMO_RING_HALF_WIDTH ) ) {
2014-02-10 02:10:30 +01:00
float d = ray_pos . distance_to ( r ) ;
2017-03-05 16:44:50 +01:00
if ( d < col_d ) {
col_d = d ;
col_axis = i ;
2014-02-10 02:10:30 +01:00
}
}
}
2017-03-05 16:44:50 +01:00
if ( col_axis ! = - 1 ) {
2014-02-10 02:10:30 +01:00
2017-05-02 22:13:12 +02:00
if ( p_highlight_only ) {
2014-02-10 02:10:30 +01:00
2017-04-06 17:35:08 +02:00
spatial_editor - > select_gizmo_highlight_axis ( col_axis + 3 ) ;
2014-02-10 02:10:30 +01:00
} else {
//handle rotate
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
}
return true ;
}
}
2017-09-21 23:11:56 +02: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 11:42:41 +02:00
if ( Geometry : : segment_intersects_sphere ( ray_pos , ray_pos + ray * MAX_Z , grabber_pos , grabber_radius , & r ) ) {
2017-09-21 23:11:56 +02:00
float d = r . distance_to ( ray_pos ) ;
if ( d < col_d ) {
col_d = d ;
col_axis = i ;
}
}
}
2017-11-14 23:50:19 +01: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 23:11:56 +02:00
if ( col_axis ! = - 1 ) {
if ( p_highlight_only ) {
2017-11-14 23:50:19 +01:00
spatial_editor - > select_gizmo_highlight_axis ( col_axis + ( is_plane_scale ? 12 : 9 ) ) ;
2017-09-21 23:11:56 +02:00
} else {
//handle scale
_edit . mode = TRANSFORM_SCALE ;
_compute_edit ( Point2 ( p_screenpos . x , p_screenpos . y ) ) ;
2017-11-14 23:50:19 +01:00
_edit . plane = TransformPlane ( TRANSFORM_X_AXIS + col_axis + ( is_plane_scale ? 3 : 0 ) ) ;
2017-09-21 23:11:56 +02:00
}
return true ;
}
}
2017-05-02 22:13:12 +02:00
if ( p_highlight_only )
2017-04-06 17:35:08 +02:00
spatial_editor - > select_gizmo_highlight_axis ( - 1 ) ;
2014-02-10 02:10:30 +01:00
return false ;
}
2017-12-19 15:29:55 +01:00
void SpatialEditorViewport : : _surface_mouse_enter ( ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( ! surface - > has_focus ( ) & & ( ! get_focus_owner ( ) | | ! get_focus_owner ( ) - > is_text_field ( ) ) )
surface - > grab_focus ( ) ;
2014-02-10 02:10:30 +01:00
}
2017-12-19 15:29:55 +01:00
void SpatialEditorViewport : : _surface_mouse_exit ( ) {
2017-09-02 21:47:16 +02:00
_remove_preview ( ) ;
}
2017-12-19 15:29:55 +01: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 21:50:00 +02: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 17:38:03 +02:00
void SpatialEditorViewport : : _list_select ( Ref < InputEventMouseButton > b ) {
2015-12-13 21:16:13 +01:00
2017-06-03 10:54:24 +02:00
_find_items_at_pos ( b - > get_position ( ) , clicked_includes_current , selection_results , b - > get_shift ( ) ) ;
2015-12-13 21:16:13 +01:00
2017-03-05 16:44:50 +01:00
Node * scene = editor - > get_edited_scene ( ) ;
2015-12-13 21:16:13 +01:00
2017-03-05 16:44:50 +01: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 21:16:13 +01:00
//invalid result
selection_results . remove ( i ) ;
i - - ;
}
}
2017-05-20 17:38:03 +02:00
clicked_wants_append = b - > get_shift ( ) ;
2015-12-13 21:16:13 +01:00
if ( selection_results . size ( ) = = 1 ) {
2017-08-07 12:17:31 +02:00
clicked = selection_results [ 0 ] . item - > get_instance_id ( ) ;
2015-12-13 21:16:13 +01:00
selection_results . clear ( ) ;
if ( clicked ) {
2017-03-05 16:44:50 +01:00
_select_clicked ( clicked_wants_append , true ) ;
clicked = 0 ;
2015-12-13 21:16:13 +01:00
}
} else if ( ! selection_results . empty ( ) ) {
NodePath root_path = get_tree ( ) - > get_edited_scene_root ( ) - > get_path ( ) ;
2017-03-05 16:44:50 +01:00
StringName root_name = root_path . get_name ( root_path . get_name_count ( ) - 1 ) ;
2015-12-13 21:16:13 +01:00
for ( int i = 0 ; i < selection_results . size ( ) ; i + + ) {
2017-03-05 16:44:50 +01:00
Spatial * spat = selection_results [ i ] . item ;
2015-12-13 21:16:13 +01:00
2018-09-02 23:40:51 +02:00
Ref < Texture > icon = EditorNode : : get_singleton ( ) - > get_object_icon ( spat , " Node " ) ;
2015-12-13 21:16:13 +01:00
2017-03-05 16:44:50 +01:00
String node_path = " / " + root_name + " / " + root_path . rel_path_to ( spat - > get_path ( ) ) ;
2015-12-13 21:16:13 +01:00
selection_menu - > add_item ( spat - > get_name ( ) ) ;
2017-03-05 16:44:50 +01:00
selection_menu - > set_item_icon ( i , icon ) ;
2015-12-13 21:16:13 +01:00
selection_menu - > set_item_metadata ( i , node_path ) ;
2017-05-01 20:57:35 +02:00
selection_menu - > set_item_tooltip ( i , String ( spat - > get_name ( ) ) + " \n Type: " + spat - > get_class ( ) + " \n Path: " + node_path ) ;
2015-12-13 21:16:13 +01:00
}
2017-06-03 10:54:24 +02:00
selection_menu - > set_global_position ( b - > get_global_position ( ) ) ;
2015-12-13 21:16:13 +01:00
selection_menu - > popup ( ) ;
}
}
2017-10-30 01:22:48 +01:00
2017-05-20 17:38:03 +02:00
void SpatialEditorViewport : : _sinput ( const Ref < InputEvent > & p_event ) {
2014-02-10 02:10:30 +01:00
if ( previewing )
return ; //do NONE
{
2017-06-08 19:57:35 +02: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 02:10:30 +01:00
EditorNode * en = editor ;
2016-03-30 01:02:53 +02:00
EditorPluginList * over_plugin_list = en - > get_editor_plugins_over ( ) ;
if ( ! over_plugin_list - > empty ( ) ) {
2017-06-08 19:57:35 +02:00
bool discard = over_plugin_list - > forward_spatial_gui_input ( camera , p_event , false ) ;
2014-02-10 02:10:30 +01:00
if ( discard )
return ;
}
}
2017-05-20 17:38:03 +02:00
Ref < InputEventMouseButton > b = p_event ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
if ( b . is_valid ( ) ) {
2017-09-19 01:30:46 +02:00
float zoom_factor = 1 + ( ZOOM_MULTIPLIER - 1 ) * b - > get_factor ( ) ;
2017-05-20 17:38:03 +02:00
switch ( b - > get_button_index ( ) ) {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
case BUTTON_WHEEL_UP : {
2017-10-08 02:43:57 +02:00
if ( is_freelook_active ( ) )
scale_freelook_speed ( zoom_factor ) ;
else
scale_cursor_distance ( 1.0 / zoom_factor ) ;
2017-05-20 17:38:03 +02:00
} break ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
case BUTTON_WHEEL_DOWN : {
2017-10-08 02:43:57 +02:00
if ( is_freelook_active ( ) )
scale_freelook_speed ( 1.0 / zoom_factor ) ;
else
scale_cursor_distance ( zoom_factor ) ;
2017-05-20 17:38:03 +02:00
} break ;
2017-05-07 22:59:05 +02:00
2017-05-20 17:38:03 +02:00
case BUTTON_RIGHT : {
2014-02-10 02:10:30 +01:00
2017-09-19 02:30:48 +02:00
NavigationScheme nav_scheme = ( NavigationScheme ) EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation/navigation_scheme " ) . operator int ( ) ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
if ( b - > is_pressed ( ) & & _edit . gizmo . is_valid ( ) ) {
//restore
_edit . gizmo - > commit_handle ( _edit . gizmo_handle , _edit . gizmo_initial_value , true ) ;
2018-07-25 00:08:49 +02:00
_edit . gizmo = Ref < EditorSpatialGizmo > ( ) ;
2017-05-20 17:38:03 +02:00
}
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
if ( _edit . mode = = TRANSFORM_NONE & & b - > is_pressed ( ) ) {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
if ( b - > get_alt ( ) ) {
2015-11-19 15:47:04 +01:00
2017-05-20 17:38:03 +02:00
if ( nav_scheme = = NAVIGATION_MAYA )
break ;
2015-11-19 15:47:04 +01:00
2017-05-20 17:38:03 +02:00
_list_select ( b ) ;
return ;
2014-02-10 02:10:30 +01:00
}
2017-05-20 17:38:03 +02:00
}
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
if ( _edit . mode ! = TRANSFORM_NONE & & b - > is_pressed ( ) ) {
//cancel motion
_edit . mode = TRANSFORM_NONE ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
2017-05-20 17:38:03 +02:00
if ( ! sp )
continue ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
if ( ! se )
continue ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
sp - > set_global_transform ( se - > original ) ;
2014-02-10 02:10:30 +01:00
}
2017-05-20 17:38:03 +02:00
surface - > update ( ) ;
set_message ( TTR ( " Transform Aborted. " ) , 3 ) ;
}
2017-05-07 22:59:05 +02:00
2017-07-23 02:02:18 +02:00
if ( b - > is_pressed ( ) ) {
int mod = _get_key_modifier ( b ) ;
2018-10-20 12:49:33 +02:00
if ( ! orthogonal ) {
if ( mod = = _get_key_modifier_setting ( " editors/3d/freelook/freelook_activation_modifier " ) ) {
set_freelook_active ( true ) ;
}
2017-07-23 02:02:18 +02:00
}
} else {
2017-10-08 02:43:57 +02:00
set_freelook_active ( false ) ;
2017-07-23 02:02:18 +02:00
}
2017-06-20 02:24:35 +02: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 22:59:05 +02:00
2017-05-20 17:38:03 +02:00
} break ;
case BUTTON_MIDDLE : {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
if ( b - > is_pressed ( ) & & _edit . mode ! = TRANSFORM_NONE ) {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
switch ( _edit . plane ) {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
case TRANSFORM_VIEW : {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
_edit . plane = TRANSFORM_X_AXIS ;
set_message ( TTR ( " X-Axis Transform. " ) , 2 ) ;
name = " " ;
_update_name ( ) ;
} break ;
case TRANSFORM_X_AXIS : {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
_edit . plane = TRANSFORM_Y_AXIS ;
set_message ( TTR ( " Y-Axis Transform. " ) , 2 ) ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
} break ;
case TRANSFORM_Y_AXIS : {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
_edit . plane = TRANSFORM_Z_AXIS ;
set_message ( TTR ( " Z-Axis Transform. " ) , 2 ) ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
} break ;
case TRANSFORM_Z_AXIS : {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
_edit . plane = TRANSFORM_VIEW ;
set_message ( TTR ( " View Plane Transform. " ) , 2 ) ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
} break ;
2018-09-26 13:13:56 +02:00
case TRANSFORM_YZ :
case TRANSFORM_XZ :
case TRANSFORM_XY : {
} break ;
2014-02-10 02:10:30 +01:00
}
2017-05-20 17:38:03 +02:00
}
} break ;
case BUTTON_LEFT : {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
if ( b - > is_pressed ( ) ) {
2014-02-10 02:10:30 +01:00
2017-09-19 02:30:48 +02:00
NavigationScheme nav_scheme = ( NavigationScheme ) EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation/navigation_scheme " ) . operator int ( ) ;
2017-05-20 17:38:03 +02:00
if ( ( nav_scheme = = NAVIGATION_MAYA | | nav_scheme = = NAVIGATION_MODO ) & & b - > get_alt ( ) ) {
break ;
}
2014-03-31 10:27:41 +02:00
2017-05-20 17:38:03 +02:00
if ( spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_LIST_SELECT ) {
_list_select ( b ) ;
break ;
}
2015-12-13 21:16:13 +01:00
2017-06-03 10:54:24 +02:00
_edit . mouse_pos = b - > get_position ( ) ;
2019-03-16 09:15:39 +01:00
_edit . snap = spatial_editor - > is_snap_enabled ( ) ;
2017-05-20 17:38:03 +02:00
_edit . mode = TRANSFORM_NONE ;
2014-10-12 07:13:22 +02:00
2017-05-20 17:38:03 +02:00
//gizmo has priority over everything
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
bool can_select_gizmos = true ;
2014-10-12 07:13:22 +02:00
2017-05-20 17:38:03 +02: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 07:13:22 +02:00
2017-05-20 17:38:03 +02:00
if ( can_select_gizmos & & spatial_editor - > get_selected ( ) ) {
2014-05-05 03:50:23 +02:00
2018-07-25 00:08:49 +02:00
Ref < EditorSpatialGizmo > seg = spatial_editor - > get_selected ( ) - > get_gizmo ( ) ;
2017-05-20 17:38:03 +02: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 03:50:23 +02:00
2017-05-20 17:38:03 +02:00
_edit . gizmo = seg ;
_edit . gizmo_handle = handle ;
_edit . gizmo_initial_value = seg - > get_handle_value ( handle ) ;
break ;
2014-05-05 03:50:23 +02:00
}
}
2017-05-20 17:38:03 +02:00
}
2014-05-05 03:50:23 +02:00
2017-05-20 17:38:03 +02:00
if ( _gizmo_select ( _edit . mouse_pos ) )
break ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
clicked = 0 ;
clicked_includes_current = false ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02: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 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
/* HANDLE ROTATION */
if ( get_selected_count ( ) = = 0 )
break ; //bye
//handle rotate
_edit . mode = TRANSFORM_ROTATE ;
2017-06-03 10:54:24 +02:00
_compute_edit ( b - > get_position ( ) ) ;
2017-05-20 17:38:03 +02:00
break ;
}
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
if ( spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_MOVE ) {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
if ( get_selected_count ( ) = = 0 )
break ; //bye
2017-08-29 03:39:45 +02:00
//handle translate
2017-05-20 17:38:03 +02:00
_edit . mode = TRANSFORM_TRANSLATE ;
2017-06-03 10:54:24 +02:00
_compute_edit ( b - > get_position ( ) ) ;
2017-05-20 17:38:03 +02:00
break ;
}
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
if ( spatial_editor - > get_tool_mode ( ) = = SpatialEditor : : TOOL_MODE_SCALE ) {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
if ( get_selected_count ( ) = = 0 )
break ; //bye
2017-10-23 21:21:15 +02:00
//handle scale
2017-05-20 17:38:03 +02:00
_edit . mode = TRANSFORM_SCALE ;
2017-06-03 10:54:24 +02:00
_compute_edit ( b - > get_position ( ) ) ;
2017-05-20 17:38:03 +02:00
break ;
}
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
// todo scale
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
int gizmo_handle = - 1 ;
2014-02-10 02:10:30 +01:00
2017-06-03 10:54:24 +02:00
clicked = _select_ray ( b - > get_position ( ) , b - > get_shift ( ) , clicked_includes_current , & gizmo_handle , b - > get_shift ( ) ) ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
//clicking is always deferred to either move or release
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
clicked_wants_append = b - > get_shift ( ) ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
if ( ! clicked ) {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
if ( ! clicked_wants_append )
_clear_selected ( ) ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
//default to regionselect
cursor . region_select = true ;
2017-06-03 10:54:24 +02:00
cursor . region_begin = b - > get_position ( ) ;
cursor . region_end = b - > get_position ( ) ;
2017-05-20 17:38:03 +02:00
}
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
if ( clicked & & gizmo_handle > = 0 ) {
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
Spatial * spa = Object : : cast_to < Spatial > ( ObjectDB : : get_instance ( clicked ) ) ;
if ( spa ) {
2014-02-10 02:10:30 +01:00
2018-07-25 00:08:49 +02:00
Ref < EditorSpatialGizmo > seg = spa - > get_gizmo ( ) ;
2017-08-24 22:58:51 +02:00
if ( seg . is_valid ( ) ) {
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
_edit . gizmo = seg ;
_edit . gizmo_handle = gizmo_handle ;
_edit . gizmo_initial_value = seg - > get_handle_value ( gizmo_handle ) ;
break ;
2014-02-10 02:10:30 +01:00
}
}
2017-05-20 17:38:03 +02:00
}
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
surface - > update ( ) ;
} else {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
if ( _edit . gizmo . is_valid ( ) ) {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
_edit . gizmo - > commit_handle ( _edit . gizmo_handle , _edit . gizmo_initial_value , false ) ;
2018-07-25 00:08:49 +02:00
_edit . gizmo = Ref < EditorSpatialGizmo > ( ) ;
2017-05-20 17:38:03 +02:00
break ;
}
if ( clicked ) {
_select_clicked ( clicked_wants_append , true ) ;
2018-10-20 12:49:33 +02:00
// Processing was deferred.
2017-05-20 17:38:03 +02:00
clicked = 0 ;
}
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
if ( cursor . region_select ) {
2018-05-06 20:49:22 +02:00
if ( ! clicked_wants_append ) _clear_selected ( ) ;
2017-05-20 17:38:03 +02:00
_select_region ( ) ;
cursor . region_select = false ;
surface - > update ( ) ;
}
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
if ( _edit . mode ! = TRANSFORM_NONE ) {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
static const char * _transform_name [ 4 ] = { " None " , " Rotate " , " Translate " , " Scale " } ;
undo_redo - > create_action ( _transform_name [ _edit . mode ] ) ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
2017-05-20 17:38:03 +02:00
if ( ! sp )
continue ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
if ( ! se )
continue ;
2014-02-10 02:10:30 +01:00
2017-10-03 18:49:32 +02:00
undo_redo - > add_do_method ( sp , " set_global_transform " , sp - > get_global_gizmo_transform ( ) ) ;
2017-05-20 17:38:03 +02:00
undo_redo - > add_undo_method ( sp , " set_global_transform " , se - > original ) ;
2014-02-10 02:10:30 +01:00
}
2017-05-20 17:38:03 +02:00
undo_redo - > commit_action ( ) ;
_edit . mode = TRANSFORM_NONE ;
set_message ( " " ) ;
2014-02-10 02:10:30 +01:00
}
2017-05-07 22:59:05 +02:00
2017-05-20 17:38:03 +02:00
surface - > update ( ) ;
}
2016-05-21 15:29:25 +02:00
2017-05-20 17:38:03 +02:00
} break ;
}
}
2014-05-05 03:50:23 +02:00
2017-05-20 17:38:03 +02:00
Ref < InputEventMouseMotion > m = p_event ;
2014-05-05 03:50:23 +02:00
2017-05-20 17:38:03 +02:00
if ( m . is_valid ( ) ) {
2014-05-05 03:50:23 +02:00
2017-06-03 10:54:24 +02:00
_edit . mouse_pos = m - > get_position ( ) ;
2014-05-05 03:50:23 +02:00
2017-05-20 17:38:03 +02:00
if ( spatial_editor - > get_selected ( ) ) {
2014-05-05 03:50:23 +02:00
2018-07-25 00:08:49 +02:00
Ref < EditorSpatialGizmo > seg = spatial_editor - > get_selected ( ) - > get_gizmo ( ) ;
2017-05-20 17:38:03 +02: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 03:50:23 +02:00
2017-05-20 17:38:03 +02:00
selected_handle = handle ;
}
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02: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 02:10:30 +01:00
}
2017-05-20 17:38:03 +02:00
}
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
if ( spatial_editor - > get_over_gizmo_handle ( ) = = - 1 & & ! ( m - > get_button_mask ( ) & 1 ) & & ! _edit . gizmo . is_valid ( ) ) {
2016-05-21 15:29:25 +02:00
2017-05-20 17:38:03 +02:00
_gizmo_select ( _edit . mouse_pos , true ) ;
}
2014-02-10 02:10:30 +01:00
2017-09-19 02:30:48 +02:00
NavigationScheme nav_scheme = ( NavigationScheme ) EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation/navigation_scheme " ) . operator int ( ) ;
2017-05-20 17:38:03 +02:00
NavigationMode nav_mode = NAVIGATION_NONE ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
if ( _edit . gizmo . is_valid ( ) ) {
2014-02-10 02:10:30 +01:00
2017-06-03 10:54:24 +02:00
_edit . gizmo - > set_handle ( _edit . gizmo_handle , camera , m - > get_position ( ) ) ;
2017-05-20 17:38:03 +02: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 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
} else if ( m - > get_button_mask ( ) & BUTTON_MASK_LEFT ) {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02: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 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
if ( ! clicked_includes_current ) {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
_select_clicked ( clicked_wants_append , true ) ;
2018-10-20 12:49:33 +02:00
// Processing was deferred.
2014-03-31 05:59:42 +02:00
}
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
_compute_edit ( _edit . mouse_pos ) ;
clicked = 0 ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
_edit . mode = TRANSFORM_TRANSLATE ;
}
2014-02-10 02:10:30 +01:00
2019-06-20 16:59:48 +02:00
if ( cursor . region_select ) {
2017-06-03 10:54:24 +02:00
cursor . region_end = m - > get_position ( ) ;
2017-05-20 17:38:03 +02:00
surface - > update ( ) ;
return ;
}
2014-02-10 02:10:30 +01:00
2019-06-20 16:59:48 +02:00
if ( _edit . mode = = TRANSFORM_NONE )
2017-05-20 17:38:03 +02:00
return ;
2014-02-10 02:10:30 +01:00
2017-06-03 10:54:24 +02:00
Vector3 ray_pos = _get_ray_pos ( m - > get_position ( ) ) ;
Vector3 ray = _get_ray ( m - > get_position ( ) ) ;
2019-07-24 14:41:09 +02:00
float snap = EDITOR_GET ( " interface/inspector/default_float_step " ) ;
int snap_step_decimals = Math : : range_step_decimals ( snap ) ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
switch ( _edit . mode ) {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
case TRANSFORM_SCALE : {
2014-02-10 02:10:30 +01:00
2017-09-21 23:11:56 +02:00
Vector3 motion_mask ;
Plane plane ;
2017-11-14 23:50:19 +01:00
bool plane_mv = false ;
2017-09-21 23:11:56 +02: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 23:50:19 +01: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 23:11:56 +02:00
}
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
Vector3 intersection ;
if ( ! plane . intersects_ray ( ray_pos , ray , & intersection ) )
break ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
Vector3 click ;
if ( ! plane . intersects_ray ( _edit . click_ray_pos , _edit . click_ray , & click ) )
break ;
2014-02-10 02:10:30 +01:00
2017-09-21 23:11:56 +02:00
Vector3 motion = intersection - click ;
2017-11-14 23:50:19 +01: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 02:10:30 +01:00
2017-11-08 16:07:30 +01:00
} else {
2017-09-21 23:11:56 +02: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 02:10:30 +01:00
2017-09-21 23:11:56 +02:00
float scale = center_inters_dist - center_click_dist ;
motion = Vector3 ( scale , scale , scale ) ;
2017-05-20 17:38:03 +02:00
}
2014-02-10 02:10:30 +01:00
2017-09-21 23:11:56 +02:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
2014-02-10 02:10:30 +01:00
2018-10-20 12:49:33 +02:00
// Disable local transformation for TRANSFORM_VIEW
bool local_coords = ( spatial_editor - > are_local_coords_enabled ( ) & & _edit . plane ! = TRANSFORM_VIEW ) ;
2014-02-10 02:10:30 +01:00
2017-09-21 23:11:56 +02:00
if ( _edit . snap | | spatial_editor - > is_snap_enabled ( ) ) {
snap = spatial_editor - > get_scale_snap ( ) / 100 ;
}
2019-07-24 14:41:09 +02: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 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
2017-09-21 23:11:56 +02:00
if ( ! sp ) {
2017-05-20 17:38:03 +02:00
continue ;
2017-09-21 23:11:56 +02:00
}
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
2017-09-21 23:11:56 +02:00
if ( ! se ) {
2017-05-20 17:38:03 +02:00
continue ;
2017-09-21 23:11:56 +02:00
}
2014-02-10 02:10:30 +01:00
2017-10-23 21:21:15 +02:00
if ( sp - > has_meta ( " _edit_lock_ " ) ) {
continue ;
}
2017-05-20 17:38:03 +02:00
Transform original = se - > original ;
2017-09-21 23:11:56 +02:00
Transform original_local = se - > original_local ;
2017-05-20 17:38:03 +02:00
Transform base = Transform ( Basis ( ) , _edit . center ) ;
2017-09-21 23:11:56 +02:00
Transform t ;
Vector3 local_scale ;
2014-02-10 02:10:30 +01:00
2017-09-21 23:11:56 +02: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 16:07:30 +01: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 23:11:56 +02: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 16:07:30 +01:00
// Apply scale
2017-09-21 23:11:56 +02:00
sp - > set_global_transform ( t ) ;
}
2017-05-20 17:38:03 +02:00
}
2014-03-31 05:59:42 +02:00
2017-05-20 17:38:03 +02:00
surface - > update ( ) ;
2014-03-31 05:59:42 +02:00
2017-05-20 17:38:03 +02:00
} break ;
2014-03-31 05:59:42 +02:00
2017-05-20 17:38:03 +02:00
case TRANSFORM_TRANSLATE : {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
Vector3 motion_mask ;
Plane plane ;
2017-11-13 22:54:33 +01:00
bool plane_mv = false ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02: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 05:59:42 +02:00
break ;
2017-05-20 17:38:03 +02: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 03:39:45 +02: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 17:38:03 +02:00
}
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
Vector3 intersection ;
if ( ! plane . intersects_ray ( ray_pos , ray , & intersection ) )
break ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
Vector3 click ;
if ( ! plane . intersects_ray ( _edit . click_ray_pos , _edit . click_ray , & click ) )
break ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
Vector3 motion = intersection - click ;
2017-11-14 23:50:19 +01:00
if ( _edit . plane ! = TRANSFORM_VIEW ) {
2017-11-08 16:07:30 +01:00
if ( ! plane_mv ) {
2017-08-29 03:39:45 +02:00
motion = motion_mask . dot ( motion ) * motion_mask ;
2017-11-08 16:07:30 +01:00
}
2017-05-20 17:38:03 +02:00
}
2014-02-10 02:10:30 +01:00
2017-08-08 12:55:21 +02:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
2018-10-20 12:49:33 +02:00
// Disable local transformation for TRANSFORM_VIEW
bool local_coords = ( spatial_editor - > are_local_coords_enabled ( ) & & _edit . plane ! = TRANSFORM_VIEW ) ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
if ( _edit . snap | | spatial_editor - > is_snap_enabled ( ) ) {
snap = spatial_editor - > get_translate_snap ( ) ;
2017-08-08 12:55:21 +02:00
}
2019-07-24 14:41:09 +02: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 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
2017-05-20 17:38:03 +02:00
if ( ! sp ) {
continue ;
2014-02-10 02:10:30 +01:00
}
2014-03-31 05:59:42 +02:00
2017-05-20 17:38:03 +02:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
if ( ! se ) {
continue ;
}
2014-03-31 05:59:42 +02:00
2017-10-23 21:21:15 +02:00
if ( sp - > has_meta ( " _edit_lock_ " ) ) {
continue ;
}
2017-11-08 16:07:30 +01: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 17:38:03 +02:00
t . origin + = motion ;
sp - > set_global_transform ( t ) ;
}
2017-11-08 16:07:30 +01:00
surface - > update ( ) ;
2017-05-20 17:38:03 +02:00
} break ;
2014-03-31 05:59:42 +02:00
2017-05-20 17:38:03 +02:00
case TRANSFORM_ROTATE : {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
Plane plane ;
2017-10-04 09:34:58 +02:00
Vector3 axis ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02: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 09:34:58 +02:00
axis = Vector3 ( 1 , 0 , 0 ) ;
2014-03-31 05:59:42 +02:00
break ;
2017-05-20 17:38:03 +02:00
case TRANSFORM_Y_AXIS :
plane = Plane ( _edit . center , spatial_editor - > get_gizmo_transform ( ) . basis . get_axis ( 1 ) ) ;
2017-10-04 09:34:58 +02:00
axis = Vector3 ( 0 , 1 , 0 ) ;
2017-05-20 17:38:03 +02:00
break ;
case TRANSFORM_Z_AXIS :
plane = Plane ( _edit . center , spatial_editor - > get_gizmo_transform ( ) . basis . get_axis ( 2 ) ) ;
2017-10-04 09:34:58 +02:00
axis = Vector3 ( 0 , 0 , 1 ) ;
2017-05-20 17:38:03 +02:00
break ;
2018-09-26 13:13:56 +02:00
case TRANSFORM_YZ :
case TRANSFORM_XZ :
case TRANSFORM_XY :
break ;
2017-05-20 17:38:03 +02:00
}
Vector3 intersection ;
if ( ! plane . intersects_ray ( ray_pos , ray , & intersection ) )
break ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
Vector3 click ;
if ( ! plane . intersects_ray ( _edit . click_ray_pos , _edit . click_ray , & click ) )
break ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
Vector3 y_axis = ( click - _edit . center ) . normalized ( ) ;
Vector3 x_axis = plane . normal . cross ( y_axis ) . normalized ( ) ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
float angle = Math : : atan2 ( x_axis . dot ( intersection - _edit . center ) , y_axis . dot ( intersection - _edit . center ) ) ;
2017-10-04 09:34:58 +02:00
2017-05-20 17:38:03 +02:00
if ( _edit . snap | | spatial_editor - > is_snap_enabled ( ) ) {
2019-07-24 14:41:09 +02:00
snap = spatial_editor - > get_rotate_snap ( ) ;
2017-05-20 17:38:03 +02:00
}
2019-07-24 14:41:09 +02: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 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
2014-02-10 02:10:30 +01:00
2017-11-13 09:15:41 +01:00
bool local_coords = ( spatial_editor - > are_local_coords_enabled ( ) & & _edit . plane ! = TRANSFORM_VIEW ) ; // Disable local transformation for TRANSFORM_VIEW
2017-10-04 09:34:58 +02:00
2017-05-20 17:38:03 +02:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
2017-05-20 17:38:03 +02:00
if ( ! sp )
continue ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
if ( ! se )
continue ;
2014-02-10 02:10:30 +01:00
2017-10-23 21:21:15 +02:00
if ( sp - > has_meta ( " _edit_lock_ " ) ) {
continue ;
}
2017-10-04 09:34:58 +02:00
Transform t ;
2014-02-10 02:10:30 +01:00
2017-10-04 09:34:58 +02:00
if ( local_coords ) {
2014-02-10 02:10:30 +01:00
2017-10-04 09:34:58 +02:00
Transform original_local = se - > original_local ;
Basis rot = Basis ( axis , angle ) ;
2017-11-08 16:07:30 +01:00
t . basis = original_local . get_basis ( ) . orthonormalized ( ) * rot ;
2017-10-04 09:34:58 +02:00
t . origin = original_local . origin ;
2017-11-08 16:07:30 +01:00
// Apply rotation
2017-10-04 09:34:58 +02:00
sp - > set_transform ( t ) ;
2017-11-08 16:07:30 +01:00
sp - > set_scale ( original_local . basis . get_scale ( ) ) ; // re-apply original scale
2017-10-04 09:34:58 +02: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 16:07:30 +01:00
// Apply rotation
2017-10-04 09:34:58 +02:00
sp - > set_global_transform ( t ) ;
}
2017-05-20 17:38:03 +02:00
}
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
surface - > update ( ) ;
2017-10-04 09:34:58 +02:00
2017-05-20 17:38:03 +02:00
} break ;
2019-04-09 17:08:36 +02:00
default : {
}
2014-02-10 02:10:30 +01:00
}
2017-05-20 17:38:03 +02:00
}
2014-02-10 02:10:30 +01:00
2017-10-30 01:22:48 +01:00
} else if ( ( m - > get_button_mask ( ) & BUTTON_MASK_RIGHT ) | | freelook_active ) {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
if ( nav_scheme = = NAVIGATION_MAYA & & m - > get_alt ( ) ) {
nav_mode = NAVIGATION_ZOOM ;
2017-07-23 02:02:18 +02:00
} else if ( freelook_active ) {
2017-05-20 17:38:03 +02:00
nav_mode = NAVIGATION_LOOK ;
2018-10-20 12:49:33 +02:00
} else if ( orthogonal ) {
nav_mode = NAVIGATION_PAN ;
2017-05-20 17:38:03 +02:00
}
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
} else if ( m - > get_button_mask ( ) & BUTTON_MASK_MIDDLE ) {
if ( nav_scheme = = NAVIGATION_GODOT ) {
2016-04-12 03:37:35 +02:00
2017-07-23 02:02:18 +02:00
int mod = _get_key_modifier ( m ) ;
2016-05-21 15:29:25 +02:00
2017-09-19 02:30:48 +02:00
if ( mod = = _get_key_modifier_setting ( " editors/3d/navigation/pan_modifier " ) )
2017-05-20 17:38:03 +02:00
nav_mode = NAVIGATION_PAN ;
2017-09-19 02:30:48 +02:00
else if ( mod = = _get_key_modifier_setting ( " editors/3d/navigation/zoom_modifier " ) )
2017-05-20 17:38:03 +02:00
nav_mode = NAVIGATION_ZOOM ;
2017-09-19 02:30:48 +02:00
else if ( mod = = _get_key_modifier_setting ( " editors/3d/navigation/orbit_modifier " ) )
2017-05-20 17:38:03 +02:00
nav_mode = NAVIGATION_ORBIT ;
} else if ( nav_scheme = = NAVIGATION_MAYA ) {
if ( m - > get_alt ( ) )
nav_mode = NAVIGATION_PAN ;
2014-03-31 05:07:21 +02:00
}
2014-02-10 02:10:30 +01:00
2017-09-19 02:30:48 +02:00
} else if ( EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation/emulate_3_button_mouse " ) ) {
2017-05-20 17:38:03 +02:00
// Handle trackpad (no external mouse) use case
2017-07-23 02:02:18 +02:00
int mod = _get_key_modifier ( m ) ;
2017-05-20 17:38:03 +02:00
if ( mod ) {
2017-09-19 02:30:48 +02:00
if ( mod = = _get_key_modifier_setting ( " editors/3d/navigation/pan_modifier " ) )
2017-05-20 17:38:03 +02:00
nav_mode = NAVIGATION_PAN ;
2017-09-19 02:30:48 +02:00
else if ( mod = = _get_key_modifier_setting ( " editors/3d/navigation/zoom_modifier " ) )
2017-05-20 17:38:03 +02:00
nav_mode = NAVIGATION_ZOOM ;
2017-09-19 02:30:48 +02:00
else if ( mod = = _get_key_modifier_setting ( " editors/3d/navigation/orbit_modifier " ) )
2017-05-20 17:38:03 +02:00
nav_mode = NAVIGATION_ORBIT ;
}
}
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
switch ( nav_mode ) {
case NAVIGATION_PAN : {
2017-11-01 21:49:39 +01:00
_nav_pan ( m , _get_warped_mouse_motion ( m ) ) ;
2014-02-10 02:10:30 +01:00
2017-11-01 21:49:39 +01: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 17:08:36 +02:00
default : {
}
2017-11-01 21:49:39 +01:00
}
}
2017-03-22 21:18:47 +01:00
2017-11-01 21:49:39 +01:00
Ref < InputEventMagnifyGesture > magnify_gesture = p_event ;
if ( magnify_gesture . is_valid ( ) ) {
2017-05-20 17:38:03 +02:00
2017-11-01 21:49:39 +01: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 17:38:03 +02:00
2017-11-01 21:49:39 +01:00
if ( nav_scheme = = NAVIGATION_GODOT ) {
int mod = _get_key_modifier ( pan_gesture ) ;
if ( mod = = _get_key_modifier_setting ( " editors/3d/navigation/pan_modifier " ) )
nav_mode = NAVIGATION_PAN ;
else if ( mod = = _get_key_modifier_setting ( " editors/3d/navigation/zoom_modifier " ) )
nav_mode = NAVIGATION_ZOOM ;
else if ( mod = = _get_key_modifier_setting ( " editors/3d/navigation/orbit_modifier " ) )
nav_mode = NAVIGATION_ORBIT ;
} else if ( nav_scheme = = NAVIGATION_MAYA ) {
if ( pan_gesture - > get_alt ( ) )
nav_mode = NAVIGATION_PAN ;
}
switch ( nav_mode ) {
case NAVIGATION_PAN : {
_nav_pan ( m , pan_gesture - > get_delta ( ) ) ;
2017-05-20 17:38:03 +02:00
} break ;
case NAVIGATION_ZOOM : {
2017-11-01 21:49:39 +01:00
_nav_zoom ( m , pan_gesture - > get_delta ( ) ) ;
2017-05-20 17:38:03 +02:00
} break ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
case NAVIGATION_ORBIT : {
2017-11-01 21:49:39 +01:00
_nav_orbit ( m , pan_gesture - > get_delta ( ) ) ;
2017-05-20 17:38:03 +02:00
} break ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
case NAVIGATION_LOOK : {
2017-11-01 21:49:39 +01:00
_nav_look ( m , pan_gesture - > get_delta ( ) ) ;
2017-05-01 20:57:35 +02:00
2017-05-20 17:38:03 +02:00
} break ;
2017-05-01 20:57:35 +02:00
2019-04-09 17:08:36 +02:00
default : {
}
2017-05-20 17:38:03 +02:00
}
}
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
Ref < InputEventKey > k = p_event ;
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02: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 09:15:39 +01:00
_edit . snap = ! _edit . snap ;
2017-05-20 17:38:03 +02:00
}
}
if ( ED_IS_SHORTCUT ( " spatial_editor/bottom_view " , p_event ) ) {
2017-12-19 15:29:55 +01:00
_menu_option ( VIEW_BOTTOM ) ;
2017-05-20 17:38:03 +02:00
}
if ( ED_IS_SHORTCUT ( " spatial_editor/top_view " , p_event ) ) {
2017-12-19 15:29:55 +01:00
_menu_option ( VIEW_TOP ) ;
2017-05-20 17:38:03 +02:00
}
if ( ED_IS_SHORTCUT ( " spatial_editor/rear_view " , p_event ) ) {
2017-12-19 15:29:55 +01:00
_menu_option ( VIEW_REAR ) ;
2017-05-20 17:38:03 +02:00
}
if ( ED_IS_SHORTCUT ( " spatial_editor/front_view " , p_event ) ) {
2017-12-19 15:29:55 +01:00
_menu_option ( VIEW_FRONT ) ;
2017-05-20 17:38:03 +02:00
}
if ( ED_IS_SHORTCUT ( " spatial_editor/left_view " , p_event ) ) {
2017-12-19 15:29:55 +01:00
_menu_option ( VIEW_LEFT ) ;
2017-05-20 17:38:03 +02:00
}
if ( ED_IS_SHORTCUT ( " spatial_editor/right_view " , p_event ) ) {
2017-12-19 15:29:55 +01: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 17:38:03 +02:00
}
2018-10-20 12:49:33 +02:00
// Orthgonal mode doesn't work in freelook.
if ( ! freelook_active & & ED_IS_SHORTCUT ( " spatial_editor/switch_perspective_orthogonal " , p_event ) ) {
2017-05-20 17:38:03 +02:00
_menu_option ( orthogonal ? VIEW_PERSPECTIVE : VIEW_ORTHOGONAL ) ;
_update_name ( ) ;
}
2018-10-27 23:43:19 +02: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 15:29:55 +01:00
}
2017-05-20 17:38:03 +02:00
if ( ED_IS_SHORTCUT ( " spatial_editor/insert_anim_key " , p_event ) ) {
if ( ! get_selected_count ( ) | | _edit . mode ! = TRANSFORM_NONE )
return ;
2014-02-10 02:10:30 +01:00
2018-06-07 17:46:14 +02:00
if ( ! AnimationPlayerEditor : : singleton - > get_track_editor ( ) - > has_keying ( ) ) {
2017-05-20 17:38:03 +02:00
set_message ( TTR ( " Keying is disabled (no key inserted). " ) ) ;
return ;
}
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
2014-03-31 17:06:36 +02:00
2017-05-20 17:38:03 +02:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-03-31 17:06:36 +02:00
2017-08-24 22:58:51 +02:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
2017-05-20 17:38:03 +02:00
if ( ! sp )
continue ;
2014-04-01 12:45:48 +02:00
2019-04-14 22:27:59 +02:00
spatial_editor - > emit_signal ( " transform_key_request " , sp , " " , sp - > get_transform ( ) ) ;
2014-02-10 02:10:30 +01:00
}
2017-05-20 17:38:03 +02:00
set_message ( TTR ( " Animation Key Inserted. " ) ) ;
}
2014-02-10 02:10:30 +01:00
2018-10-20 12:49:33 +02:00
// Freelook doesn't work in orthogonal mode.
if ( ! orthogonal & & ED_IS_SHORTCUT ( " spatial_editor/freelook_toggle " , p_event ) ) {
2017-10-30 01:22:48 +01:00
set_freelook_active ( ! is_freelook_active ( ) ) ;
} else if ( k - > get_scancode ( ) = = KEY_ESCAPE ) {
set_freelook_active ( false ) ;
}
2017-05-20 17:38:03 +02:00
if ( k - > get_scancode ( ) = = KEY_SPACE ) {
if ( ! k - > is_pressed ( ) ) emit_signal ( " toggle_maximize_view " , this ) ;
}
2014-02-10 02:10:30 +01:00
}
2017-10-29 21:31:38 +01: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 02:10:30 +01:00
}
2017-11-01 21:49:39 +01: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 ) ;
Vector3 translation ( - p_relative . x * pan_speed , p_relative . y * pan_speed , 0 ) ;
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 03:24:31 +02:00
if ( lock_rotation ) {
_nav_pan ( p_event , p_relative ) ;
return ;
}
2017-11-01 21:49:39 +01:00
real_t degrees_per_pixel = EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation_feel/orbit_sensitivity " ) ;
real_t radians_per_pixel = Math : : deg2rad ( degrees_per_pixel ) ;
2018-11-17 16:19:02 +01:00
bool invert_y_axis = EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation/invert_y_axis " ) ;
2017-11-01 21:49:39 +01:00
2018-03-14 14:32:29 +01: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 21:49:39 +01:00
cursor . y_rot + = p_relative . x * radians_per_pixel ;
if ( cursor . x_rot > Math_PI / 2.0 )
cursor . x_rot = Math_PI / 2.0 ;
if ( cursor . x_rot < - Math_PI / 2.0 )
cursor . x_rot = - Math_PI / 2.0 ;
name = " " ;
_update_name ( ) ;
}
void SpatialEditorViewport : : _nav_look ( Ref < InputEventWithModifiers > p_event , const Vector2 & p_relative ) {
2018-10-20 12:49:33 +02:00
if ( orthogonal ) {
_nav_pan ( p_event , p_relative ) ;
return ;
}
2017-11-01 21:49:39 +01:00
2018-10-20 12:49:33 +02:00
real_t degrees_per_pixel = EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation_feel/orbit_sensitivity " ) ;
real_t radians_per_pixel = Math : : deg2rad ( degrees_per_pixel ) ;
2018-11-17 16:19:02 +01:00
bool invert_y_axis = EditorSettings : : get_singleton ( ) - > get ( " editors/3d/navigation/invert_y_axis " ) ;
2017-11-01 21:49:39 +01:00
2018-10-20 12:49:33 +02:00
// Note: do NOT assume the camera has the "current" transform, because it is interpolated and may have "lag".
Transform prev_camera_transform = to_camera_transform ( cursor ) ;
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 21:49:39 +01:00
}
2018-10-20 12:49:33 +02:00
cursor . y_rot + = p_relative . x * radians_per_pixel ;
if ( cursor . x_rot > Math_PI / 2.0 )
cursor . x_rot = Math_PI / 2.0 ;
if ( cursor . x_rot < - Math_PI / 2.0 )
cursor . x_rot = - Math_PI / 2.0 ;
// 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 21:49:39 +01:00
}
2017-10-08 02:43:57 +02: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 ;
}
2017-10-30 01:22:48 +01:00
// Hide mouse like in an FPS (warping doesn't work)
OS : : get_singleton ( ) - > set_mouse_mode ( OS : : MOUSE_MODE_CAPTURED ) ;
2017-10-08 02:43:57 +02: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 01:22:48 +01:00
// Restore mouse
OS : : get_singleton ( ) - > set_mouse_mode ( OS : : MOUSE_MODE_VISIBLE ) ;
2017-10-08 02:43:57 +02:00
}
freelook_active = active_now ;
}
2017-05-07 22:59:05 +02: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 02:43:57 +02: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 22:59:05 +02:00
zoom_indicator_delay = ZOOM_INDICATOR_DELAY_S ;
surface - > update ( ) ;
}
2017-05-20 17:38:03 +02:00
Point2i SpatialEditorViewport : : _get_warped_mouse_motion ( const Ref < InputEventMouseMotion > & p_ev_mouse_motion ) const {
2017-05-05 23:42:48 +02:00
Point2i relative ;
2017-09-19 02:30:48 +02:00
if ( bool ( EDITOR_DEF ( " editors/3d/navigation/warped_mouse_panning " , false ) ) ) {
2017-05-05 23:42:48 +02:00
relative = Input : : get_singleton ( ) - > warp_mouse_motion ( p_ev_mouse_motion , surface - > get_global_rect ( ) ) ;
} else {
2017-05-20 17:38:03 +02:00
relative = p_ev_mouse_motion - > get_relative ( ) ;
2017-05-05 23:42:48 +02:00
}
return relative ;
}
2018-01-15 00:32:27 +01: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 20:57:35 +02:00
void SpatialEditorViewport : : _update_freelook ( real_t delta ) {
2017-08-26 21:55:09 +02:00
if ( ! is_freelook_active ( ) ) {
2017-05-01 20:57:35 +02:00
return ;
2017-08-26 21:55:09 +02:00
}
2017-05-01 20:57:35 +02:00
Vector3 forward = camera - > get_transform ( ) . basis . xform ( Vector3 ( 0 , 0 , - 1 ) ) ;
Vector3 right = camera - > get_transform ( ) . basis . xform ( Vector3 ( 1 , 0 , 0 ) ) ;
2017-05-07 22:59:05 +02:00
Vector3 up = camera - > get_transform ( ) . basis . xform ( Vector3 ( 0 , 1 , 0 ) ) ;
2017-05-01 20:57:35 +02:00
2017-08-26 21:55:09 +02:00
Vector3 direction ;
2017-05-01 20:57:35 +02:00
bool speed_modifier = false ;
2018-01-15 00:32:27 +01:00
if ( is_shortcut_pressed ( " spatial_editor/freelook_left " ) ) {
2017-08-26 21:55:09 +02:00
direction - = right ;
2017-05-01 20:57:35 +02:00
}
2018-01-15 00:32:27 +01:00
if ( is_shortcut_pressed ( " spatial_editor/freelook_right " ) ) {
2017-08-26 21:55:09 +02:00
direction + = right ;
2017-05-01 20:57:35 +02:00
}
2018-01-15 00:32:27 +01:00
if ( is_shortcut_pressed ( " spatial_editor/freelook_forward " ) ) {
2017-08-26 21:55:09 +02:00
direction + = forward ;
2017-05-01 20:57:35 +02:00
}
2018-01-15 00:32:27 +01:00
if ( is_shortcut_pressed ( " spatial_editor/freelook_backwards " ) ) {
2017-08-26 21:55:09 +02:00
direction - = forward ;
2017-05-01 20:57:35 +02:00
}
2018-01-15 00:32:27 +01:00
if ( is_shortcut_pressed ( " spatial_editor/freelook_up " ) ) {
2017-08-26 21:55:09 +02:00
direction + = up ;
2017-05-01 20:57:35 +02:00
}
2018-01-15 00:32:27 +01:00
if ( is_shortcut_pressed ( " spatial_editor/freelook_down " ) ) {
2017-08-26 21:55:09 +02:00
direction - = up ;
2017-05-01 20:57:35 +02:00
}
2018-01-15 00:32:27 +01:00
if ( is_shortcut_pressed ( " spatial_editor/freelook_speed_modifier " ) ) {
2017-05-01 20:57:35 +02:00
speed_modifier = true ;
}
2017-10-08 02:43:57 +02:00
real_t speed = freelook_speed ;
if ( speed_modifier ) {
real_t modifier_speed_factor = EditorSettings : : get_singleton ( ) - > get ( " editors/3d/freelook/freelook_modifier_speed_factor " ) ;
2017-08-26 21:55:09 +02:00
speed * = modifier_speed_factor ;
2017-10-08 02:43:57 +02:00
}
2017-05-07 22:59:05 +02:00
2017-10-08 02:43:57 +02:00
Vector3 motion = direction * speed * delta ;
cursor . pos + = motion ;
cursor . eye_pos + = motion ;
2017-05-01 20:57:35 +02:00
}
2017-03-05 16:44:50 +01:00
void SpatialEditorViewport : : set_message ( String p_message , float p_time ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
message = p_message ;
message_time = p_time ;
2014-02-10 02:10:30 +01:00
}
2018-08-14 23:13:48 +02:00
void SpatialEditorPlugin : : edited_scene_changed ( ) {
2018-09-26 17:38:02 +02:00
for ( uint32_t i = 0 ; i < SpatialEditor : : VIEWPORTS_COUNT ; i + + ) {
2018-08-14 23:13:48 +02:00
SpatialEditorViewport * viewport = SpatialEditor : : get_singleton ( ) - > get_editor_viewport ( i ) ;
if ( viewport - > is_visible ( ) ) {
viewport - > notification ( Control : : NOTIFICATION_VISIBILITY_CHANGED ) ;
}
}
}
2014-02-10 02:10:30 +01:00
void SpatialEditorViewport : : _notification ( int p_what ) {
2017-03-05 16:44:50 +01:00
if ( p_what = = NOTIFICATION_VISIBILITY_CHANGED ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
bool visible = is_visible_in_tree ( ) ;
2014-02-10 02:10:30 +01:00
set_process ( visible ) ;
2016-04-06 08:34:34 +02:00
2019-01-30 14:46:44 +01:00
if ( visible ) {
2017-08-26 05:40:45 +02:00
_update_camera ( 0 ) ;
2019-01-30 14:46:44 +01:00
} else {
set_freelook_active ( false ) ;
}
2014-05-05 03:50:23 +02:00
call_deferred ( " update_transform_gizmo_view " ) ;
}
2017-03-05 16:44:50 +01:00
if ( p_what = = NOTIFICATION_RESIZED ) {
2014-05-05 03:50:23 +02:00
call_deferred ( " update_transform_gizmo_view " ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
if ( p_what = = NOTIFICATION_PROCESS ) {
2014-02-10 02:10:30 +01:00
2017-10-08 02:43:57 +02:00
real_t delta = get_process_delta_time ( ) ;
2017-05-07 22:59:05 +02:00
if ( zoom_indicator_delay > 0 ) {
zoom_indicator_delay - = delta ;
if ( zoom_indicator_delay < = 0 ) {
surface - > update ( ) ;
}
}
_update_freelook ( delta ) ;
2017-05-01 20:57:35 +02:00
2018-07-27 00:36:05 +02:00
Node * scene_root = editor - > get_scene_tree_dock ( ) - > get_editor_data ( ) - > get_edited_scene_root ( ) ;
2018-10-03 19:40:37 +02:00
if ( previewing_cinema & & scene_root ! = NULL ) {
2018-07-27 00:36:05 +02: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 02:43:57 +02:00
_update_camera ( delta ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Map < Node * , Object * > & selection = editor_selection - > get_selection ( ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
bool changed = false ;
bool exist = false ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( Map < Node * , Object * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > key ( ) ) ;
2014-02-10 02:10:30 +01:00
if ( ! sp )
continue ;
2017-03-05 16:44:50 +01:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
2014-02-10 02:10:30 +01:00
if ( ! se )
continue ;
2017-08-24 22:58:51 +02:00
VisualInstance * vi = Object : : cast_to < VisualInstance > ( sp ) ;
2014-02-10 02:10:30 +01:00
2018-05-06 20:49:22 +02:00
se - > aabb = vi ? vi - > get_aabb ( ) : AABB ( Vector3 ( - 0.2 , - 0.2 , - 0.2 ) , Vector3 ( 0.4 , 0.4 , 0.4 ) ) ;
2014-02-10 02:10:30 +01:00
2017-10-03 18:49:32 +02:00
Transform t = sp - > get_global_gizmo_transform ( ) ;
2017-06-06 20:33:51 +02:00
t . translate ( se - > aabb . position ) ;
2017-08-23 02:05:41 +02: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 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
exist = true ;
if ( se - > last_xform = = t )
2014-02-10 02:10:30 +01:00
continue ;
2017-03-05 16:44:50 +01:00
changed = true ;
se - > last_xform = t ;
VisualServer : : get_singleton ( ) - > instance_set_transform ( se - > sbox_instance , t ) ;
2014-02-10 02:10:30 +01:00
}
if ( changed | | ( spatial_editor - > is_gizmo_visible ( ) & & ! exist ) ) {
spatial_editor - > update_transform_gizmo ( ) ;
}
2017-03-05 16:44:50 +01:00
if ( message_time > 0 ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( message ! = last_message ) {
2014-02-10 02:10:30 +01:00
surface - > update ( ) ;
2017-03-05 16:44:50 +01:00
last_message = message ;
2014-02-10 02:10:30 +01:00
}
2017-09-30 16:19:07 +02:00
message_time - = get_physics_process_delta_time ( ) ;
2017-03-05 16:44:50 +01:00
if ( message_time < 0 )
2014-02-10 02:10:30 +01:00
surface - > update ( ) ;
}
2017-01-02 02:16:52 +01:00
//update shadow atlas if changed
2016-11-10 03:55:06 +01:00
2017-07-19 22:00:46 +02: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 03:55:06 +01:00
viewport - > set_shadow_atlas_size ( shadowmap_size ) ;
2017-03-05 16:44:50 +01: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 03:55:06 +01:00
2017-10-31 18:23:25 +01:00
bool shrink = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_HALF_RESOLUTION ) ) ;
2018-09-26 16:35:32 +02:00
if ( shrink ! = ( viewport_container - > get_stretch_shrink ( ) > 1 ) ) {
2017-10-31 18:23:25 +01:00
viewport_container - > set_stretch_shrink ( shrink ? 2 : 1 ) ;
}
2017-01-02 02:16:52 +01:00
//update msaa if changed
2017-07-19 22:00:46 +02:00
int msaa_mode = ProjectSettings : : get_singleton ( ) - > get ( " rendering/quality/filters/msaa " ) ;
2017-01-02 02:16:52 +01:00
viewport - > set_msaa ( Viewport : : MSAA ( msaa_mode ) ) ;
2017-07-19 22:00:46 +02:00
bool hdr = ProjectSettings : : get_singleton ( ) - > get ( " rendering/quality/depth/hdr " ) ;
2017-01-02 02:16:52 +01:00
viewport - > set_hdr ( hdr ) ;
2017-06-11 23:13:04 +02:00
bool show_info = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_INFORMATION ) ) ;
2017-12-17 13:06:21 +01:00
info_label - > set_visible ( show_info ) ;
2017-06-11 23:13:04 +02:00
2018-08-30 00:44:47 +02:00
Camera * current_camera ;
if ( previewing ) {
current_camera = previewing ;
} else {
current_camera = camera ;
}
2017-06-11 23:13:04 +02:00
if ( show_info ) {
String text ;
2018-08-30 00:44:47 +02: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 23:13:04 +02: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 13:06:21 +01:00
info_label - > set_text ( text ) ;
2017-06-11 23:13:04 +02:00
}
2017-11-19 21:00:16 +01: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 13:06:21 +01:00
fps_label - > set_visible ( show_fps ) ;
2017-11-19 21:00:16 +01:00
if ( show_fps ) {
String text ;
const float temp_fps = Engine : : get_singleton ( ) - > get_frames_per_second ( ) ;
2019-02-20 12:07:49 +01:00
text + = TTR ( vformat ( " FPS: %d (%s ms) " , temp_fps , String : : num ( 1000.0f / temp_fps , 2 ) ) ) ;
2017-12-17 13:06:21 +01:00
fps_label - > set_text ( text ) ;
2017-11-19 21:00:16 +01:00
}
2018-07-27 00:36:05 +02: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 09:25:59 +02: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 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
if ( p_what = = NOTIFICATION_ENTER_TREE ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
surface - > connect ( " draw " , this , " _draw " ) ;
surface - > connect ( " gui_input " , this , " _sinput " ) ;
2017-12-19 15:29:55 +01: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 09:25:59 +02:00
2014-05-05 03:50:23 +02:00
_init_gizmo_instance ( index ) ;
2015-04-21 00:38:02 +02:00
}
2018-10-10 09:25:59 +02:00
2017-03-05 16:44:50 +01:00
if ( p_what = = NOTIFICATION_EXIT_TREE ) {
2015-04-21 00:38:02 +02:00
_finish_gizmo_instances ( ) ;
2014-02-10 02:10:30 +01:00
}
2018-10-10 09:25:59 +02:00
if ( p_what = = NOTIFICATION_THEME_CHANGED ) {
view_menu - > set_icon ( get_icon ( " GuiMiniTabMenu " , " EditorIcons " ) ) ;
preview_camera - > set_icon ( get_icon ( " Camera " , " EditorIcons " ) ) ;
2014-02-10 02:10:30 +01:00
2018-10-10 09:25:59 +02: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 02:10:30 +01:00
}
}
2017-10-15 21:20:51 +02:00
static void draw_indicator_bar ( Control & surface , real_t fill , Ref < Texture > icon ) {
// Adjust bar size from control height
Vector2 surface_size = surface . get_size ( ) ;
real_t h = surface_size . y / 2.0 ;
real_t y = ( surface_size . y - h ) / 2.0 ;
Rect2 r ( 10 , y , 6 , h ) ;
real_t sy = r . size . y * fill ;
// 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 15:22:01 +02:00
surface . draw_rect ( r . grow ( 1 ) , Color ( 0 , 0 , 0 , 0.7 ) , false , Math : : round ( EDSCALE ) ) ;
2017-10-15 21:20:51 +02:00
Vector2 icon_size = icon - > get_size ( ) ;
Vector2 icon_pos = Vector2 ( r . position . x - ( icon_size . x - r . size . x ) / 2 , r . position . y + r . size . y + 2 ) ;
surface . draw_texture ( icon , icon_pos ) ;
2017-05-07 22:59:05 +02:00
}
2014-02-10 02:10:30 +01:00
void SpatialEditorViewport : : _draw ( ) {
2017-10-29 20:32:09 +01:00
EditorPluginList * over_plugin_list = EditorNode : : get_singleton ( ) - > get_editor_plugins_over ( ) ;
if ( ! over_plugin_list - > empty ( ) ) {
2018-09-18 20:00:07 +02:00
over_plugin_list - > forward_spatial_draw_over_viewport ( surface ) ;
2017-10-29 20:32:09 +01:00
}
EditorPluginList * force_over_plugin_list = editor - > get_editor_plugins_force_over ( ) ;
if ( ! force_over_plugin_list - > empty ( ) ) {
2018-09-18 20:00:07 +02:00
force_over_plugin_list - > forward_spatial_force_draw_over_viewport ( surface ) ;
2017-10-29 20:32:09 +01:00
}
2014-02-10 02:10:30 +01:00
if ( surface - > has_focus ( ) ) {
Size2 size = surface - > get_size ( ) ;
2017-03-05 16:44:50 +01:00
Rect2 r = Rect2 ( Point2 ( ) , size ) ;
2017-05-02 22:13:12 +02:00
get_stylebox ( " Focus " , " EditorStyles " ) - > draw ( surface - > get_canvas_item ( ) , r ) ;
2014-02-10 02:10:30 +01:00
}
if ( cursor . region_select ) {
2019-08-15 22:17:08 +02: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 02:10:30 +01:00
2019-08-15 22:17:08 +02:00
surface - > draw_rect (
selection_rect ,
get_color ( " box_selection_stroke_color " , " Editor " ) ,
false ,
Math : : round ( EDSCALE ) ) ;
2014-02-10 02:10:30 +01:00
}
2019-08-15 22:17:08 +02:00
RID ci = surface - > get_canvas_item ( ) ;
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
if ( _edit . mode = = TRANSFORM_ROTATE ) {
2014-02-10 02:10:30 +01:00
Point2 center = _point_to_screen ( _edit . center ) ;
2019-03-29 14:19:44 +01: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 02:10:30 +01:00
}
2014-09-16 01:06:37 +02:00
if ( previewing ) {
2017-07-19 22:00:46 +02:00
Size2 ss = Size2 ( ProjectSettings : : get_singleton ( ) - > get ( " display/window/size/width " ) , ProjectSettings : : get_singleton ( ) - > get ( " display/window/size/height " ) ) ;
2017-01-14 00:00:43 +01:00
float aspect = ss . aspect ( ) ;
2014-09-16 01:06:37 +02:00
Size2 s = get_size ( ) ;
Rect2 draw_rect ;
2017-03-05 16:44:50 +01:00
switch ( previewing - > get_keep_aspect_mode ( ) ) {
2014-09-16 01:06:37 +02:00
case Camera : : KEEP_WIDTH : {
2017-03-05 16:44:50 +01:00
draw_rect . size = Size2 ( s . width , s . width / aspect ) ;
2017-06-04 00:25:13 +02:00
draw_rect . position . x = 0 ;
draw_rect . position . y = ( s . height - draw_rect . size . y ) * 0.5 ;
2014-09-16 01:06:37 +02:00
} break ;
case Camera : : KEEP_HEIGHT : {
2017-03-05 16:44:50 +01:00
draw_rect . size = Size2 ( s . height * aspect , s . height ) ;
2017-06-04 00:25:13 +02:00
draw_rect . position . y = 0 ;
draw_rect . position . x = ( s . width - draw_rect . size . x ) * 0.5 ;
2014-09-16 01:06:37 +02:00
} break ;
}
2017-03-05 16:44:50 +01:00
draw_rect = Rect2 ( Vector2 ( ) , s ) . clip ( draw_rect ) ;
2014-09-16 01:06:37 +02:00
2019-07-09 15:22:01 +02:00
surface - > draw_rect ( draw_rect , Color ( 0.6 , 0.6 , 0.1 , 0.5 ) , false , Math : : round ( 2 * EDSCALE ) ) ;
2017-05-07 22:59:05 +02:00
} else {
if ( zoom_indicator_delay > 0.0 ) {
2017-10-15 21:20:51 +02:00
if ( is_freelook_active ( ) ) {
// Show speed
2017-05-07 22:59:05 +02:00
2017-10-15 21:20:51 +02: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 22:59:05 +02:00
2019-01-16 16:42:53 +01:00
if ( ! Math : : is_zero_approx ( scale_length ) ) {
2017-10-15 21:20:51 +02:00
real_t logscale_t = 1.0 - Math : : log ( 1 + freelook_speed - min_speed ) / Math : : log ( 1 + scale_length ) ;
2017-05-07 22:59:05 +02:00
2017-10-15 21:20:51 +02: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 22:59:05 +02:00
2017-10-15 21:20:51 +02:00
draw_indicator_bar ( * surface , 1.0 - logscale_t , get_icon ( " ViewportSpeed " , " EditorIcons " ) ) ;
}
2017-05-07 22:59:05 +02:00
2017-10-15 21:20:51 +02: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 16:42:53 +01:00
if ( ! Math : : is_zero_approx ( scale_length ) ) {
2017-10-15 21:20:51 +02: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 ) ;
draw_indicator_bar ( * surface , logscale_t , get_icon ( " ViewportZoom " , " EditorIcons " ) ) ;
}
2017-05-07 22:59:05 +02:00
}
}
2014-09-16 01:06:37 +02:00
}
2014-02-10 02:10:30 +01:00
}
void SpatialEditorViewport : : _menu_option ( int p_option ) {
2017-03-05 16:44:50 +01:00
switch ( p_option ) {
2014-02-10 02:10:30 +01:00
case VIEW_TOP : {
2017-03-05 16:44:50 +01:00
cursor . y_rot = 0 ;
2017-12-19 15:29:55 +01:00
cursor . x_rot = Math_PI / 2.0 ;
set_message ( TTR ( " Top View. " ) , 2 ) ;
2017-03-05 16:44:50 +01:00
name = TTR ( " Top " ) ;
2015-03-21 21:47:21 +01:00
_update_name ( ) ;
2017-12-19 15:29:55 +01:00
2014-02-10 02:10:30 +01:00
} break ;
case VIEW_BOTTOM : {
2017-03-05 16:44:50 +01:00
cursor . y_rot = 0 ;
2017-12-19 15:29:55 +01:00
cursor . x_rot = - Math_PI / 2.0 ;
set_message ( TTR ( " Bottom View. " ) , 2 ) ;
2017-03-05 16:44:50 +01:00
name = TTR ( " Bottom " ) ;
2015-03-21 21:47:21 +01:00
_update_name ( ) ;
2014-02-10 02:10:30 +01:00
} break ;
case VIEW_LEFT : {
2017-03-05 16:44:50 +01:00
cursor . x_rot = 0 ;
2017-12-19 15:29:55 +01:00
cursor . y_rot = Math_PI / 2.0 ;
set_message ( TTR ( " Left View. " ) , 2 ) ;
2017-03-05 16:44:50 +01:00
name = TTR ( " Left " ) ;
2015-03-21 21:47:21 +01:00
_update_name ( ) ;
2014-02-10 02:10:30 +01:00
} break ;
case VIEW_RIGHT : {
2017-03-05 16:44:50 +01:00
cursor . x_rot = 0 ;
2017-12-19 15:29:55 +01:00
cursor . y_rot = - Math_PI / 2.0 ;
set_message ( TTR ( " Right View. " ) , 2 ) ;
2017-03-05 16:44:50 +01:00
name = TTR ( " Right " ) ;
2015-03-21 21:47:21 +01:00
_update_name ( ) ;
2014-02-10 02:10:30 +01:00
} break ;
case VIEW_FRONT : {
2017-03-05 16:44:50 +01:00
cursor . x_rot = 0 ;
2017-12-19 15:29:55 +01:00
cursor . y_rot = 0 ;
set_message ( TTR ( " Front View. " ) , 2 ) ;
2017-03-05 16:44:50 +01:00
name = TTR ( " Front " ) ;
2015-03-21 21:47:21 +01:00
_update_name ( ) ;
2014-02-10 02:10:30 +01:00
} break ;
case VIEW_REAR : {
2017-03-05 16:44:50 +01:00
cursor . x_rot = 0 ;
2017-12-19 15:29:55 +01:00
cursor . y_rot = Math_PI ;
set_message ( TTR ( " Rear View. " ) , 2 ) ;
2017-03-05 16:44:50 +01:00
name = TTR ( " Rear " ) ;
2015-03-21 21:47:21 +01:00
_update_name ( ) ;
2014-02-10 02:10:30 +01:00
2016-10-04 20:39:38 +02:00
} break ;
case VIEW_CENTER_TO_ORIGIN : {
2017-03-05 16:44:50 +01:00
cursor . pos = Vector3 ( 0 , 0 , 0 ) ;
2016-10-04 20:39:38 +02:00
2014-02-10 02:10:30 +01:00
} break ;
case VIEW_CENTER_TO_SELECTION : {
2016-07-28 21:37:52 +02:00
focus_selection ( ) ;
2014-02-10 02:10:30 +01:00
} break ;
2018-10-27 23:43:19 +02:00
case VIEW_ALIGN_TRANSFORM_WITH_VIEW : {
2014-03-31 17:06:36 +02:00
if ( ! get_selected_count ( ) )
break ;
Transform camera_transform = camera - > get_global_transform ( ) ;
2017-03-05 16:44:50 +01:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
2014-03-31 17:06:36 +02:00
2018-10-27 23:43:19 +02:00
undo_redo - > create_action ( TTR ( " Align Transform with View " ) ) ;
2017-03-05 16:44:50 +01:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-03-31 17:06:36 +02:00
2017-08-24 22:58:51 +02:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
2014-03-31 17:06:36 +02:00
if ( ! sp )
continue ;
2017-03-05 16:44:50 +01:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
2014-03-31 17:06:36 +02:00
if ( ! se )
continue ;
2018-10-22 16:52:39 +02: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-30 00:44:12 +01:00
2017-03-05 16:44:50 +01:00
undo_redo - > add_do_method ( sp , " set_global_transform " , xform ) ;
2017-10-03 18:49:32 +02:00
undo_redo - > add_undo_method ( sp , " set_global_transform " , sp - > get_global_gizmo_transform ( ) ) ;
2014-03-31 17:06:36 +02:00
}
undo_redo - > commit_action ( ) ;
2018-10-27 23:43:19 +02:00
focus_selection ( ) ;
} 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 17:06:36 +02:00
} break ;
2014-02-10 02:10:30 +01:00
case VIEW_ENVIRONMENT : {
int idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_ENVIRONMENT ) ;
2017-03-05 16:44:50 +01:00
bool current = view_menu - > get_popup ( ) - > is_item_checked ( idx ) ;
current = ! current ;
2014-02-10 02:10:30 +01:00
if ( current ) {
camera - > set_environment ( RES ( ) ) ;
} else {
camera - > set_environment ( SpatialEditor : : get_singleton ( ) - > get_viewport_environment ( ) ) ;
}
2017-03-05 16:44:50 +01:00
view_menu - > get_popup ( ) - > set_item_checked ( idx , current ) ;
2014-02-10 02:10:30 +01:00
} break ;
case VIEW_PERSPECTIVE : {
2017-03-05 16:44:50 +01: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 ;
2014-05-05 03:50:23 +02:00
call_deferred ( " update_transform_gizmo_view " ) ;
2015-03-21 21:47:21 +01:00
_update_name ( ) ;
2014-05-05 03:50:23 +02:00
2014-02-10 02:10:30 +01:00
} break ;
case VIEW_ORTHOGONAL : {
2017-03-05 16:44:50 +01: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 ;
2014-05-05 03:50:23 +02:00
call_deferred ( " update_transform_gizmo_view " ) ;
2015-03-21 21:47:21 +01:00
_update_name ( ) ;
2014-02-10 02:10:30 +01:00
2018-06-25 03:24:31 +02:00
} break ;
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 09:25:59 +02:00
locked_label - > show ( ) ;
2018-06-25 03:24:31 +02:00
} else {
2018-10-10 09:25:59 +02:00
locked_label - > hide ( ) ;
2018-06-25 03:24:31 +02:00
}
2014-02-10 02:10:30 +01:00
} break ;
2014-10-03 05:10:51 +02:00
case VIEW_AUDIO_LISTENER : {
int idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_AUDIO_LISTENER ) ;
2017-03-05 16:44:50 +01:00
bool current = view_menu - > get_popup ( ) - > is_item_checked ( idx ) ;
current = ! current ;
2014-10-03 05:10:51 +02:00
viewport - > set_as_audio_listener ( current ) ;
2017-03-05 16:44:50 +01:00
view_menu - > get_popup ( ) - > set_item_checked ( idx , current ) ;
2014-10-03 05:10:51 +02:00
2017-07-15 06:23:10 +02: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 05:10:51 +02:00
} break ;
2018-07-27 00:36:05 +02: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 07:13:22 +02:00
case VIEW_GIZMOS : {
int idx = view_menu - > get_popup ( ) - > get_item_index ( VIEW_GIZMOS ) ;
2017-03-05 16:44:50 +01:00
bool current = view_menu - > get_popup ( ) - > is_item_checked ( idx ) ;
current = ! current ;
2014-10-12 07:13:22 +02:00
if ( current )
2017-03-05 16:44:50 +01:00
camera - > set_cull_mask ( ( ( 1 < < 20 ) - 1 ) | ( 1 < < ( GIZMO_BASE_LAYER + index ) ) | ( 1 < < GIZMO_EDIT_LAYER ) | ( 1 < < GIZMO_GRID_LAYER ) ) ;
2014-10-12 07:13:22 +02:00
else
2017-03-05 16:44:50 +01: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 07:13:22 +02:00
2017-06-11 23:13:04 +02:00
} break ;
2017-10-31 18:23:25 +01: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 23:13:04 +02: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 21:00:16 +01: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 07:13:22 +02:00
} break ;
2017-06-11 20:52:03 +02: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 02:10:30 +01:00
}
}
void SpatialEditorViewport : : _preview_exited_scene ( ) {
preview_camera - > set_pressed ( false ) ;
_toggle_camera_preview ( false ) ;
view_menu - > show ( ) ;
}
2014-05-05 03:50:23 +02:00
void SpatialEditorViewport : : _init_gizmo_instance ( int p_idx ) {
2017-12-19 06:25:00 +01:00
uint32_t layer = 1 < < ( GIZMO_BASE_LAYER + p_idx ) ;
2014-05-05 03:50:23 +02:00
2017-03-05 16:44:50 +01: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-08 00:00:55 +01:00
VS : : get_singleton ( ) - > instance_geometry_set_cast_shadows_setting ( move_gizmo_instance [ i ] , VS : : SHADOW_CASTING_SETTING_OFF ) ;
2017-03-05 16:44:50 +01:00
VS : : get_singleton ( ) - > instance_set_layer_mask ( move_gizmo_instance [ i ] , layer ) ;
2014-05-05 03:50:23 +02:00
2017-08-29 03:39:45 +02: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 16:44:50 +01: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-08 00:00:55 +01:00
VS : : get_singleton ( ) - > instance_geometry_set_cast_shadows_setting ( rotate_gizmo_instance [ i ] , VS : : SHADOW_CASTING_SETTING_OFF ) ;
2017-03-05 16:44:50 +01:00
VS : : get_singleton ( ) - > instance_set_layer_mask ( rotate_gizmo_instance [ i ] , layer ) ;
2017-09-21 23:11:56 +02: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 23:50:19 +01: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 03:50:23 +02:00
}
}
2015-04-21 00:38:02 +02:00
void SpatialEditorViewport : : _finish_gizmo_instances ( ) {
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 3 ; i + + ) {
2015-04-21 00:38:02 +02:00
VS : : get_singleton ( ) - > free ( move_gizmo_instance [ i ] ) ;
2017-08-29 03:39:45 +02:00
VS : : get_singleton ( ) - > free ( move_plane_gizmo_instance [ i ] ) ;
2015-04-21 00:38:02 +02:00
VS : : get_singleton ( ) - > free ( rotate_gizmo_instance [ i ] ) ;
2017-09-21 23:11:56 +02:00
VS : : get_singleton ( ) - > free ( scale_gizmo_instance [ i ] ) ;
2017-11-14 23:50:19 +01:00
VS : : get_singleton ( ) - > free ( scale_plane_gizmo_instance [ i ] ) ;
2015-04-21 00:38:02 +02:00
}
}
2014-02-10 02:10:30 +01:00
void SpatialEditorViewport : : _toggle_camera_preview ( bool p_activate ) {
ERR_FAIL_COND ( p_activate & & ! preview ) ;
ERR_FAIL_COND ( ! p_activate & & ! previewing ) ;
if ( ! p_activate ) {
2018-01-12 12:28:39 +01:00
previewing - > disconnect ( " tree_exiting " , this , " _preview_exited_scene " ) ;
2017-03-05 16:44:50 +01:00
previewing = NULL ;
VS : : get_singleton ( ) - > viewport_attach_camera ( viewport - > get_viewport_rid ( ) , camera - > get_camera ( ) ) ; //restore
2014-02-10 02:10:30 +01:00
if ( ! preview )
preview_camera - > hide ( ) ;
2018-10-10 09:25:59 +02:00
view_menu - > set_disabled ( false ) ;
2014-09-16 01:06:37 +02:00
surface - > update ( ) ;
2014-02-10 02:10:30 +01:00
} else {
2017-03-05 16:44:50 +01:00
previewing = preview ;
2018-01-12 12:28:39 +01:00
previewing - > connect ( " tree_exiting " , this , " _preview_exited_scene " ) ;
2017-03-05 16:44:50 +01:00
VS : : get_singleton ( ) - > viewport_attach_camera ( viewport - > get_viewport_rid ( ) , preview - > get_camera ( ) ) ; //replace
2018-10-10 09:25:59 +02:00
view_menu - > set_disabled ( true ) ;
2014-09-16 01:06:37 +02:00
surface - > update ( ) ;
2014-02-10 02:10:30 +01:00
}
}
2018-07-27 00:36:05 +02: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 22:39:07 +01:00
void SpatialEditorViewport : : _selection_result_pressed ( int p_result ) {
if ( selection_results . size ( ) < = p_result )
return ;
2017-08-07 12:17:31 +02:00
clicked = selection_results [ p_result ] . item - > get_instance_id ( ) ;
2015-11-04 22:39:07 +01:00
if ( clicked ) {
2017-03-05 16:44:50 +01:00
_select_clicked ( clicked_wants_append , true ) ;
clicked = 0 ;
2015-11-04 22:39:07 +01:00
}
}
void SpatialEditorViewport : : _selection_menu_hide ( ) {
selection_results . clear ( ) ;
selection_menu - > clear ( ) ;
selection_menu - > set_size ( Vector2 ( 0 , 0 ) ) ;
}
2017-03-05 16:44:50 +01:00
void SpatialEditorViewport : : set_can_preview ( Camera * p_preview ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
preview = p_preview ;
2014-02-10 02:10:30 +01:00
2018-07-27 00:36:05 +02:00
if ( ! preview_camera - > is_pressed ( ) & & ! previewing_cinema )
2017-12-19 06:25:00 +01:00
preview_camera - > set_visible ( p_preview ) ;
2014-02-10 02:10:30 +01:00
}
2014-05-05 03:50:23 +02:00
void SpatialEditorViewport : : update_transform_gizmo_view ( ) {
2017-01-13 14:45:50 +01:00
if ( ! is_visible_in_tree ( ) )
2014-05-05 03:50:23 +02:00
return ;
Transform xform = spatial_editor - > get_gizmo_transform ( ) ;
Transform camera_xform = camera - > get_transform ( ) ;
2019-01-25 00:52:28 +01: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 03:50:23 +02:00
Vector3 camz = - camera_xform . get_basis ( ) . get_axis ( 2 ) . normalized ( ) ;
Vector3 camy = - camera_xform . get_basis ( ) . get_axis ( 1 ) . normalized ( ) ;
2017-03-05 16:44:50 +01:00
Plane p ( camera_xform . origin , camz ) ;
float gizmo_d = Math : : abs ( p . distance_to ( xform . origin ) ) ;
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 03:50:23 +02:00
2019-08-03 03:01:32 +02: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 16:44:50 +01:00
Vector3 scale = Vector3 ( 1 , 1 , 1 ) * gizmo_scale ;
2014-05-05 03:50:23 +02:00
xform . basis . scale ( scale ) ;
2017-03-05 16:44:50 +01: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 03:39:45 +02: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 16:44:50 +01: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 23:11:56 +02: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 23:50:19 +01: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 03:50:23 +02:00
}
}
2017-03-05 16:44:50 +01:00
void SpatialEditorViewport : : set_state ( const Dictionary & p_state ) {
2014-02-10 02:10:30 +01:00
2017-12-19 06:25:00 +01: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 ) ;
}
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 03:24:31 +02: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 06:25:00 +01: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 05:10:51 +02: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 16:44:50 +01:00
view_menu - > get_popup ( ) - > set_item_checked ( idx , listener ) ;
2014-10-03 05:10:51 +02:00
}
2017-07-15 06:23:10 +02: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 01:45:56 +01: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 06:25:00 +01: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 18:23:25 +01: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-27 00:36:05 +02: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 02:10:30 +01:00
2015-08-30 03:59:25 +02:00
if ( p_state . has ( " previewing " ) ) {
Node * pv = EditorNode : : get_singleton ( ) - > get_edited_scene ( ) - > get_node ( p_state [ " previewing " ] ) ;
2017-08-24 22:58:51 +02:00
if ( Object : : cast_to < Camera > ( pv ) ) {
previewing = Object : : cast_to < Camera > ( pv ) ;
2018-01-12 12:28:39 +01:00
previewing - > connect ( " tree_exiting " , this , " _preview_exited_scene " ) ;
2017-03-05 16:44:50 +01:00
VS : : get_singleton ( ) - > viewport_attach_camera ( viewport - > get_viewport_rid ( ) , previewing - > get_camera ( ) ) ; //replace
2019-03-11 18:10:00 +01:00
view_menu - > set_disabled ( true ) ;
2015-08-30 03:59:25 +02:00
surface - > update ( ) ;
preview_camera - > set_pressed ( true ) ;
preview_camera - > show ( ) ;
}
}
2014-02-10 02:10:30 +01:00
}
Dictionary SpatialEditorViewport : : get_state ( ) const {
Dictionary d ;
2017-09-10 15:37:49 +02:00
d [ " position " ] = cursor . pos ;
d [ " x_rotation " ] = cursor . x_rot ;
d [ " y_rotation " ] = cursor . y_rot ;
2017-03-05 16:44:50 +01:00
d [ " distance " ] = cursor . distance ;
d [ " use_environment " ] = camera - > get_environment ( ) . is_valid ( ) ;
d [ " use_orthogonal " ] = camera - > get_projection ( ) = = Camera : : PROJECTION_ORTHOGONAL ;
2017-12-19 06:25:00 +01: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 16:44:50 +01:00
d [ " listener " ] = viewport - > is_audio_listener ( ) ;
2017-11-20 01:45:56 +01: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 06:25:00 +01:00
d [ " fps " ] = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_FPS ) ) ;
2017-10-31 18:23:25 +01:00
d [ " half_res " ] = viewport_container - > get_stretch_shrink ( ) > 1 ;
2018-07-27 00:36:05 +02:00
d [ " cinematic_preview " ] = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_CINEMATIC_PREVIEW ) ) ;
2017-12-19 06:25:00 +01:00
if ( previewing )
2017-03-05 16:44:50 +01:00
d [ " previewing " ] = EditorNode : : get_singleton ( ) - > get_edited_scene ( ) - > get_path_to ( previewing ) ;
2018-06-25 03:24:31 +02:00
if ( lock_rotation )
d [ " lock_rotation " ] = lock_rotation ;
2015-08-30 03:59:25 +02:00
2014-02-10 02:10:30 +01:00
return d ;
}
2017-03-05 16:44:50 +01:00
void SpatialEditorViewport : : _bind_methods ( ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " _draw " ) , & SpatialEditorViewport : : _draw ) ;
2017-12-19 15:29:55 +01: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 16:44:50 +01: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 ) ;
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 21:47:16 +02: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 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ADD_SIGNAL ( MethodInfo ( " toggle_maximize_view " , PropertyInfo ( Variant : : OBJECT , " viewport " ) ) ) ;
2014-02-10 02:10:30 +01:00
}
2014-09-19 23:39:50 +02:00
void SpatialEditorViewport : : reset ( ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
orthogonal = false ;
2018-06-25 03:24:31 +02:00
lock_rotation = false ;
2017-03-05 16:44:50 +01:00
message_time = 0 ;
message = " " ;
last_message = " " ;
name = " " ;
2014-09-19 23:39:50 +02:00
2017-03-05 16:44:50 +01:00
cursor . x_rot = 0.5 ;
cursor . y_rot = 0.5 ;
cursor . distance = 4 ;
cursor . region_select = false ;
2017-10-15 02:05:09 +02:00
cursor . pos = Vector3 ( ) ;
2015-03-21 21:47:21 +01:00
_update_name ( ) ;
2014-09-19 23:39:50 +02:00
}
2014-02-10 02:10:30 +01:00
2016-07-28 21:37:52 +02:00
void SpatialEditorViewport : : focus_selection ( ) {
if ( ! get_selected_count ( ) )
return ;
Vector3 center ;
2017-03-05 16:44:50 +01:00
int count = 0 ;
2016-07-28 21:37:52 +02:00
2017-03-05 16:44:50 +01:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
2016-07-28 21:37:52 +02:00
2017-03-05 16:44:50 +01:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2016-07-28 21:37:52 +02:00
2017-08-24 22:58:51 +02:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
2016-07-28 21:37:52 +02:00
if ( ! sp )
continue ;
2017-03-05 16:44:50 +01:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
2016-07-28 21:37:52 +02:00
if ( ! se )
continue ;
2017-10-03 18:49:32 +02:00
center + = sp - > get_global_gizmo_transform ( ) . origin ;
2016-07-28 21:37:52 +02:00
count + + ;
}
2017-03-05 16:44:50 +01:00
if ( count ! = 0 ) {
center / = float ( count ) ;
2016-07-28 21:37:52 +02:00
}
2017-03-05 16:44:50 +01:00
cursor . pos = center ;
2016-07-28 21:37:52 +02:00
}
2017-11-17 03:09:00 +01:00
void SpatialEditorViewport : : assign_pending_data_pointers ( Spatial * p_preview_node , AABB * p_preview_bounds , AcceptDialog * p_accept ) {
2017-09-02 21:47:16 +02: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-25 00:08:49 +02:00
Set < Ref < EditorSpatialGizmo > > found_gizmos ;
2017-09-02 21:47:16 +02: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-25 00:08:49 +02:00
Ref < EditorSpatialGizmo > seg = mesh_instance - > get_gizmo ( ) ;
2017-09-02 21:47:16 +02: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 06:16:05 +02: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 21:47:16 +02:00
}
2019-07-10 11:54:12 +02:00
AABB SpatialEditorViewport : : _calculate_spatial_bounds ( const Spatial * p_parent , const AABB & p_bounds ) {
2017-11-17 03:09:00 +01:00
AABB bounds = p_bounds ;
2017-09-02 21:47:16 +02: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 ) {
MeshInstance * mesh_instance = Object : : cast_to < MeshInstance > ( child ) ;
if ( mesh_instance ) {
2017-11-17 03:09:00 +01:00
AABB mesh_instance_bounds = mesh_instance - > get_aabb ( ) ;
2017-10-03 18:49:32 +02:00
mesh_instance_bounds . position + = mesh_instance - > get_global_gizmo_transform ( ) . origin - p_parent - > get_global_gizmo_transform ( ) . origin ;
2017-09-02 21:47:16 +02:00
bounds . merge_with ( mesh_instance_bounds ) ;
}
bounds = _calculate_spatial_bounds ( child , bounds ) ;
}
}
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 ) ;
Ref < PackedScene > scene = Ref < PackedScene > ( Object : : cast_to < PackedScene > ( * res ) ) ;
2017-09-16 15:57:17 +02: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 21:47:16 +02:00
}
}
editor - > get_scene_root ( ) - > add_child ( preview_node ) ;
}
}
2017-11-17 03:09:00 +01:00
* preview_bounds = _calculate_spatial_bounds ( preview_node , AABB ( ) ) ;
2017-09-02 21:47:16 +02: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 15:57:17 +02:00
RES res = ResourceLoader : : load ( path ) ;
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 21:14:53 +01:00
mesh_instance - > set_name ( path . get_file ( ) . get_basename ( ) ) ;
2017-09-16 15:57:17 +02:00
instanced_scene = mesh_instance ;
} else {
if ( ! scene . is_valid ( ) ) { // invalid scene
return false ;
} else {
2018-05-06 19:13:23 +02:00
instanced_scene = scene - > instance ( PackedScene : : GEN_EDIT_STATE_INSTANCE ) ;
2017-09-16 15:57:17 +02:00
}
}
2017-09-02 21:47:16 +02:00
}
2017-09-16 15:57:17 +02:00
if ( instanced_scene = = NULL ) {
2017-09-02 21:47:16 +02: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 22:31:53 +01:00
if ( scene ! = NULL ) {
instanced_scene - > set_filename ( ProjectSettings : : get_singleton ( ) - > localize_path ( path ) ) ;
}
2017-09-02 21:47:16 +02: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 ) ) ;
Transform global_transform ;
Spatial * parent_spatial = Object : : cast_to < Spatial > ( parent ) ;
if ( parent_spatial )
2017-10-03 18:49:32 +02:00
global_transform = parent_spatial - > get_global_gizmo_transform ( ) ;
2017-09-02 21:47:16 +02:00
2017-09-18 23:44:04 +02:00
global_transform . origin = spatial_editor - > snap_point ( _get_instance_position ( p_point ) ) ;
2017-09-02 21:47:16 +02:00
editor_data - > get_undo_redo ( ) . add_do_method ( instanced_scene , " set_global_transform " , global_transform ) ;
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 15:57:17 +02:00
Ref < Mesh > mesh = Ref < Mesh > ( Object : : cast_to < Mesh > ( * res ) ) ;
if ( mesh ! = NULL | | scene ! = NULL ) {
2017-09-02 21:47:16 +02: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 15:57:17 +02:00
List < String > mesh_extensions ;
ResourceLoader : : get_recognized_extensions_for_type ( " Mesh " , & mesh_extensions ) ;
2017-09-02 21:47:16 +02:00
for ( int i = 0 ; i < files . size ( ) ; i + + ) {
2017-09-16 15:57:17 +02:00
if ( mesh_extensions . find ( files [ i ] . get_extension ( ) ) | | scene_extensions . find ( files [ i ] . get_extension ( ) ) ) {
2017-09-02 21:47:16 +02: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 05:22:16 +01:00
} else if ( type = = " Mesh " | | type = = " ArrayMesh " | | type = = " PrimitiveMesh " ) {
2017-09-16 15:57:17 +02:00
Ref < Mesh > mesh = ResourceLoader : : load ( files [ i ] ) ;
if ( ! mesh . is_valid ( ) ) {
continue ;
}
} else {
continue ;
2017-09-02 21:47:16 +02: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 03:50:23 +02:00
SpatialEditorViewport : : SpatialEditorViewport ( SpatialEditor * p_spatial_editor , EditorNode * p_editor , int p_index ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01: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 21:47:16 +02:00
editor_data = editor - > get_scene_tree_dock ( ) - > get_editor_data ( ) ;
2017-03-05 16:44:50 +01:00
editor_selection = editor - > get_editor_selection ( ) ;
undo_redo = editor - > get_undo_redo ( ) ;
clicked = 0 ;
clicked_includes_current = false ;
orthogonal = false ;
2018-08-05 20:24:11 +02:00
lock_rotation = false ;
2017-03-05 16:44:50 +01:00
message_time = 0 ;
2017-05-07 22:59:05 +02:00
zoom_indicator_delay = 0.0 ;
2017-03-05 16:44:50 +01:00
spatial_editor = p_spatial_editor ;
ViewportContainer * c = memnew ( ViewportContainer ) ;
2017-10-31 18:23:25 +01:00
viewport_container = c ;
2016-10-19 16:14:41 +02:00
c - > set_stretch ( true ) ;
2014-02-10 02:10:30 +01:00
add_child ( c ) ;
2017-09-22 00:12:33 +02:00
c - > set_anchors_and_margins_preset ( Control : : PRESET_WIDE ) ;
2017-03-05 16:44:50 +01:00
viewport = memnew ( Viewport ) ;
2016-01-18 23:49:11 +01:00
viewport - > set_disable_input ( true ) ;
2016-11-10 03:55:06 +01:00
2014-02-10 02:10:30 +01:00
c - > add_child ( viewport ) ;
2017-03-05 16:44:50 +01:00
surface = memnew ( Control ) ;
2017-09-02 21:47:16 +02:00
surface - > set_drag_forwarding ( this ) ;
2014-02-10 02:10:30 +01:00
add_child ( surface ) ;
2017-09-22 00:12:33 +02:00
surface - > set_anchors_and_margins_preset ( Control : : PRESET_WIDE ) ;
2017-06-11 23:13:04 +02:00
surface - > set_clip_contents ( true ) ;
2014-02-10 02:10:30 +01:00
camera = memnew ( Camera ) ;
camera - > set_disable_gizmo ( true ) ;
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
viewport - > add_child ( camera ) ;
camera - > make_current ( ) ;
surface - > set_focus_mode ( FOCUS_ALL ) ;
2019-05-24 21:21:07 +02:00
VBoxContainer * vbox = memnew ( VBoxContainer ) ;
surface - > add_child ( vbox ) ;
vbox - > set_position ( Point2 ( 10 , 10 ) * EDSCALE ) ;
2017-03-05 16:44:50 +01:00
view_menu = memnew ( MenuButton ) ;
2018-10-10 09:25:59 +02:00
view_menu - > set_flat ( false ) ;
2019-05-24 21:21:07 +02:00
vbox - > add_child ( view_menu ) ;
view_menu - > set_h_size_flags ( 0 ) ;
2018-10-10 09:25:59 +02:00
2016-06-30 22:54:34 +02: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 02:10:30 +01:00
view_menu - > get_popup ( ) - > add_separator ( ) ;
2018-03-24 03:05:20 +01: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 16:44:50 +01:00
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_PERSPECTIVE ) , true ) ;
2014-02-10 02:10:30 +01:00
view_menu - > get_popup ( ) - > add_separator ( ) ;
2018-06-25 03:24:31 +02: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 03:05:20 +01: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 20:52:03 +02: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 21:00:16 +01:00
view_menu - > get_popup ( ) - > add_check_shortcut ( ED_SHORTCUT ( " spatial_editor/view_fps " , TTR ( " View FPS " ) ) , VIEW_FPS ) ;
2017-03-05 16:44:50 +01:00
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_ENVIRONMENT ) , true ) ;
2014-10-03 05:10:51 +02:00
view_menu - > get_popup ( ) - > add_separator ( ) ;
2017-10-31 18:23:25 +01: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 22:54:34 +02:00
view_menu - > get_popup ( ) - > add_check_shortcut ( ED_SHORTCUT ( " spatial_editor/view_audio_listener " , TTR ( " Audio Listener " ) ) , VIEW_AUDIO_LISTENER ) ;
2019-08-12 22:23:00 +02:00
view_menu - > get_popup ( ) - > add_check_shortcut ( ED_SHORTCUT ( " spatial_editor/view_audio_doppler " , TTR ( " Enable Doppler " ) ) , VIEW_AUDIO_DOPPLER ) ;
2017-03-05 16:44:50 +01:00
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( VIEW_GIZMOS ) , true ) ;
2014-10-03 05:10:51 +02:00
2018-07-27 00:36:05 +02: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 02:10:30 +01:00
view_menu - > get_popup ( ) - > add_separator ( ) ;
2016-10-04 20:39:38 +02:00
view_menu - > get_popup ( ) - > add_shortcut ( ED_GET_SHORTCUT ( " spatial_editor/focus_origin " ) , VIEW_CENTER_TO_ORIGIN ) ;
2016-06-30 22:54:34 +02:00
view_menu - > get_popup ( ) - > add_shortcut ( ED_GET_SHORTCUT ( " spatial_editor/focus_selection " ) , VIEW_CENTER_TO_SELECTION ) ;
2018-10-27 23:43:19 +02: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 16:44:50 +01:00
view_menu - > get_popup ( ) - > connect ( " id_pressed " , this , " _menu_option " ) ;
2014-02-10 02:10:30 +01:00
2017-12-19 15:29:55 +01:00
view_menu - > set_disable_shortcuts ( true ) ;
2017-07-27 04:00:23 +02: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-14 01:36:42 +02: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 04:00:23 +02:00
ED_SHORTCUT ( " spatial_editor/freelook_speed_modifier " , TTR ( " Freelook Speed Modifier " ) , KEY_SHIFT ) ;
2018-10-10 09:25:59 +02:00
preview_camera = memnew ( CheckBox ) ;
2017-12-19 06:25:00 +01:00
preview_camera - > set_text ( TTR ( " Preview " ) ) ;
2019-05-24 21:21:07 +02:00
vbox - > add_child ( preview_camera ) ;
preview_camera - > set_h_size_flags ( 0 ) ;
2014-02-10 02:10:30 +01:00
preview_camera - > hide ( ) ;
2017-03-05 16:44:50 +01:00
preview_camera - > connect ( " toggled " , this , " _toggle_camera_preview " ) ;
previewing = NULL ;
gizmo_scale = 1.0 ;
2017-05-07 22:59:05 +02:00
2017-09-02 21:47:16 +02:00
preview_node = NULL ;
2017-06-11 23:13:04 +02:00
info_label = memnew ( Label ) ;
2017-12-17 13:06:21 +01: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 23:13:04 +02:00
2017-11-19 21:00:16 +01:00
fps_label = memnew ( Label ) ;
2017-12-17 13:06:21 +01:00
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 ) ;
2019-02-20 12:07:49 +01:00
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.
2017-12-17 13:06:21 +01:00
surface - > add_child ( fps_label ) ;
fps_label - > hide ( ) ;
2017-11-19 21:00:16 +01:00
2018-07-27 00:36:05 +02: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 09:25:59 +02: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 ( ) ;
2017-09-02 21:47:16 +02:00
accept = NULL ;
2017-05-07 22:59:05 +02:00
freelook_active = false ;
2017-10-08 02:43:57 +02:00
freelook_speed = EditorSettings : : get_singleton ( ) - > get ( " editors/3d/freelook/freelook_base_speed " ) ;
2014-10-03 05:10:51 +02:00
2017-03-05 16:44:50 +01:00
selection_menu = memnew ( PopupMenu ) ;
2015-11-04 22:39:07 +01:00
add_child ( selection_menu ) ;
2017-08-04 15:46:22 +02:00
selection_menu - > set_custom_minimum_size ( Size2 ( 100 , 0 ) * EDSCALE ) ;
2017-01-08 22:18:54 +01:00
selection_menu - > connect ( " id_pressed " , this , " _selection_result_pressed " ) ;
2015-11-04 22:39:07 +01:00
selection_menu - > connect ( " popup_hide " , this , " _selection_menu_hide " ) ;
2017-03-05 16:44:50 +01: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 05:10:51 +02:00
viewport - > set_as_audio_listener ( true ) ;
}
2017-08-04 15:46:22 +02:00
name = " " ;
2015-03-21 21:47:21 +01:00
_update_name ( ) ;
2017-03-05 16:44:50 +01:00
EditorSettings : : get_singleton ( ) - > connect ( " settings_changed " , this , " update_transform_gizmo_view " ) ;
2014-02-10 02:10:30 +01:00
}
2017-06-11 16:29:27 +02:00
//////////////////////////////////////////////////////////////
void SpatialEditorViewportContainer : : _gui_input ( const Ref < InputEvent > & p_event ) {
Ref < InputEventMouseButton > mb = p_event ;
2018-08-25 08:47:04 +02:00
if ( mb . is_valid ( ) & & mb - > get_button_index ( ) = = BUTTON_LEFT ) {
2017-06-11 16:29:27 +02:00
2018-08-25 08:47:04 +02:00
if ( mb - > is_pressed ( ) ) {
Vector2 size = get_size ( ) ;
2017-06-11 16:29:27 +02:00
2018-08-25 08:47:04 +02:00
int h_sep = get_constant ( " separation " , " HSplitContainer " ) ;
int v_sep = get_constant ( " separation " , " VSplitContainer " ) ;
2017-06-11 16:29:27 +02:00
2018-08-25 08:47:04 +02:00
int mid_w = size . width * ratio_h ;
int mid_h = size . height * ratio_v ;
2017-06-11 16:29:27 +02:00
2018-08-25 08:47:04 +02: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 16:29:27 +02:00
2018-08-25 08:47:04 +02:00
drag_begin_pos = mb - > get_position ( ) ;
drag_begin_ratio . x = ratio_h ;
drag_begin_ratio . y = ratio_v ;
2017-06-11 16:29:27 +02:00
2018-08-25 08:47:04 +02:00
switch ( view ) {
case VIEW_USE_1_VIEWPORT : {
2017-06-11 16:29:27 +02:00
2018-08-25 08:47:04 +02:00
dragging_h = false ;
dragging_v = false ;
2017-06-11 16:29:27 +02:00
2018-08-25 08:47:04 +02:00
} break ;
case VIEW_USE_2_VIEWPORTS : {
2017-06-11 16:29:27 +02:00
2018-08-25 08:47:04 +02:00
dragging_h = false ;
2017-06-11 16:29:27 +02:00
2018-08-25 08:47:04 +02:00
} break ;
case VIEW_USE_2_VIEWPORTS_ALT : {
2017-06-11 16:29:27 +02:00
dragging_v = false ;
2018-08-25 08:47:04 +02:00
} break ;
case VIEW_USE_3_VIEWPORTS :
case VIEW_USE_3_VIEWPORTS_ALT :
case VIEW_USE_4_VIEWPORTS : {
2017-06-11 16:29:27 +02:00
2018-08-25 08:47:04 +02:00
// Do nothing.
2017-06-11 16:29:27 +02:00
2018-08-25 08:47:04 +02:00
} break ;
}
} else {
dragging_h = false ;
dragging_v = false ;
2017-06-11 16:29:27 +02:00
}
}
Ref < InputEventMouseMotion > mm = p_event ;
2018-08-25 08:47:04 +02: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 16:29:27 +02: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 08:47:04 +02: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 16:29:27 +02: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 08:47:04 +02:00
// Nothing to show.
2017-06-11 16:29:27 +02: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 08:47:04 +02:00
set_default_cursor_shape ( CURSOR_VSPLIT ) ;
2017-06-11 16:29:27 +02: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 08:47:04 +02:00
set_default_cursor_shape ( CURSOR_HSPLIT ) ;
2017-06-11 16:29:27 +02:00
} break ;
case VIEW_USE_3_VIEWPORTS : {
2018-08-25 08:47:04 +02: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 16:29:27 +02:00
} break ;
case VIEW_USE_3_VIEWPORTS_ALT : {
2018-08-25 08:47:04 +02: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 16:29:27 +02:00
} break ;
case VIEW_USE_4_VIEWPORTS : {
Vector2 half ( mid_w , mid_h ) ;
2018-08-25 08:47:04 +02: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 16:29:27 +02: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 22:58:51 +02:00
viewports [ vc ] = Object : : cast_to < SpatialEditorViewport > ( get_child ( i ) ) ;
2017-06-11 16:29:27 +02: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 19:09:31 +02:00
viewports [ 0 ] - > show ( ) ;
2017-06-11 16:29:27 +02: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 19:09:31 +02:00
for ( int i = 0 ; i < 4 ; i + + ) {
2017-06-11 16:29:27 +02: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 19:09:31 +02:00
for ( int i = 0 ; i < 4 ; i + + ) {
2017-06-11 16:29:27 +02: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 19:09:31 +02:00
for ( int i = 0 ; i < 4 ; i + + ) {
2017-06-11 16:29:27 +02: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 19:09:31 +02:00
for ( int i = 0 ; i < 4 ; i + + ) {
2017-06-11 16:29:27 +02: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 19:09:31 +02:00
for ( int i = 0 ; i < 4 ; i + + ) {
2017-06-11 16:29:27 +02: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 08:47:04 +02:00
set_clip_contents ( true ) ;
2017-06-11 16:29:27 +02:00
view = VIEW_USE_1_VIEWPORT ;
mouseover = false ;
ratio_h = 0.5 ;
ratio_v = 0.5 ;
2018-08-25 08:47:04 +02:00
hovering_v = false ;
hovering_h = false ;
2017-06-11 16:29:27 +02:00
dragging_v = false ;
dragging_h = false ;
}
///////////////////////////////////////////////////////////////////
2017-03-05 16:44:50 +01:00
SpatialEditor * SpatialEditor : : singleton = NULL ;
2014-02-10 02:10:30 +01:00
SpatialEditorSelectedItem : : ~ SpatialEditorSelectedItem ( ) {
if ( sbox_instance . is_valid ( ) )
VisualServer : : get_singleton ( ) - > free ( sbox_instance ) ;
}
2017-04-06 17:35:08 +02:00
void SpatialEditor : : select_gizmo_highlight_axis ( int p_axis ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 3 ; i + + ) {
2014-02-10 02:10:30 +01:00
2019-08-01 14:23:29 +02: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 02:10:30 +01:00
}
}
void SpatialEditor : : update_transform_gizmo ( ) {
2017-03-05 16:44:50 +01:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
2017-11-17 03:09:00 +01:00
AABB center ;
2017-03-05 16:44:50 +01:00
bool first = true ;
2014-02-10 02:10:30 +01:00
2017-01-11 04:52:51 +01:00
Basis gizmo_basis ;
2017-09-21 23:11:56 +02:00
bool local_gizmo_coords = are_local_coords_enabled ( ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
2014-02-10 02:10:30 +01:00
if ( ! sp )
continue ;
2017-03-05 16:44:50 +01:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
2014-02-10 02:10:30 +01:00
if ( ! se )
continue ;
2017-10-03 18:49:32 +02:00
Transform xf = se - > sp - > get_global_gizmo_transform ( ) ;
2014-02-10 02:10:30 +01:00
if ( first ) {
2017-06-06 20:33:51 +02:00
center . position = xf . origin ;
2017-03-05 16:44:50 +01:00
first = false ;
2014-02-10 02:10:30 +01:00
if ( local_gizmo_coords ) {
2017-03-05 16:44:50 +01:00
gizmo_basis = xf . basis ;
2014-02-10 02:10:30 +01:00
gizmo_basis . orthonormalize ( ) ;
}
} else {
center . expand_to ( xf . origin ) ;
2017-03-05 16:44:50 +01:00
gizmo_basis = Basis ( ) ;
2014-02-10 02:10:30 +01:00
}
}
2017-06-06 20:33:51 +02:00
Vector3 pcenter = center . position + center . size * 0.5 ;
2017-03-05 16:44:50 +01:00
gizmo . visible = ! first ;
gizmo . transform . origin = pcenter ;
gizmo . transform . basis = gizmo_basis ;
2014-02-10 02:10:30 +01:00
2017-08-31 23:30:35 +02:00
for ( uint32_t i = 0 ; i < VIEWPORTS_COUNT ; i + + ) {
2014-05-05 03:50:23 +02:00
viewports [ i ] - > update_transform_gizmo_view ( ) ;
}
2014-02-10 02:10:30 +01:00
}
2017-11-22 22:29:27 +01: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 22:31:03 +02:00
void SpatialEditor : : update_all_gizmos ( Node * p_node ) {
if ( ! p_node ) p_node = SceneTree : : get_singleton ( ) - > get_root ( ) ;
_update_all_gizmos ( p_node ) ;
2017-11-22 22:29:27 +01:00
}
2014-02-10 02:10:30 +01:00
Object * SpatialEditor : : _get_editor_data ( Object * p_what ) {
2017-08-24 22:58:51 +02:00
Spatial * sp = Object : : cast_to < Spatial > ( p_what ) ;
2014-02-10 02:10:30 +01:00
if ( ! sp )
return NULL ;
2017-03-05 16:44:50 +01:00
SpatialEditorSelectedItem * si = memnew ( SpatialEditorSelectedItem ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
si - > sp = sp ;
si - > sbox_instance = VisualServer : : get_singleton ( ) - > instance_create2 ( selection_box - > get_rid ( ) , sp - > get_world ( ) - > get_scenario ( ) ) ;
2016-03-08 00:00:55 +01:00
VS : : get_singleton ( ) - > instance_geometry_set_cast_shadows_setting ( si - > sbox_instance , VS : : SHADOW_CASTING_SETTING_OFF ) ;
2014-02-10 02:10:30 +01:00
return si ;
}
2019-08-01 14:23:29 +02:00
Color SpatialEditor : : _get_axis_color ( int axis ) {
switch ( axis ) {
case 0 :
// X axis
return Color ( 0.96 , 0.20 , 0.32 ) ;
case 1 :
// Y axis
return Color ( 0.53 , 0.84 , 0.01 ) ;
case 2 :
// Z axis
return Color ( 0.16 , 0.55 , 0.96 ) ;
default :
return Color ( 0 , 0 , 0 ) ;
}
}
2014-02-10 02:10:30 +01:00
void SpatialEditor : : _generate_selection_box ( ) {
2017-11-17 03:09:00 +01:00
AABB aabb ( Vector3 ( ) , Vector3 ( 1 , 1 , 1 ) ) ;
2017-03-05 16:44:50 +01:00
aabb . grow_by ( aabb . get_longest_axis_size ( ) / 20.0 ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Ref < SurfaceTool > st = memnew ( SurfaceTool ) ;
2016-03-09 00:00:52 +01:00
2014-02-10 02:10:30 +01:00
st - > begin ( Mesh : : PRIMITIVE_LINES ) ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 12 ; i + + ) {
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
Vector3 a , b ;
aabb . get_edge ( i , a , b ) ;
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
st - > add_color ( Color ( 1.0 , 1.0 , 0.8 , 0.8 ) ) ;
2014-02-10 02:10:30 +01:00
st - > add_vertex ( a ) ;
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
st - > add_vertex ( b ) ;
}
2017-04-07 04:36:37 +02:00
Ref < SpatialMaterial > mat = memnew ( SpatialMaterial ) ;
mat - > set_flag ( SpatialMaterial : : FLAG_UNSHADED , true ) ;
2017-03-05 16:44:50 +01:00
mat - > set_albedo ( Color ( 1 , 1 , 1 ) ) ;
2017-04-07 04:36:37 +02: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 02:10:30 +01:00
st - > set_material ( mat ) ;
selection_box = st - > commit ( ) ;
}
Dictionary SpatialEditor : : get_state ( ) const {
Dictionary d ;
2017-03-05 16:44:50 +01: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 19:51:37 +01:00
d [ " local_coords " ] = tool_option_button [ TOOL_OPT_LOCAL_COORDS ] - > is_pressed ( ) ;
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
Array vpdata ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 4 ; i + + ) {
vpdata . push_back ( viewports [ i ] - > get_state ( ) ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
d [ " viewports " ] = vpdata ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
2018-07-25 00:08:49 +02:00
Dictionary gizmos_status ;
2019-03-12 00:30:50 +01: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 23:07:00 +02:00
int state = gizmos_menu - > get_item_state ( gizmos_menu - > get_item_index ( i ) ) ;
2019-03-12 00:30:50 +01:00
String name = gizmo_plugins_by_name [ i ] - > get_name ( ) ;
2018-08-11 23:07:00 +02:00
gizmos_status [ name ] = state ;
2018-07-25 00:08:49 +02:00
}
d [ " gizmos_status " ] = gizmos_status ;
2014-02-10 02:10:30 +01:00
return d ;
}
2017-03-05 16:44:50 +01:00
void SpatialEditor : : set_state ( const Dictionary & p_state ) {
2014-02-10 02:10:30 +01:00
Dictionary d = p_state ;
2016-01-10 21:59:12 +01:00
if ( d . has ( " snap_enabled " ) ) {
2017-03-05 16:44:50 +01:00
snap_enabled = d [ " snap_enabled " ] ;
2018-01-10 21:22:49 +01:00
tool_option_button [ TOOL_OPT_USE_SNAP ] - > set_pressed ( d [ " snap_enabled " ] ) ;
2016-01-10 21:59:12 +01:00
}
if ( d . has ( " translate_snap " ) )
snap_translate - > set_text ( d [ " translate_snap " ] ) ;
if ( d . has ( " rotate_snap " ) )
snap_rotate - > set_text ( d [ " rotate_snap " ] ) ;
if ( d . has ( " scale_snap " ) )
snap_scale - > set_text ( d [ " scale_snap " ] ) ;
if ( d . has ( " local_coords " ) ) {
2017-11-18 19:51:37 +01:00
tool_option_button [ TOOL_OPT_LOCAL_COORDS ] - > set_pressed ( d [ " local_coords " ] ) ;
2016-01-10 21:59:12 +01:00
update_transform_gizmo ( ) ;
}
2016-01-11 14:35:11 +01:00
if ( d . has ( " viewport_mode " ) ) {
int vc = d [ " viewport_mode " ] ;
2017-03-05 16:44:50 +01:00
if ( vc = = 1 )
2016-01-11 14:35:11 +01:00
_menu_item_pressed ( MENU_VIEW_USE_1_VIEWPORT ) ;
2017-03-05 16:44:50 +01:00
else if ( vc = = 2 )
2016-01-11 14:35:11 +01:00
_menu_item_pressed ( MENU_VIEW_USE_2_VIEWPORTS ) ;
2017-03-05 16:44:50 +01:00
else if ( vc = = 3 )
2016-01-11 14:35:11 +01:00
_menu_item_pressed ( MENU_VIEW_USE_3_VIEWPORTS ) ;
2017-03-05 16:44:50 +01:00
else if ( vc = = 4 )
2016-01-11 14:35:11 +01:00
_menu_item_pressed ( MENU_VIEW_USE_4_VIEWPORTS ) ;
2017-03-05 16:44:50 +01:00
else if ( vc = = 5 )
2016-01-11 14:35:11 +01:00
_menu_item_pressed ( MENU_VIEW_USE_2_VIEWPORTS_ALT ) ;
2017-03-05 16:44:50 +01:00
else if ( vc = = 6 )
2016-01-11 14:35:11 +01:00
_menu_item_pressed ( MENU_VIEW_USE_3_VIEWPORTS_ALT ) ;
}
2014-02-10 02:10:30 +01:00
2016-01-11 14:35:11 +01:00
if ( d . has ( " viewports " ) ) {
Array vp = d [ " viewports " ] ;
2019-03-12 03:17:30 +01:00
uint32_t vp_size = static_cast < uint32_t > ( vp . size ( ) ) ;
if ( vp_size > VIEWPORTS_COUNT ) {
2019-06-11 14:49:34 +02:00
WARN_PRINT ( " Ignoring superfluous viewport settings from spatial editor state. " ) ;
2019-03-12 03:17:30 +01:00
vp_size = VIEWPORTS_COUNT ;
}
2014-02-10 02:10:30 +01:00
2019-03-12 03:17:30 +01:00
for ( uint32_t i = 0 ; i < vp_size ; i + + ) {
2016-01-11 14:35:11 +01:00
viewports [ i ] - > set_state ( vp [ i ] ) ;
}
2014-02-10 02:10:30 +01:00
}
if ( d . has ( " zfar " ) )
2017-01-04 05:16:14 +01:00
settings_zfar - > set_value ( float ( d [ " zfar " ] ) ) ;
2014-02-10 02:10:30 +01:00
if ( d . has ( " znear " ) )
2017-01-04 05:16:14 +01:00
settings_znear - > set_value ( float ( d [ " znear " ] ) ) ;
2014-02-10 02:10:30 +01:00
if ( d . has ( " fov " ) )
2017-01-04 05:16:14 +01:00
settings_fov - > set_value ( float ( d [ " fov " ] ) ) ;
2014-02-10 02:10:30 +01:00
if ( d . has ( " show_grid " ) ) {
bool use = d [ " show_grid " ] ;
2017-03-05 16:44:50 +01:00
if ( use ! = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_GRID ) ) ) {
2014-07-15 09:06:55 +02:00
_menu_item_pressed ( MENU_VIEW_GRID ) ;
2014-02-10 02:10:30 +01:00
}
}
if ( d . has ( " show_origin " ) ) {
bool use = d [ " show_origin " ] ;
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
}
}
2018-07-25 00:08:49 +02:00
if ( d . has ( " gizmos_status " ) ) {
Dictionary gizmos_status = d [ " gizmos_status " ] ;
List < Variant > keys ;
gizmos_status . get_key_list ( & keys ) ;
2019-03-12 00:30:50 +01: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 17:38:02 +02:00
for ( int i = 0 ; i < keys . size ( ) ; i + + ) {
2019-03-12 00:30:50 +01:00
if ( gizmo_plugins_by_name . write [ j ] - > get_name ( ) = = keys [ i ] ) {
2018-08-11 23:07:00 +02:00
state = gizmos_status [ keys [ i ] ] ;
2019-03-12 00:30:50 +01:00
break ;
2018-07-25 00:08:49 +02:00
}
}
2018-08-11 23:07:00 +02:00
2019-03-12 00:30:50 +01:00
gizmo_plugins_by_name . write [ j ] - > set_state ( state ) ;
2018-07-25 00:08:49 +02:00
}
2019-03-12 00:30:50 +01:00
_update_gizmos_menu ( ) ;
2018-07-25 00:08:49 +02:00
}
2014-02-10 02:10:30 +01:00
}
void SpatialEditor : : edit ( Spatial * p_spatial ) {
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
if ( p_spatial ! = selected ) {
2014-05-05 03:50:23 +02:00
if ( selected ) {
2018-07-25 00:08:49 +02:00
Ref < EditorSpatialGizmo > seg = selected - > get_gizmo ( ) ;
2014-05-05 03:50:23 +02:00
if ( seg . is_valid ( ) ) {
seg - > set_selected ( false ) ;
selected - > update_gizmo ( ) ;
}
}
2017-03-05 16:44:50 +01:00
selected = p_spatial ;
over_gizmo_handle = - 1 ;
2014-05-05 03:50:23 +02:00
if ( selected ) {
2018-07-25 00:08:49 +02:00
Ref < EditorSpatialGizmo > seg = selected - > get_gizmo ( ) ;
2014-05-05 03:50:23 +02:00
if ( seg . is_valid ( ) ) {
seg - > set_selected ( true ) ;
selected - > update_gizmo ( ) ;
}
}
}
2014-02-10 02:10:30 +01:00
}
void SpatialEditor : : _xform_dialog_action ( ) {
Transform t ;
//translation
Vector3 scale ;
Vector3 rotate ;
Vector3 translate ;
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
2017-01-05 18:31:39 +01:00
t . basis . scale ( scale ) ;
t . basis . rotate ( rotate ) ;
2017-03-05 16:44:50 +01:00
t . origin = translate ;
2014-02-10 02:10:30 +01:00
2016-05-04 03:25:37 +02:00
undo_redo - > create_action ( TTR ( " XForm Dialog " ) ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
Spatial * sp = Object : : cast_to < Spatial > ( E - > get ( ) ) ;
2014-02-10 02:10:30 +01:00
if ( ! sp )
continue ;
2017-03-05 16:44:50 +01:00
SpatialEditorSelectedItem * se = editor_selection - > get_node_editor_data < SpatialEditorSelectedItem > ( sp ) ;
2014-02-10 02:10:30 +01:00
if ( ! se )
continue ;
2017-03-05 16:44:50 +01:00
bool post = xform_type - > get_selected ( ) > 0 ;
2014-02-10 02:10:30 +01:00
2017-10-03 18:49:32 +02:00
Transform tr = sp - > get_global_gizmo_transform ( ) ;
2014-02-10 02:10:30 +01:00
if ( post )
tr = tr * t ;
else {
tr . basis = t . basis * tr . basis ;
2017-03-05 16:44:50 +01:00
tr . origin + = t . origin ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
undo_redo - > add_do_method ( sp , " set_global_transform " , tr ) ;
2017-10-03 18:49:32 +02:00
undo_redo - > add_undo_method ( sp , " set_global_transform " , sp - > get_global_gizmo_transform ( ) ) ;
2014-02-10 02:10:30 +01:00
}
undo_redo - > commit_action ( ) ;
}
2017-11-18 19:51:37 +01: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 ;
}
}
2018-07-25 00:08:49 +02:00
void SpatialEditor : : _menu_gizmo_toggled ( int p_option ) {
2018-08-11 23:07:00 +02: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 22:01:09 +01:00
case EditorSpatialGizmoPlugin : : VISIBLE :
2018-08-11 23:07:00 +02:00
gizmos_menu - > set_item_icon ( idx , view_menu - > get_popup ( ) - > get_icon ( " visibility_visible " ) ) ;
break ;
2018-11-18 22:01:09 +01:00
case EditorSpatialGizmoPlugin : : ON_TOP :
2018-08-11 23:07:00 +02: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-12 00:30:50 +01:00
gizmo_plugins_by_name . write [ p_option ] - > set_state ( state ) ;
2018-07-25 00:08:49 +02:00
2018-08-11 23:07:00 +02:00
update_all_gizmos ( ) ;
2018-07-25 00:08:49 +02:00
}
2014-02-10 02:10:30 +01:00
void SpatialEditor : : _menu_item_pressed ( int p_option ) {
2017-03-05 16:44:50 +01:00
switch ( p_option ) {
2014-02-10 02:10:30 +01:00
case MENU_TOOL_SELECT :
case MENU_TOOL_MOVE :
case MENU_TOOL_ROTATE :
2015-12-13 21:16:13 +01:00
case MENU_TOOL_SCALE :
case MENU_TOOL_LIST_SELECT : {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
update_transform_gizmo ( ) ;
} break ;
case MENU_TRANSFORM_CONFIGURE_SNAP : {
2017-03-05 16:44:50 +01:00
snap_dialog - > popup_centered ( Size2 ( 200 , 180 ) ) ;
2014-02-10 02:10:30 +01:00
} break ;
case MENU_TRANSFORM_DIALOG : {
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 3 ; i + + ) {
2014-02-10 02:10:30 +01:00
xform_translate [ i ] - > set_text ( " 0 " ) ;
xform_rotate [ i ] - > set_text ( " 0 " ) ;
xform_scale [ i ] - > set_text ( " 1 " ) ;
}
2017-07-31 15:00:02 +02:00
xform_dialog - > popup_centered ( Size2 ( 320 , 240 ) * EDSCALE ) ;
2014-02-10 02:10:30 +01:00
} break ;
case MENU_VIEW_USE_1_VIEWPORT : {
2017-06-11 16:29:27 +02:00
viewport_base - > set_view ( SpatialEditorViewportContainer : : VIEW_USE_1_VIEWPORT ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
} break ;
case MENU_VIEW_USE_2_VIEWPORTS : {
2017-06-11 16:29:27 +02:00
viewport_base - > set_view ( SpatialEditorViewportContainer : : VIEW_USE_2_VIEWPORTS ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01: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 05:06:51 +02:00
} break ;
case MENU_VIEW_USE_2_VIEWPORTS_ALT : {
2017-06-11 16:29:27 +02:00
viewport_base - > set_view ( SpatialEditorViewportContainer : : VIEW_USE_2_VIEWPORTS_ALT ) ;
2014-10-09 05:06:51 +02:00
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
} break ;
case MENU_VIEW_USE_3_VIEWPORTS : {
2017-06-11 16:29:27 +02:00
viewport_base - > set_view ( SpatialEditorViewportContainer : : VIEW_USE_3_VIEWPORTS ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01: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 05:06:51 +02:00
} break ;
case MENU_VIEW_USE_3_VIEWPORTS_ALT : {
2017-06-11 16:29:27 +02:00
viewport_base - > set_view ( SpatialEditorViewportContainer : : VIEW_USE_3_VIEWPORTS_ALT ) ;
2014-10-09 05:06:51 +02:00
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
} break ;
case MENU_VIEW_USE_4_VIEWPORTS : {
2017-06-11 16:29:27 +02:00
viewport_base - > set_view ( SpatialEditorViewportContainer : : VIEW_USE_4_VIEWPORTS ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
} break ;
case MENU_VIEW_ORIGIN : {
2017-03-05 16:44:50 +01:00
bool is_checked = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( p_option ) ) ;
2014-02-10 02:10:30 +01:00
2018-08-17 23:21:08 +02: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 02:10:30 +01:00
2018-08-17 23:21:08 +02:00
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( p_option ) , origin_enabled ) ;
2014-02-10 02:10:30 +01:00
} break ;
case MENU_VIEW_GRID : {
2017-03-05 16:44:50 +01:00
bool is_checked = view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( p_option ) ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
grid_enabled = ! is_checked ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 3 ; + + i ) {
2014-07-15 07:29:03 +02:00
if ( grid_enable [ i ] ) {
2017-03-05 16:44:50 +01:00
VisualServer : : get_singleton ( ) - > instance_set_visible ( grid_instance [ i ] , grid_enabled ) ;
grid_visible [ i ] = grid_enabled ;
2014-07-15 07:29:03 +02:00
}
}
2017-03-05 16:44:50 +01:00
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( p_option ) , grid_enabled ) ;
2014-02-10 02:10:30 +01:00
} break ;
case MENU_VIEW_CAMERA_SETTINGS : {
2017-03-05 16:44:50 +01:00
settings_dialog - > popup_centered ( settings_vbc - > get_combined_minimum_size ( ) + Size2 ( 50 , 50 ) ) ;
2014-02-10 02:10:30 +01:00
} break ;
2018-07-26 08:34:40 +02:00
case MENU_SNAP_TO_FLOOR : {
snap_selected_nodes_to_floor ( ) ;
} break ;
2017-10-23 21:21:15 +02:00
case MENU_LOCK_SELECTED : {
2019-04-26 19:23:50 +02:00
undo_redo - > create_action ( TTR ( " Lock Selected " ) ) ;
2017-10-23 21:21:15 +02: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 19:23:50 +02: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 21:21:15 +02:00
}
2019-04-26 19:23:50 +02: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 21:21:15 +02:00
} break ;
case MENU_UNLOCK_SELECTED : {
2019-04-26 19:23:50 +02:00
undo_redo - > create_action ( TTR ( " Unlock Selected " ) ) ;
2017-10-23 21:21:15 +02: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 19:23:50 +02: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 21:21:15 +02:00
}
2019-04-26 19:23:50 +02: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 18:24:28 +02:00
} break ;
case MENU_GROUP_SELECTED : {
2019-04-26 19:23:50 +02:00
undo_redo - > create_action ( TTR ( " Group Selected " ) ) ;
2019-04-17 18:24:28 +02: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 19:23:50 +02: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 18:24:28 +02:00
}
2019-04-26 19:23:50 +02: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 18:24:28 +02:00
} break ;
case MENU_UNGROUP_SELECTED : {
2019-04-26 19:23:50 +02:00
undo_redo - > create_action ( TTR ( " Ungroup Selected " ) ) ;
2019-04-17 18:24:28 +02: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 19:23:50 +02: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 18:24:28 +02:00
}
2019-04-26 19:23:50 +02: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 21:21:15 +02:00
} break ;
2014-02-10 02:10:30 +01:00
}
}
void SpatialEditor : : _init_indicators ( ) {
{
2018-09-20 13:27:32 +02:00
origin_enabled = true ;
grid_enabled = true ;
2014-02-10 02:10:30 +01:00
2017-01-14 18:03:38 +01:00
indicator_mat . instance ( ) ;
2017-04-07 04:36:37 +02: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-30 01:48:09 +02:00
2014-02-10 02:10:30 +01:00
Vector < Color > origin_colors ;
Vector < Vector3 > origin_points ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 3 ; i + + ) {
2014-02-10 02:10:30 +01:00
Vector3 axis ;
2017-03-05 16:44:50 +01:00
axis [ i ] = 1 ;
2019-08-01 14:23:29 +02:00
Color origin_color = _get_axis_color ( i ) ;
2017-12-08 23:45:33 +01:00
grid_enable [ i ] = false ;
grid_visible [ i ] = false ;
2014-02-10 02:10:30 +01:00
2019-08-01 14:23:29 +02:00
origin_colors . push_back ( origin_color ) ;
origin_colors . push_back ( origin_color ) ;
2017-03-05 16:44:50 +01:00
origin_points . push_back ( axis * 4096 ) ;
origin_points . push_back ( axis * - 4096 ) ;
2017-12-08 23:45:33 +01:00
}
2014-02-10 02:10:30 +01:00
2017-12-08 23:45:33 +01:00
grid_enable [ 1 ] = true ;
grid_visible [ 1 ] = true ;
2017-03-05 16:44:50 +01:00
2017-12-08 23:45:33 +01:00
_init_grid ( ) ;
2014-02-10 02:10:30 +01:00
origin = VisualServer : : get_singleton ( ) - > mesh_create ( ) ;
Array d ;
d . resize ( VS : : ARRAY_MAX ) ;
2017-03-05 16:44:50 +01:00
d [ VisualServer : : ARRAY_VERTEX ] = origin_points ;
d [ VisualServer : : ARRAY_COLOR ] = origin_colors ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
2017-03-05 16:44:50 +01: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 05:06:34 +02:00
2016-03-08 00:00:55 +01:00
VisualServer : : get_singleton ( ) - > instance_geometry_set_cast_shadows_setting ( origin_instance , VS : : SHADOW_CASTING_SETTING_OFF ) ;
2014-02-10 02:10:30 +01:00
}
{
//move gizmo
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 3 ; i + + ) {
2014-02-10 02:10:30 +01:00
2019-08-01 14:23:29 +02:00
Color col = _get_axis_color ( i ) ;
col . a = EditorSettings : : get_singleton ( ) - > get ( " editors/3d/manipulator_gizmo_opacity " ) ;
2017-06-07 23:18:55 +02:00
move_gizmo [ i ] = Ref < ArrayMesh > ( memnew ( ArrayMesh ) ) ;
2017-08-29 03:39:45 +02:00
move_plane_gizmo [ i ] = Ref < ArrayMesh > ( memnew ( ArrayMesh ) ) ;
2017-06-07 23:18:55 +02:00
rotate_gizmo [ i ] = Ref < ArrayMesh > ( memnew ( ArrayMesh ) ) ;
2017-09-21 23:11:56 +02:00
scale_gizmo [ i ] = Ref < ArrayMesh > ( memnew ( ArrayMesh ) ) ;
2017-11-14 23:50:19 +01:00
scale_plane_gizmo [ i ] = Ref < ArrayMesh > ( memnew ( ArrayMesh ) ) ;
2014-02-10 02:10:30 +01:00
2017-04-07 04:36:37 +02:00
Ref < SpatialMaterial > mat = memnew ( SpatialMaterial ) ;
mat - > set_flag ( SpatialMaterial : : FLAG_UNSHADED , true ) ;
2017-09-01 17:56:52 +02:00
mat - > set_on_top_of_alpha ( ) ;
2017-04-07 04:36:37 +02:00
mat - > set_feature ( SpatialMaterial : : FEATURE_TRANSPARENT , true ) ;
2016-10-27 16:50:26 +02:00
mat - > set_albedo ( col ) ;
2017-03-05 16:44:50 +01:00
gizmo_color [ i ] = mat ;
2014-02-10 02:10:30 +01:00
2019-08-01 14:23:29 +02: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 02:10:30 +01:00
Vector3 ivec ;
2017-03-05 16:44:50 +01:00
ivec [ i ] = 1 ;
2014-02-10 02:10:30 +01:00
Vector3 nivec ;
2017-03-05 16:44:50 +01:00
nivec [ ( i + 1 ) % 3 ] = 1 ;
nivec [ ( i + 2 ) % 3 ] = 1 ;
2014-02-10 02:10:30 +01:00
Vector3 ivec2 ;
2017-03-05 16:44:50 +01:00
ivec2 [ ( i + 1 ) % 3 ] = 1 ;
2014-02-10 02:10:30 +01:00
Vector3 ivec3 ;
2017-03-05 16:44:50 +01:00
ivec3 [ ( i + 2 ) % 3 ] = 1 ;
2014-02-10 02:10:30 +01:00
2017-09-21 23:11:56 +02:00
//translate
2014-02-10 02:10:30 +01:00
{
2017-03-05 16:44:50 +01:00
Ref < SurfaceTool > surftool = memnew ( SurfaceTool ) ;
2014-02-10 02:10:30 +01:00
surftool - > begin ( Mesh : : PRIMITIVE_TRIANGLES ) ;
2017-09-21 23:11:56 +02:00
// Arrow profile
2017-03-05 16:44:50 +01:00
const int arrow_points = 5 ;
Vector3 arrow [ 5 ] = {
nivec * 0.0 + ivec * 0.0 ,
nivec * 0.01 + ivec * 0.0 ,
2017-09-21 23:11:56 +02: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 02:10:30 +01:00
} ;
2018-08-09 16:34:18 +02:00
int arrow_sides = 16 ;
2014-02-10 02:10:30 +01:00
2018-08-09 16:34:18 +02:00
for ( int k = 0 ; k < arrow_sides ; k + + ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int j = 0 ; j < arrow_points - 1 ; j + + ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Vector3 points [ 4 ] = {
2014-02-10 02:10:30 +01:00
ma . xform ( arrow [ j ] ) ,
mb . xform ( arrow [ j ] ) ,
2017-03-05 16:44:50 +01:00
mb . xform ( arrow [ j + 1 ] ) ,
ma . xform ( arrow [ j + 1 ] ) ,
2014-02-10 02:10:30 +01: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 23:11:56 +02:00
// Plane Translation
2017-08-29 03:39:45 +02: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 17:56:52 +02:00
plane_mat - > set_on_top_of_alpha ( ) ;
2017-08-29 03:39:45 +02:00
plane_mat - > set_feature ( SpatialMaterial : : FEATURE_TRANSPARENT , true ) ;
plane_mat - > set_cull_mode ( SpatialMaterial : : CULL_DISABLED ) ;
2019-08-01 14:23:29 +02:00
plane_mat - > set_albedo ( col ) ;
2017-08-29 03:39:45 +02: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 14:23:29 +02: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 03:39:45 +02:00
}
2017-09-21 23:11:56 +02:00
// Rotate
2014-02-10 02:10:30 +01:00
{
2017-03-05 16:44:50 +01:00
Ref < SurfaceTool > surftool = memnew ( SurfaceTool ) ;
2014-02-10 02:10:30 +01:00
surftool - > begin ( Mesh : : PRIMITIVE_TRIANGLES ) ;
2017-03-05 16:44:50 +01:00
Vector3 circle [ 5 ] = {
2017-08-29 03:39:45 +02: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 02:10:30 +01:00
} ;
2018-08-09 16:34:18 +02:00
for ( int k = 0 ; k < 64 ; k + + ) {
2014-02-10 02:10:30 +01:00
2018-08-09 16:34:18 +02:00
Basis ma ( ivec , Math_PI * 2 * float ( k ) / 64 ) ;
Basis mb ( ivec , Math_PI * 2 * float ( k + 1 ) / 64 ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int j = 0 ; j < 4 ; j + + ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Vector3 points [ 4 ] = {
2014-02-10 02:10:30 +01:00
ma . xform ( circle [ j ] ) ,
mb . xform ( circle [ j ] ) ,
2017-03-05 16:44:50 +01:00
mb . xform ( circle [ j + 1 ] ) ,
ma . xform ( circle [ j + 1 ] ) ,
2014-02-10 02:10:30 +01: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 23:11:56 +02:00
// Scale
{
Ref < SurfaceTool > surftool = memnew ( SurfaceTool ) ;
surftool - > begin ( Mesh : : PRIMITIVE_TRIANGLES ) ;
2014-05-05 03:50:23 +02:00
2017-09-21 23:11:56 +02: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 02:10:30 +01:00
2017-09-21 23:11:56 +02:00
int arrow_sides = 4 ;
for ( int k = 0 ; k < 4 ; k + + ) {
2014-02-10 02:10:30 +01:00
2017-09-21 23:11:56 +02: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 02:10:30 +01:00
2017-09-21 23:11:56 +02: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 23:50:19 +01: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 14:23:29 +02:00
plane_mat - > set_albedo ( col ) ;
2017-11-14 23:50:19 +01: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 14:23:29 +02: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 23:50:19 +01:00
}
2017-09-21 23:11:56 +02:00
}
}
_generate_selection_box ( ) ;
2014-02-10 02:10:30 +01:00
}
2018-10-29 11:30:28 +01:00
void SpatialEditor : : _update_gizmos_menu ( ) {
2018-07-25 00:08:49 +02:00
2018-10-29 11:30:28 +01:00
gizmos_menu - > clear ( ) ;
2018-07-25 00:08:49 +02:00
2019-03-12 00:30:50 +01: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 ) ;
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-25 00:08:49 +02:00
}
}
2019-02-15 18:32:38 +01:00
void SpatialEditor : : _update_gizmos_menu_theme ( ) {
2019-03-12 00:30:50 +01: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 18:32:38 +01:00
}
}
2017-12-08 23:45:33 +01:00
void SpatialEditor : : _init_grid ( ) {
PoolVector < Color > grid_colors [ 3 ] ;
PoolVector < Vector3 > grid_points [ 3 ] ;
2018-04-30 01:43:20 +02: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 23:45:33 +01: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-30 01:43:20 +02:00
for ( int j = - grid_size ; j < = grid_size ; j + + ) {
Vector3 p1 = axis_n1 * j + axis_n2 * - grid_size ;
2017-12-08 23:45:33 +01:00
Vector3 p1_dest = p1 * ( - axis_n2 + axis_n1 ) ;
2018-04-30 01:43:20 +02:00
Vector3 p2 = axis_n2 * j + axis_n1 * - grid_size ;
2017-12-08 23:45:33 +01:00
Vector3 p2_dest = p2 * ( - axis_n1 + axis_n2 ) ;
2018-04-30 01:43:20 +02:00
Color line_color = secondary_grid_color ;
2018-08-17 23:21:08 +02: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-30 01:43:20 +02:00
line_color = primary_grid_color ;
2017-12-08 23:45:33 +01: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 02:10:30 +01:00
void SpatialEditor : : _finish_indicators ( ) {
VisualServer : : get_singleton ( ) - > free ( origin_instance ) ;
VisualServer : : get_singleton ( ) - > free ( origin ) ;
2017-12-08 23:45:33 +01:00
_finish_grid ( ) ;
}
void SpatialEditor : : _finish_grid ( ) {
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 3 ; i + + ) {
2014-02-10 02:10:30 +01:00
VisualServer : : get_singleton ( ) - > free ( grid_instance [ i ] ) ;
VisualServer : : get_singleton ( ) - > free ( grid [ i ] ) ;
}
}
2017-05-07 22:59:05 +02: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 21:21:15 +02:00
void SpatialEditor : : _refresh_menu_icons ( ) {
bool all_locked = true ;
2019-04-17 18:24:28 +02:00
bool all_grouped = true ;
2017-10-23 21:21:15 +02:00
List < Node * > & selection = editor_selection - > get_selected_node_list ( ) ;
if ( selection . empty ( ) ) {
all_locked = false ;
2019-04-17 18:24:28 +02:00
all_grouped = false ;
2017-10-23 21:21:15 +02: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 18:24:28 +02: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 21:21:15 +02: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 18:24:28 +02: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 21:21:15 +02:00
}
2018-07-26 08:34:40 +02: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-18 01:42:42 +02:00
from = from + Vector3 ( 0.0 , 0.2 , 0.0 ) ;
2018-07-26 08:34:40 +02: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-18 01:42:42 +02:00
// The maximum height an object can travel to be snapped
const float max_snap_height = 20.0 ;
// Will be set to `true` if at least one node from the selection was sucessfully snapped
bool snapped_to_floor = false ;
2018-07-26 08:34:40 +02:00
2019-08-18 01:42:42 +02: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 08:34:40 +02: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-18 01:42:42 +02:00
Vector3 to = from - Vector3 ( 0.0 , max_snap_height , 0.0 ) ;
2018-07-26 08:34:40 +02:00
Set < RID > excluded = _get_physics_bodies_rid ( sp ) ;
if ( ss - > intersect_ray ( from , to , result , excluded ) ) {
2019-08-18 01:42:42 +02:00
snapped_to_floor = true ;
2018-07-26 08:34:40 +02:00
}
}
2019-08-18 01:42:42 +02: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 08:34:40 +02:00
}
}
2017-05-20 17:38:03 +02:00
void SpatialEditor : : _unhandled_key_input ( Ref < InputEvent > p_event ) {
2014-02-10 02:10:30 +01:00
2017-01-13 14:45:50 +01:00
if ( ! is_visible_in_tree ( ) | | get_viewport ( ) - > gui_has_modal_stack ( ) )
2014-02-10 02:10:30 +01:00
return ;
2018-02-21 15:14:26 +01:00
snap_key_enabled = Input : : get_singleton ( ) - > is_key_pressed ( KEY_CONTROL ) ;
2014-02-10 02:10:30 +01:00
}
void SpatialEditor : : _notification ( int p_what ) {
2017-03-05 16:44:50 +01:00
if ( p_what = = NOTIFICATION_READY ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01: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 21:21:15 +02: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 18:24:28 +02: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 02:10:30 +01:00
2017-11-18 19:51:37 +01: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-03-05 16:44:50 +01: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 02:10:30 +01:00
_menu_item_pressed ( MENU_VIEW_USE_1_VIEWPORT ) ;
2017-10-23 21:21:15 +02:00
_refresh_menu_icons ( ) ;
2017-03-05 16:44:50 +01:00
get_tree ( ) - > connect ( " node_removed " , this , " _node_removed " ) ;
2017-10-23 21:21:15 +02: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-02-15 18:32:38 +01:00
} else if ( p_what = = NOTIFICATION_ENTER_TREE ) {
2014-02-10 02:10:30 +01:00
2018-10-29 11:30:28 +01:00
_register_all_gizmos ( ) ;
_update_gizmos_menu ( ) ;
2014-02-10 02:10:30 +01:00
_init_indicators ( ) ;
2019-02-15 18:32:38 +01:00
} else if ( p_what = = NOTIFICATION_THEME_CHANGED ) {
_update_gizmos_menu_theme ( ) ;
} else if ( p_what = = NOTIFICATION_EXIT_TREE ) {
2014-02-10 02:10:30 +01:00
_finish_indicators ( ) ;
2019-02-15 18:32:38 +01:00
} else if ( p_what = = EditorSettings : : NOTIFICATION_EDITOR_SETTINGS_CHANGED ) {
2017-08-30 01:03:13 +02: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-11-18 19:51:37 +01: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-30 01:03:13 +02: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 23:45:33 +01:00
// Update grid color by rebuilding grid.
_finish_grid ( ) ;
_init_grid ( ) ;
2017-08-30 01:03:13 +02:00
}
2014-02-10 02:10:30 +01:00
}
void SpatialEditor : : add_control_to_menu_panel ( Control * p_control ) {
hbc_menu - > add_child ( p_control ) ;
}
2018-02-13 22:21:19 +01:00
void SpatialEditor : : remove_control_from_menu_panel ( Control * p_control ) {
hbc_menu - > remove_child ( p_control ) ;
}
2017-03-05 16:44:50 +01:00
void SpatialEditor : : set_can_preview ( Camera * p_preview ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 4 ; i + + ) {
2014-02-10 02:10:30 +01:00
viewports [ i ] - > set_can_preview ( p_preview ) ;
}
}
VSplitContainer * SpatialEditor : : get_shader_split ( ) {
return shader_split ;
}
2017-12-01 01:50:09 +01:00
HSplitContainer * SpatialEditor : : get_palette_split ( ) {
2014-02-10 02:10:30 +01:00
2017-12-01 01:50:09 +01:00
return palette_split ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
void SpatialEditor : : _request_gizmo ( Object * p_obj ) {
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
Spatial * sp = Object : : cast_to < Spatial > ( p_obj ) ;
2014-02-10 02:10:30 +01:00
if ( ! sp )
return ;
2017-08-26 05:40:45 +02: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 02:10:30 +01:00
2018-07-25 00:08:49 +02:00
Ref < EditorSpatialGizmo > seg ;
2014-02-10 02:10:30 +01:00
2019-03-12 00:30:50 +01: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 02:10:30 +01:00
2018-07-25 00:08:49 +02:00
if ( seg . is_valid ( ) ) {
sp - > set_gizmo ( seg ) ;
2014-05-05 03:50:23 +02:00
2018-07-25 00:08:49 +02:00
if ( sp = = selected ) {
seg - > set_selected ( true ) ;
selected - > update_gizmo ( ) ;
}
2014-05-05 03:50:23 +02:00
2018-07-25 00:08:49 +02:00
break ;
}
2014-05-05 03:50:23 +02:00
}
2014-02-10 02:10:30 +01:00
}
}
2017-03-05 16:44:50 +01:00
void SpatialEditor : : _toggle_maximize_view ( Object * p_viewport ) {
2014-04-01 12:45:48 +02:00
if ( ! p_viewport ) return ;
2017-08-24 22:58:51 +02:00
SpatialEditorViewport * current_viewport = Object : : cast_to < SpatialEditorViewport > ( p_viewport ) ;
2014-04-01 12:45:48 +02:00
if ( ! current_viewport ) return ;
2017-03-05 16:44:50 +01:00
int index = - 1 ;
2014-04-01 12:45:48 +02:00
bool maximized = false ;
2017-03-05 16:44:50 +01: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 12:45:48 +02:00
break ;
}
}
2017-03-05 16:44:50 +01:00
if ( index = = - 1 ) return ;
2014-04-01 12:45:48 +02:00
if ( ! maximized ) {
2017-08-31 23:30:35 +02:00
for ( uint32_t i = 0 ; i < VIEWPORTS_COUNT ; i + + ) {
if ( i = = ( uint32_t ) index )
2017-09-22 00:12:33 +02:00
viewports [ i ] - > set_anchors_and_margins_preset ( Control : : PRESET_WIDE ) ;
2014-04-01 12:45:48 +02:00
else
viewports [ i ] - > hide ( ) ;
}
} else {
2017-08-31 23:30:35 +02:00
for ( uint32_t i = 0 ; i < VIEWPORTS_COUNT ; i + + )
2014-04-01 12:45:48 +02:00
viewports [ i ] - > show ( ) ;
2017-03-05 16:44:50 +01:00
if ( view_menu - > get_popup ( ) - > is_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_USE_1_VIEWPORT ) ) )
2014-04-01 12:45:48 +02:00
_menu_item_pressed ( MENU_VIEW_USE_1_VIEWPORT ) ;
2017-03-05 16:44:50 +01: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 12:45:48 +02:00
_menu_item_pressed ( MENU_VIEW_USE_2_VIEWPORTS ) ;
2017-03-05 16:44:50 +01: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 05:06:51 +02:00
_menu_item_pressed ( MENU_VIEW_USE_2_VIEWPORTS_ALT ) ;
2017-03-05 16:44:50 +01: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 12:45:48 +02:00
_menu_item_pressed ( MENU_VIEW_USE_3_VIEWPORTS ) ;
2017-03-05 16:44:50 +01: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 05:06:51 +02:00
_menu_item_pressed ( MENU_VIEW_USE_3_VIEWPORTS_ALT ) ;
2017-03-05 16:44:50 +01: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 12:45:48 +02:00
_menu_item_pressed ( MENU_VIEW_USE_4_VIEWPORTS ) ;
}
}
2017-03-05 16:44:50 +01:00
void SpatialEditor : : _node_removed ( Node * p_node ) {
2014-05-05 03:50:23 +02:00
2017-03-05 16:44:50 +01:00
if ( p_node = = selected )
selected = NULL ;
2014-05-05 03:50:23 +02:00
}
2018-07-25 00:08:49 +02:00
void SpatialEditor : : _register_all_gizmos ( ) {
2018-10-29 11:30:28 +01: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 08:18:09 +02:00
add_gizmo_plugin ( Ref < CPUParticlesGizmoPlugin > ( memnew ( CPUParticlesGizmoPlugin ) ) ) ;
2018-10-29 11:30:28 +01: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-25 00:08:49 +02:00
}
2014-02-10 02:10:30 +01:00
void SpatialEditor : : _bind_methods ( ) {
2017-03-05 16:44:50 +01: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-25 00:08:49 +02:00
ClassDB : : bind_method ( " _menu_gizmo_toggled " , & SpatialEditor : : _menu_gizmo_toggled ) ;
2017-11-18 19:51:37 +01:00
ClassDB : : bind_method ( " _menu_item_toggled " , & SpatialEditor : : _menu_item_toggled ) ;
2017-03-05 16:44:50 +01: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 21:21:15 +02:00
ClassDB : : bind_method ( " _refresh_menu_icons " , & SpatialEditor : : _refresh_menu_icons ) ;
2014-04-01 12:45:48 +02:00
2017-03-05 16:44:50 +01:00
ADD_SIGNAL ( MethodInfo ( " transform_key_request " ) ) ;
2017-10-23 21:21:15 +02:00
ADD_SIGNAL ( MethodInfo ( " item_lock_status_changed " ) ) ;
2019-04-17 18:24:28 +02:00
ADD_SIGNAL ( MethodInfo ( " item_group_status_changed " ) ) ;
2014-09-19 23:39:50 +02:00
}
void SpatialEditor : : clear ( ) {
2017-11-25 23:03:26 +01: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 16:44:50 +01:00
settings_zfar - > set_value ( EDITOR_DEF ( " editors/3d/default_z_far " , 1500.0 ) ) ;
2014-09-19 23:39:50 +02:00
2017-08-31 23:30:35 +02:00
for ( uint32_t i = 0 ; i < VIEWPORTS_COUNT ; i + + ) {
2014-09-19 23:39:50 +02:00
viewports [ i ] - > reset ( ) ;
}
2017-03-05 16:44:50 +01: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 23:39:50 +02:00
if ( grid_enable [ i ] ) {
2017-03-05 16:44:50 +01:00
VisualServer : : get_singleton ( ) - > instance_set_visible ( grid_instance [ i ] , true ) ;
grid_visible [ i ] = true ;
2014-09-19 23:39:50 +02:00
}
}
2017-08-31 23:30:35 +02:00
for ( uint32_t i = 0 ; i < VIEWPORTS_COUNT ; i + + ) {
2014-10-03 05:10:51 +02:00
2017-03-05 16:44:50 +01: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 05:10:51 +02:00
}
2014-10-12 07:13:22 +02:00
2017-03-05 16:44:50 +01:00
view_menu - > get_popup ( ) - > set_item_checked ( view_menu - > get_popup ( ) - > get_item_index ( MENU_VIEW_GRID ) , true ) ;
2014-02-10 02:10:30 +01:00
}
SpatialEditor : : SpatialEditor ( EditorNode * p_editor ) {
2017-03-05 16:44:50 +01:00
gizmo . visible = true ;
gizmo . scale = 1.0 ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
viewport_environment = Ref < Environment > ( memnew ( Environment ) ) ;
undo_redo = p_editor - > get_undo_redo ( ) ;
2014-02-10 02:10:30 +01:00
VBoxContainer * vbc = this ;
2017-03-05 16:44:50 +01:00
custom_camera = NULL ;
singleton = this ;
editor = p_editor ;
editor_selection = editor - > get_editor_selection ( ) ;
2014-02-10 02:10:30 +01:00
editor_selection - > add_editor_plugin ( this ) ;
2017-03-05 16:44:50 +01:00
snap_enabled = false ;
2018-02-21 15:14:26 +01:00
snap_key_enabled = false ;
2014-02-10 02:10:30 +01:00
tool_mode = TOOL_MODE_SELECT ;
2017-03-05 16:44:50 +01:00
hbc_menu = memnew ( HBoxContainer ) ;
2014-02-10 02:10:30 +01:00
vbc - > add_child ( hbc_menu ) ;
Vector < Variant > button_binds ;
button_binds . resize ( 1 ) ;
2017-11-18 19:51:37 +01:00
String sct ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
tool_button [ TOOL_MODE_SELECT ] = memnew ( ToolButton ) ;
hbc_menu - > add_child ( tool_button [ TOOL_MODE_SELECT ] ) ;
2014-02-10 02:10:30 +01: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 03:11:03 +02:00
button_binds . write [ 0 ] = MENU_TOOL_SELECT ;
2017-03-05 16:44:50 +01:00
tool_button [ TOOL_MODE_SELECT ] - > connect ( " pressed " , this , " _menu_item_pressed " , button_binds ) ;
2019-08-17 23:37:13 +02: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 02:10:30 +01:00
2018-09-15 17:44:26 +02:00
hbc_menu - > add_child ( memnew ( VSeparator ) ) ;
2017-03-05 16:44:50 +01:00
tool_button [ TOOL_MODE_MOVE ] = memnew ( ToolButton ) ;
hbc_menu - > add_child ( tool_button [ TOOL_MODE_MOVE ] ) ;
2014-02-10 02:10:30 +01:00
tool_button [ TOOL_MODE_MOVE ] - > set_toggle_mode ( true ) ;
tool_button [ TOOL_MODE_MOVE ] - > set_flat ( true ) ;
2018-07-25 03:11:03 +02:00
button_binds . write [ 0 ] = MENU_TOOL_MOVE ;
2017-03-05 16:44:50 +01:00
tool_button [ TOOL_MODE_MOVE ] - > connect ( " pressed " , this , " _menu_item_pressed " , button_binds ) ;
2019-08-17 23:37:13 +02:00
tool_button [ TOOL_MODE_MOVE ] - > set_shortcut ( ED_SHORTCUT ( " spatial_editor/tool_move " , TTR ( " Move Mode " ) , KEY_W ) ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
tool_button [ TOOL_MODE_ROTATE ] = memnew ( ToolButton ) ;
hbc_menu - > add_child ( tool_button [ TOOL_MODE_ROTATE ] ) ;
2014-02-10 02:10:30 +01:00
tool_button [ TOOL_MODE_ROTATE ] - > set_toggle_mode ( true ) ;
tool_button [ TOOL_MODE_ROTATE ] - > set_flat ( true ) ;
2018-07-25 03:11:03 +02:00
button_binds . write [ 0 ] = MENU_TOOL_ROTATE ;
2017-03-05 16:44:50 +01:00
tool_button [ TOOL_MODE_ROTATE ] - > connect ( " pressed " , this , " _menu_item_pressed " , button_binds ) ;
2019-08-17 23:37:13 +02:00
tool_button [ TOOL_MODE_ROTATE ] - > set_shortcut ( ED_SHORTCUT ( " spatial_editor/tool_rotate " , TTR ( " Rotate Mode " ) , KEY_E ) ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
tool_button [ TOOL_MODE_SCALE ] = memnew ( ToolButton ) ;
hbc_menu - > add_child ( tool_button [ TOOL_MODE_SCALE ] ) ;
2014-02-10 02:10:30 +01:00
tool_button [ TOOL_MODE_SCALE ] - > set_toggle_mode ( true ) ;
tool_button [ TOOL_MODE_SCALE ] - > set_flat ( true ) ;
2018-07-25 03:11:03 +02:00
button_binds . write [ 0 ] = MENU_TOOL_SCALE ;
2017-03-05 16:44:50 +01:00
tool_button [ TOOL_MODE_SCALE ] - > connect ( " pressed " , this , " _menu_item_pressed " , button_binds ) ;
2019-08-17 23:37:13 +02:00
tool_button [ TOOL_MODE_SCALE ] - > set_shortcut ( ED_SHORTCUT ( " spatial_editor/tool_scale " , TTR ( " Scale Mode " ) , KEY_R ) ) ;
2014-02-10 02:10:30 +01:00
2018-09-15 17:44:26 +02:00
hbc_menu - > add_child ( memnew ( VSeparator ) ) ;
2017-03-05 16:44:50 +01:00
tool_button [ TOOL_MODE_LIST_SELECT ] = memnew ( ToolButton ) ;
hbc_menu - > add_child ( tool_button [ TOOL_MODE_LIST_SELECT ] ) ;
2015-12-13 21:16:13 +01:00
tool_button [ TOOL_MODE_LIST_SELECT ] - > set_toggle_mode ( true ) ;
tool_button [ TOOL_MODE_LIST_SELECT ] - > set_flat ( true ) ;
2018-07-25 03:11:03 +02:00
button_binds . write [ 0 ] = MENU_TOOL_LIST_SELECT ;
2017-03-05 16:44:50 +01:00
tool_button [ TOOL_MODE_LIST_SELECT ] - > connect ( " pressed " , this , " _menu_item_pressed " , button_binds ) ;
2016-06-01 13:32:20 +02: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 21:16:13 +01:00
2017-10-23 21:21:15 +02:00
tool_button [ TOOL_LOCK_SELECTED ] = memnew ( ToolButton ) ;
hbc_menu - > add_child ( tool_button [ TOOL_LOCK_SELECTED ] ) ;
2018-07-25 03:11:03 +02:00
button_binds . write [ 0 ] = MENU_LOCK_SELECTED ;
2017-10-23 21:21:15 +02: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 03:11:03 +02:00
button_binds . write [ 0 ] = MENU_UNLOCK_SELECTED ;
2017-10-23 21:21:15 +02: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 18:24:28 +02: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 17:44:26 +02:00
hbc_menu - > add_child ( memnew ( VSeparator ) ) ;
2017-11-18 19:51:37 +01: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 03:11:03 +02:00
button_binds . write [ 0 ] = MENU_TOOL_LOCAL_COORDS ;
2017-11-18 19:51:37 +01:00
tool_option_button [ TOOL_OPT_LOCAL_COORDS ] - > connect ( " toggled " , this , " _menu_item_toggled " , button_binds ) ;
2019-08-17 23:37:13 +02: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 19:51:37 +01: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 03:11:03 +02:00
button_binds . write [ 0 ] = MENU_TOOL_USE_SNAP ;
2017-11-18 19:51:37 +01:00
tool_option_button [ TOOL_OPT_USE_SNAP ] - > connect ( " toggled " , this , " _menu_item_toggled " , button_binds ) ;
2019-08-17 23:37:13 +02:00
tool_option_button [ TOOL_OPT_USE_SNAP ] - > set_shortcut ( ED_SHORTCUT ( " spatial_editor/snap " , TTR ( " Use Snap " ) , KEY_Y ) ) ;
2017-11-18 19:51:37 +01:00
2018-09-15 17:44:26 +02:00
hbc_menu - > add_child ( memnew ( VSeparator ) ) ;
2015-12-13 21:16:13 +01:00
2017-09-02 21:47:16 +02:00
// Drag and drop support;
preview_node = memnew ( Spatial ) ;
2017-11-17 03:09:00 +01:00
preview_bounds = AABB ( ) ;
2017-09-02 21:47:16 +02:00
2017-03-05 16:44:50 +01:00
ED_SHORTCUT ( " spatial_editor/bottom_view " , TTR ( " Bottom View " ) , KEY_MASK_ALT + KEY_KP_7 ) ;
2016-06-30 22:54:34 +02:00
ED_SHORTCUT ( " spatial_editor/top_view " , TTR ( " Top View " ) , KEY_KP_7 ) ;
2017-03-05 16:44:50 +01:00
ED_SHORTCUT ( " spatial_editor/rear_view " , TTR ( " Rear View " ) , KEY_MASK_ALT + KEY_KP_1 ) ;
2016-06-30 22:54:34 +02:00
ED_SHORTCUT ( " spatial_editor/front_view " , TTR ( " Front View " ) , KEY_KP_1 ) ;
2017-03-05 16:44:50 +01:00
ED_SHORTCUT ( " spatial_editor/left_view " , TTR ( " Left View " ) , KEY_MASK_ALT + KEY_KP_3 ) ;
2016-06-30 22:54:34 +02:00
ED_SHORTCUT ( " spatial_editor/right_view " , TTR ( " Right View " ) , KEY_KP_3 ) ;
2019-05-19 23:08:07 +02:00
ED_SHORTCUT ( " spatial_editor/switch_perspective_orthogonal " , TTR ( " Switch Perspective/Orthogonal View " ) , KEY_KP_5 ) ;
2016-06-30 22:54:34 +02:00
ED_SHORTCUT ( " spatial_editor/insert_anim_key " , TTR ( " Insert Animation Key " ) , KEY_K ) ;
2016-10-04 20:39:38 +02:00
ED_SHORTCUT ( " spatial_editor/focus_origin " , TTR ( " Focus Origin " ) , KEY_O ) ;
2016-06-30 22:54:34 +02:00
ED_SHORTCUT ( " spatial_editor/focus_selection " , TTR ( " Focus Selection " ) , KEY_F ) ;
2018-10-27 23:43:19 +02: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 01:22:48 +01:00
ED_SHORTCUT ( " spatial_editor/freelook_toggle " , TTR ( " Toggle Freelook " ) , KEY_MASK_SHIFT + KEY_F ) ;
2014-02-10 02:10:30 +01:00
PopupMenu * p ;
2017-03-05 16:44:50 +01:00
transform_menu = memnew ( MenuButton ) ;
2016-05-30 20:47:53 +02:00
transform_menu - > set_text ( TTR ( " Transform " ) ) ;
2018-07-30 00:26:43 +02:00
transform_menu - > set_switch_on_hover ( true ) ;
2017-03-05 16:44:50 +01:00
hbc_menu - > add_child ( transform_menu ) ;
2014-02-10 02:10:30 +01:00
p = transform_menu - > get_popup ( ) ;
2019-05-19 23:08:07 +02: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 19:36:01 +02:00
p - > add_shortcut ( ED_SHORTCUT ( " spatial_editor/transform_dialog " , TTR ( " Transform Dialog... " ) ) , MENU_TRANSFORM_DIALOG ) ;
2014-02-10 02:10:30 +01:00
2019-08-12 22:23:00 +02:00
p - > add_separator ( ) ;
p - > add_shortcut ( ED_SHORTCUT ( " spatial_editor/configure_snap " , TTR ( " Configure Snap... " ) ) , MENU_TRANSFORM_CONFIGURE_SNAP ) ;
2017-03-05 16:44:50 +01:00
p - > connect ( " id_pressed " , this , " _menu_item_pressed " ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
view_menu = memnew ( MenuButton ) ;
2016-05-04 03:25:37 +02:00
view_menu - > set_text ( TTR ( " View " ) ) ;
2018-07-30 00:26:43 +02:00
view_menu - > set_switch_on_hover ( true ) ;
2017-03-05 16:44:50 +01:00
hbc_menu - > add_child ( view_menu ) ;
2014-02-10 02:10:30 +01:00
p = view_menu - > get_popup ( ) ;
2017-09-02 21:47:16 +02:00
accept = memnew ( AcceptDialog ) ;
editor - > get_gui_base ( ) - > add_child ( accept ) ;
2018-03-24 03:05:20 +01: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 02:10:30 +01:00
p - > add_separator ( ) ;
2018-08-11 23:07:00 +02:00
p - > add_submenu_item ( TTR ( " Gizmos " ) , " GizmosMenu " ) ;
2018-08-12 15:20:20 +02:00
p - > add_separator ( ) ;
2016-06-30 22:54:34 +02: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 22:23:00 +02:00
2014-02-10 02:10:30 +01:00
p - > add_separator ( ) ;
2019-08-12 22:23:00 +02:00
p - > add_shortcut ( ED_SHORTCUT ( " spatial_editor/settings " , TTR ( " Settings... " ) ) , MENU_VIEW_CAMERA_SETTINGS ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
p - > connect ( " id_pressed " , this , " _menu_item_pressed " ) ;
2014-02-10 02:10:30 +01:00
2018-08-11 23:07:00 +02: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-25 00:08:49 +02:00
2014-02-10 02:10:30 +01:00
/* REST OF MENU */
2017-03-05 16:44:50 +01:00
palette_split = memnew ( HSplitContainer ) ;
2014-02-10 02:10:30 +01:00
palette_split - > set_v_size_flags ( SIZE_EXPAND_FILL ) ;
vbc - > add_child ( palette_split ) ;
2017-03-05 16:44:50 +01:00
shader_split = memnew ( VSplitContainer ) ;
2014-02-10 02:10:30 +01:00
shader_split - > set_h_size_flags ( SIZE_EXPAND_FILL ) ;
palette_split - > add_child ( shader_split ) ;
2017-06-11 16:29:27 +02:00
viewport_base = memnew ( SpatialEditorViewportContainer ) ;
2014-02-10 02:10:30 +01:00
shader_split - > add_child ( viewport_base ) ;
viewport_base - > set_v_size_flags ( SIZE_EXPAND_FILL ) ;
2017-08-31 23:30:35 +02:00
for ( uint32_t i = 0 ; i < VIEWPORTS_COUNT ; i + + ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
viewports [ i ] = memnew ( SpatialEditorViewport ( this , editor , i ) ) ;
viewports [ i ] - > connect ( " toggle_maximize_view " , this , " _toggle_maximize_view " ) ;
2017-09-02 21:47:16 +02:00
viewports [ i ] - > assign_pending_data_pointers ( preview_node , & preview_bounds , accept ) ;
2014-02-10 02:10:30 +01:00
viewport_base - > add_child ( viewports [ i ] ) ;
}
/* SNAP DIALOG */
2017-03-05 16:44:50 +01:00
snap_dialog = memnew ( ConfirmationDialog ) ;
2016-05-04 03:25:37 +02:00
snap_dialog - > set_title ( TTR ( " Snap Settings " ) ) ;
2014-02-10 02:10:30 +01:00
add_child ( snap_dialog ) ;
2015-10-18 18:31:44 +02:00
2017-03-05 16:44:50 +01:00
VBoxContainer * snap_dialog_vbc = memnew ( VBoxContainer ) ;
2015-10-18 18:31:44 +02:00
snap_dialog - > add_child ( snap_dialog_vbc ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
snap_translate = memnew ( LineEdit ) ;
2014-02-10 02:10:30 +01:00
snap_translate - > set_text ( " 1 " ) ;
2017-03-05 16:44:50 +01:00
snap_dialog_vbc - > add_margin_child ( TTR ( " Translate Snap: " ) , snap_translate ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
snap_rotate = memnew ( LineEdit ) ;
2019-04-09 17:55:44 +02:00
snap_rotate - > set_text ( " 15 " ) ;
2017-03-05 16:44:50 +01:00
snap_dialog_vbc - > add_margin_child ( TTR ( " Rotate Snap (deg.): " ) , snap_rotate ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
snap_scale = memnew ( LineEdit ) ;
2019-04-09 17:55:44 +02:00
snap_scale - > set_text ( " 10 " ) ;
2017-03-05 16:44:50 +01:00
snap_dialog_vbc - > add_margin_child ( TTR ( " Scale Snap (%): " ) , snap_scale ) ;
2014-02-10 02:10:30 +01:00
2015-10-18 18:31:44 +02:00
/* SETTINGS DIALOG */
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
settings_dialog = memnew ( ConfirmationDialog ) ;
2016-05-04 03:25:37 +02:00
settings_dialog - > set_title ( TTR ( " Viewport Settings " ) ) ;
2014-02-10 02:10:30 +01:00
add_child ( settings_dialog ) ;
2017-03-05 16:44:50 +01:00
settings_vbc = memnew ( VBoxContainer ) ;
2017-08-04 13:23:10 +02:00
settings_vbc - > set_custom_minimum_size ( Size2 ( 200 , 0 ) * EDSCALE ) ;
2014-10-12 07:13:22 +02:00
settings_dialog - > add_child ( settings_vbc ) ;
2017-03-05 16:44:50 +01:00
settings_fov = memnew ( SpinBox ) ;
2017-08-04 13:23:10 +02:00
settings_fov - > set_max ( MAX_FOV ) ;
settings_fov - > set_min ( MIN_FOV ) ;
2014-10-12 07:13:22 +02:00
settings_fov - > set_step ( 0.01 ) ;
2017-11-25 23:03:26 +01:00
settings_fov - > set_value ( EDITOR_DEF ( " editors/3d/default_fov " , 70.0 ) ) ;
2017-03-05 16:44:50 +01:00
settings_vbc - > add_margin_child ( TTR ( " Perspective FOV (deg.): " ) , settings_fov ) ;
2014-10-12 07:13:22 +02:00
2017-03-05 16:44:50 +01:00
settings_znear = memnew ( SpinBox ) ;
2017-08-04 13:23:10 +02:00
settings_znear - > set_max ( MAX_Z ) ;
settings_znear - > set_min ( MIN_Z ) ;
2014-10-12 07:13:22 +02:00
settings_znear - > set_step ( 0.01 ) ;
2017-11-25 23:03:26 +01:00
settings_znear - > set_value ( EDITOR_DEF ( " editors/3d/default_z_near " , 0.05 ) ) ;
2017-03-05 16:44:50 +01:00
settings_vbc - > add_margin_child ( TTR ( " View Z-Near: " ) , settings_znear ) ;
2014-10-12 07:13:22 +02:00
2017-03-05 16:44:50 +01:00
settings_zfar = memnew ( SpinBox ) ;
2017-08-04 13:23:10 +02:00
settings_zfar - > set_max ( MAX_Z ) ;
settings_zfar - > set_min ( MIN_Z ) ;
2014-10-12 07:13:22 +02:00
settings_zfar - > set_step ( 0.01 ) ;
2017-03-05 16:44:50 +01: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 02:10:30 +01:00
/* XFORM DIALOG */
2017-03-05 16:44:50 +01:00
xform_dialog = memnew ( ConfirmationDialog ) ;
2016-05-04 03:25:37 +02:00
xform_dialog - > set_title ( TTR ( " Transform Change " ) ) ;
2014-02-10 02:10:30 +01:00
add_child ( xform_dialog ) ;
2017-07-31 15:00:02 +02:00
VBoxContainer * xform_vbc = memnew ( VBoxContainer ) ;
xform_dialog - > add_child ( xform_vbc ) ;
2015-10-18 18:31:44 +02:00
Label * l = memnew ( Label ) ;
2016-05-04 03:25:37 +02:00
l - > set_text ( TTR ( " Translate: " ) ) ;
2017-07-31 15:00:02 +02:00
xform_vbc - > add_child ( l ) ;
HBoxContainer * xform_hbc = memnew ( HBoxContainer ) ;
xform_vbc - > add_child ( xform_hbc ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 3 ; i + + ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
xform_translate [ i ] = memnew ( LineEdit ) ;
2017-07-31 15:00:02 +02:00
xform_translate [ i ] - > set_h_size_flags ( SIZE_EXPAND_FILL ) ;
xform_hbc - > add_child ( xform_translate [ i ] ) ;
2014-02-10 02:10:30 +01:00
}
l = memnew ( Label ) ;
2016-05-04 03:25:37 +02:00
l - > set_text ( TTR ( " Rotate (deg.): " ) ) ;
2017-07-31 15:00:02 +02:00
xform_vbc - > add_child ( l ) ;
xform_hbc = memnew ( HBoxContainer ) ;
xform_vbc - > add_child ( xform_hbc ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 3 ; i + + ) {
xform_rotate [ i ] = memnew ( LineEdit ) ;
2017-07-31 15:00:02 +02:00
xform_rotate [ i ] - > set_h_size_flags ( SIZE_EXPAND_FILL ) ;
xform_hbc - > add_child ( xform_rotate [ i ] ) ;
2014-02-10 02:10:30 +01:00
}
l = memnew ( Label ) ;
2016-05-04 03:25:37 +02:00
l - > set_text ( TTR ( " Scale (ratio): " ) ) ;
2017-07-31 15:00:02 +02:00
xform_vbc - > add_child ( l ) ;
xform_hbc = memnew ( HBoxContainer ) ;
xform_vbc - > add_child ( xform_hbc ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 3 ; i + + ) {
xform_scale [ i ] = memnew ( LineEdit ) ;
2017-07-31 15:00:02 +02:00
xform_scale [ i ] - > set_h_size_flags ( SIZE_EXPAND_FILL ) ;
xform_hbc - > add_child ( xform_scale [ i ] ) ;
2014-02-10 02:10:30 +01:00
}
l = memnew ( Label ) ;
2016-05-04 03:25:37 +02:00
l - > set_text ( TTR ( " Transform Type " ) ) ;
2017-07-31 15:00:02 +02:00
xform_vbc - > add_child ( l ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
xform_type = memnew ( OptionButton ) ;
2017-07-31 15:00:02 +02:00
xform_type - > set_h_size_flags ( SIZE_EXPAND_FILL ) ;
2016-05-04 03:25:37 +02:00
xform_type - > add_item ( TTR ( " Pre " ) ) ;
xform_type - > add_item ( TTR ( " Post " ) ) ;
2017-07-31 15:00:02 +02:00
xform_vbc - > add_child ( xform_type ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
xform_dialog - > connect ( " confirmed " , this , " _xform_dialog_action " ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
scenario_debug = VisualServer : : SCENARIO_DEBUG_DISABLED ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
selected = NULL ;
2014-02-10 02:10:30 +01:00
2014-04-10 05:18:27 +02:00
set_process_unhandled_key_input ( true ) ;
2014-02-10 02:10:30 +01:00
add_to_group ( " _spatial_editor_group " ) ;
2014-05-05 03:50:23 +02:00
2017-03-05 16:44:50 +01: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 14:23:29 +02: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 " ) ) ;
2014-05-05 03:50:23 +02:00
2017-03-05 16:44:50 +01:00
over_gizmo_handle = - 1 ;
2014-02-10 02:10:30 +01:00
}
SpatialEditor : : ~ SpatialEditor ( ) {
2017-09-02 21:47:16 +02:00
memdelete ( preview_node ) ;
2014-02-10 02:10:30 +01:00
}
void SpatialEditorPlugin : : make_visible ( bool p_visible ) {
if ( p_visible ) {
2016-03-09 00:00:52 +01:00
2014-02-10 02:10:30 +01:00
spatial_editor - > show ( ) ;
spatial_editor - > set_process ( true ) ;
} else {
2016-03-09 00:00:52 +01:00
2014-02-10 02:10:30 +01:00
spatial_editor - > hide ( ) ;
spatial_editor - > set_process ( false ) ;
}
}
void SpatialEditorPlugin : : edit ( Object * p_object ) {
2014-05-05 03:50:23 +02:00
2017-08-24 22:58:51 +02:00
spatial_editor - > edit ( Object : : cast_to < Spatial > ( p_object ) ) ;
2014-02-10 02:10:30 +01:00
}
bool SpatialEditorPlugin : : handles ( Object * p_object ) const {
2016-03-09 00:00:52 +01:00
2017-01-03 03:03:46 +01:00
return p_object - > is_class ( " Spatial " ) ;
2014-02-10 02:10:30 +01:00
}
Dictionary SpatialEditorPlugin : : get_state ( ) const {
return spatial_editor - > get_state ( ) ;
}
2017-03-05 16:44:50 +01:00
void SpatialEditorPlugin : : set_state ( const Dictionary & p_state ) {
2014-02-10 02:10:30 +01:00
spatial_editor - > set_state ( p_state ) ;
}
2017-03-05 16:44:50 +01:00
void SpatialEditor : : snap_cursor_to_plane ( const Plane & p_plane ) {
2014-02-10 02:10:30 +01:00
2017-01-14 12:26:56 +01:00
//cursor.pos=p_plane.project(cursor.pos);
2014-02-10 02:10:30 +01:00
}
2017-09-18 23:44:04 +02: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 17:55:44 +02: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 02:10:30 +01:00
void SpatialEditorPlugin : : _bind_methods ( ) {
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( " snap_cursor_to_plane " , & SpatialEditorPlugin : : snap_cursor_to_plane ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
void SpatialEditorPlugin : : snap_cursor_to_plane ( const Plane & p_plane ) {
2014-02-10 02:10:30 +01:00
spatial_editor - > snap_cursor_to_plane ( p_plane ) ;
}
2019-03-12 00:30:50 +01: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 11:30:28 +01:00
void SpatialEditor : : add_gizmo_plugin ( Ref < EditorSpatialGizmoPlugin > p_plugin ) {
2019-01-25 12:57:32 +01:00
ERR_FAIL_NULL ( p_plugin . ptr ( ) ) ;
2019-03-12 00:30:50 +01: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 11:30:28 +01:00
_update_gizmos_menu ( ) ;
SpatialEditor : : get_singleton ( ) - > update_all_gizmos ( ) ;
}
void SpatialEditor : : remove_gizmo_plugin ( Ref < EditorSpatialGizmoPlugin > p_plugin ) {
2019-03-12 00:30:50 +01:00
gizmo_plugins_by_priority . erase ( p_plugin ) ;
gizmo_plugins_by_name . erase ( p_plugin ) ;
2018-10-29 11:30:28 +01:00
_update_gizmos_menu ( ) ;
2018-07-25 00:08:49 +02:00
}
2014-02-10 02:10:30 +01:00
SpatialEditorPlugin : : SpatialEditorPlugin ( EditorNode * p_node ) {
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
editor = p_node ;
spatial_editor = memnew ( SpatialEditor ( p_node ) ) ;
2016-02-08 17:01:54 +01:00
spatial_editor - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2014-02-10 02:10:30 +01:00
editor - > get_viewport ( ) - > add_child ( spatial_editor ) ;
2016-02-08 17:01:54 +01:00
2014-02-10 02:10:30 +01:00
spatial_editor - > hide ( ) ;
2019-04-14 22:27:59 +02:00
spatial_editor - > connect ( " transform_key_request " , editor - > get_inspector_dock ( ) , " _transform_keyed " ) ;
2014-02-10 02:10:30 +01:00
}
SpatialEditorPlugin : : ~ SpatialEditorPlugin ( ) {
}
2018-07-25 00:08:49 +02: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 22:31:03 +02:00
Color instanced_color = EDITOR_DEF ( " editors/3d_gizmos/gizmo_colors/instanced " , Color ( 0.7 , 0.7 , 0.7 , 0.6 ) ) ;
2018-07-25 00:08:49 +02: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 23:07:00 +02:00
material - > set_render_priority ( SpatialMaterial : : RENDER_PRIORITY_MIN + 1 ) ;
2018-07-25 00:08:49 +02: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 22:31:03 +02:00
Color instanced_color = EDITOR_DEF ( " editors/3d_gizmos/gizmo_colors/instanced " , Color ( 0.7 , 0.7 , 0.7 , 0.6 ) ) ;
2018-07-25 00:08:49 +02: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 22:31:03 +02:00
color . a * = 0.85 ;
2018-07-25 00:08:49 +02:00
}
icon - > set_albedo ( color ) ;
icon - > set_flag ( SpatialMaterial : : FLAG_UNSHADED , true ) ;
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 23:07:00 +02:00
icon - > set_render_priority ( SpatialMaterial : : RENDER_PRIORITY_MIN ) ;
2018-07-25 00:08:49 +02: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 11:30:28 +01:00
Ref < SpatialMaterial > EditorSpatialGizmoPlugin : : get_material ( const String & p_name , const Ref < EditorSpatialGizmo > & p_gizmo ) {
2018-07-25 00:08:49 +02: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 12:57:32 +01:00
if ( p_gizmo . is_null ( ) | | materials [ p_name ] . size ( ) = = 1 ) return materials [ p_name ] [ 0 ] ;
2018-07-25 00:08:49 +02:00
int index = ( p_gizmo - > is_selected ( ) ? 1 : 0 ) + ( p_gizmo - > is_editable ( ) ? 2 : 0 ) ;
2018-08-11 23:07:00 +02: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-25 00:08:49 +02:00
}
2018-10-29 11:30:28 +01: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 12:57:32 +01:00
return TTR ( " Nameless gizmo " ) ;
2018-10-29 11:30:28 +01:00
}
2019-03-12 00:30:50 +01: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-25 00:08:49 +02:00
Ref < EditorSpatialGizmo > EditorSpatialGizmoPlugin : : get_gizmo ( Spatial * p_spatial ) {
2018-10-29 11:30:28 +01:00
if ( get_script_instance ( ) & & get_script_instance ( ) - > has_method ( " get_gizmo " ) ) {
return get_script_instance ( ) - > call ( " get_gizmo " , p_spatial ) ;
}
2018-07-25 00:08:49 +02: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 23:07:00 +02:00
ref - > set_hidden ( current_state = = HIDDEN ) ;
2018-07-25 00:08:49 +02:00
current_gizmos . push_back ( ref . ptr ( ) ) ;
return ref ;
}
2018-10-29 11:30:28 +01: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-12 00:30:50 +01:00
BIND_VMETHOD ( MethodInfo ( Variant : : STRING , " get_priority " ) ) ;
2018-10-29 11:30:28 +01: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 12:57:32 +01:00
BIND_VMETHOD ( MethodInfo ( Variant : : BOOL , " is_handle_highlighted " , GIZMO_REF , PropertyInfo ( Variant : : INT , " index " ) ) ) ;
2018-10-29 11:30:28 +01:00
# undef GIZMO_REF
}
2018-07-25 00:08:49 +02:00
bool EditorSpatialGizmoPlugin : : has_gizmo ( Spatial * p_spatial ) {
2018-10-29 11:30:28 +01:00
if ( get_script_instance ( ) & & get_script_instance ( ) - > has_method ( " has_gizmo " ) ) {
return get_script_instance ( ) - > call ( " has_gizmo " , p_spatial ) ;
}
2018-07-25 00:08:49 +02:00
return false ;
}
Ref < EditorSpatialGizmo > EditorSpatialGizmoPlugin : : create_gizmo ( Spatial * p_spatial ) {
2018-10-29 11:30:28 +01:00
if ( get_script_instance ( ) & & get_script_instance ( ) - > has_method ( " create_gizmo " ) ) {
return get_script_instance ( ) - > call ( " create_gizmo " , p_spatial ) ;
}
2018-07-25 00:08:49 +02:00
Ref < EditorSpatialGizmo > ref ;
if ( has_gizmo ( p_spatial ) ) ref . instance ( ) ;
return ref ;
}
bool EditorSpatialGizmoPlugin : : can_be_hidden ( ) const {
2018-10-29 11:30:28 +01:00
if ( get_script_instance ( ) & & get_script_instance ( ) - > has_method ( " can_be_hidden " ) ) {
return get_script_instance ( ) - > call ( " can_be_hidden " ) ;
}
2018-07-25 00:08:49 +02:00
return true ;
}
bool EditorSpatialGizmoPlugin : : is_selectable_when_hidden ( ) const {
2018-10-29 11:30:28 +01: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 12:57:32 +01: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 11:30:28 +01:00
}
2018-07-25 00:08:49 +02:00
return false ;
}
2018-08-11 23:07:00 +02:00
void EditorSpatialGizmoPlugin : : set_state ( int p_state ) {
current_state = p_state ;
2018-07-25 00:08:49 +02:00
for ( int i = 0 ; i < current_gizmos . size ( ) ; + + i ) {
2018-08-11 23:07:00 +02:00
current_gizmos [ i ] - > set_hidden ( current_state = = HIDDEN ) ;
2018-07-25 00:08:49 +02:00
}
}
2019-03-12 00:30:50 +01:00
int EditorSpatialGizmoPlugin : : get_state ( ) const {
return current_state ;
}
2018-07-25 00:08:49 +02:00
void EditorSpatialGizmoPlugin : : unregister_gizmo ( EditorSpatialGizmo * p_gizmo ) {
current_gizmos . erase ( p_gizmo ) ;
}
EditorSpatialGizmoPlugin : : EditorSpatialGizmoPlugin ( ) {
2018-11-18 22:01:09 +01:00
current_state = VISIBLE ;
2018-07-25 00:08:49 +02:00
}
EditorSpatialGizmoPlugin : : ~ EditorSpatialGizmoPlugin ( ) {
2018-10-29 11:30:28 +01: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 ) ;
}
SpatialEditor : : get_singleton ( ) - > update_all_gizmos ( ) ;
2018-07-25 00:08:49 +02:00
}