2014-02-09 22:10:30 -03:00
/*************************************************************************/
2020-03-26 18:49:16 -03:00
/* node_3d.cpp */
2014-02-09 22:10:30 -03:00
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 14:16:55 +02:00
/* https://godotengine.org */
2014-02-09 22:10:30 -03:00
/*************************************************************************/
2022-01-03 21:27:34 +01:00
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
2014-02-09 22:10:30 -03: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
2020-03-26 18:49:16 -03:00
# include "node_3d.h"
2016-03-09 00:00:52 +01:00
2020-11-07 19:33:38 -03:00
# include "core/object/message_queue.h"
2021-05-09 18:23:20 +02:00
# include "scene/3d/visual_instance_3d.h"
2021-08-12 18:05:59 -05:00
# include "scene/main/viewport.h"
2022-01-02 15:33:17 +00:00
# include "scene/property_utils.h"
2014-02-09 22:10:30 -03:00
# include "scene/scene_string_names.h"
/*
possible algorithms:
Algorithm 1: (current)
definition of invalidation: global is invalid
1) If a node sets a LOCAL, it produces an invalidation of everything above
2021-10-28 15:43:36 +02:00
. a) If above is invalid, don't keep invalidating upwards
2014-02-09 22:10:30 -03:00
2) If a node sets a GLOBAL, it is converted to LOCAL (and forces validation of everything pending below)
2021-03-12 19:05:16 +05:30
drawback: setting/reading globals is useful and used very often, and using affine inverses is slow
2014-02-09 22:10:30 -03:00
---
Algorithm 2: (no longer current)
definition of invalidation: NONE dirty, LOCAL dirty, GLOBAL dirty
1) If a node sets a LOCAL, it must climb the tree and set it as GLOBAL dirty
2021-10-28 15:43:36 +02:00
. a) marking GLOBALs as dirty up all the tree must be done always
2014-02-09 22:10:30 -03:00
2) If a node sets a GLOBAL, it marks local as dirty, and that's all?
//is clearing the dirty state correct in this case?
drawback: setting a local down the tree forces many tree walks often
--
future: no idea
*/
2020-03-26 18:49:16 -03:00
Node3DGizmo : : Node3DGizmo ( ) {
2014-02-09 22:10:30 -03:00
}
2020-03-26 18:49:16 -03:00
void Node3D : : _notify_dirty ( ) {
2017-08-09 08:18:07 -03:00
# ifdef TOOLS_ENABLED
2021-06-23 16:49:50 +02:00
if ( ( ! data . gizmos . is_empty ( ) | | data . notify_transform ) & & ! data . ignore_notification & & ! xform_change . in_list ( ) ) {
2017-08-09 08:18:07 -03:00
# else
2017-01-12 20:35:46 -03:00
if ( data . notify_transform & & ! data . ignore_notification & & ! xform_change . in_list ( ) ) {
2014-02-09 22:10:30 -03:00
2017-08-09 08:18:07 -03:00
# endif
2014-11-05 21:20:42 -03:00
get_tree ( ) - > xform_change_list . add ( & xform_change ) ;
2014-02-09 22:10:30 -03:00
}
}
2020-03-26 18:49:16 -03:00
void Node3D : : _update_local_transform ( ) const {
2021-10-09 19:24:26 +09:00
if ( this - > get_rotation_edit_mode ( ) ! = ROTATION_EDIT_MODE_BASIS ) {
data . local_transform = data . local_transform . orthogonalized ( ) ;
}
2018-04-14 15:53:25 -04:00
data . local_transform . basis . set_euler_scale ( data . rotation , data . scale ) ;
2014-02-09 22:10:30 -03:00
2017-03-05 16:44:50 +01:00
data . dirty & = ~ DIRTY_LOCAL ;
2014-02-09 22:10:30 -03:00
}
2020-05-14 14:29:06 +02:00
2020-03-26 18:49:16 -03:00
void Node3D : : _propagate_transform_changed ( Node3D * p_origin ) {
2014-11-05 21:20:42 -03:00
if ( ! is_inside_tree ( ) ) {
2014-02-09 22:10:30 -03:00
return ;
}
data . children_lock + + ;
2016-03-09 00:00:52 +01:00
2021-07-15 23:45:57 -04:00
for ( Node3D * & E : data . children ) {
if ( E - > data . top_level_active ) {
2020-10-02 17:03:52 -04:00
continue ; //don't propagate to a top_level
2020-05-14 16:41:43 +02:00
}
2021-07-15 23:45:57 -04:00
E - > _propagate_transform_changed ( p_origin ) ;
2014-02-09 22:10:30 -03:00
}
2017-08-09 08:18:07 -03:00
# ifdef TOOLS_ENABLED
2021-06-23 16:49:50 +02:00
if ( ( ! data . gizmos . is_empty ( ) | | data . notify_transform ) & & ! data . ignore_notification & & ! xform_change . in_list ( ) ) {
2017-08-09 08:18:07 -03:00
# else
2017-01-12 20:35:46 -03:00
if ( data . notify_transform & & ! data . ignore_notification & & ! xform_change . in_list ( ) ) {
2017-08-09 08:18:07 -03:00
# endif
2014-11-05 21:20:42 -03:00
get_tree ( ) - > xform_change_list . add ( & xform_change ) ;
2014-02-09 22:10:30 -03:00
}
2017-03-05 16:44:50 +01:00
data . dirty | = DIRTY_GLOBAL ;
2014-02-09 22:10:30 -03:00
data . children_lock - - ;
}
2020-03-26 18:49:16 -03:00
void Node3D : : _notification ( int p_what ) {
2017-03-05 16:44:50 +01:00
switch ( p_what ) {
2014-11-05 21:20:42 -03:00
case NOTIFICATION_ENTER_TREE : {
2020-01-25 13:16:27 +08:00
ERR_FAIL_COND ( ! get_tree ( ) ) ;
2014-02-09 22:10:30 -03:00
Node * p = get_parent ( ) ;
2020-05-14 16:41:43 +02:00
if ( p ) {
2020-03-26 18:49:16 -03:00
data . parent = Object : : cast_to < Node3D > ( p ) ;
2020-05-14 16:41:43 +02:00
}
2014-02-09 22:10:30 -03:00
2020-05-14 16:41:43 +02:00
if ( data . parent ) {
2017-03-05 16:44:50 +01:00
data . C = data . parent - > data . children . push_back ( this ) ;
2020-05-14 16:41:43 +02:00
} else {
2020-04-02 01:20:12 +02:00
data . C = nullptr ;
2020-05-14 16:41:43 +02:00
}
2014-02-09 22:10:30 -03:00
2020-10-01 03:17:33 -04:00
if ( data . top_level & & ! Engine : : get_singleton ( ) - > is_editor_hint ( ) ) {
2014-02-09 22:10:30 -03:00
if ( data . parent ) {
data . local_transform = data . parent - > get_global_transform ( ) * get_transform ( ) ;
2017-03-05 16:44:50 +01:00
data . dirty = DIRTY_VECTORS ; //global is always dirty upon entering a scene
2014-02-09 22:10:30 -03:00
}
2020-10-01 03:17:33 -04:00
data . top_level_active = true ;
2014-02-09 22:10:30 -03:00
}
2017-03-05 16:44:50 +01:00
data . dirty | = DIRTY_GLOBAL ; //global is always dirty upon entering a scene
2014-02-09 22:10:30 -03:00
_notify_dirty ( ) ;
notification ( NOTIFICATION_ENTER_WORLD ) ;
2021-05-09 18:23:20 +02:00
_update_visibility_parent ( true ) ;
2014-02-09 22:10:30 -03:00
} break ;
2014-11-05 21:20:42 -03:00
case NOTIFICATION_EXIT_TREE : {
2017-03-05 16:44:50 +01:00
notification ( NOTIFICATION_EXIT_WORLD , true ) ;
2020-05-14 16:41:43 +02:00
if ( xform_change . in_list ( ) ) {
2014-11-05 21:20:42 -03:00
get_tree ( ) - > xform_change_list . remove ( & xform_change ) ;
2020-05-14 16:41:43 +02:00
}
if ( data . C ) {
2014-02-09 22:10:30 -03:00
data . parent - > data . children . erase ( data . C ) ;
2020-05-14 16:41:43 +02:00
}
2020-04-02 01:20:12 +02:00
data . parent = nullptr ;
data . C = nullptr ;
2020-10-01 03:17:33 -04:00
data . top_level_active = false ;
2021-05-09 18:23:20 +02:00
_update_visibility_parent ( true ) ;
2014-02-09 22:10:30 -03:00
} break ;
case NOTIFICATION_ENTER_WORLD : {
2017-03-05 16:44:50 +01:00
data . inside_world = true ;
2020-04-02 01:20:12 +02:00
data . viewport = nullptr ;
2014-02-09 22:10:30 -03:00
Node * parent = get_parent ( ) ;
2017-03-05 16:44:50 +01:00
while ( parent & & ! data . viewport ) {
2017-08-24 22:58:51 +02:00
data . viewport = Object : : cast_to < Viewport > ( parent ) ;
2017-03-05 16:44:50 +01:00
parent = parent - > get_parent ( ) ;
2014-02-09 22:10:30 -03:00
}
ERR_FAIL_COND ( ! data . viewport ) ;
if ( get_script_instance ( ) ) {
2020-07-24 14:13:58 -03:00
get_script_instance ( ) - > call ( SceneStringNames : : get_singleton ( ) - > _enter_world ) ;
2014-02-09 22:10:30 -03:00
}
2022-01-04 12:07:36 +01:00
2014-02-09 22:10:30 -03:00
# ifdef TOOLS_ENABLED
2019-03-07 09:25:35 -03:00
if ( Engine : : get_singleton ( ) - > is_editor_hint ( ) & & get_tree ( ) - > is_node_being_edited ( this ) ) {
2017-03-05 16:44:50 +01:00
get_tree ( ) - > call_group_flags ( 0 , SceneStringNames : : get_singleton ( ) - > _spatial_editor_group , SceneStringNames : : get_singleton ( ) - > _request_gizmo , this ) ;
2021-06-23 16:49:50 +02:00
if ( ! data . gizmos_disabled ) {
for ( int i = 0 ; i < data . gizmos . size ( ) ; i + + ) {
data . gizmos . write [ i ] - > create ( ) ;
2018-09-02 22:31:03 +02:00
if ( is_visible_in_tree ( ) ) {
2021-06-23 16:49:50 +02:00
data . gizmos . write [ i ] - > redraw ( ) ;
2017-08-26 00:40:45 -03:00
}
2021-06-23 16:49:50 +02:00
data . gizmos . write [ i ] - > transform ( ) ;
2017-08-26 00:40:45 -03:00
}
2014-02-09 22:10:30 -03:00
}
}
# endif
} break ;
case NOTIFICATION_EXIT_WORLD : {
# ifdef TOOLS_ENABLED
2021-06-23 16:49:50 +02:00
clear_gizmos ( ) ;
2014-02-09 22:10:30 -03:00
# endif
if ( get_script_instance ( ) ) {
2020-07-24 14:13:58 -03:00
get_script_instance ( ) - > call ( SceneStringNames : : get_singleton ( ) - > _exit_world ) ;
2014-02-09 22:10:30 -03:00
}
2020-04-02 01:20:12 +02:00
data . viewport = nullptr ;
2017-03-05 16:44:50 +01:00
data . inside_world = false ;
2014-02-09 22:10:30 -03:00
} break ;
case NOTIFICATION_TRANSFORM_CHANGED : {
# ifdef TOOLS_ENABLED
2021-06-23 16:49:50 +02:00
for ( int i = 0 ; i < data . gizmos . size ( ) ; i + + ) {
data . gizmos . write [ i ] - > transform ( ) ;
2014-02-09 22:10:30 -03:00
}
# endif
} break ;
2016-03-09 00:00:52 +01:00
2019-04-09 17:08:36 +02:00
default : {
}
2014-02-09 22:10:30 -03:00
}
}
2021-10-21 13:38:20 -03:00
void Node3D : : set_basis ( const Basis & p_basis ) {
set_transform ( Transform3D ( p_basis , data . local_transform . origin ) ) ;
}
void Node3D : : set_quaternion ( const Quaternion & p_quaternion ) {
set_transform ( Transform3D ( Basis ( p_quaternion ) , data . local_transform . origin ) ) ;
}
2020-10-17 01:08:21 -04:00
void Node3D : : set_transform ( const Transform3D & p_transform ) {
2017-03-05 16:44:50 +01:00
data . local_transform = p_transform ;
data . dirty | = DIRTY_VECTORS ;
2014-02-09 22:10:30 -03:00
_propagate_transform_changed ( this ) ;
2015-09-15 22:07:03 -03:00
if ( data . notify_local_transform ) {
notification ( NOTIFICATION_LOCAL_TRANSFORM_CHANGED ) ;
}
2014-02-09 22:10:30 -03:00
}
2021-10-21 13:38:20 -03:00
Basis Node3D : : get_basis ( ) const {
return get_transform ( ) . basis ;
}
Quaternion Node3D : : get_quaternion ( ) const {
return Quaternion ( get_transform ( ) . basis ) ;
}
2020-10-17 01:08:21 -04:00
void Node3D : : set_global_transform ( const Transform3D & p_transform ) {
2021-10-28 15:57:41 +02:00
Transform3D xform = ( data . parent & & ! data . top_level_active )
? data . parent - > get_global_transform ( ) . affine_inverse ( ) * p_transform
: p_transform ;
2014-02-09 22:10:30 -03:00
set_transform ( xform ) ;
}
2020-10-17 01:08:21 -04:00
Transform3D Node3D : : get_transform ( ) const {
2014-02-09 22:10:30 -03:00
if ( data . dirty & DIRTY_LOCAL ) {
_update_local_transform ( ) ;
}
2016-03-09 00:00:52 +01:00
2014-02-09 22:10:30 -03:00
return data . local_transform ;
}
2020-10-17 01:08:21 -04:00
Transform3D Node3D : : get_global_transform ( ) const {
ERR_FAIL_COND_V ( ! is_inside_tree ( ) , Transform3D ( ) ) ;
2014-02-09 22:10:30 -03:00
if ( data . dirty & DIRTY_GLOBAL ) {
if ( data . dirty & DIRTY_LOCAL ) {
_update_local_transform ( ) ;
}
2020-10-01 03:17:33 -04:00
if ( data . parent & & ! data . top_level_active ) {
2017-03-05 16:44:50 +01:00
data . global_transform = data . parent - > get_global_transform ( ) * data . local_transform ;
2014-02-09 22:10:30 -03:00
} else {
2017-03-05 16:44:50 +01:00
data . global_transform = data . local_transform ;
2014-02-09 22:10:30 -03:00
}
2016-03-09 00:00:52 +01:00
2018-07-18 13:47:42 -03:00
if ( data . disable_scale ) {
data . global_transform . basis . orthonormalize ( ) ;
}
2017-03-05 16:44:50 +01:00
data . dirty & = ~ DIRTY_GLOBAL ;
2014-02-09 22:10:30 -03:00
}
2016-03-09 00:00:52 +01:00
2014-02-09 22:10:30 -03:00
return data . global_transform ;
}
2017-10-03 18:49:32 +02:00
# ifdef TOOLS_ENABLED
2020-10-17 01:08:21 -04:00
Transform3D Node3D : : get_global_gizmo_transform ( ) const {
2017-10-03 18:49:32 +02:00
return get_global_transform ( ) ;
}
2020-10-17 01:08:21 -04:00
Transform3D Node3D : : get_local_gizmo_transform ( ) const {
2017-10-03 18:49:32 +02:00
return get_transform ( ) ;
}
# endif
2021-06-09 13:06:38 +02:00
Node3D * Node3D : : get_parent_node_3d ( ) const {
if ( data . top_level ) {
return nullptr ;
}
return Object : : cast_to < Node3D > ( get_parent ( ) ) ;
2014-02-09 22:10:30 -03:00
}
2020-10-17 01:08:21 -04:00
Transform3D Node3D : : get_relative_transform ( const Node * p_parent ) const {
if ( p_parent = = this )
return Transform3D ( ) ;
2014-02-09 22:10:30 -03:00
2020-10-17 01:08:21 -04:00
ERR_FAIL_COND_V ( ! data . parent , Transform3D ( ) ) ;
2014-02-09 22:10:30 -03:00
2020-05-14 16:41:43 +02:00
if ( p_parent = = data . parent ) {
2014-02-09 22:10:30 -03:00
return get_transform ( ) ;
2020-05-14 16:41:43 +02:00
} else {
2014-02-09 22:10:30 -03:00
return data . parent - > get_relative_transform ( p_parent ) * get_transform ( ) ;
2020-05-14 16:41:43 +02:00
}
2014-02-09 22:10:30 -03:00
}
2020-12-08 17:35:30 +00:00
void Node3D : : set_position ( const Vector3 & p_position ) {
data . local_transform . origin = p_position ;
2014-02-09 22:10:30 -03:00
_propagate_transform_changed ( this ) ;
2015-09-15 22:07:03 -03:00
if ( data . notify_local_transform ) {
notification ( NOTIFICATION_LOCAL_TRANSFORM_CHANGED ) ;
}
2014-02-09 22:10:30 -03:00
}
2021-10-21 13:38:20 -03:00
void Node3D : : set_rotation_edit_mode ( RotationEditMode p_mode ) {
if ( data . rotation_edit_mode = = p_mode ) {
return ;
}
data . rotation_edit_mode = p_mode ;
2021-10-09 19:24:26 +09:00
// Shearing is not allowed except in ROTATION_EDIT_MODE_BASIS.
data . dirty | = DIRTY_LOCAL ;
_propagate_transform_changed ( this ) ;
if ( data . notify_local_transform ) {
notification ( NOTIFICATION_LOCAL_TRANSFORM_CHANGED ) ;
}
2021-10-21 13:38:20 -03:00
notify_property_list_changed ( ) ;
}
Node3D : : RotationEditMode Node3D : : get_rotation_edit_mode ( ) const {
return data . rotation_edit_mode ;
}
void Node3D : : set_rotation_order ( RotationOrder p_order ) {
Basis : : EulerOrder order = Basis : : EulerOrder ( p_order ) ;
if ( data . rotation_order = = order ) {
return ;
}
ERR_FAIL_INDEX ( int32_t ( order ) , 6 ) ;
if ( data . dirty & DIRTY_VECTORS ) {
data . rotation = data . local_transform . basis . get_euler_normalized ( order ) ;
data . scale = data . local_transform . basis . get_scale ( ) ;
data . dirty & = ~ DIRTY_VECTORS ;
} else {
data . rotation = Basis : : from_euler ( data . rotation , data . rotation_order ) . get_euler_normalized ( order ) ;
}
data . rotation_order = order ;
//changing rotation order should not affect transform
notify_property_list_changed ( ) ; //will change rotation
}
Node3D : : RotationOrder Node3D : : get_rotation_order ( ) const {
return RotationOrder ( data . rotation_order ) ;
}
2020-03-26 18:49:16 -03:00
void Node3D : : set_rotation ( const Vector3 & p_euler_rad ) {
2017-03-05 16:44:50 +01:00
if ( data . dirty & DIRTY_VECTORS ) {
data . scale = data . local_transform . basis . get_scale ( ) ;
data . dirty & = ~ DIRTY_VECTORS ;
2014-02-09 22:10:30 -03:00
}
2017-03-05 16:44:50 +01:00
data . rotation = p_euler_rad ;
data . dirty | = DIRTY_LOCAL ;
2014-02-09 22:10:30 -03:00
_propagate_transform_changed ( this ) ;
2015-09-15 22:07:03 -03:00
if ( data . notify_local_transform ) {
notification ( NOTIFICATION_LOCAL_TRANSFORM_CHANGED ) ;
}
2014-02-09 22:10:30 -03:00
}
2016-05-06 23:38:08 +02:00
2020-03-26 18:49:16 -03:00
void Node3D : : set_scale ( const Vector3 & p_scale ) {
2017-03-05 16:44:50 +01:00
if ( data . dirty & DIRTY_VECTORS ) {
2021-10-21 13:38:20 -03:00
data . rotation = data . local_transform . basis . get_euler_normalized ( data . rotation_order ) ;
2017-03-05 16:44:50 +01:00
data . dirty & = ~ DIRTY_VECTORS ;
2014-02-09 22:10:30 -03:00
}
2017-03-05 16:44:50 +01:00
data . scale = p_scale ;
data . dirty | = DIRTY_LOCAL ;
2014-02-09 22:10:30 -03:00
_propagate_transform_changed ( this ) ;
2015-09-15 22:07:03 -03:00
if ( data . notify_local_transform ) {
notification ( NOTIFICATION_LOCAL_TRANSFORM_CHANGED ) ;
}
2014-02-09 22:10:30 -03:00
}
2020-12-08 17:35:30 +00:00
Vector3 Node3D : : get_position ( ) const {
2014-02-09 22:10:30 -03:00
return data . local_transform . origin ;
}
2016-05-06 23:38:08 +02:00
2020-03-26 18:49:16 -03:00
Vector3 Node3D : : get_rotation ( ) const {
2017-03-05 16:44:50 +01:00
if ( data . dirty & DIRTY_VECTORS ) {
data . scale = data . local_transform . basis . get_scale ( ) ;
2021-10-21 13:38:20 -03:00
data . rotation = data . local_transform . basis . get_euler_normalized ( data . rotation_order ) ;
2017-01-05 11:31:39 -06:00
2017-03-05 16:44:50 +01:00
data . dirty & = ~ DIRTY_VECTORS ;
2014-02-09 22:10:30 -03:00
}
return data . rotation ;
}
2016-05-06 23:38:08 +02:00
2020-03-26 18:49:16 -03:00
Vector3 Node3D : : get_scale ( ) const {
2017-03-05 16:44:50 +01:00
if ( data . dirty & DIRTY_VECTORS ) {
data . scale = data . local_transform . basis . get_scale ( ) ;
2021-10-21 13:38:20 -03:00
data . rotation = data . local_transform . basis . get_euler_normalized ( data . rotation_order ) ;
2017-01-05 11:31:39 -06:00
2017-03-05 16:44:50 +01:00
data . dirty & = ~ DIRTY_VECTORS ;
2014-02-09 22:10:30 -03:00
}
return data . scale ;
}
2021-06-23 16:49:50 +02:00
void Node3D : : update_gizmos ( ) {
2014-02-09 22:10:30 -03:00
# ifdef TOOLS_ENABLED
2020-05-14 16:41:43 +02:00
if ( ! is_inside_world ( ) ) {
2014-02-09 22:10:30 -03:00
return ;
2020-05-14 16:41:43 +02:00
}
2021-06-23 16:49:50 +02:00
if ( data . gizmos . is_empty ( ) ) {
return ;
2020-05-14 16:41:43 +02:00
}
2021-10-15 19:04:35 -03:00
if ( data . gizmos_dirty ) {
return ;
}
2021-06-23 16:49:50 +02:00
data . gizmos_dirty = true ;
MessageQueue : : get_singleton ( ) - > push_callable ( callable_mp ( this , & Node3D : : _update_gizmos ) ) ;
# endif
}
2021-02-04 17:20:26 +09:00
void Node3D : : set_subgizmo_selection ( Ref < Node3DGizmo > p_gizmo , int p_id , Transform3D p_transform ) {
# ifdef TOOLS_ENABLED
if ( ! is_inside_world ( ) ) {
return ;
}
if ( Engine : : get_singleton ( ) - > is_editor_hint ( ) & & get_tree ( ) - > is_node_being_edited ( this ) ) {
get_tree ( ) - > call_group_flags ( 0 , SceneStringNames : : get_singleton ( ) - > _spatial_editor_group , SceneStringNames : : get_singleton ( ) - > _set_subgizmo_selection , this , p_gizmo , p_id , p_transform ) ;
}
# endif
}
2021-06-23 16:49:50 +02:00
void Node3D : : clear_subgizmo_selection ( ) {
# ifdef TOOLS_ENABLED
if ( ! is_inside_world ( ) ) {
2014-02-09 22:10:30 -03:00
return ;
2020-05-14 16:41:43 +02:00
}
2021-06-23 16:49:50 +02:00
if ( data . gizmos . is_empty ( ) ) {
2014-02-09 22:10:30 -03:00
return ;
2020-05-14 16:41:43 +02:00
}
2021-06-23 16:49:50 +02:00
if ( Engine : : get_singleton ( ) - > is_editor_hint ( ) & & get_tree ( ) - > is_node_being_edited ( this ) ) {
get_tree ( ) - > call_group_flags ( 0 , SceneStringNames : : get_singleton ( ) - > _spatial_editor_group , SceneStringNames : : get_singleton ( ) - > _clear_subgizmo_selection , this ) ;
}
2014-02-09 22:10:30 -03:00
# endif
}
2021-06-23 16:49:50 +02:00
void Node3D : : add_gizmo ( Ref < Node3DGizmo > p_gizmo ) {
2014-02-09 22:10:30 -03:00
# ifdef TOOLS_ENABLED
2021-06-23 16:49:50 +02:00
if ( data . gizmos_disabled | | p_gizmo . is_null ( ) ) {
2014-02-09 22:10:30 -03:00
return ;
2020-05-14 16:41:43 +02:00
}
2021-06-23 16:49:50 +02:00
data . gizmos . push_back ( p_gizmo ) ;
if ( p_gizmo . is_valid ( ) & & is_inside_world ( ) ) {
p_gizmo - > create ( ) ;
2018-09-02 22:31:03 +02:00
if ( is_visible_in_tree ( ) ) {
2021-06-23 16:49:50 +02:00
p_gizmo - > redraw ( ) ;
2017-08-26 00:40:45 -03:00
}
2021-06-23 16:49:50 +02:00
p_gizmo - > transform ( ) ;
2014-02-09 22:10:30 -03:00
}
2021-06-23 16:49:50 +02:00
# endif
}
void Node3D : : remove_gizmo ( Ref < Node3DGizmo > p_gizmo ) {
# ifdef TOOLS_ENABLED
int idx = data . gizmos . find ( p_gizmo ) ;
if ( idx ! = - 1 ) {
p_gizmo - > free ( ) ;
2021-07-03 16:17:03 -06:00
data . gizmos . remove_at ( idx ) ;
2021-06-23 16:49:50 +02:00
}
# endif
}
void Node3D : : clear_gizmos ( ) {
# ifdef TOOLS_ENABLED
for ( int i = 0 ; i < data . gizmos . size ( ) ; i + + ) {
data . gizmos . write [ i ] - > free ( ) ;
}
data . gizmos . clear ( ) ;
# endif
}
Array Node3D : : get_gizmos_bind ( ) const {
Array ret ;
# ifdef TOOLS_ENABLED
for ( int i = 0 ; i < data . gizmos . size ( ) ; i + + ) {
ret . push_back ( Variant ( data . gizmos [ i ] . ptr ( ) ) ) ;
}
2014-02-09 22:10:30 -03:00
# endif
2021-06-23 16:49:50 +02:00
return ret ;
2014-02-09 22:10:30 -03:00
}
2021-06-23 16:49:50 +02:00
Vector < Ref < Node3DGizmo > > Node3D : : get_gizmos ( ) const {
2014-02-09 22:10:30 -03:00
# ifdef TOOLS_ENABLED
2021-06-23 16:49:50 +02:00
return data . gizmos ;
2014-02-09 22:10:30 -03:00
# else
2021-06-23 16:49:50 +02:00
return Vector < Ref < Node3DGizmo > > ( ) ;
2014-02-09 22:10:30 -03:00
# endif
}
2021-06-23 16:49:50 +02:00
void Node3D : : _update_gizmos ( ) {
2018-04-29 19:49:26 +02:00
# ifdef TOOLS_ENABLED
2021-06-23 16:49:50 +02:00
if ( data . gizmos_disabled | | ! is_inside_world ( ) | | ! data . gizmos_dirty ) {
2021-10-15 19:04:35 -03:00
data . gizmos_dirty = false ;
2017-08-26 00:40:45 -03:00
return ;
2020-05-14 16:41:43 +02:00
}
2021-06-23 16:49:50 +02:00
data . gizmos_dirty = false ;
for ( int i = 0 ; i < data . gizmos . size ( ) ; i + + ) {
2020-05-14 16:41:43 +02:00
if ( is_visible_in_tree ( ) ) {
2021-06-23 16:49:50 +02:00
data . gizmos . write [ i ] - > redraw ( ) ;
2020-05-14 16:41:43 +02:00
} else {
2021-06-23 16:49:50 +02:00
data . gizmos . write [ i ] - > clear ( ) ;
2020-05-14 16:41:43 +02:00
}
2014-09-19 18:39:50 -03:00
}
2018-04-29 19:49:26 +02:00
# endif
2014-02-09 22:10:30 -03:00
}
2021-06-23 16:49:50 +02:00
void Node3D : : set_disable_gizmos ( bool p_enabled ) {
2021-10-21 17:26:51 +01:00
# ifdef TOOLS_ENABLED
2021-06-23 16:49:50 +02:00
data . gizmos_disabled = p_enabled ;
if ( ! p_enabled ) {
clear_gizmos ( ) ;
2020-05-14 16:41:43 +02:00
}
2014-02-09 22:10:30 -03:00
# endif
2021-10-21 17:26:51 +01:00
}
2014-02-09 22:10:30 -03:00
2020-03-26 18:49:16 -03:00
void Node3D : : set_disable_scale ( bool p_enabled ) {
2018-07-18 13:47:42 -03:00
data . disable_scale = p_enabled ;
}
2020-03-26 18:49:16 -03:00
bool Node3D : : is_scale_disabled ( ) const {
2018-07-18 13:47:42 -03:00
return data . disable_scale ;
}
2020-10-01 03:17:33 -04:00
void Node3D : : set_as_top_level ( bool p_enabled ) {
if ( data . top_level = = p_enabled ) {
2014-02-09 22:10:30 -03:00
return ;
2020-05-14 16:41:43 +02:00
}
2017-08-19 01:02:56 +02:00
if ( is_inside_tree ( ) & & ! Engine : : get_singleton ( ) - > is_editor_hint ( ) ) {
2020-05-14 16:41:43 +02:00
if ( p_enabled ) {
2014-02-09 22:10:30 -03:00
set_transform ( get_global_transform ( ) ) ;
2020-05-14 16:41:43 +02:00
} else if ( data . parent ) {
2014-02-09 22:10:30 -03:00
set_transform ( data . parent - > get_global_transform ( ) . affine_inverse ( ) * get_global_transform ( ) ) ;
2020-05-14 16:41:43 +02:00
}
2014-02-09 22:10:30 -03:00
2020-10-01 03:17:33 -04:00
data . top_level = p_enabled ;
data . top_level_active = p_enabled ;
2014-02-09 22:10:30 -03:00
} else {
2020-10-01 03:17:33 -04:00
data . top_level = p_enabled ;
2014-02-09 22:10:30 -03:00
}
}
2020-10-01 03:17:33 -04:00
bool Node3D : : is_set_as_top_level ( ) const {
return data . top_level ;
2014-02-09 22:10:30 -03:00
}
2020-04-18 11:00:51 +02:00
Ref < World3D > Node3D : : get_world_3d ( ) const {
2020-03-27 08:44:44 +01:00
ERR_FAIL_COND_V ( ! is_inside_world ( ) , Ref < World3D > ( ) ) ;
ERR_FAIL_COND_V ( ! data . viewport , Ref < World3D > ( ) ) ;
2019-06-22 15:52:51 +03:00
2020-04-18 11:00:51 +02:00
return data . viewport - > find_world_3d ( ) ;
2014-02-09 22:10:30 -03:00
}
2020-03-26 18:49:16 -03:00
void Node3D : : _propagate_visibility_changed ( ) {
2014-08-14 10:31:38 -03:00
notification ( NOTIFICATION_VISIBILITY_CHANGED ) ;
emit_signal ( SceneStringNames : : get_singleton ( ) - > visibility_changed ) ;
2022-01-04 12:07:36 +01:00
2014-09-19 18:39:50 -03:00
# ifdef TOOLS_ENABLED
2021-06-23 16:49:50 +02:00
if ( ! data . gizmos . is_empty ( ) ) {
data . gizmos_dirty = true ;
_update_gizmos ( ) ;
2020-05-14 16:41:43 +02:00
}
2014-09-19 18:39:50 -03:00
# endif
2014-08-14 10:31:38 -03:00
2021-07-15 23:45:57 -04:00
for ( Node3D * c : data . children ) {
2020-05-14 16:41:43 +02:00
if ( ! c | | ! c - > data . visible ) {
2014-08-14 10:31:38 -03:00
continue ;
2020-05-14 16:41:43 +02:00
}
2014-08-14 10:31:38 -03:00
c - > _propagate_visibility_changed ( ) ;
}
}
2020-03-26 18:49:16 -03:00
void Node3D : : show ( ) {
2022-01-04 12:07:36 +01:00
set_visible ( true ) ;
2014-08-14 10:31:38 -03:00
}
2020-03-26 18:49:16 -03:00
void Node3D : : hide ( ) {
2022-01-04 12:07:36 +01:00
set_visible ( false ) ;
}
void Node3D : : set_visible ( bool p_visible ) {
if ( data . visible = = p_visible ) {
2014-08-14 10:31:38 -03:00
return ;
2020-05-14 16:41:43 +02:00
}
2014-08-14 10:31:38 -03:00
2022-01-04 12:07:36 +01:00
data . visible = p_visible ;
2014-08-14 10:31:38 -03:00
2020-05-14 16:41:43 +02:00
if ( ! is_inside_tree ( ) ) {
2017-07-03 00:27:27 +09:00
return ;
2020-05-14 16:41:43 +02:00
}
2017-07-03 00:27:27 +09:00
_propagate_visibility_changed ( ) ;
2014-08-14 10:31:38 -03:00
}
2017-07-03 00:27:27 +09:00
2022-01-04 12:07:36 +01:00
bool Node3D : : is_visible ( ) const {
return data . visible ;
}
2020-03-26 18:49:16 -03:00
bool Node3D : : is_visible_in_tree ( ) const {
const Node3D * s = this ;
2014-08-14 10:31:38 -03:00
2017-03-05 16:44:50 +01:00
while ( s ) {
2014-08-14 10:31:38 -03:00
if ( ! s - > data . visible ) {
return false ;
}
2017-03-05 16:44:50 +01:00
s = s - > data . parent ;
2014-08-14 10:31:38 -03:00
}
return true ;
}
2021-01-29 19:55:54 -05:00
void Node3D : : rotate_object_local ( const Vector3 & p_axis , real_t p_angle ) {
2020-10-17 01:08:21 -04:00
Transform3D t = get_transform ( ) ;
2017-12-26 19:15:20 -05:00
t . basis . rotate_local ( p_axis , p_angle ) ;
set_transform ( t ) ;
}
2021-01-29 19:55:54 -05:00
void Node3D : : rotate ( const Vector3 & p_axis , real_t p_angle ) {
2020-10-17 01:08:21 -04:00
Transform3D t = get_transform ( ) ;
2017-12-26 19:15:20 -05:00
t . basis . rotate ( p_axis , p_angle ) ;
2015-03-22 10:33:58 -03:00
set_transform ( t ) ;
}
2021-01-29 19:55:54 -05:00
void Node3D : : rotate_x ( real_t p_angle ) {
2020-10-17 01:08:21 -04:00
Transform3D t = get_transform ( ) ;
2017-12-26 19:15:20 -05:00
t . basis . rotate ( Vector3 ( 1 , 0 , 0 ) , p_angle ) ;
2015-03-22 10:33:58 -03:00
set_transform ( t ) ;
}
2021-01-29 19:55:54 -05:00
void Node3D : : rotate_y ( real_t p_angle ) {
2020-10-17 01:08:21 -04:00
Transform3D t = get_transform ( ) ;
2017-12-26 19:15:20 -05:00
t . basis . rotate ( Vector3 ( 0 , 1 , 0 ) , p_angle ) ;
2015-03-22 10:33:58 -03:00
set_transform ( t ) ;
}
2020-05-14 14:29:06 +02:00
2021-01-29 19:55:54 -05:00
void Node3D : : rotate_z ( real_t p_angle ) {
2020-10-17 01:08:21 -04:00
Transform3D t = get_transform ( ) ;
2017-12-26 19:15:20 -05:00
t . basis . rotate ( Vector3 ( 0 , 0 , 1 ) , p_angle ) ;
2015-03-22 10:33:58 -03:00
set_transform ( t ) ;
}
2020-03-26 18:49:16 -03:00
void Node3D : : translate ( const Vector3 & p_offset ) {
2020-10-17 01:08:21 -04:00
Transform3D t = get_transform ( ) ;
2015-06-06 09:44:38 -03:00
t . translate ( p_offset ) ;
2015-03-22 10:33:58 -03:00
set_transform ( t ) ;
}
2015-06-06 09:44:38 -03:00
2020-03-26 18:49:16 -03:00
void Node3D : : translate_object_local ( const Vector3 & p_offset ) {
2020-10-17 01:08:21 -04:00
Transform3D t = get_transform ( ) ;
2017-12-26 19:15:20 -05:00
2020-10-17 01:08:21 -04:00
Transform3D s ;
2017-12-26 19:15:20 -05:00
s . translate ( p_offset ) ;
set_transform ( t * s ) ;
}
2020-03-26 18:49:16 -03:00
void Node3D : : scale ( const Vector3 & p_ratio ) {
2020-10-17 01:08:21 -04:00
Transform3D t = get_transform ( ) ;
2015-03-22 10:33:58 -03:00
t . basis . scale ( p_ratio ) ;
set_transform ( t ) ;
}
2020-03-26 18:49:16 -03:00
void Node3D : : scale_object_local ( const Vector3 & p_scale ) {
2020-10-17 01:08:21 -04:00
Transform3D t = get_transform ( ) ;
2017-12-26 19:15:20 -05:00
t . basis . scale_local ( p_scale ) ;
set_transform ( t ) ;
}
2021-01-29 19:55:54 -05:00
void Node3D : : global_rotate ( const Vector3 & p_axis , real_t p_angle ) {
2020-10-17 01:08:21 -04:00
Transform3D t = get_global_transform ( ) ;
2018-05-16 20:32:35 -04:00
t . basis . rotate ( p_axis , p_angle ) ;
2015-03-22 10:33:58 -03:00
set_global_transform ( t ) ;
}
2017-12-26 19:15:20 -05:00
2020-03-26 18:49:16 -03:00
void Node3D : : global_scale ( const Vector3 & p_scale ) {
2020-10-17 01:08:21 -04:00
Transform3D t = get_global_transform ( ) ;
2018-05-16 20:32:35 -04:00
t . basis . scale ( p_scale ) ;
2017-12-26 19:15:20 -05:00
set_global_transform ( t ) ;
}
2020-03-26 18:49:16 -03:00
void Node3D : : global_translate ( const Vector3 & p_offset ) {
2020-10-17 01:08:21 -04:00
Transform3D t = get_global_transform ( ) ;
2017-03-05 16:44:50 +01:00
t . origin + = p_offset ;
2015-03-22 10:33:58 -03:00
set_global_transform ( t ) ;
}
2020-03-26 18:49:16 -03:00
void Node3D : : orthonormalize ( ) {
2020-10-17 01:08:21 -04:00
Transform3D t = get_transform ( ) ;
2015-03-22 10:33:58 -03:00
t . orthonormalize ( ) ;
set_transform ( t ) ;
}
2020-03-26 18:49:16 -03:00
void Node3D : : set_identity ( ) {
2020-10-17 01:08:21 -04:00
set_transform ( Transform3D ( ) ) ;
2015-03-22 11:52:07 -03:00
}
2020-03-26 18:49:16 -03:00
void Node3D : : look_at ( const Vector3 & p_target , const Vector3 & p_up ) {
2021-07-20 23:32:00 -04:00
Vector3 origin = get_global_transform ( ) . origin ;
2019-05-23 09:49:50 -03:00
look_at_from_position ( origin , p_target , p_up ) ;
}
2020-03-26 18:49:16 -03:00
void Node3D : : look_at_from_position ( const Vector3 & p_pos , const Vector3 & p_target , const Vector3 & p_up ) {
2021-07-20 23:32:00 -04:00
ERR_FAIL_COND_MSG ( p_pos . is_equal_approx ( p_target ) , " Node origin and target are in the same position, look_at() failed. " ) ;
ERR_FAIL_COND_MSG ( p_up . is_equal_approx ( Vector3 ( ) ) , " The up vector can't be zero, look_at() failed. " ) ;
ERR_FAIL_COND_MSG ( p_up . cross ( p_target - p_pos ) . is_equal_approx ( Vector3 ( ) ) , " Up vector and direction between node origin and target are aligned, look_at() failed. " ) ;
2015-03-22 10:33:58 -03:00
2021-07-20 23:32:00 -04:00
Transform3D lookat = Transform3D ( Basis : : looking_at ( p_target - p_pos , p_up ) , p_pos ) ;
Vector3 original_scale = get_scale ( ) ;
2015-03-22 10:33:58 -03:00
set_global_transform ( lookat ) ;
2019-10-11 02:22:02 -03:00
set_scale ( original_scale ) ;
2015-03-22 10:33:58 -03:00
}
2020-03-26 18:49:16 -03:00
Vector3 Node3D : : to_local ( Vector3 p_global ) const {
2017-07-23 14:37:26 +03:00
return get_global_transform ( ) . affine_inverse ( ) . xform ( p_global ) ;
}
2020-03-26 18:49:16 -03:00
Vector3 Node3D : : to_global ( Vector3 p_local ) const {
2017-07-23 14:37:26 +03:00
return get_global_transform ( ) . xform ( p_local ) ;
}
2022-01-04 12:07:36 +01:00
void Node3D : : set_notify_transform ( bool p_enabled ) {
data . notify_transform = p_enabled ;
2017-01-12 20:35:46 -03:00
}
2020-03-26 18:49:16 -03:00
bool Node3D : : is_transform_notification_enabled ( ) const {
2017-01-12 20:35:46 -03:00
return data . notify_transform ;
}
2022-01-04 12:07:36 +01:00
void Node3D : : set_notify_local_transform ( bool p_enabled ) {
data . notify_local_transform = p_enabled ;
2015-09-15 22:07:03 -03:00
}
2020-03-26 18:49:16 -03:00
bool Node3D : : is_local_transform_notification_enabled ( ) const {
2015-09-15 22:07:03 -03:00
return data . notify_local_transform ;
}
2014-08-14 10:31:38 -03:00
2020-03-26 18:49:16 -03:00
void Node3D : : force_update_transform ( ) {
2018-09-06 20:38:16 -03:00
ERR_FAIL_COND ( ! is_inside_tree ( ) ) ;
if ( ! xform_change . in_list ( ) ) {
return ; //nothing to update
}
get_tree ( ) - > xform_change_list . remove ( & xform_change ) ;
notification ( NOTIFICATION_TRANSFORM_CHANGED ) ;
}
2021-05-09 18:23:20 +02:00
void Node3D : : _update_visibility_parent ( bool p_update_root ) {
RID new_parent ;
if ( ! visibility_parent_path . is_empty ( ) ) {
if ( ! p_update_root ) {
return ;
}
Node * parent = get_node_or_null ( visibility_parent_path ) ;
ERR_FAIL_COND_MSG ( ! parent , " Can't find visibility parent node at path: " + visibility_parent_path ) ;
ERR_FAIL_COND_MSG ( parent = = this , " The visibility parent can't be the same node. " ) ;
GeometryInstance3D * gi = Object : : cast_to < GeometryInstance3D > ( parent ) ;
ERR_FAIL_COND_MSG ( ! gi , " The visibility parent node must be a GeometryInstance3D, at path: " + visibility_parent_path ) ;
new_parent = gi ? gi - > get_instance ( ) : RID ( ) ;
} else if ( data . parent ) {
new_parent = data . parent - > data . visibility_parent ;
}
if ( new_parent = = data . visibility_parent ) {
return ;
}
data . visibility_parent = new_parent ;
VisualInstance3D * vi = Object : : cast_to < VisualInstance3D > ( this ) ;
if ( vi ) {
RS : : get_singleton ( ) - > instance_set_visibility_parent ( vi - > get_instance ( ) , data . visibility_parent ) ;
}
2021-07-15 23:45:57 -04:00
for ( Node3D * c : data . children ) {
2021-05-09 18:23:20 +02:00
c - > _update_visibility_parent ( false ) ;
}
}
void Node3D : : set_visibility_parent ( const NodePath & p_path ) {
visibility_parent_path = p_path ;
if ( is_inside_tree ( ) ) {
_update_visibility_parent ( true ) ;
}
}
NodePath Node3D : : get_visibility_parent ( ) const {
return visibility_parent_path ;
}
2021-10-21 13:38:20 -03:00
void Node3D : : _validate_property ( PropertyInfo & property ) const {
if ( data . rotation_edit_mode ! = ROTATION_EDIT_MODE_BASIS & & property . name = = " basis " ) {
property . usage = 0 ;
}
if ( data . rotation_edit_mode = = ROTATION_EDIT_MODE_BASIS & & property . name = = " scale " ) {
property . usage = 0 ;
}
if ( data . rotation_edit_mode ! = ROTATION_EDIT_MODE_QUATERNION & & property . name = = " quaternion " ) {
property . usage = 0 ;
}
if ( data . rotation_edit_mode ! = ROTATION_EDIT_MODE_EULER & & property . name = = " rotation " ) {
property . usage = 0 ;
}
if ( data . rotation_edit_mode ! = ROTATION_EDIT_MODE_EULER & & property . name = = " rotation_order " ) {
property . usage = 0 ;
}
}
2022-01-02 15:33:17 +00:00
bool Node3D : : property_can_revert ( const String & p_name ) {
if ( p_name = = " basis " ) {
return true ;
} else if ( p_name = = " scale " ) {
return true ;
} else if ( p_name = = " quaternion " ) {
return true ;
} else if ( p_name = = " rotation " ) {
return true ;
} else if ( p_name = = " position " ) {
return true ;
}
return false ;
}
Variant Node3D : : property_get_revert ( const String & p_name ) {
Variant r_ret ;
bool valid = false ;
if ( p_name = = " basis " ) {
Variant variant = PropertyUtils : : get_property_default_value ( this , " transform " , & valid ) ;
if ( valid & & variant . get_type ( ) = = Variant : : Type : : TRANSFORM3D ) {
r_ret = Transform3D ( variant ) . get_basis ( ) ;
} else {
r_ret = Basis ( ) ;
}
} else if ( p_name = = " scale " ) {
Variant variant = PropertyUtils : : get_property_default_value ( this , " transform " , & valid ) ;
if ( valid & & variant . get_type ( ) = = Variant : : Type : : TRANSFORM3D ) {
r_ret = Transform3D ( variant ) . get_basis ( ) . get_scale ( ) ;
} else {
return Vector3 ( 1.0 , 1.0 , 1.0 ) ;
}
} else if ( p_name = = " quaternion " ) {
Variant variant = PropertyUtils : : get_property_default_value ( this , " transform " , & valid ) ;
if ( valid & & variant . get_type ( ) = = Variant : : Type : : TRANSFORM3D ) {
r_ret = Quaternion ( Transform3D ( variant ) . get_basis ( ) ) ;
} else {
return Quaternion ( ) ;
}
} else if ( p_name = = " rotation " ) {
Variant variant = PropertyUtils : : get_property_default_value ( this , " transform " , & valid ) ;
if ( valid & & variant . get_type ( ) = = Variant : : Type : : TRANSFORM3D ) {
r_ret = Transform3D ( variant ) . get_basis ( ) . get_euler_normalized ( data . rotation_order ) ;
} else {
return Vector3 ( ) ;
}
} else if ( p_name = = " position " ) {
Variant variant = PropertyUtils : : get_property_default_value ( this , " transform " , & valid ) ;
if ( valid ) {
r_ret = Transform3D ( variant ) . get_origin ( ) ;
} else {
return Vector3 ( ) ;
}
}
return r_ret ;
}
2020-03-26 18:49:16 -03:00
void Node3D : : _bind_methods ( ) {
2021-08-29 17:01:07 -03:00
ClassDB : : bind_method ( D_METHOD ( " set_transform " , " local " ) , & Node3D : : set_transform ) ;
2020-03-26 18:49:16 -03:00
ClassDB : : bind_method ( D_METHOD ( " get_transform " ) , & Node3D : : get_transform ) ;
2020-12-08 17:35:30 +00:00
ClassDB : : bind_method ( D_METHOD ( " set_position " , " position " ) , & Node3D : : set_position ) ;
ClassDB : : bind_method ( D_METHOD ( " get_position " ) , & Node3D : : get_position ) ;
2020-03-26 18:49:16 -03:00
ClassDB : : bind_method ( D_METHOD ( " set_rotation " , " euler " ) , & Node3D : : set_rotation ) ;
ClassDB : : bind_method ( D_METHOD ( " get_rotation " ) , & Node3D : : get_rotation ) ;
2021-10-21 13:38:20 -03:00
ClassDB : : bind_method ( D_METHOD ( " set_rotation_order " , " order " ) , & Node3D : : set_rotation_order ) ;
ClassDB : : bind_method ( D_METHOD ( " get_rotation_order " ) , & Node3D : : get_rotation_order ) ;
ClassDB : : bind_method ( D_METHOD ( " set_rotation_edit_mode " , " edit_mode " ) , & Node3D : : set_rotation_edit_mode ) ;
ClassDB : : bind_method ( D_METHOD ( " get_rotation_edit_mode " ) , & Node3D : : get_rotation_edit_mode ) ;
2020-03-26 18:49:16 -03:00
ClassDB : : bind_method ( D_METHOD ( " set_scale " , " scale " ) , & Node3D : : set_scale ) ;
ClassDB : : bind_method ( D_METHOD ( " get_scale " ) , & Node3D : : get_scale ) ;
2021-10-21 13:38:20 -03:00
ClassDB : : bind_method ( D_METHOD ( " set_quaternion " , " quaternion " ) , & Node3D : : set_quaternion ) ;
ClassDB : : bind_method ( D_METHOD ( " get_quaternion " ) , & Node3D : : get_quaternion ) ;
ClassDB : : bind_method ( D_METHOD ( " set_basis " , " basis " ) , & Node3D : : set_basis ) ;
ClassDB : : bind_method ( D_METHOD ( " get_basis " ) , & Node3D : : get_basis ) ;
2020-03-26 18:49:16 -03:00
ClassDB : : bind_method ( D_METHOD ( " set_global_transform " , " global " ) , & Node3D : : set_global_transform ) ;
ClassDB : : bind_method ( D_METHOD ( " get_global_transform " ) , & Node3D : : get_global_transform ) ;
2021-06-09 13:06:38 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_parent_node_3d " ) , & Node3D : : get_parent_node_3d ) ;
2020-03-26 18:49:16 -03:00
ClassDB : : bind_method ( D_METHOD ( " set_ignore_transform_notification " , " enabled " ) , & Node3D : : set_ignore_transform_notification ) ;
2020-10-02 17:03:52 -04:00
ClassDB : : bind_method ( D_METHOD ( " set_as_top_level " , " enable " ) , & Node3D : : set_as_top_level ) ;
ClassDB : : bind_method ( D_METHOD ( " is_set_as_top_level " ) , & Node3D : : is_set_as_top_level ) ;
2020-03-26 18:49:16 -03:00
ClassDB : : bind_method ( D_METHOD ( " set_disable_scale " , " disable " ) , & Node3D : : set_disable_scale ) ;
ClassDB : : bind_method ( D_METHOD ( " is_scale_disabled " ) , & Node3D : : is_scale_disabled ) ;
2020-04-18 11:00:51 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_world_3d " ) , & Node3D : : get_world_3d ) ;
2020-03-26 18:49:16 -03:00
ClassDB : : bind_method ( D_METHOD ( " force_update_transform " ) , & Node3D : : force_update_transform ) ;
2021-05-09 18:23:20 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_visibility_parent " , " path " ) , & Node3D : : set_visibility_parent ) ;
ClassDB : : bind_method ( D_METHOD ( " get_visibility_parent " ) , & Node3D : : get_visibility_parent ) ;
2021-06-23 16:49:50 +02:00
ClassDB : : bind_method ( D_METHOD ( " update_gizmos " ) , & Node3D : : update_gizmos ) ;
ClassDB : : bind_method ( D_METHOD ( " add_gizmo " , " gizmo " ) , & Node3D : : add_gizmo ) ;
ClassDB : : bind_method ( D_METHOD ( " get_gizmos " ) , & Node3D : : get_gizmos_bind ) ;
ClassDB : : bind_method ( D_METHOD ( " clear_gizmos " ) , & Node3D : : clear_gizmos ) ;
2021-02-04 17:20:26 +09:00
ClassDB : : bind_method ( D_METHOD ( " set_subgizmo_selection " , " gizmo " , " id " , " transform " ) , & Node3D : : set_subgizmo_selection ) ;
2021-06-23 16:49:50 +02:00
ClassDB : : bind_method ( D_METHOD ( " clear_subgizmo_selection " ) , & Node3D : : clear_subgizmo_selection ) ;
2020-03-26 18:49:16 -03:00
ClassDB : : bind_method ( D_METHOD ( " set_visible " , " visible " ) , & Node3D : : set_visible ) ;
ClassDB : : bind_method ( D_METHOD ( " is_visible " ) , & Node3D : : is_visible ) ;
ClassDB : : bind_method ( D_METHOD ( " is_visible_in_tree " ) , & Node3D : : is_visible_in_tree ) ;
ClassDB : : bind_method ( D_METHOD ( " show " ) , & Node3D : : show ) ;
ClassDB : : bind_method ( D_METHOD ( " hide " ) , & Node3D : : hide ) ;
ClassDB : : bind_method ( D_METHOD ( " set_notify_local_transform " , " enable " ) , & Node3D : : set_notify_local_transform ) ;
ClassDB : : bind_method ( D_METHOD ( " is_local_transform_notification_enabled " ) , & Node3D : : is_local_transform_notification_enabled ) ;
ClassDB : : bind_method ( D_METHOD ( " set_notify_transform " , " enable " ) , & Node3D : : set_notify_transform ) ;
ClassDB : : bind_method ( D_METHOD ( " is_transform_notification_enabled " ) , & Node3D : : is_transform_notification_enabled ) ;
ClassDB : : bind_method ( D_METHOD ( " rotate " , " axis " , " angle " ) , & Node3D : : rotate ) ;
ClassDB : : bind_method ( D_METHOD ( " global_rotate " , " axis " , " angle " ) , & Node3D : : global_rotate ) ;
ClassDB : : bind_method ( D_METHOD ( " global_scale " , " scale " ) , & Node3D : : global_scale ) ;
ClassDB : : bind_method ( D_METHOD ( " global_translate " , " offset " ) , & Node3D : : global_translate ) ;
ClassDB : : bind_method ( D_METHOD ( " rotate_object_local " , " axis " , " angle " ) , & Node3D : : rotate_object_local ) ;
ClassDB : : bind_method ( D_METHOD ( " scale_object_local " , " scale " ) , & Node3D : : scale_object_local ) ;
ClassDB : : bind_method ( D_METHOD ( " translate_object_local " , " offset " ) , & Node3D : : translate_object_local ) ;
ClassDB : : bind_method ( D_METHOD ( " rotate_x " , " angle " ) , & Node3D : : rotate_x ) ;
ClassDB : : bind_method ( D_METHOD ( " rotate_y " , " angle " ) , & Node3D : : rotate_y ) ;
ClassDB : : bind_method ( D_METHOD ( " rotate_z " , " angle " ) , & Node3D : : rotate_z ) ;
ClassDB : : bind_method ( D_METHOD ( " translate " , " offset " ) , & Node3D : : translate ) ;
ClassDB : : bind_method ( D_METHOD ( " orthonormalize " ) , & Node3D : : orthonormalize ) ;
ClassDB : : bind_method ( D_METHOD ( " set_identity " ) , & Node3D : : set_identity ) ;
2021-01-30 04:22:20 -05:00
ClassDB : : bind_method ( D_METHOD ( " look_at " , " target " , " up " ) , & Node3D : : look_at , DEFVAL ( Vector3 ( 0 , 1 , 0 ) ) ) ;
ClassDB : : bind_method ( D_METHOD ( " look_at_from_position " , " position " , " target " , " up " ) , & Node3D : : look_at_from_position , DEFVAL ( Vector3 ( 0 , 1 , 0 ) ) ) ;
2020-03-26 18:49:16 -03:00
ClassDB : : bind_method ( D_METHOD ( " to_local " , " global_point " ) , & Node3D : : to_local ) ;
ClassDB : : bind_method ( D_METHOD ( " to_global " , " local_point " ) , & Node3D : : to_global ) ;
2017-07-23 14:37:26 +03:00
2022-01-02 15:33:17 +00:00
ClassDB : : bind_method ( D_METHOD ( " property_can_revert " , " name " ) , & Node3D : : property_can_revert ) ;
ClassDB : : bind_method ( D_METHOD ( " property_get_revert " , " name " ) , & Node3D : : property_get_revert ) ;
2017-03-05 16:44:50 +01:00
BIND_CONSTANT ( NOTIFICATION_TRANSFORM_CHANGED ) ;
BIND_CONSTANT ( NOTIFICATION_ENTER_WORLD ) ;
BIND_CONSTANT ( NOTIFICATION_EXIT_WORLD ) ;
BIND_CONSTANT ( NOTIFICATION_VISIBILITY_CHANGED ) ;
2014-02-09 22:10:30 -03:00
2021-10-21 13:38:20 -03:00
BIND_ENUM_CONSTANT ( ROTATION_EDIT_MODE_EULER ) ;
BIND_ENUM_CONSTANT ( ROTATION_EDIT_MODE_QUATERNION ) ;
BIND_ENUM_CONSTANT ( ROTATION_EDIT_MODE_BASIS ) ;
BIND_ENUM_CONSTANT ( ROTATION_ORDER_XYZ ) ;
BIND_ENUM_CONSTANT ( ROTATION_ORDER_XZY ) ;
BIND_ENUM_CONSTANT ( ROTATION_ORDER_YXZ ) ;
BIND_ENUM_CONSTANT ( ROTATION_ORDER_YZX ) ;
BIND_ENUM_CONSTANT ( ROTATION_ORDER_ZXY ) ;
BIND_ENUM_CONSTANT ( ROTATION_ORDER_ZYX ) ;
2021-04-28 03:36:08 -04:00
//ADD_PROPERTY( PropertyInfo(Variant::TRANSFORM3D,"transform/global",PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR ), "set_global_transform", "get_global_transform") ;
2017-03-05 16:44:50 +01:00
ADD_GROUP ( " Transform " , " " ) ;
2022-01-02 15:33:17 +00:00
ADD_PROPERTY ( PropertyInfo ( Variant : : TRANSFORM3D , " transform " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NO_EDITOR ) , " set_transform " , " get_transform " ) ;
2021-06-17 19:10:18 -04:00
ADD_PROPERTY ( PropertyInfo ( Variant : : TRANSFORM3D , " global_transform " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NONE ) , " set_global_transform " , " get_global_transform " ) ;
2021-06-29 16:42:12 -03:00
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR3 , " position " , PROPERTY_HINT_RANGE , " -99999,99999,0,or_greater,or_lesser,noslider,suffix:m " , PROPERTY_USAGE_EDITOR ) , " set_position " , " get_position " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR3 , " rotation " , PROPERTY_HINT_RANGE , " -360,360,0.1,or_lesser,or_greater,radians " , PROPERTY_USAGE_EDITOR ) , " set_rotation " , " get_rotation " ) ;
2021-10-21 13:38:20 -03:00
ADD_PROPERTY ( PropertyInfo ( Variant : : QUATERNION , " quaternion " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_EDITOR ) , " set_quaternion " , " get_quaternion " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : BASIS , " basis " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_EDITOR ) , " set_basis " , " get_basis " ) ;
2017-03-05 16:44:50 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR3 , " scale " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_EDITOR ) , " set_scale " , " get_scale " ) ;
2021-10-21 13:38:20 -03:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " rotation_edit_mode " , PROPERTY_HINT_ENUM , " Euler,Quaternion,Basis " ) , " set_rotation_edit_mode " , " get_rotation_edit_mode " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " rotation_order " , PROPERTY_HINT_ENUM , " XYZ,XZY,YXZ,YZX,ZXY,ZYX " ) , " set_rotation_order " , " get_rotation_order " ) ;
2020-10-02 17:03:52 -04:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " top_level " ) , " set_as_top_level " , " is_set_as_top_level " ) ;
2017-03-05 16:44:50 +01:00
ADD_GROUP ( " Visibility " , " " ) ;
2018-11-08 11:30:02 -03:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " visible " ) , " set_visible " , " is_visible " ) ;
2021-05-09 18:23:20 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : NODE_PATH , " visibility_parent " , PROPERTY_HINT_NODE_PATH_VALID_TYPES , " GeometryInstance3D " ) , " set_visibility_parent " , " get_visibility_parent " ) ;
2014-02-09 22:10:30 -03:00
2017-03-05 16:44:50 +01:00
ADD_SIGNAL ( MethodInfo ( " visibility_changed " ) ) ;
2014-02-09 22:10:30 -03:00
}
2020-03-26 18:49:16 -03:00
Node3D : : Node3D ( ) :
2020-12-11 15:54:03 +01:00
xform_change ( this ) { }