2014-02-10 09:10:30 +08:00
/*************************************************************************/
2020-03-27 05:49:16 +08:00
/* physics_body_3d.cpp */
2014-02-10 09:10:30 +08:00
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 20:16:55 +08:00
/* https://godotengine.org */
2014-02-10 09:10:30 +08:00
/*************************************************************************/
2021-01-02 03:13:46 +08:00
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
2014-02-10 09:10:30 +08: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 07:50:27 +08:00
2020-03-27 05:49:16 +08:00
# include "physics_body_3d.h"
2017-08-19 07:02:56 +08:00
2020-11-08 06:33:38 +08:00
# include "core/config/engine.h"
2017-10-25 00:10:30 +08:00
# include "core/core_string_names.h"
2020-11-08 06:33:38 +08:00
# include "core/object/class_db.h"
# include "core/templates/list.h"
# include "core/templates/rid.h"
2020-03-27 05:49:16 +08:00
# include "scene/3d/collision_shape_3d.h"
2014-02-10 09:10:30 +08:00
# include "scene/scene_string_names.h"
2020-03-28 02:21:27 +08:00
# include "servers/navigation_server_3d.h"
2014-02-10 09:10:30 +08:00
2017-10-04 00:49:32 +08:00
# ifdef TOOLS_ENABLED
2020-03-27 15:44:44 +08:00
# include "editor/plugins/node_3d_editor_plugin.h"
2017-10-04 00:49:32 +08:00
# endif
2021-05-20 09:14:33 +08:00
void PhysicsBody3D : : _bind_methods ( ) {
2021-06-02 10:11:56 +08:00
ClassDB : : bind_method ( D_METHOD ( " move_and_collide " , " rel_vec " , " infinite_inertia " , " exclude_raycast_shapes " , " test_only " , " safe_margin " ) , & PhysicsBody3D : : _move , DEFVAL ( true ) , DEFVAL ( true ) , DEFVAL ( false ) , DEFVAL ( 0.001 ) ) ;
ClassDB : : bind_method ( D_METHOD ( " test_move " , " from " , " rel_vec " , " infinite_inertia " , " exclude_raycast_shapes " , " collision " , " safe_margin " ) , & PhysicsBody3D : : test_move , DEFVAL ( true ) , DEFVAL ( true ) , DEFVAL ( Variant ( ) ) , DEFVAL ( 0.001 ) ) ;
2021-05-20 09:14:33 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_axis_lock " , " axis " , " lock " ) , & PhysicsBody3D : : set_axis_lock ) ;
ClassDB : : bind_method ( D_METHOD ( " get_axis_lock " , " axis " ) , & PhysicsBody3D : : get_axis_lock ) ;
ClassDB : : bind_method ( D_METHOD ( " get_collision_exceptions " ) , & PhysicsBody3D : : get_collision_exceptions ) ;
ClassDB : : bind_method ( D_METHOD ( " add_collision_exception_with " , " body " ) , & PhysicsBody3D : : add_collision_exception_with ) ;
ClassDB : : bind_method ( D_METHOD ( " remove_collision_exception_with " , " body " ) , & PhysicsBody3D : : remove_collision_exception_with ) ;
ADD_GROUP ( " Axis Lock " , " axis_lock_ " ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : BOOL , " axis_lock_linear_x " ) , " set_axis_lock " , " get_axis_lock " , PhysicsServer3D : : BODY_AXIS_LINEAR_X ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : BOOL , " axis_lock_linear_y " ) , " set_axis_lock " , " get_axis_lock " , PhysicsServer3D : : BODY_AXIS_LINEAR_Y ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : BOOL , " axis_lock_linear_z " ) , " set_axis_lock " , " get_axis_lock " , PhysicsServer3D : : BODY_AXIS_LINEAR_Z ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : BOOL , " axis_lock_angular_x " ) , " set_axis_lock " , " get_axis_lock " , PhysicsServer3D : : BODY_AXIS_ANGULAR_X ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : BOOL , " axis_lock_angular_y " ) , " set_axis_lock " , " get_axis_lock " , PhysicsServer3D : : BODY_AXIS_ANGULAR_Y ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : BOOL , " axis_lock_angular_z " ) , " set_axis_lock " , " get_axis_lock " , PhysicsServer3D : : BODY_AXIS_ANGULAR_Z ) ;
2014-08-14 21:31:38 +08:00
}
2020-05-14 20:29:06 +08:00
2021-05-20 09:14:33 +08:00
PhysicsBody3D : : PhysicsBody3D ( PhysicsServer3D : : BodyMode p_mode ) :
CollisionObject3D ( PhysicsServer3D : : get_singleton ( ) - > body_create ( ) , false ) {
PhysicsServer3D : : get_singleton ( ) - > body_set_mode ( get_rid ( ) , p_mode ) ;
2014-08-14 21:31:38 +08:00
}
2021-05-20 09:14:33 +08:00
PhysicsBody3D : : ~ PhysicsBody3D ( ) {
if ( motion_cache . is_valid ( ) ) {
motion_cache - > owner = nullptr ;
}
2014-08-14 21:31:38 +08:00
}
2020-04-21 23:16:45 +08:00
TypedArray < PhysicsBody3D > PhysicsBody3D : : get_collision_exceptions ( ) {
2018-10-25 03:32:55 +08:00
List < RID > exceptions ;
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_get_collision_exceptions ( get_rid ( ) , & exceptions ) ;
2018-10-25 03:32:55 +08:00
Array ret ;
for ( List < RID > : : Element * E = exceptions . front ( ) ; E ; E = E - > next ( ) ) {
RID body = E - > get ( ) ;
2020-03-28 02:21:27 +08:00
ObjectID instance_id = PhysicsServer3D : : get_singleton ( ) - > body_get_object_instance_id ( body ) ;
2018-10-25 03:32:55 +08:00
Object * obj = ObjectDB : : get_instance ( instance_id ) ;
2020-03-27 05:49:16 +08:00
PhysicsBody3D * physics_body = Object : : cast_to < PhysicsBody3D > ( obj ) ;
2018-10-25 03:32:55 +08:00
ret . append ( physics_body ) ;
}
return ret ;
}
2020-03-27 05:49:16 +08:00
void PhysicsBody3D : : add_collision_exception_with ( Node * p_node ) {
2014-09-22 12:03:56 +08:00
ERR_FAIL_NULL ( p_node ) ;
2020-03-27 05:49:16 +08:00
CollisionObject3D * collision_object = Object : : cast_to < CollisionObject3D > ( p_node ) ;
2020-03-31 00:22:57 +08:00
ERR_FAIL_COND_MSG ( ! collision_object , " Collision exception only works between two CollisionObject3Ds. " ) ;
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_add_collision_exception ( get_rid ( ) , collision_object - > get_rid ( ) ) ;
2014-09-22 12:03:56 +08:00
}
2020-03-27 05:49:16 +08:00
void PhysicsBody3D : : remove_collision_exception_with ( Node * p_node ) {
2014-09-22 12:03:56 +08:00
ERR_FAIL_NULL ( p_node ) ;
2020-03-27 05:49:16 +08:00
CollisionObject3D * collision_object = Object : : cast_to < CollisionObject3D > ( p_node ) ;
2020-03-31 00:22:57 +08:00
ERR_FAIL_COND_MSG ( ! collision_object , " Collision exception only works between two CollisionObject3Ds. " ) ;
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_remove_collision_exception ( get_rid ( ) , collision_object - > get_rid ( ) ) ;
2014-09-22 12:03:56 +08:00
}
2021-06-02 10:11:56 +08:00
Ref < KinematicCollision3D > PhysicsBody3D : : _move ( const Vector3 & p_motion , bool p_infinite_inertia , bool p_exclude_raycast_shapes , bool p_test_only , real_t p_margin ) {
2021-05-20 09:14:33 +08:00
PhysicsServer3D : : MotionResult result ;
2021-06-02 10:11:56 +08:00
if ( move_and_collide ( p_motion , p_infinite_inertia , result , p_margin , p_exclude_raycast_shapes , p_test_only ) ) {
2021-05-20 09:14:33 +08:00
if ( motion_cache . is_null ( ) ) {
motion_cache . instance ( ) ;
motion_cache - > owner = this ;
}
2014-02-10 09:10:30 +08:00
2021-05-20 09:14:33 +08:00
motion_cache - > result = result ;
return motion_cache ;
}
return Ref < KinematicCollision3D > ( ) ;
}
2021-06-02 10:11:56 +08:00
bool PhysicsBody3D : : move_and_collide ( const Vector3 & p_motion , bool p_infinite_inertia , PhysicsServer3D : : MotionResult & r_result , real_t p_margin , bool p_exclude_raycast_shapes , bool p_test_only ) {
2021-05-20 09:14:33 +08:00
Transform3D gt = get_global_transform ( ) ;
2021-06-02 10:11:56 +08:00
bool colliding = PhysicsServer3D : : get_singleton ( ) - > body_test_motion ( get_rid ( ) , gt , p_motion , p_infinite_inertia , p_margin , & r_result , p_exclude_raycast_shapes ) ;
2021-05-20 09:14:33 +08:00
for ( int i = 0 ; i < 3 ; i + + ) {
if ( locked_axis & ( 1 < < i ) ) {
r_result . motion [ i ] = 0 ;
}
}
if ( ! p_test_only ) {
gt . origin + = r_result . motion ;
set_global_transform ( gt ) ;
}
return colliding ;
}
2021-06-02 10:11:56 +08:00
bool PhysicsBody3D : : test_move ( const Transform3D & p_from , const Vector3 & p_motion , bool p_infinite_inertia , bool p_exclude_raycast_shapes , const Ref < KinematicCollision3D > & r_collision , real_t p_margin ) {
2021-05-20 09:14:33 +08:00
ERR_FAIL_COND_V ( ! is_inside_tree ( ) , false ) ;
PhysicsServer3D : : MotionResult * r = nullptr ;
if ( r_collision . is_valid ( ) ) {
// Needs const_cast because method bindings don't support non-const Ref.
r = const_cast < PhysicsServer3D : : MotionResult * > ( & r_collision - > result ) ;
}
2021-06-02 10:11:56 +08:00
return PhysicsServer3D : : get_singleton ( ) - > body_test_motion ( get_rid ( ) , p_from , p_motion , p_infinite_inertia , p_margin , r , p_exclude_raycast_shapes ) ;
2021-05-20 09:14:33 +08:00
}
void PhysicsBody3D : : set_axis_lock ( PhysicsServer3D : : BodyAxis p_axis , bool p_lock ) {
if ( p_lock ) {
locked_axis | = p_axis ;
} else {
locked_axis & = ( ~ p_axis ) ;
}
PhysicsServer3D : : get_singleton ( ) - > body_set_axis_lock ( get_rid ( ) , p_axis , p_lock ) ;
}
bool PhysicsBody3D : : get_axis_lock ( PhysicsServer3D : : BodyAxis p_axis ) const {
return ( locked_axis & p_axis ) ;
}
Vector3 PhysicsBody3D : : get_linear_velocity ( ) const {
return Vector3 ( ) ;
}
Vector3 PhysicsBody3D : : get_angular_velocity ( ) const {
return Vector3 ( ) ;
}
real_t PhysicsBody3D : : get_inverse_mass ( ) const {
return 0 ;
2014-09-03 10:13:40 +08:00
}
2014-02-10 09:10:30 +08:00
2020-03-27 05:49:16 +08:00
void StaticBody3D : : set_physics_material_override ( const Ref < PhysicsMaterial > & p_physics_material_override ) {
2017-10-25 00:10:30 +08:00
if ( physics_material_override . is_valid ( ) ) {
2020-03-27 05:49:16 +08:00
if ( physics_material_override - > is_connected ( CoreStringNames : : get_singleton ( ) - > changed , callable_mp ( this , & StaticBody3D : : _reload_physics_characteristics ) ) ) {
physics_material_override - > disconnect ( CoreStringNames : : get_singleton ( ) - > changed , callable_mp ( this , & StaticBody3D : : _reload_physics_characteristics ) ) ;
2020-02-22 06:26:13 +08:00
}
2017-10-25 00:10:30 +08:00
}
physics_material_override = p_physics_material_override ;
if ( physics_material_override . is_valid ( ) ) {
2020-03-27 05:49:16 +08:00
physics_material_override - > connect ( CoreStringNames : : get_singleton ( ) - > changed , callable_mp ( this , & StaticBody3D : : _reload_physics_characteristics ) ) ;
2017-10-25 00:10:30 +08:00
}
_reload_physics_characteristics ( ) ;
}
2020-03-27 05:49:16 +08:00
Ref < PhysicsMaterial > StaticBody3D : : get_physics_material_override ( ) const {
2017-10-25 00:10:30 +08:00
return physics_material_override ;
2014-09-03 10:13:40 +08:00
}
2014-02-10 09:10:30 +08:00
2021-05-21 02:02:16 +08:00
void StaticBody3D : : set_kinematic_motion_enabled ( bool p_enabled ) {
if ( p_enabled = = kinematic_motion ) {
return ;
}
kinematic_motion = p_enabled ;
if ( kinematic_motion ) {
PhysicsServer3D : : get_singleton ( ) - > body_set_mode ( get_rid ( ) , PhysicsServer3D : : BODY_MODE_KINEMATIC ) ;
} else {
PhysicsServer3D : : get_singleton ( ) - > body_set_mode ( get_rid ( ) , PhysicsServer3D : : BODY_MODE_STATIC ) ;
}
_update_kinematic_motion ( ) ;
}
bool StaticBody3D : : is_kinematic_motion_enabled ( ) const {
return kinematic_motion ;
}
2020-03-27 05:49:16 +08:00
void StaticBody3D : : set_constant_linear_velocity ( const Vector3 & p_vel ) {
2017-03-05 23:44:50 +08:00
constant_linear_velocity = p_vel ;
2021-05-21 02:02:16 +08:00
if ( kinematic_motion ) {
_update_kinematic_motion ( ) ;
} else {
PhysicsServer3D : : get_singleton ( ) - > body_set_state ( get_rid ( ) , PhysicsServer3D : : BODY_STATE_LINEAR_VELOCITY , constant_linear_velocity ) ;
}
2014-09-03 10:13:40 +08:00
}
2014-02-10 09:10:30 +08:00
2020-03-27 05:49:16 +08:00
void StaticBody3D : : set_constant_angular_velocity ( const Vector3 & p_vel ) {
2017-03-05 23:44:50 +08:00
constant_angular_velocity = p_vel ;
2021-05-21 02:02:16 +08:00
if ( kinematic_motion ) {
_update_kinematic_motion ( ) ;
} else {
PhysicsServer3D : : get_singleton ( ) - > body_set_state ( get_rid ( ) , PhysicsServer3D : : BODY_STATE_ANGULAR_VELOCITY , constant_angular_velocity ) ;
}
2014-02-10 09:10:30 +08:00
}
2020-03-27 05:49:16 +08:00
Vector3 StaticBody3D : : get_constant_linear_velocity ( ) const {
2014-09-03 10:13:40 +08:00
return constant_linear_velocity ;
}
2020-05-14 20:29:06 +08:00
2020-03-27 05:49:16 +08:00
Vector3 StaticBody3D : : get_constant_angular_velocity ( ) const {
2014-09-03 10:13:40 +08:00
return constant_angular_velocity ;
2014-02-10 09:10:30 +08:00
}
2021-05-21 02:02:16 +08:00
void StaticBody3D : : _notification ( int p_what ) {
if ( p_what = = NOTIFICATION_INTERNAL_PHYSICS_PROCESS ) {
# ifdef TOOLS_ENABLED
if ( Engine : : get_singleton ( ) - > is_editor_hint ( ) ) {
return ;
}
# endif
ERR_FAIL_COND ( ! kinematic_motion ) ;
real_t delta_time = get_physics_process_delta_time ( ) ;
Transform3D new_transform = get_global_transform ( ) ;
new_transform . origin + = constant_linear_velocity * delta_time ;
real_t ang_vel = constant_angular_velocity . length ( ) ;
if ( ! Math : : is_zero_approx ( ang_vel ) ) {
Vector3 ang_vel_axis = constant_angular_velocity / ang_vel ;
Basis rot ( ang_vel_axis , ang_vel * delta_time ) ;
new_transform . basis = rot * new_transform . basis ;
new_transform . orthonormalize ( ) ;
}
PhysicsServer3D : : get_singleton ( ) - > body_set_state ( get_rid ( ) , PhysicsServer3D : : BODY_STATE_TRANSFORM , new_transform ) ;
// Propagate transform change to node.
set_ignore_transform_notification ( true ) ;
set_global_transform ( new_transform ) ;
set_ignore_transform_notification ( false ) ;
_on_transform_changed ( ) ;
}
}
2020-03-27 05:49:16 +08:00
void StaticBody3D : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " set_constant_linear_velocity " , " vel " ) , & StaticBody3D : : set_constant_linear_velocity ) ;
ClassDB : : bind_method ( D_METHOD ( " set_constant_angular_velocity " , " vel " ) , & StaticBody3D : : set_constant_angular_velocity ) ;
ClassDB : : bind_method ( D_METHOD ( " get_constant_linear_velocity " ) , & StaticBody3D : : get_constant_linear_velocity ) ;
ClassDB : : bind_method ( D_METHOD ( " get_constant_angular_velocity " ) , & StaticBody3D : : get_constant_angular_velocity ) ;
2014-02-10 09:10:30 +08:00
2021-05-21 02:02:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_kinematic_motion_enabled " , " enabled " ) , & StaticBody3D : : set_kinematic_motion_enabled ) ;
ClassDB : : bind_method ( D_METHOD ( " is_kinematic_motion_enabled " ) , & StaticBody3D : : is_kinematic_motion_enabled ) ;
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_physics_material_override " , " physics_material_override " ) , & StaticBody3D : : set_physics_material_override ) ;
ClassDB : : bind_method ( D_METHOD ( " get_physics_material_override " ) , & StaticBody3D : : get_physics_material_override ) ;
2017-10-25 00:10:30 +08:00
2018-11-08 22:30:02 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : OBJECT , " physics_material_override " , PROPERTY_HINT_RESOURCE_TYPE , " PhysicsMaterial " ) , " set_physics_material_override " , " get_physics_material_override " ) ;
2017-03-05 23:44:50 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR3 , " constant_linear_velocity " ) , " set_constant_linear_velocity " , " get_constant_linear_velocity " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR3 , " constant_angular_velocity " ) , " set_constant_angular_velocity " , " get_constant_angular_velocity " ) ;
2021-05-21 02:02:16 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " kinematic_motion " ) , " set_kinematic_motion_enabled " , " is_kinematic_motion_enabled " ) ;
2014-02-10 09:10:30 +08:00
}
2020-03-27 05:49:16 +08:00
StaticBody3D : : StaticBody3D ( ) :
2020-03-28 02:21:27 +08:00
PhysicsBody3D ( PhysicsServer3D : : BODY_MODE_STATIC ) {
2014-02-10 09:10:30 +08:00
}
2020-03-27 05:49:16 +08:00
void StaticBody3D : : _reload_physics_characteristics ( ) {
2017-10-25 00:10:30 +08:00
if ( physics_material_override . is_null ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer3D : : BODY_PARAM_BOUNCE , 0 ) ;
PhysicsServer3D : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer3D : : BODY_PARAM_FRICTION , 1 ) ;
2017-10-25 00:10:30 +08:00
} else {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer3D : : BODY_PARAM_BOUNCE , physics_material_override - > computed_bounce ( ) ) ;
PhysicsServer3D : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer3D : : BODY_PARAM_FRICTION , physics_material_override - > computed_friction ( ) ) ;
2017-10-25 00:10:30 +08:00
}
2014-02-10 09:10:30 +08:00
}
2021-05-21 02:02:16 +08:00
void StaticBody3D : : _update_kinematic_motion ( ) {
# ifdef TOOLS_ENABLED
if ( Engine : : get_singleton ( ) - > is_editor_hint ( ) ) {
return ;
}
# endif
if ( kinematic_motion ) {
if ( ! constant_angular_velocity . is_equal_approx ( Vector3 ( ) ) | | ! constant_linear_velocity . is_equal_approx ( Vector3 ( ) ) ) {
set_physics_process_internal ( true ) ;
return ;
}
}
set_physics_process_internal ( false ) ;
}
2020-03-27 05:49:16 +08:00
void RigidBody3D : : _body_enter_tree ( ObjectID p_id ) {
2014-02-10 09:10:30 +08:00
Object * obj = ObjectDB : : get_instance ( p_id ) ;
2017-08-25 04:58:51 +08:00
Node * node = Object : : cast_to < Node > ( obj ) ;
2014-02-10 09:10:30 +08:00
ERR_FAIL_COND ( ! node ) ;
2018-01-21 19:46:13 +08:00
ERR_FAIL_COND ( ! contact_monitor ) ;
2017-03-05 23:44:50 +08:00
Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . find ( p_id ) ;
2014-02-10 09:10:30 +08:00
ERR_FAIL_COND ( ! E ) ;
2014-11-06 08:20:42 +08:00
ERR_FAIL_COND ( E - > get ( ) . in_tree ) ;
2014-02-10 09:10:30 +08:00
2017-03-05 23:44:50 +08:00
E - > get ( ) . in_tree = true ;
2016-01-12 17:14:15 +08:00
2017-03-05 23:44:50 +08:00
contact_monitor - > locked = true ;
2016-01-12 17:14:15 +08:00
2017-03-05 23:44:50 +08:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_entered , node ) ;
2014-02-10 09:10:30 +08:00
2017-03-05 23:44:50 +08:00
for ( int i = 0 ; i < E - > get ( ) . shapes . size ( ) ; i + + ) {
2020-10-12 23:25:32 +08:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_shape_entered , E - > get ( ) . rid , node , E - > get ( ) . shapes [ i ] . body_shape , E - > get ( ) . shapes [ i ] . local_shape ) ;
2014-02-10 09:10:30 +08:00
}
2017-03-05 23:44:50 +08:00
contact_monitor - > locked = false ;
2014-02-10 09:10:30 +08:00
}
2020-03-27 05:49:16 +08:00
void RigidBody3D : : _body_exit_tree ( ObjectID p_id ) {
2014-02-10 09:10:30 +08:00
Object * obj = ObjectDB : : get_instance ( p_id ) ;
2017-08-25 04:58:51 +08:00
Node * node = Object : : cast_to < Node > ( obj ) ;
2014-02-10 09:10:30 +08:00
ERR_FAIL_COND ( ! node ) ;
2018-01-21 19:46:13 +08:00
ERR_FAIL_COND ( ! contact_monitor ) ;
2017-03-05 23:44:50 +08:00
Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . find ( p_id ) ;
2014-02-10 09:10:30 +08:00
ERR_FAIL_COND ( ! E ) ;
2014-11-06 08:20:42 +08:00
ERR_FAIL_COND ( ! E - > get ( ) . in_tree ) ;
2017-03-05 23:44:50 +08:00
E - > get ( ) . in_tree = false ;
2016-01-12 17:14:15 +08:00
2017-03-05 23:44:50 +08:00
contact_monitor - > locked = true ;
2016-01-12 17:14:15 +08:00
2017-03-05 23:44:50 +08:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_exited , node ) ;
2016-01-12 17:14:15 +08:00
2017-03-05 23:44:50 +08:00
for ( int i = 0 ; i < E - > get ( ) . shapes . size ( ) ; i + + ) {
2020-10-12 23:25:32 +08:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_shape_exited , E - > get ( ) . rid , node , E - > get ( ) . shapes [ i ] . body_shape , E - > get ( ) . shapes [ i ] . local_shape ) ;
2014-02-10 09:10:30 +08:00
}
2016-01-12 17:14:15 +08:00
2017-03-05 23:44:50 +08:00
contact_monitor - > locked = false ;
2014-02-10 09:10:30 +08:00
}
2020-10-12 23:25:32 +08:00
void RigidBody3D : : _body_inout ( int p_status , const RID & p_body , ObjectID p_instance , int p_body_shape , int p_local_shape ) {
2017-03-05 23:44:50 +08:00
bool body_in = p_status = = 1 ;
ObjectID objid = p_instance ;
2014-02-10 09:10:30 +08:00
Object * obj = ObjectDB : : get_instance ( objid ) ;
2017-08-25 04:58:51 +08:00
Node * node = Object : : cast_to < Node > ( obj ) ;
2014-02-10 09:10:30 +08:00
2018-01-21 19:46:13 +08:00
ERR_FAIL_COND ( ! contact_monitor ) ;
2017-03-05 23:44:50 +08:00
Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . find ( objid ) ;
2014-02-10 09:10:30 +08:00
ERR_FAIL_COND ( ! body_in & & ! E ) ;
if ( body_in ) {
if ( ! E ) {
2017-03-05 23:44:50 +08:00
E = contact_monitor - > body_map . insert ( objid , BodyState ( ) ) ;
2020-10-12 23:25:32 +08:00
E - > get ( ) . rid = p_body ;
2014-10-03 19:58:41 +08:00
//E->get().rc=0;
2017-03-05 23:44:50 +08:00
E - > get ( ) . in_tree = node & & node - > is_inside_tree ( ) ;
2014-02-10 09:10:30 +08:00
if ( node ) {
2020-03-27 05:49:16 +08:00
node - > connect ( SceneStringNames : : get_singleton ( ) - > tree_entered , callable_mp ( this , & RigidBody3D : : _body_enter_tree ) , make_binds ( objid ) ) ;
node - > connect ( SceneStringNames : : get_singleton ( ) - > tree_exiting , callable_mp ( this , & RigidBody3D : : _body_exit_tree ) , make_binds ( objid ) ) ;
2014-11-06 08:20:42 +08:00
if ( E - > get ( ) . in_tree ) {
2017-03-05 23:44:50 +08:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_entered , node ) ;
2014-02-10 09:10:30 +08:00
}
}
}
2014-10-03 19:58:41 +08:00
//E->get().rc++;
2020-05-14 22:41:43 +08:00
if ( node ) {
2017-03-05 23:44:50 +08:00
E - > get ( ) . shapes . insert ( ShapePair ( p_body_shape , p_local_shape ) ) ;
2020-05-14 22:41:43 +08:00
}
2014-02-10 09:10:30 +08:00
2014-11-06 08:20:42 +08:00
if ( E - > get ( ) . in_tree ) {
2020-10-12 23:25:32 +08:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_shape_entered , p_body , node , p_body_shape , p_local_shape ) ;
2014-02-10 09:10:30 +08:00
}
} else {
2014-10-03 19:58:41 +08:00
//E->get().rc--;
2014-02-10 09:10:30 +08:00
2020-05-14 22:41:43 +08:00
if ( node ) {
2017-03-05 23:44:50 +08:00
E - > get ( ) . shapes . erase ( ShapePair ( p_body_shape , p_local_shape ) ) ;
2020-05-14 22:41:43 +08:00
}
2014-02-10 09:10:30 +08:00
2014-11-06 08:20:42 +08:00
bool in_tree = E - > get ( ) . in_tree ;
2014-10-03 19:58:41 +08:00
2020-12-15 20:04:21 +08:00
if ( E - > get ( ) . shapes . is_empty ( ) ) {
2014-02-10 09:10:30 +08:00
if ( node ) {
2020-03-27 05:49:16 +08:00
node - > disconnect ( SceneStringNames : : get_singleton ( ) - > tree_entered , callable_mp ( this , & RigidBody3D : : _body_enter_tree ) ) ;
node - > disconnect ( SceneStringNames : : get_singleton ( ) - > tree_exiting , callable_mp ( this , & RigidBody3D : : _body_exit_tree ) ) ;
2020-05-14 22:41:43 +08:00
if ( in_tree ) {
2018-09-01 18:05:51 +08:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_exited , node ) ;
2020-05-14 22:41:43 +08:00
}
2014-02-10 09:10:30 +08:00
}
contact_monitor - > body_map . erase ( E ) ;
}
2014-11-06 08:20:42 +08:00
if ( node & & in_tree ) {
2020-10-12 23:25:32 +08:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_shape_exited , p_body , obj , p_body_shape , p_local_shape ) ;
2014-02-10 09:10:30 +08:00
}
}
}
struct _RigidBodyInOut {
2020-10-12 23:25:32 +08:00
RID rid ;
2014-02-10 09:10:30 +08:00
ObjectID id ;
2021-02-08 05:29:31 +08:00
int shape = 0 ;
int local_shape = 0 ;
2014-02-10 09:10:30 +08:00
} ;
2020-03-27 05:49:16 +08:00
void RigidBody3D : : _direct_state_changed ( Object * p_state ) {
2014-02-10 09:10:30 +08:00
# ifdef DEBUG_ENABLED
2020-03-28 02:21:27 +08:00
state = Object : : cast_to < PhysicsDirectBodyState3D > ( p_state ) ;
2021-03-30 14:22:23 +08:00
ERR_FAIL_NULL_MSG ( state , " Method '_direct_state_changed' must receive a valid PhysicsDirectBodyState3D object as argument " ) ;
2014-02-10 09:10:30 +08:00
# else
2020-03-28 08:50:00 +08:00
state = ( PhysicsDirectBodyState3D * ) p_state ; //trust it
2014-02-10 09:10:30 +08:00
# endif
2016-06-18 03:45:10 +08:00
set_ignore_transform_notification ( true ) ;
set_global_transform ( state - > get_transform ( ) ) ;
2017-03-05 23:44:50 +08:00
linear_velocity = state - > get_linear_velocity ( ) ;
angular_velocity = state - > get_angular_velocity ( ) ;
2020-07-20 00:45:36 +08:00
inverse_inertia_tensor = state - > get_inverse_inertia_tensor ( ) ;
2017-03-05 23:44:50 +08:00
if ( sleeping ! = state - > is_sleeping ( ) ) {
sleeping = state - > is_sleeping ( ) ;
2016-06-18 03:45:10 +08:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > sleeping_state_changed ) ;
}
2020-05-14 22:41:43 +08:00
if ( get_script_instance ( ) ) {
2017-03-05 23:44:50 +08:00
get_script_instance ( ) - > call ( " _integrate_forces " , state ) ;
2020-05-14 22:41:43 +08:00
}
2016-06-18 03:45:10 +08:00
set_ignore_transform_notification ( false ) ;
2021-04-25 17:27:13 +08:00
_on_transform_changed ( ) ;
2016-06-18 03:45:10 +08:00
2014-02-10 09:10:30 +08:00
if ( contact_monitor ) {
2017-03-05 23:44:50 +08:00
contact_monitor - > locked = true ;
2016-01-12 17:14:15 +08:00
2014-02-10 09:10:30 +08:00
//untag all
2017-03-05 23:44:50 +08:00
int rc = 0 ;
for ( Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . front ( ) ; E ; E = E - > next ( ) ) {
for ( int i = 0 ; i < E - > get ( ) . shapes . size ( ) ; i + + ) {
E - > get ( ) . shapes [ i ] . tagged = false ;
2014-02-10 09:10:30 +08:00
rc + + ;
}
}
2017-03-05 23:44:50 +08:00
_RigidBodyInOut * toadd = ( _RigidBodyInOut * ) alloca ( state - > get_contact_count ( ) * sizeof ( _RigidBodyInOut ) ) ;
int toadd_count = 0 ; //state->get_contact_count();
2020-03-31 00:22:57 +08:00
RigidBody3D_RemoveAction * toremove = ( RigidBody3D_RemoveAction * ) alloca ( rc * sizeof ( RigidBody3D_RemoveAction ) ) ;
2017-03-05 23:44:50 +08:00
int toremove_count = 0 ;
2014-02-10 09:10:30 +08:00
//put the ones to add
2017-03-05 23:44:50 +08:00
for ( int i = 0 ; i < state - > get_contact_count ( ) ; i + + ) {
2020-10-12 23:25:32 +08:00
RID rid = state - > get_contact_collider ( i ) ;
2014-02-10 09:10:30 +08:00
ObjectID obj = state - > get_contact_collider_id ( i ) ;
int local_shape = state - > get_contact_local_shape ( i ) ;
int shape = state - > get_contact_collider_shape ( i ) ;
2017-01-14 19:26:56 +08:00
//bool found=false;
2014-02-10 09:10:30 +08:00
2017-03-05 23:44:50 +08:00
Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . find ( obj ) ;
2014-02-10 09:10:30 +08:00
if ( ! E ) {
2020-10-12 23:25:32 +08:00
toadd [ toadd_count ] . rid = rid ;
2017-03-05 23:44:50 +08:00
toadd [ toadd_count ] . local_shape = local_shape ;
toadd [ toadd_count ] . id = obj ;
toadd [ toadd_count ] . shape = shape ;
2014-02-10 09:10:30 +08:00
toadd_count + + ;
continue ;
}
2017-03-05 23:44:50 +08:00
ShapePair sp ( shape , local_shape ) ;
2014-02-10 09:10:30 +08:00
int idx = E - > get ( ) . shapes . find ( sp ) ;
2017-03-05 23:44:50 +08:00
if ( idx = = - 1 ) {
2020-10-12 23:25:32 +08:00
toadd [ toadd_count ] . rid = rid ;
2017-03-05 23:44:50 +08:00
toadd [ toadd_count ] . local_shape = local_shape ;
toadd [ toadd_count ] . id = obj ;
toadd [ toadd_count ] . shape = shape ;
2014-02-10 09:10:30 +08:00
toadd_count + + ;
continue ;
}
2017-03-05 23:44:50 +08:00
E - > get ( ) . shapes [ idx ] . tagged = true ;
2014-02-10 09:10:30 +08:00
}
//put the ones to remove
2017-03-05 23:44:50 +08:00
for ( Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . front ( ) ; E ; E = E - > next ( ) ) {
for ( int i = 0 ; i < E - > get ( ) . shapes . size ( ) ; i + + ) {
2014-02-10 09:10:30 +08:00
if ( ! E - > get ( ) . shapes [ i ] . tagged ) {
2020-10-12 23:25:32 +08:00
toremove [ toremove_count ] . rid = E - > get ( ) . rid ;
2017-03-05 23:44:50 +08:00
toremove [ toremove_count ] . body_id = E - > key ( ) ;
toremove [ toremove_count ] . pair = E - > get ( ) . shapes [ i ] ;
2014-02-10 09:10:30 +08:00
toremove_count + + ;
}
}
}
2021-03-12 21:35:16 +08:00
//process removals
2014-02-10 09:10:30 +08:00
2017-03-05 23:44:50 +08:00
for ( int i = 0 ; i < toremove_count ; i + + ) {
2020-10-12 23:25:32 +08:00
_body_inout ( 0 , toremove [ i ] . rid , toremove [ i ] . body_id , toremove [ i ] . pair . body_shape , toremove [ i ] . pair . local_shape ) ;
2014-02-10 09:10:30 +08:00
}
2021-03-12 21:35:16 +08:00
//process additions
2014-02-10 09:10:30 +08:00
2017-03-05 23:44:50 +08:00
for ( int i = 0 ; i < toadd_count ; i + + ) {
2020-10-12 23:25:32 +08:00
_body_inout ( 1 , toremove [ i ] . rid , toadd [ i ] . id , toadd [ i ] . shape , toadd [ i ] . local_shape ) ;
2014-02-10 09:10:30 +08:00
}
2017-03-05 23:44:50 +08:00
contact_monitor - > locked = false ;
2014-02-10 09:10:30 +08:00
}
2020-04-02 07:20:12 +08:00
state = nullptr ;
2014-02-10 09:10:30 +08:00
}
2020-03-27 05:49:16 +08:00
void RigidBody3D : : _notification ( int p_what ) {
2017-08-06 03:06:15 +08:00
# ifdef TOOLS_ENABLED
if ( p_what = = NOTIFICATION_ENTER_TREE ) {
2017-08-19 07:02:56 +08:00
if ( Engine : : get_singleton ( ) - > is_editor_hint ( ) ) {
2017-08-06 03:06:15 +08:00
set_notify_local_transform ( true ) ; //used for warnings and only in editor
}
}
if ( p_what = = NOTIFICATION_LOCAL_TRANSFORM_CHANGED ) {
2017-08-19 07:02:56 +08:00
if ( Engine : : get_singleton ( ) - > is_editor_hint ( ) ) {
2020-10-29 18:01:28 +08:00
update_configuration_warnings ( ) ;
2017-08-06 03:06:15 +08:00
}
}
# endif
2014-02-10 09:10:30 +08:00
}
2020-03-27 05:49:16 +08:00
void RigidBody3D : : set_mode ( Mode p_mode ) {
2017-03-05 23:44:50 +08:00
mode = p_mode ;
switch ( p_mode ) {
2021-05-20 09:15:07 +08:00
case MODE_DYNAMIC : {
PhysicsServer3D : : get_singleton ( ) - > body_set_mode ( get_rid ( ) , PhysicsServer3D : : BODY_MODE_DYNAMIC ) ;
2014-02-10 09:10:30 +08:00
} break ;
case MODE_STATIC : {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_mode ( get_rid ( ) , PhysicsServer3D : : BODY_MODE_STATIC ) ;
2014-02-10 09:10:30 +08:00
} break ;
2021-05-20 09:15:07 +08:00
case MODE_DYNAMIC_LOCKED : {
PhysicsServer3D : : get_singleton ( ) - > body_set_mode ( get_rid ( ) , PhysicsServer3D : : BODY_MODE_DYNAMIC_LOCKED ) ;
2014-02-10 09:10:30 +08:00
} break ;
2014-02-19 22:57:14 +08:00
case MODE_KINEMATIC : {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_mode ( get_rid ( ) , PhysicsServer3D : : BODY_MODE_KINEMATIC ) ;
2014-02-10 09:10:30 +08:00
} break ;
}
2020-10-29 18:01:28 +08:00
update_configuration_warnings ( ) ;
2014-02-10 09:10:30 +08:00
}
2020-03-27 05:49:16 +08:00
RigidBody3D : : Mode RigidBody3D : : get_mode ( ) const {
2014-02-10 09:10:30 +08:00
return mode ;
}
2020-03-27 05:49:16 +08:00
void RigidBody3D : : set_mass ( real_t p_mass ) {
2017-03-05 23:44:50 +08:00
ERR_FAIL_COND ( p_mass < = 0 ) ;
mass = p_mass ;
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer3D : : BODY_PARAM_MASS , mass ) ;
2014-02-10 09:10:30 +08:00
}
2020-05-14 20:29:06 +08:00
2020-03-27 05:49:16 +08:00
real_t RigidBody3D : : get_mass ( ) const {
2014-02-10 09:10:30 +08:00
return mass ;
}
2020-03-27 05:49:16 +08:00
void RigidBody3D : : set_physics_material_override ( const Ref < PhysicsMaterial > & p_physics_material_override ) {
2017-10-25 00:10:30 +08:00
if ( physics_material_override . is_valid ( ) ) {
2020-03-27 05:49:16 +08:00
if ( physics_material_override - > is_connected ( CoreStringNames : : get_singleton ( ) - > changed , callable_mp ( this , & RigidBody3D : : _reload_physics_characteristics ) ) ) {
physics_material_override - > disconnect ( CoreStringNames : : get_singleton ( ) - > changed , callable_mp ( this , & RigidBody3D : : _reload_physics_characteristics ) ) ;
2020-02-22 06:26:13 +08:00
}
2017-10-25 00:10:30 +08:00
}
physics_material_override = p_physics_material_override ;
if ( physics_material_override . is_valid ( ) ) {
2020-03-27 05:49:16 +08:00
physics_material_override - > connect ( CoreStringNames : : get_singleton ( ) - > changed , callable_mp ( this , & RigidBody3D : : _reload_physics_characteristics ) ) ;
2017-10-25 00:10:30 +08:00
}
_reload_physics_characteristics ( ) ;
}
2020-03-27 05:49:16 +08:00
Ref < PhysicsMaterial > RigidBody3D : : get_physics_material_override ( ) const {
2017-10-25 00:10:30 +08:00
return physics_material_override ;
2014-02-10 09:10:30 +08:00
}
2020-03-27 05:49:16 +08:00
void RigidBody3D : : set_gravity_scale ( real_t p_gravity_scale ) {
2017-03-05 23:44:50 +08:00
gravity_scale = p_gravity_scale ;
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer3D : : BODY_PARAM_GRAVITY_SCALE , gravity_scale ) ;
2015-08-31 05:57:17 +08:00
}
2020-05-14 20:29:06 +08:00
2020-03-27 05:49:16 +08:00
real_t RigidBody3D : : get_gravity_scale ( ) const {
2015-08-31 05:57:17 +08:00
return gravity_scale ;
}
2020-03-27 05:49:16 +08:00
void RigidBody3D : : set_linear_damp ( real_t p_linear_damp ) {
2017-03-05 23:44:50 +08:00
ERR_FAIL_COND ( p_linear_damp < - 1 ) ;
linear_damp = p_linear_damp ;
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer3D : : BODY_PARAM_LINEAR_DAMP , linear_damp ) ;
2015-08-31 05:57:17 +08:00
}
2020-05-14 20:29:06 +08:00
2020-03-27 05:49:16 +08:00
real_t RigidBody3D : : get_linear_damp ( ) const {
2015-08-31 05:57:17 +08:00
return linear_damp ;
}
2020-03-27 05:49:16 +08:00
void RigidBody3D : : set_angular_damp ( real_t p_angular_damp ) {
2017-03-05 23:44:50 +08:00
ERR_FAIL_COND ( p_angular_damp < - 1 ) ;
angular_damp = p_angular_damp ;
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer3D : : BODY_PARAM_ANGULAR_DAMP , angular_damp ) ;
2015-08-31 05:57:17 +08:00
}
2020-05-14 20:29:06 +08:00
2020-03-27 05:49:16 +08:00
real_t RigidBody3D : : get_angular_damp ( ) const {
2015-08-31 05:57:17 +08:00
return angular_damp ;
}
2020-03-27 05:49:16 +08:00
void RigidBody3D : : set_axis_velocity ( const Vector3 & p_axis ) {
2017-03-05 23:44:50 +08:00
Vector3 v = state ? state - > get_linear_velocity ( ) : linear_velocity ;
2014-02-10 09:10:30 +08:00
Vector3 axis = p_axis . normalized ( ) ;
2017-03-05 23:44:50 +08:00
v - = axis * axis . dot ( v ) ;
v + = p_axis ;
2014-02-10 09:10:30 +08:00
if ( state ) {
set_linear_velocity ( v ) ;
} else {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_axis_velocity ( get_rid ( ) , p_axis ) ;
2017-03-05 23:44:50 +08:00
linear_velocity = v ;
2014-02-10 09:10:30 +08:00
}
}
2020-03-27 05:49:16 +08:00
void RigidBody3D : : set_linear_velocity ( const Vector3 & p_velocity ) {
2017-03-05 23:44:50 +08:00
linear_velocity = p_velocity ;
2020-05-14 22:41:43 +08:00
if ( state ) {
2014-02-10 09:10:30 +08:00
state - > set_linear_velocity ( linear_velocity ) ;
2020-05-14 22:41:43 +08:00
} else {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_state ( get_rid ( ) , PhysicsServer3D : : BODY_STATE_LINEAR_VELOCITY , linear_velocity ) ;
2020-05-14 22:41:43 +08:00
}
2014-02-10 09:10:30 +08:00
}
2020-03-27 05:49:16 +08:00
Vector3 RigidBody3D : : get_linear_velocity ( ) const {
2014-02-10 09:10:30 +08:00
return linear_velocity ;
}
2020-03-27 05:49:16 +08:00
void RigidBody3D : : set_angular_velocity ( const Vector3 & p_velocity ) {
2017-03-05 23:44:50 +08:00
angular_velocity = p_velocity ;
2020-05-14 22:41:43 +08:00
if ( state ) {
2014-02-10 09:10:30 +08:00
state - > set_angular_velocity ( angular_velocity ) ;
2020-05-14 22:41:43 +08:00
} else {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_state ( get_rid ( ) , PhysicsServer3D : : BODY_STATE_ANGULAR_VELOCITY , angular_velocity ) ;
2020-05-14 22:41:43 +08:00
}
2014-02-10 09:10:30 +08:00
}
2020-05-14 20:29:06 +08:00
2020-03-27 05:49:16 +08:00
Vector3 RigidBody3D : : get_angular_velocity ( ) const {
2014-02-10 09:10:30 +08:00
return angular_velocity ;
}
2021-05-20 04:16:49 +08:00
Basis RigidBody3D : : get_inverse_inertia_tensor ( ) const {
2020-07-20 00:45:36 +08:00
return inverse_inertia_tensor ;
}
2020-03-27 05:49:16 +08:00
void RigidBody3D : : set_use_custom_integrator ( bool p_enable ) {
2020-05-14 22:41:43 +08:00
if ( custom_integrator = = p_enable ) {
2014-02-10 09:10:30 +08:00
return ;
2020-05-14 22:41:43 +08:00
}
2014-02-10 09:10:30 +08:00
2017-03-05 23:44:50 +08:00
custom_integrator = p_enable ;
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_omit_force_integration ( get_rid ( ) , p_enable ) ;
2014-02-10 09:10:30 +08:00
}
2020-05-14 20:29:06 +08:00
2020-03-27 05:49:16 +08:00
bool RigidBody3D : : is_using_custom_integrator ( ) {
2014-02-10 09:10:30 +08:00
return custom_integrator ;
}
2020-03-27 05:49:16 +08:00
void RigidBody3D : : set_sleeping ( bool p_sleeping ) {
2017-03-05 23:44:50 +08:00
sleeping = p_sleeping ;
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_state ( get_rid ( ) , PhysicsServer3D : : BODY_STATE_SLEEPING , sleeping ) ;
2014-02-10 09:10:30 +08:00
}
2020-03-27 05:49:16 +08:00
void RigidBody3D : : set_can_sleep ( bool p_active ) {
2017-03-05 23:44:50 +08:00
can_sleep = p_active ;
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_state ( get_rid ( ) , PhysicsServer3D : : BODY_STATE_CAN_SLEEP , p_active ) ;
2014-02-10 09:10:30 +08:00
}
2020-03-27 05:49:16 +08:00
bool RigidBody3D : : is_able_to_sleep ( ) const {
2014-02-10 09:10:30 +08:00
return can_sleep ;
}
2020-03-27 05:49:16 +08:00
bool RigidBody3D : : is_sleeping ( ) const {
2014-09-22 11:50:48 +08:00
return sleeping ;
2014-02-10 09:10:30 +08:00
}
2020-03-27 05:49:16 +08:00
void RigidBody3D : : set_max_contacts_reported ( int p_amount ) {
2017-03-05 23:44:50 +08:00
max_contacts_reported = p_amount ;
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_max_contacts_reported ( get_rid ( ) , p_amount ) ;
2014-02-10 09:10:30 +08:00
}
2020-03-27 05:49:16 +08:00
int RigidBody3D : : get_max_contacts_reported ( ) const {
2014-02-10 09:10:30 +08:00
return max_contacts_reported ;
}
2020-03-27 05:49:16 +08:00
void RigidBody3D : : add_central_force ( const Vector3 & p_force ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_add_central_force ( get_rid ( ) , p_force ) ;
2018-07-24 15:49:12 +08:00
}
2020-03-26 12:23:34 +08:00
void RigidBody3D : : add_force ( const Vector3 & p_force , const Vector3 & p_position ) {
PhysicsServer3D * singleton = PhysicsServer3D : : get_singleton ( ) ;
singleton - > body_add_force ( get_rid ( ) , p_force , p_position ) ;
2018-07-24 15:49:12 +08:00
}
2020-03-27 05:49:16 +08:00
void RigidBody3D : : add_torque ( const Vector3 & p_torque ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_add_torque ( get_rid ( ) , p_torque ) ;
2018-07-24 15:49:12 +08:00
}
2020-03-27 05:49:16 +08:00
void RigidBody3D : : apply_central_impulse ( const Vector3 & p_impulse ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_apply_central_impulse ( get_rid ( ) , p_impulse ) ;
2018-07-24 15:49:12 +08:00
}
2020-03-26 12:23:34 +08:00
void RigidBody3D : : apply_impulse ( const Vector3 & p_impulse , const Vector3 & p_position ) {
PhysicsServer3D * singleton = PhysicsServer3D : : get_singleton ( ) ;
singleton - > body_apply_impulse ( get_rid ( ) , p_impulse , p_position ) ;
2014-02-10 09:10:30 +08:00
}
2020-03-27 05:49:16 +08:00
void RigidBody3D : : apply_torque_impulse ( const Vector3 & p_impulse ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_apply_torque_impulse ( get_rid ( ) , p_impulse ) ;
2018-01-25 16:45:00 +08:00
}
2020-03-27 05:49:16 +08:00
void RigidBody3D : : set_use_continuous_collision_detection ( bool p_enable ) {
2017-03-05 23:44:50 +08:00
ccd = p_enable ;
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_enable_continuous_collision_detection ( get_rid ( ) , p_enable ) ;
2014-02-10 09:10:30 +08:00
}
2020-03-27 05:49:16 +08:00
bool RigidBody3D : : is_using_continuous_collision_detection ( ) const {
2014-02-10 09:10:30 +08:00
return ccd ;
}
2020-03-27 05:49:16 +08:00
void RigidBody3D : : set_contact_monitor ( bool p_enabled ) {
2020-05-14 22:41:43 +08:00
if ( p_enabled = = is_contact_monitor_enabled ( ) ) {
2014-02-10 09:10:30 +08:00
return ;
2020-05-14 22:41:43 +08:00
}
2014-02-10 09:10:30 +08:00
if ( ! p_enabled ) {
2019-08-09 04:11:48 +08:00
ERR_FAIL_COND_MSG ( contact_monitor - > locked , " Can't disable contact monitoring during in/out callback. Use call_deferred( \" set_contact_monitor \" , false) instead. " ) ;
2016-01-12 17:14:15 +08:00
2017-03-05 23:44:50 +08:00
for ( Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 09:10:30 +08:00
//clean up mess
2018-01-21 19:46:13 +08:00
Object * obj = ObjectDB : : get_instance ( E - > key ( ) ) ;
Node * node = Object : : cast_to < Node > ( obj ) ;
if ( node ) {
2020-03-27 05:49:16 +08:00
node - > disconnect ( SceneStringNames : : get_singleton ( ) - > tree_entered , callable_mp ( this , & RigidBody3D : : _body_enter_tree ) ) ;
node - > disconnect ( SceneStringNames : : get_singleton ( ) - > tree_exiting , callable_mp ( this , & RigidBody3D : : _body_exit_tree ) ) ;
2018-01-21 19:46:13 +08:00
}
2014-02-10 09:10:30 +08:00
}
2017-03-05 23:44:50 +08:00
memdelete ( contact_monitor ) ;
2020-04-02 07:20:12 +08:00
contact_monitor = nullptr ;
2014-02-10 09:10:30 +08:00
} else {
2017-03-05 23:44:50 +08:00
contact_monitor = memnew ( ContactMonitor ) ;
contact_monitor - > locked = false ;
2014-02-10 09:10:30 +08:00
}
}
2020-03-27 05:49:16 +08:00
bool RigidBody3D : : is_contact_monitor_enabled ( ) const {
2020-04-02 07:20:12 +08:00
return contact_monitor ! = nullptr ;
2014-02-10 09:10:30 +08:00
}
2020-03-27 05:49:16 +08:00
Array RigidBody3D : : get_colliding_bodies ( ) const {
2017-03-05 23:44:50 +08:00
ERR_FAIL_COND_V ( ! contact_monitor , Array ( ) ) ;
2014-11-13 11:53:12 +08:00
Array ret ;
ret . resize ( contact_monitor - > body_map . size ( ) ) ;
2017-03-05 23:44:50 +08:00
int idx = 0 ;
for ( const Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . front ( ) ; E ; E = E - > next ( ) ) {
2014-11-13 11:53:12 +08:00
Object * obj = ObjectDB : : get_instance ( E - > key ( ) ) ;
if ( ! obj ) {
2017-03-05 23:44:50 +08:00
ret . resize ( ret . size ( ) - 1 ) ; //ops
2014-11-13 11:53:12 +08:00
} else {
2017-03-05 23:44:50 +08:00
ret [ idx + + ] = obj ;
2014-11-13 11:53:12 +08:00
}
}
return ret ;
}
2020-10-29 18:01:28 +08:00
TypedArray < String > RigidBody3D : : get_configuration_warnings ( ) const {
2020-10-17 13:08:21 +08:00
Transform3D t = get_transform ( ) ;
2017-08-06 03:06:15 +08:00
2020-10-29 18:01:28 +08:00
TypedArray < String > warnings = Node : : get_configuration_warnings ( ) ;
2017-08-06 03:06:15 +08:00
2021-05-20 09:15:07 +08:00
if ( ( get_mode ( ) = = MODE_DYNAMIC | | get_mode ( ) = = MODE_DYNAMIC_LOCKED ) & & ( ABS ( t . basis . get_axis ( 0 ) . length ( ) - 1.0 ) > 0.05 | | ABS ( t . basis . get_axis ( 1 ) . length ( ) - 1.0 ) > 0.05 | | ABS ( t . basis . get_axis ( 2 ) . length ( ) - 1.0 ) > 0.05 ) ) {
warnings . push_back ( TTR ( " Size changes to RigidBody3D (in dynamic modes) will be overridden by the physics engine when running. \n Change the size in children collision shapes instead. " ) ) ;
2017-08-06 03:06:15 +08:00
}
2020-10-29 18:01:28 +08:00
return warnings ;
2017-08-06 03:06:15 +08:00
}
2020-03-27 05:49:16 +08:00
void RigidBody3D : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " set_mode " , " mode " ) , & RigidBody3D : : set_mode ) ;
ClassDB : : bind_method ( D_METHOD ( " get_mode " ) , & RigidBody3D : : get_mode ) ;
2014-02-10 09:10:30 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_mass " , " mass " ) , & RigidBody3D : : set_mass ) ;
ClassDB : : bind_method ( D_METHOD ( " get_mass " ) , & RigidBody3D : : get_mass ) ;
2014-02-10 09:10:30 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_physics_material_override " , " physics_material_override " ) , & RigidBody3D : : set_physics_material_override ) ;
ClassDB : : bind_method ( D_METHOD ( " get_physics_material_override " ) , & RigidBody3D : : get_physics_material_override ) ;
2017-10-25 00:10:30 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_linear_velocity " , " linear_velocity " ) , & RigidBody3D : : set_linear_velocity ) ;
ClassDB : : bind_method ( D_METHOD ( " get_linear_velocity " ) , & RigidBody3D : : get_linear_velocity ) ;
2014-02-10 09:10:30 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_angular_velocity " , " angular_velocity " ) , & RigidBody3D : : set_angular_velocity ) ;
ClassDB : : bind_method ( D_METHOD ( " get_angular_velocity " ) , & RigidBody3D : : get_angular_velocity ) ;
2014-02-10 09:10:30 +08:00
2020-07-20 00:45:36 +08:00
ClassDB : : bind_method ( D_METHOD ( " get_inverse_inertia_tensor " ) , & RigidBody3D : : get_inverse_inertia_tensor ) ;
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_gravity_scale " , " gravity_scale " ) , & RigidBody3D : : set_gravity_scale ) ;
ClassDB : : bind_method ( D_METHOD ( " get_gravity_scale " ) , & RigidBody3D : : get_gravity_scale ) ;
2015-08-31 05:57:17 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_linear_damp " , " linear_damp " ) , & RigidBody3D : : set_linear_damp ) ;
ClassDB : : bind_method ( D_METHOD ( " get_linear_damp " ) , & RigidBody3D : : get_linear_damp ) ;
2015-08-31 05:57:17 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_angular_damp " , " angular_damp " ) , & RigidBody3D : : set_angular_damp ) ;
ClassDB : : bind_method ( D_METHOD ( " get_angular_damp " ) , & RigidBody3D : : get_angular_damp ) ;
2015-08-31 05:57:17 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_max_contacts_reported " , " amount " ) , & RigidBody3D : : set_max_contacts_reported ) ;
ClassDB : : bind_method ( D_METHOD ( " get_max_contacts_reported " ) , & RigidBody3D : : get_max_contacts_reported ) ;
2015-08-31 05:57:17 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_use_custom_integrator " , " enable " ) , & RigidBody3D : : set_use_custom_integrator ) ;
ClassDB : : bind_method ( D_METHOD ( " is_using_custom_integrator " ) , & RigidBody3D : : is_using_custom_integrator ) ;
2014-02-10 09:10:30 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_contact_monitor " , " enabled " ) , & RigidBody3D : : set_contact_monitor ) ;
ClassDB : : bind_method ( D_METHOD ( " is_contact_monitor_enabled " ) , & RigidBody3D : : is_contact_monitor_enabled ) ;
2014-02-10 09:10:30 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_use_continuous_collision_detection " , " enable " ) , & RigidBody3D : : set_use_continuous_collision_detection ) ;
ClassDB : : bind_method ( D_METHOD ( " is_using_continuous_collision_detection " ) , & RigidBody3D : : is_using_continuous_collision_detection ) ;
2014-02-10 09:10:30 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_axis_velocity " , " axis_velocity " ) , & RigidBody3D : : set_axis_velocity ) ;
2018-07-24 15:49:12 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " add_central_force " , " force " ) , & RigidBody3D : : add_central_force ) ;
2020-03-26 12:23:34 +08:00
ClassDB : : bind_method ( D_METHOD ( " add_force " , " force " , " position " ) , & RigidBody3D : : add_force , Vector3 ( ) ) ;
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " add_torque " , " torque " ) , & RigidBody3D : : add_torque ) ;
2018-07-24 15:49:12 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " apply_central_impulse " , " impulse " ) , & RigidBody3D : : apply_central_impulse ) ;
2020-03-26 12:23:34 +08:00
ClassDB : : bind_method ( D_METHOD ( " apply_impulse " , " impulse " , " position " ) , & RigidBody3D : : apply_impulse , Vector3 ( ) ) ;
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " apply_torque_impulse " , " impulse " ) , & RigidBody3D : : apply_torque_impulse ) ;
2014-02-10 09:10:30 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_sleeping " , " sleeping " ) , & RigidBody3D : : set_sleeping ) ;
ClassDB : : bind_method ( D_METHOD ( " is_sleeping " ) , & RigidBody3D : : is_sleeping ) ;
2014-02-10 09:10:30 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_can_sleep " , " able_to_sleep " ) , & RigidBody3D : : set_can_sleep ) ;
ClassDB : : bind_method ( D_METHOD ( " is_able_to_sleep " ) , & RigidBody3D : : is_able_to_sleep ) ;
2014-02-10 09:10:30 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " get_colliding_bodies " ) , & RigidBody3D : : get_colliding_bodies ) ;
2014-05-14 12:22:15 +08:00
2020-03-31 00:22:57 +08:00
BIND_VMETHOD ( MethodInfo ( " _integrate_forces " , PropertyInfo ( Variant : : OBJECT , " state " , PROPERTY_HINT_RESOURCE_TYPE , " PhysicsDirectBodyState3D " ) ) ) ;
2014-11-13 11:53:12 +08:00
2021-05-20 09:15:07 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " mode " , PROPERTY_HINT_ENUM , " Dynamic,Static,DynamicLocked,Kinematic " ) , " set_mode " , " get_mode " ) ;
Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
2020-02-25 02:20:53 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : FLOAT , " mass " , PROPERTY_HINT_EXP_RANGE , " 0.01,65535,0.01 " ) , " set_mass " , " get_mass " ) ;
2018-11-08 22:30:02 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : OBJECT , " physics_material_override " , PROPERTY_HINT_RESOURCE_TYPE , " PhysicsMaterial " ) , " set_physics_material_override " , " get_physics_material_override " ) ;
Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
2020-02-25 02:20:53 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : FLOAT , " gravity_scale " , PROPERTY_HINT_RANGE , " -128,128,0.01 " ) , " set_gravity_scale " , " get_gravity_scale " ) ;
2017-03-05 23:44:50 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " custom_integrator " ) , " set_use_custom_integrator " , " is_using_custom_integrator " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " continuous_cd " ) , " set_use_continuous_collision_detection " , " is_using_continuous_collision_detection " ) ;
2019-12-22 05:25:01 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " contacts_reported " , PROPERTY_HINT_RANGE , " 0,64,1,or_greater " ) , " set_max_contacts_reported " , " get_max_contacts_reported " ) ;
2017-03-05 23:44:50 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " contact_monitor " ) , " set_contact_monitor " , " is_contact_monitor_enabled " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " sleeping " ) , " set_sleeping " , " is_sleeping " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " can_sleep " ) , " set_can_sleep " , " is_able_to_sleep " ) ;
ADD_GROUP ( " Linear " , " linear_ " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR3 , " linear_velocity " ) , " set_linear_velocity " , " get_linear_velocity " ) ;
Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
2020-02-25 02:20:53 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : FLOAT , " linear_damp " , PROPERTY_HINT_RANGE , " -1,100,0.001,or_greater " ) , " set_linear_damp " , " get_linear_damp " ) ;
2017-03-05 23:44:50 +08:00
ADD_GROUP ( " Angular " , " angular_ " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR3 , " angular_velocity " ) , " set_angular_velocity " , " get_angular_velocity " ) ;
Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
2020-02-25 02:20:53 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : FLOAT , " angular_damp " , PROPERTY_HINT_RANGE , " -1,100,0.001,or_greater " ) , " set_angular_damp " , " get_angular_damp " ) ;
2014-02-10 09:10:30 +08:00
2020-10-12 23:25:32 +08:00
ADD_SIGNAL ( MethodInfo ( " body_shape_entered " , PropertyInfo ( Variant : : RID , " body_rid " ) , PropertyInfo ( Variant : : OBJECT , " body " , PROPERTY_HINT_RESOURCE_TYPE , " Node " ) , PropertyInfo ( Variant : : INT , " body_shape " ) , PropertyInfo ( Variant : : INT , " local_shape " ) ) ) ;
ADD_SIGNAL ( MethodInfo ( " body_shape_exited " , PropertyInfo ( Variant : : RID , " body_rid " ) , PropertyInfo ( Variant : : OBJECT , " body " , PROPERTY_HINT_RESOURCE_TYPE , " Node " ) , PropertyInfo ( Variant : : INT , " body_shape " ) , PropertyInfo ( Variant : : INT , " local_shape " ) ) ) ;
2018-09-01 18:05:51 +08:00
ADD_SIGNAL ( MethodInfo ( " body_entered " , PropertyInfo ( Variant : : OBJECT , " body " , PROPERTY_HINT_RESOURCE_TYPE , " Node " ) ) ) ;
ADD_SIGNAL ( MethodInfo ( " body_exited " , PropertyInfo ( Variant : : OBJECT , " body " , PROPERTY_HINT_RESOURCE_TYPE , " Node " ) ) ) ;
2017-03-05 23:44:50 +08:00
ADD_SIGNAL ( MethodInfo ( " sleeping_state_changed " ) ) ;
2014-02-10 09:10:30 +08:00
2021-05-20 09:15:07 +08:00
BIND_ENUM_CONSTANT ( MODE_DYNAMIC ) ;
2017-10-22 02:58:02 +08:00
BIND_ENUM_CONSTANT ( MODE_STATIC ) ;
2021-05-20 09:15:07 +08:00
BIND_ENUM_CONSTANT ( MODE_DYNAMIC_LOCKED ) ;
2017-10-22 02:58:02 +08:00
BIND_ENUM_CONSTANT ( MODE_KINEMATIC ) ;
2014-02-10 09:10:30 +08:00
}
2020-03-27 05:49:16 +08:00
RigidBody3D : : RigidBody3D ( ) :
2021-05-20 09:15:07 +08:00
PhysicsBody3D ( PhysicsServer3D : : BODY_MODE_DYNAMIC ) {
2021-03-30 14:22:23 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_force_integration_callback ( get_rid ( ) , callable_mp ( this , & RigidBody3D : : _direct_state_changed ) ) ;
2014-02-10 09:10:30 +08:00
}
2020-03-27 05:49:16 +08:00
RigidBody3D : : ~ RigidBody3D ( ) {
2020-05-14 22:41:43 +08:00
if ( contact_monitor ) {
2017-03-05 23:44:50 +08:00
memdelete ( contact_monitor ) ;
2020-05-14 22:41:43 +08:00
}
2014-02-10 09:10:30 +08:00
}
2017-10-25 00:10:30 +08:00
2020-03-27 05:49:16 +08:00
void RigidBody3D : : _reload_physics_characteristics ( ) {
2017-10-25 00:10:30 +08:00
if ( physics_material_override . is_null ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer3D : : BODY_PARAM_BOUNCE , 0 ) ;
PhysicsServer3D : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer3D : : BODY_PARAM_FRICTION , 1 ) ;
2017-10-25 00:10:30 +08:00
} else {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer3D : : BODY_PARAM_BOUNCE , physics_material_override - > computed_bounce ( ) ) ;
PhysicsServer3D : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer3D : : BODY_PARAM_FRICTION , physics_material_override - > computed_friction ( ) ) ;
2017-10-25 00:10:30 +08:00
}
}
2021-05-20 09:14:33 +08:00
///////////////////////////////////////
2014-09-03 10:13:40 +08:00
2021-05-20 09:14:33 +08:00
Vector3 CharacterBody3D : : get_linear_velocity ( ) const {
2020-01-10 19:22:34 +08:00
return linear_velocity ;
}
2021-05-20 09:14:33 +08:00
Vector3 CharacterBody3D : : get_angular_velocity ( ) const {
2020-01-10 19:22:34 +08:00
return angular_velocity ;
}
Fix misc. source comment typos
Found using `codespell -q 3 -S ./thirdparty,*.po -L ang,ba,cas,dof,doubleclick,fave,hist,leapyear,lod,nd,numer,ois,paket,seeked,sinc,switchs,te,uint -D ~/Projects/codespell/codespell_lib/data/dictionary.txt `
2019-09-20 02:36:39 +08:00
//so, if you pass 45 as limit, avoid numerical precision errors when angle is 45.
2018-08-11 00:06:34 +08:00
# define FLOOR_ANGLE_THRESHOLD 0.01
2021-05-20 09:14:57 +08:00
Vector3 CharacterBody3D : : move_and_slide ( const Vector3 & p_linear_velocity ) {
2019-11-25 07:10:36 +08:00
Vector3 body_velocity = p_linear_velocity ;
Vector3 body_velocity_normal = body_velocity . normalized ( ) ;
2021-05-20 09:14:57 +08:00
bool was_on_floor = on_floor ;
2017-04-14 02:37:17 +08:00
2017-11-09 05:35:47 +08:00
for ( int i = 0 ; i < 3 ; i + + ) {
2017-12-11 00:21:14 +08:00
if ( locked_axis & ( 1 < < i ) ) {
2019-11-25 07:10:36 +08:00
body_velocity [ i ] = 0 ;
}
}
2018-03-15 20:29:22 +08:00
// Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky
2020-01-06 00:15:51 +08:00
Vector3 motion = ( floor_velocity + body_velocity ) * ( Engine : : get_singleton ( ) - > is_in_physics_frame ( ) ? get_physics_process_delta_time ( ) : get_process_delta_time ( ) ) ;
2017-11-09 05:35:47 +08:00
2017-07-15 12:23:10 +08:00
on_floor = false ;
2019-11-25 07:10:36 +08:00
on_floor_body = RID ( ) ;
2017-07-15 12:23:10 +08:00
on_ceiling = false ;
on_wall = false ;
2021-05-20 09:14:33 +08:00
motion_results . clear ( ) ;
2020-01-15 15:04:02 +08:00
floor_normal = Vector3 ( ) ;
2017-07-15 12:23:10 +08:00
floor_velocity = Vector3 ( ) ;
2017-04-14 02:37:17 +08:00
2021-05-20 09:14:57 +08:00
int slide_count = max_slides ;
while ( slide_count ) {
2021-05-20 09:14:33 +08:00
PhysicsServer3D : : MotionResult result ;
2018-08-15 01:20:48 +08:00
bool found_collision = false ;
2017-04-14 02:37:17 +08:00
2019-03-26 05:46:26 +08:00
for ( int i = 0 ; i < 2 ; + + i ) {
2018-08-15 01:20:48 +08:00
bool collided ;
2019-03-26 05:46:26 +08:00
if ( i = = 0 ) { //collide
2021-06-02 10:11:56 +08:00
collided = move_and_collide ( motion , infinite_inertia , result , margin ) ;
2018-08-15 01:20:48 +08:00
if ( ! collided ) {
motion = Vector3 ( ) ; //clear because no collision happened and motion completed
}
2019-03-26 05:46:26 +08:00
} else { //separate raycasts (if any)
2021-05-20 09:14:57 +08:00
collided = separate_raycast_shapes ( result ) ;
2018-08-15 01:20:48 +08:00
if ( collided ) {
2021-05-20 09:14:33 +08:00
result . remainder = motion ; //keep
result . motion = Vector3 ( ) ;
2018-08-15 01:20:48 +08:00
}
}
2017-04-14 02:37:17 +08:00
2018-08-15 01:20:48 +08:00
if ( collided ) {
found_collision = true ;
2018-08-11 16:25:56 +08:00
2021-05-20 09:14:33 +08:00
motion_results . push_back ( result ) ;
motion = result . remainder ;
2018-08-11 16:25:56 +08:00
2020-02-10 22:30:06 +08:00
if ( up_direction = = Vector3 ( ) ) {
2018-08-15 01:20:48 +08:00
//all is a wall
2017-07-15 12:23:10 +08:00
on_wall = true ;
2018-08-15 01:20:48 +08:00
} else {
2021-05-20 09:14:57 +08:00
if ( Math : : acos ( result . collision_normal . dot ( up_direction ) ) < = floor_max_angle + FLOOR_ANGLE_THRESHOLD ) { //floor
2018-08-15 01:20:48 +08:00
on_floor = true ;
2021-05-20 09:14:33 +08:00
floor_normal = result . collision_normal ;
on_floor_body = result . collider ;
floor_velocity = result . collider_velocity ;
2018-08-15 01:20:48 +08:00
2021-05-20 09:14:57 +08:00
if ( stop_on_slope ) {
2021-05-20 09:14:33 +08:00
if ( ( body_velocity_normal + up_direction ) . length ( ) < 0.01 & & result . motion . length ( ) < 1 ) {
2020-10-17 13:08:21 +08:00
Transform3D gt = get_global_transform ( ) ;
2021-05-20 09:14:33 +08:00
gt . origin - = result . motion . slide ( up_direction ) ;
2018-08-15 01:20:48 +08:00
set_global_transform ( gt ) ;
return Vector3 ( ) ;
}
}
2021-05-20 09:14:57 +08:00
} else if ( Math : : acos ( result . collision_normal . dot ( - up_direction ) ) < = floor_max_angle + FLOOR_ANGLE_THRESHOLD ) { //ceiling
2018-08-15 01:20:48 +08:00
on_ceiling = true ;
} else {
on_wall = true ;
}
2017-04-14 02:37:17 +08:00
}
2021-05-20 09:14:33 +08:00
motion = motion . slide ( result . collision_normal ) ;
body_velocity = body_velocity . slide ( result . collision_normal ) ;
2017-07-15 12:23:10 +08:00
2019-03-26 05:46:26 +08:00
for ( int j = 0 ; j < 3 ; j + + ) {
if ( locked_axis & ( 1 < < j ) ) {
2019-11-25 07:10:36 +08:00
body_velocity [ j ] = 0 ;
2018-08-15 01:20:48 +08:00
}
2017-11-09 05:35:47 +08:00
}
}
2019-03-26 05:46:26 +08:00
}
2017-04-14 02:37:17 +08:00
2020-05-14 22:41:43 +08:00
if ( ! found_collision | | motion = = Vector3 ( ) ) {
2017-04-14 02:37:17 +08:00
break ;
2020-05-14 22:41:43 +08:00
}
2018-08-15 01:20:48 +08:00
2021-05-20 09:14:57 +08:00
- - slide_count ;
2017-04-14 02:37:17 +08:00
}
2021-05-20 09:14:57 +08:00
if ( ! was_on_floor | | snap = = Vector3 ( ) ) {
return body_velocity ;
2018-08-15 01:20:48 +08:00
}
2021-05-20 09:14:57 +08:00
// Apply snap.
2020-10-17 13:08:21 +08:00
Transform3D gt = get_global_transform ( ) ;
2021-05-20 09:14:57 +08:00
PhysicsServer3D : : MotionResult result ;
2021-06-02 10:11:56 +08:00
if ( move_and_collide ( snap , infinite_inertia , result , margin , false , true ) ) {
2019-02-17 02:49:55 +08:00
bool apply = true ;
2020-02-10 22:30:06 +08:00
if ( up_direction ! = Vector3 ( ) ) {
2021-05-20 09:14:57 +08:00
if ( Math : : acos ( result . collision_normal . dot ( up_direction ) ) < = floor_max_angle + FLOOR_ANGLE_THRESHOLD ) {
2019-02-17 02:49:55 +08:00
on_floor = true ;
2021-05-20 09:14:33 +08:00
floor_normal = result . collision_normal ;
on_floor_body = result . collider ;
floor_velocity = result . collider_velocity ;
2021-05-20 09:14:57 +08:00
if ( stop_on_slope ) {
2019-02-23 21:23:38 +08:00
// move and collide may stray the object a bit because of pre un-stucking,
// so only ensure that motion happens on floor direction in this case.
2021-05-20 09:14:33 +08:00
result . motion = result . motion . project ( up_direction ) ;
2019-02-23 21:23:38 +08:00
}
2019-02-17 02:49:55 +08:00
} else {
apply = false ; //snapped with floor direction, but did not snap to a floor, do not snap.
}
}
if ( apply ) {
2021-05-20 09:14:33 +08:00
gt . origin + = result . motion ;
2019-02-17 02:49:55 +08:00
set_global_transform ( gt ) ;
2018-08-15 01:20:48 +08:00
}
}
2021-05-20 09:14:57 +08:00
return body_velocity ;
2018-08-15 01:20:48 +08:00
}
2021-05-20 09:14:33 +08:00
bool CharacterBody3D : : separate_raycast_shapes ( PhysicsServer3D : : MotionResult & r_result ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : SeparationResult sep_res [ 8 ] ; //max 8 rays
2018-08-15 01:20:48 +08:00
2020-10-17 13:08:21 +08:00
Transform3D gt = get_global_transform ( ) ;
2018-08-15 01:20:48 +08:00
Vector3 recover ;
2021-05-20 09:14:33 +08:00
int hits = PhysicsServer3D : : get_singleton ( ) - > body_test_ray_separation ( get_rid ( ) , gt , infinite_inertia , recover , sep_res , 8 , margin ) ;
2018-08-15 01:20:48 +08:00
int deepest = - 1 ;
2021-01-30 07:22:12 +08:00
real_t deepest_depth ;
2018-08-15 01:20:48 +08:00
for ( int i = 0 ; i < hits ; i + + ) {
if ( deepest = = - 1 | | sep_res [ i ] . collision_depth > deepest_depth ) {
deepest = i ;
deepest_depth = sep_res [ i ] . collision_depth ;
}
}
gt . origin + = recover ;
set_global_transform ( gt ) ;
if ( deepest ! = - 1 ) {
2021-05-20 09:14:33 +08:00
r_result . collider_id = sep_res [ deepest ] . collider_id ;
r_result . collider_metadata = sep_res [ deepest ] . collider_metadata ;
r_result . collider_shape = sep_res [ deepest ] . collider_shape ;
r_result . collider_velocity = sep_res [ deepest ] . collider_velocity ;
r_result . collision_point = sep_res [ deepest ] . collision_point ;
r_result . collision_normal = sep_res [ deepest ] . collision_normal ;
r_result . collision_local_shape = sep_res [ deepest ] . collision_local_shape ;
r_result . motion = recover ;
r_result . remainder = Vector3 ( ) ;
2018-08-15 01:20:48 +08:00
return true ;
} else {
return false ;
}
}
2021-06-02 10:11:56 +08:00
void CharacterBody3D : : set_safe_margin ( real_t p_margin ) {
margin = p_margin ;
}
real_t CharacterBody3D : : get_safe_margin ( ) const {
return margin ;
}
2021-05-20 09:14:33 +08:00
bool CharacterBody3D : : is_on_floor ( ) const {
return on_floor ;
2017-11-09 05:35:47 +08:00
}
2021-05-20 09:14:33 +08:00
bool CharacterBody3D : : is_on_wall ( ) const {
return on_wall ;
2017-11-09 05:35:47 +08:00
}
2021-05-20 09:14:33 +08:00
bool CharacterBody3D : : is_on_ceiling ( ) const {
return on_ceiling ;
2014-09-03 10:13:40 +08:00
}
2021-05-20 09:14:33 +08:00
Vector3 CharacterBody3D : : get_floor_normal ( ) const {
return floor_normal ;
}
Vector3 CharacterBody3D : : get_floor_velocity ( ) const {
return floor_velocity ;
2014-09-03 10:13:40 +08:00
}
2020-05-14 20:29:06 +08:00
2021-05-20 09:14:33 +08:00
int CharacterBody3D : : get_slide_count ( ) const {
return motion_results . size ( ) ;
2014-09-03 10:13:40 +08:00
}
2021-05-20 09:14:33 +08:00
PhysicsServer3D : : MotionResult CharacterBody3D : : get_slide_collision ( int p_bounce ) const {
ERR_FAIL_INDEX_V ( p_bounce , motion_results . size ( ) , PhysicsServer3D : : MotionResult ( ) ) ;
return motion_results [ p_bounce ] ;
2014-09-03 10:13:40 +08:00
}
2021-05-20 09:14:33 +08:00
Ref < KinematicCollision3D > CharacterBody3D : : _get_slide_collision ( int p_bounce ) {
ERR_FAIL_INDEX_V ( p_bounce , motion_results . size ( ) , Ref < KinematicCollision3D > ( ) ) ;
2017-09-11 00:07:47 +08:00
if ( p_bounce > = slide_colliders . size ( ) ) {
2017-09-04 18:48:14 +08:00
slide_colliders . resize ( p_bounce + 1 ) ;
2017-07-15 12:23:10 +08:00
}
2014-09-03 10:13:40 +08:00
2017-09-04 18:48:14 +08:00
if ( slide_colliders [ p_bounce ] . is_null ( ) ) {
2018-07-25 09:11:03 +08:00
slide_colliders . write [ p_bounce ] . instance ( ) ;
slide_colliders . write [ p_bounce ] - > owner = this ;
2017-07-15 12:23:10 +08:00
}
2014-09-03 10:13:40 +08:00
2021-05-20 09:14:33 +08:00
slide_colliders . write [ p_bounce ] - > result = motion_results [ p_bounce ] ;
2017-09-04 18:48:14 +08:00
return slide_colliders [ p_bounce ] ;
2014-09-03 10:13:40 +08:00
}
2021-05-20 09:14:57 +08:00
bool CharacterBody3D : : is_stop_on_slope_enabled ( ) const {
return stop_on_slope ;
}
void CharacterBody3D : : set_stop_on_slope_enabled ( bool p_enabled ) {
stop_on_slope = p_enabled ;
}
bool CharacterBody3D : : is_infinite_inertia_enabled ( ) const {
return infinite_inertia ;
}
void CharacterBody3D : : set_infinite_inertia_enabled ( bool p_enabled ) {
infinite_inertia = p_enabled ;
}
int CharacterBody3D : : get_max_slides ( ) const {
return max_slides ;
}
void CharacterBody3D : : set_max_slides ( int p_max_slides ) {
ERR_FAIL_COND ( p_max_slides > 0 ) ;
max_slides = p_max_slides ;
}
real_t CharacterBody3D : : get_floor_max_angle ( ) const {
return floor_max_angle ;
}
void CharacterBody3D : : set_floor_max_angle ( real_t p_floor_max_angle ) {
floor_max_angle = p_floor_max_angle ;
}
const Vector3 & CharacterBody3D : : get_snap ( ) const {
return snap ;
}
void CharacterBody3D : : set_snap ( const Vector3 & p_snap ) {
snap = p_snap ;
}
const Vector3 & CharacterBody3D : : get_up_direction ( ) const {
return up_direction ;
}
void CharacterBody3D : : set_up_direction ( const Vector3 & p_up_direction ) {
up_direction = p_up_direction . normalized ( ) ;
}
2021-05-20 09:14:33 +08:00
void CharacterBody3D : : _notification ( int p_what ) {
2019-08-19 17:11:14 +08:00
if ( p_what = = NOTIFICATION_ENTER_TREE ) {
// Reset move_and_slide() data.
on_floor = false ;
on_floor_body = RID ( ) ;
on_ceiling = false ;
on_wall = false ;
2021-05-20 09:14:33 +08:00
motion_results . clear ( ) ;
2019-08-19 17:11:14 +08:00
floor_velocity = Vector3 ( ) ;
}
}
2021-05-20 09:14:33 +08:00
void CharacterBody3D : : _bind_methods ( ) {
2021-05-20 09:14:57 +08:00
ClassDB : : bind_method ( D_METHOD ( " move_and_slide " , " linear_velocity " ) , & CharacterBody3D : : move_and_slide ) ;
2021-06-02 10:11:56 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_safe_margin " , " pixels " ) , & CharacterBody3D : : set_safe_margin ) ;
ClassDB : : bind_method ( D_METHOD ( " get_safe_margin " ) , & CharacterBody3D : : get_safe_margin ) ;
2021-05-20 09:14:57 +08:00
ClassDB : : bind_method ( D_METHOD ( " is_stop_on_slope_enabled " ) , & CharacterBody3D : : is_stop_on_slope_enabled ) ;
ClassDB : : bind_method ( D_METHOD ( " set_stop_on_slope_enabled " , " enabled " ) , & CharacterBody3D : : set_stop_on_slope_enabled ) ;
ClassDB : : bind_method ( D_METHOD ( " is_infinite_inertia_enabled " ) , & CharacterBody3D : : is_infinite_inertia_enabled ) ;
ClassDB : : bind_method ( D_METHOD ( " set_infinite_inertia_enabled " , " enabled " ) , & CharacterBody3D : : set_infinite_inertia_enabled ) ;
ClassDB : : bind_method ( D_METHOD ( " get_max_slides " ) , & CharacterBody3D : : get_max_slides ) ;
ClassDB : : bind_method ( D_METHOD ( " set_max_slides " , " max_slides " ) , & CharacterBody3D : : set_max_slides ) ;
ClassDB : : bind_method ( D_METHOD ( " get_floor_max_angle " ) , & CharacterBody3D : : get_floor_max_angle ) ;
ClassDB : : bind_method ( D_METHOD ( " set_floor_max_angle " , " floor_max_angle " ) , & CharacterBody3D : : set_floor_max_angle ) ;
ClassDB : : bind_method ( D_METHOD ( " get_snap " ) , & CharacterBody3D : : get_snap ) ;
ClassDB : : bind_method ( D_METHOD ( " set_snap " , " snap " ) , & CharacterBody3D : : set_snap ) ;
ClassDB : : bind_method ( D_METHOD ( " get_up_direction " ) , & CharacterBody3D : : get_up_direction ) ;
ClassDB : : bind_method ( D_METHOD ( " set_up_direction " , " up_direction " ) , & CharacterBody3D : : set_up_direction ) ;
2014-09-03 10:13:40 +08:00
2021-05-20 09:14:33 +08:00
ClassDB : : bind_method ( D_METHOD ( " is_on_floor " ) , & CharacterBody3D : : is_on_floor ) ;
ClassDB : : bind_method ( D_METHOD ( " is_on_ceiling " ) , & CharacterBody3D : : is_on_ceiling ) ;
ClassDB : : bind_method ( D_METHOD ( " is_on_wall " ) , & CharacterBody3D : : is_on_wall ) ;
ClassDB : : bind_method ( D_METHOD ( " get_floor_normal " ) , & CharacterBody3D : : get_floor_normal ) ;
ClassDB : : bind_method ( D_METHOD ( " get_floor_velocity " ) , & CharacterBody3D : : get_floor_velocity ) ;
2017-11-09 05:35:47 +08:00
2021-05-20 09:14:33 +08:00
ClassDB : : bind_method ( D_METHOD ( " get_slide_count " ) , & CharacterBody3D : : get_slide_count ) ;
ClassDB : : bind_method ( D_METHOD ( " get_slide_collision " , " slide_idx " ) , & CharacterBody3D : : _get_slide_collision ) ;
2021-05-20 09:14:57 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " stop_on_slope " ) , " set_stop_on_slope_enabled " , " is_stop_on_slope_enabled " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " infinite_inertia " ) , " set_infinite_inertia_enabled " , " is_infinite_inertia_enabled " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " max_slides " ) , " set_max_slides " , " get_max_slides " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : FLOAT , " floor_max_angle " ) , " set_floor_max_angle " , " get_floor_max_angle " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR3 , " snap " ) , " set_snap " , " get_snap " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR3 , " up_direction " ) , " set_up_direction " , " get_up_direction " ) ;
2021-06-02 10:11:56 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : FLOAT , " collision/safe_margin " , PROPERTY_HINT_RANGE , " 0.001,256,0.001 " ) , " set_safe_margin " , " get_safe_margin " ) ;
2014-09-03 10:13:40 +08:00
}
2021-05-20 09:14:33 +08:00
void CharacterBody3D : : _direct_state_changed ( Object * p_state ) {
2020-01-10 19:22:34 +08:00
# ifdef DEBUG_ENABLED
2020-03-28 02:21:27 +08:00
PhysicsDirectBodyState3D * state = Object : : cast_to < PhysicsDirectBodyState3D > ( p_state ) ;
2021-03-30 14:22:23 +08:00
ERR_FAIL_NULL_MSG ( state , " Method '_direct_state_changed' must receive a valid PhysicsDirectBodyState3D object as argument " ) ;
2020-01-10 19:22:34 +08:00
# else
2020-03-28 08:50:00 +08:00
PhysicsDirectBodyState3D * state = ( PhysicsDirectBodyState3D * ) p_state ; //trust it
2020-01-10 19:22:34 +08:00
# endif
linear_velocity = state - > get_linear_velocity ( ) ;
angular_velocity = state - > get_angular_velocity ( ) ;
}
2021-05-20 09:14:33 +08:00
CharacterBody3D : : CharacterBody3D ( ) :
2020-03-28 02:21:27 +08:00
PhysicsBody3D ( PhysicsServer3D : : BODY_MODE_KINEMATIC ) {
2021-05-20 09:14:33 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_force_integration_callback ( get_rid ( ) , callable_mp ( this , & CharacterBody3D : : _direct_state_changed ) ) ;
2014-09-03 10:13:40 +08:00
}
2020-05-14 20:29:06 +08:00
2021-05-20 09:14:33 +08:00
CharacterBody3D : : ~ CharacterBody3D ( ) {
2017-09-04 18:48:14 +08:00
for ( int i = 0 ; i < slide_colliders . size ( ) ; i + + ) {
if ( slide_colliders [ i ] . is_valid ( ) ) {
2020-04-02 07:20:12 +08:00
slide_colliders . write [ i ] - > owner = nullptr ;
2017-09-04 18:48:14 +08:00
}
}
}
2020-05-14 20:29:06 +08:00
2017-09-04 18:48:14 +08:00
///////////////////////////////////////
2020-03-27 05:49:16 +08:00
Vector3 KinematicCollision3D : : get_position ( ) const {
2021-05-20 09:14:33 +08:00
return result . collision_point ;
2017-09-04 18:48:14 +08:00
}
2020-05-14 20:29:06 +08:00
2020-03-27 05:49:16 +08:00
Vector3 KinematicCollision3D : : get_normal ( ) const {
2021-05-20 09:14:33 +08:00
return result . collision_normal ;
2017-09-04 18:48:14 +08:00
}
2020-05-14 20:29:06 +08:00
2020-03-27 05:49:16 +08:00
Vector3 KinematicCollision3D : : get_travel ( ) const {
2021-05-20 09:14:33 +08:00
return result . motion ;
2017-09-04 18:48:14 +08:00
}
2020-05-14 20:29:06 +08:00
2020-03-27 05:49:16 +08:00
Vector3 KinematicCollision3D : : get_remainder ( ) const {
2021-05-20 09:14:33 +08:00
return result . remainder ;
2017-09-04 18:48:14 +08:00
}
2020-05-14 20:29:06 +08:00
2020-03-27 05:49:16 +08:00
Object * KinematicCollision3D : : get_local_shape ( ) const {
2020-05-14 22:41:43 +08:00
if ( ! owner ) {
2020-05-10 18:56:01 +08:00
return nullptr ;
2020-05-14 22:41:43 +08:00
}
2021-05-20 09:14:33 +08:00
uint32_t ownerid = owner - > shape_find_owner ( result . collision_local_shape ) ;
2017-09-04 18:48:14 +08:00
return owner - > shape_owner_get_owner ( ownerid ) ;
}
2020-03-27 05:49:16 +08:00
Object * KinematicCollision3D : : get_collider ( ) const {
2021-05-20 09:14:33 +08:00
if ( result . collider_id . is_valid ( ) ) {
return ObjectDB : : get_instance ( result . collider_id ) ;
2017-09-04 18:48:14 +08:00
}
2020-04-02 07:20:12 +08:00
return nullptr ;
2017-09-04 18:48:14 +08:00
}
2020-05-14 20:29:06 +08:00
2020-03-27 05:49:16 +08:00
ObjectID KinematicCollision3D : : get_collider_id ( ) const {
2021-05-20 09:14:33 +08:00
return result . collider_id ;
2017-09-04 18:48:14 +08:00
}
2020-05-14 20:29:06 +08:00
2020-03-27 05:49:16 +08:00
Object * KinematicCollision3D : : get_collider_shape ( ) const {
2017-09-04 18:48:14 +08:00
Object * collider = get_collider ( ) ;
if ( collider ) {
2020-03-27 05:49:16 +08:00
CollisionObject3D * obj2d = Object : : cast_to < CollisionObject3D > ( collider ) ;
2017-09-04 18:48:14 +08:00
if ( obj2d ) {
2021-05-20 09:14:33 +08:00
uint32_t ownerid = obj2d - > shape_find_owner ( result . collider_shape ) ;
2017-09-04 18:48:14 +08:00
return obj2d - > shape_owner_get_owner ( ownerid ) ;
}
}
2020-04-02 07:20:12 +08:00
return nullptr ;
2017-09-04 18:48:14 +08:00
}
2020-05-14 20:29:06 +08:00
2020-03-27 05:49:16 +08:00
int KinematicCollision3D : : get_collider_shape_index ( ) const {
2021-05-20 09:14:33 +08:00
return result . collider_shape ;
2017-09-04 18:48:14 +08:00
}
2020-05-14 20:29:06 +08:00
2020-03-27 05:49:16 +08:00
Vector3 KinematicCollision3D : : get_collider_velocity ( ) const {
2021-05-20 09:14:33 +08:00
return result . collider_velocity ;
2017-09-04 18:48:14 +08:00
}
2020-05-14 20:29:06 +08:00
2020-03-27 05:49:16 +08:00
Variant KinematicCollision3D : : get_collider_metadata ( ) const {
2017-09-04 18:48:14 +08:00
return Variant ( ) ;
}
2020-03-27 05:49:16 +08:00
void KinematicCollision3D : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " get_position " ) , & KinematicCollision3D : : get_position ) ;
ClassDB : : bind_method ( D_METHOD ( " get_normal " ) , & KinematicCollision3D : : get_normal ) ;
ClassDB : : bind_method ( D_METHOD ( " get_travel " ) , & KinematicCollision3D : : get_travel ) ;
ClassDB : : bind_method ( D_METHOD ( " get_remainder " ) , & KinematicCollision3D : : get_remainder ) ;
ClassDB : : bind_method ( D_METHOD ( " get_local_shape " ) , & KinematicCollision3D : : get_local_shape ) ;
ClassDB : : bind_method ( D_METHOD ( " get_collider " ) , & KinematicCollision3D : : get_collider ) ;
ClassDB : : bind_method ( D_METHOD ( " get_collider_id " ) , & KinematicCollision3D : : get_collider_id ) ;
ClassDB : : bind_method ( D_METHOD ( " get_collider_shape " ) , & KinematicCollision3D : : get_collider_shape ) ;
ClassDB : : bind_method ( D_METHOD ( " get_collider_shape_index " ) , & KinematicCollision3D : : get_collider_shape_index ) ;
ClassDB : : bind_method ( D_METHOD ( " get_collider_velocity " ) , & KinematicCollision3D : : get_collider_velocity ) ;
ClassDB : : bind_method ( D_METHOD ( " get_collider_metadata " ) , & KinematicCollision3D : : get_collider_metadata ) ;
2017-09-04 18:48:14 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR3 , " position " ) , " " , " get_position " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR3 , " normal " ) , " " , " get_normal " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR3 , " travel " ) , " " , " get_travel " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR3 , " remainder " ) , " " , " get_remainder " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : OBJECT , " local_shape " ) , " " , " get_local_shape " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : OBJECT , " collider " ) , " " , " get_collider " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " collider_id " ) , " " , " get_collider_id " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : OBJECT , " collider_shape " ) , " " , " get_collider_shape " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " collider_shape_index " ) , " " , " get_collider_shape_index " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR3 , " collider_velocity " ) , " " , " get_collider_velocity " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : NIL , " collider_metadata " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NIL_IS_VARIANT ) , " " , " get_collider_metadata " ) ;
}
2017-10-04 00:49:32 +08:00
///////////////////////////////////////
2020-03-27 05:49:16 +08:00
bool PhysicalBone3D : : JointData : : _set ( const StringName & p_name , const Variant & p_value , RID j ) {
2017-10-04 00:49:32 +08:00
return false ;
}
2020-03-27 05:49:16 +08:00
bool PhysicalBone3D : : JointData : : _get ( const StringName & p_name , Variant & r_ret ) const {
2017-10-04 00:49:32 +08:00
return false ;
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : JointData : : _get_property_list ( List < PropertyInfo > * p_list ) const {
2017-10-04 00:49:32 +08:00
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : apply_central_impulse ( const Vector3 & p_impulse ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_apply_central_impulse ( get_rid ( ) , p_impulse ) ;
2019-12-12 07:08:11 +08:00
}
2020-03-26 12:23:34 +08:00
void PhysicalBone3D : : apply_impulse ( const Vector3 & p_impulse , const Vector3 & p_position ) {
PhysicsServer3D : : get_singleton ( ) - > body_apply_impulse ( get_rid ( ) , p_impulse , p_position ) ;
2019-12-12 07:08:11 +08:00
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : reset_physics_simulation_state ( ) {
2020-02-08 16:52:58 +08:00
if ( simulate_physics ) {
_start_physics_simulation ( ) ;
} else {
_stop_physics_simulation ( ) ;
}
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : reset_to_rest_position ( ) {
2020-02-08 16:52:58 +08:00
if ( parent_skeleton ) {
if ( - 1 = = bone_id ) {
set_global_transform ( parent_skeleton - > get_global_transform ( ) * body_offset ) ;
} else {
set_global_transform ( parent_skeleton - > get_global_transform ( ) * parent_skeleton - > get_bone_global_pose ( bone_id ) * body_offset ) ;
}
}
}
2020-03-27 05:49:16 +08:00
bool PhysicalBone3D : : PinJointData : : _set ( const StringName & p_name , const Variant & p_value , RID j ) {
2017-10-04 00:49:32 +08:00
if ( JointData : : _set ( p_name , p_value , j ) ) {
return true ;
}
if ( " joint_constraints/bias " = = p_name ) {
bias = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > pin_joint_set_param ( j , PhysicsServer3D : : PIN_JOINT_BIAS , bias ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " joint_constraints/damping " = = p_name ) {
damping = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > pin_joint_set_param ( j , PhysicsServer3D : : PIN_JOINT_DAMPING , damping ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " joint_constraints/impulse_clamp " = = p_name ) {
impulse_clamp = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > pin_joint_set_param ( j , PhysicsServer3D : : PIN_JOINT_IMPULSE_CLAMP , impulse_clamp ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else {
return false ;
}
return true ;
}
2020-03-27 05:49:16 +08:00
bool PhysicalBone3D : : PinJointData : : _get ( const StringName & p_name , Variant & r_ret ) const {
2017-10-04 00:49:32 +08:00
if ( JointData : : _get ( p_name , r_ret ) ) {
return true ;
}
if ( " joint_constraints/bias " = = p_name ) {
r_ret = bias ;
} else if ( " joint_constraints/damping " = = p_name ) {
r_ret = damping ;
} else if ( " joint_constraints/impulse_clamp " = = p_name ) {
r_ret = impulse_clamp ;
} else {
return false ;
}
return true ;
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : PinJointData : : _get_property_list ( List < PropertyInfo > * p_list ) const {
2017-10-04 00:49:32 +08:00
JointData : : _get_property_list ( p_list ) ;
Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
2020-02-25 02:20:53 +08:00
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/bias " , PROPERTY_HINT_RANGE , " 0.01,0.99,0.01 " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/damping " , PROPERTY_HINT_RANGE , " 0.01,8.0,0.01 " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/impulse_clamp " , PROPERTY_HINT_RANGE , " 0.0,64.0,0.01 " ) ) ;
2017-10-04 00:49:32 +08:00
}
2020-03-27 05:49:16 +08:00
bool PhysicalBone3D : : ConeJointData : : _set ( const StringName & p_name , const Variant & p_value , RID j ) {
2017-10-04 00:49:32 +08:00
if ( JointData : : _set ( p_name , p_value , j ) ) {
return true ;
}
if ( " joint_constraints/swing_span " = = p_name ) {
swing_span = Math : : deg2rad ( real_t ( p_value ) ) ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > cone_twist_joint_set_param ( j , PhysicsServer3D : : CONE_TWIST_JOINT_SWING_SPAN , swing_span ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " joint_constraints/twist_span " = = p_name ) {
twist_span = Math : : deg2rad ( real_t ( p_value ) ) ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > cone_twist_joint_set_param ( j , PhysicsServer3D : : CONE_TWIST_JOINT_TWIST_SPAN , twist_span ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " joint_constraints/bias " = = p_name ) {
bias = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > cone_twist_joint_set_param ( j , PhysicsServer3D : : CONE_TWIST_JOINT_BIAS , bias ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " joint_constraints/softness " = = p_name ) {
softness = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > cone_twist_joint_set_param ( j , PhysicsServer3D : : CONE_TWIST_JOINT_SOFTNESS , softness ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " joint_constraints/relaxation " = = p_name ) {
relaxation = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > cone_twist_joint_set_param ( j , PhysicsServer3D : : CONE_TWIST_JOINT_RELAXATION , relaxation ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else {
return false ;
}
return true ;
}
2020-03-27 05:49:16 +08:00
bool PhysicalBone3D : : ConeJointData : : _get ( const StringName & p_name , Variant & r_ret ) const {
2017-10-04 00:49:32 +08:00
if ( JointData : : _get ( p_name , r_ret ) ) {
return true ;
}
if ( " joint_constraints/swing_span " = = p_name ) {
r_ret = Math : : rad2deg ( swing_span ) ;
} else if ( " joint_constraints/twist_span " = = p_name ) {
r_ret = Math : : rad2deg ( twist_span ) ;
} else if ( " joint_constraints/bias " = = p_name ) {
r_ret = bias ;
} else if ( " joint_constraints/softness " = = p_name ) {
r_ret = softness ;
} else if ( " joint_constraints/relaxation " = = p_name ) {
r_ret = relaxation ;
} else {
return false ;
}
return true ;
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : ConeJointData : : _get_property_list ( List < PropertyInfo > * p_list ) const {
2017-10-04 00:49:32 +08:00
JointData : : _get_property_list ( p_list ) ;
Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
2020-02-25 02:20:53 +08:00
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/swing_span " , PROPERTY_HINT_RANGE , " -180,180,0.01 " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/twist_span " , PROPERTY_HINT_RANGE , " -40000,40000,0.1,or_lesser,or_greater " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/bias " , PROPERTY_HINT_RANGE , " 0.01,16.0,0.01 " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/softness " , PROPERTY_HINT_RANGE , " 0.01,16.0,0.01 " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/relaxation " , PROPERTY_HINT_RANGE , " 0.01,16.0,0.01 " ) ) ;
2017-10-04 00:49:32 +08:00
}
2020-03-27 05:49:16 +08:00
bool PhysicalBone3D : : HingeJointData : : _set ( const StringName & p_name , const Variant & p_value , RID j ) {
2017-10-04 00:49:32 +08:00
if ( JointData : : _set ( p_name , p_value , j ) ) {
return true ;
}
if ( " joint_constraints/angular_limit_enabled " = = p_name ) {
angular_limit_enabled = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > hinge_joint_set_flag ( j , PhysicsServer3D : : HINGE_JOINT_FLAG_USE_LIMIT , angular_limit_enabled ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " joint_constraints/angular_limit_upper " = = p_name ) {
angular_limit_upper = Math : : deg2rad ( real_t ( p_value ) ) ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > hinge_joint_set_param ( j , PhysicsServer3D : : HINGE_JOINT_LIMIT_UPPER , angular_limit_upper ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " joint_constraints/angular_limit_lower " = = p_name ) {
angular_limit_lower = Math : : deg2rad ( real_t ( p_value ) ) ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > hinge_joint_set_param ( j , PhysicsServer3D : : HINGE_JOINT_LIMIT_LOWER , angular_limit_lower ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " joint_constraints/angular_limit_bias " = = p_name ) {
angular_limit_bias = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > hinge_joint_set_param ( j , PhysicsServer3D : : HINGE_JOINT_LIMIT_BIAS , angular_limit_bias ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " joint_constraints/angular_limit_softness " = = p_name ) {
angular_limit_softness = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > hinge_joint_set_param ( j , PhysicsServer3D : : HINGE_JOINT_LIMIT_SOFTNESS , angular_limit_softness ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " joint_constraints/angular_limit_relaxation " = = p_name ) {
angular_limit_relaxation = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > hinge_joint_set_param ( j , PhysicsServer3D : : HINGE_JOINT_LIMIT_RELAXATION , angular_limit_relaxation ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else {
return false ;
}
return true ;
}
2020-03-27 05:49:16 +08:00
bool PhysicalBone3D : : HingeJointData : : _get ( const StringName & p_name , Variant & r_ret ) const {
2017-10-04 00:49:32 +08:00
if ( JointData : : _get ( p_name , r_ret ) ) {
return true ;
}
if ( " joint_constraints/angular_limit_enabled " = = p_name ) {
r_ret = angular_limit_enabled ;
} else if ( " joint_constraints/angular_limit_upper " = = p_name ) {
r_ret = Math : : rad2deg ( angular_limit_upper ) ;
} else if ( " joint_constraints/angular_limit_lower " = = p_name ) {
r_ret = Math : : rad2deg ( angular_limit_lower ) ;
} else if ( " joint_constraints/angular_limit_bias " = = p_name ) {
r_ret = angular_limit_bias ;
} else if ( " joint_constraints/angular_limit_softness " = = p_name ) {
r_ret = angular_limit_softness ;
} else if ( " joint_constraints/angular_limit_relaxation " = = p_name ) {
r_ret = angular_limit_relaxation ;
} else {
return false ;
}
return true ;
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : HingeJointData : : _get_property_list ( List < PropertyInfo > * p_list ) const {
2017-10-04 00:49:32 +08:00
JointData : : _get_property_list ( p_list ) ;
p_list - > push_back ( PropertyInfo ( Variant : : BOOL , " joint_constraints/angular_limit_enabled " ) ) ;
Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
2020-02-25 02:20:53 +08:00
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/angular_limit_upper " , PROPERTY_HINT_RANGE , " -180,180,0.01 " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/angular_limit_lower " , PROPERTY_HINT_RANGE , " -180,180,0.01 " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/angular_limit_bias " , PROPERTY_HINT_RANGE , " 0.01,0.99,0.01 " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/angular_limit_softness " , PROPERTY_HINT_RANGE , " 0.01,16,0.01 " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/angular_limit_relaxation " , PROPERTY_HINT_RANGE , " 0.01,16,0.01 " ) ) ;
2017-10-04 00:49:32 +08:00
}
2020-03-27 05:49:16 +08:00
bool PhysicalBone3D : : SliderJointData : : _set ( const StringName & p_name , const Variant & p_value , RID j ) {
2017-10-04 00:49:32 +08:00
if ( JointData : : _set ( p_name , p_value , j ) ) {
return true ;
}
if ( " joint_constraints/linear_limit_upper " = = p_name ) {
linear_limit_upper = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > slider_joint_set_param ( j , PhysicsServer3D : : SLIDER_JOINT_LINEAR_LIMIT_UPPER , linear_limit_upper ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " joint_constraints/linear_limit_lower " = = p_name ) {
linear_limit_lower = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > slider_joint_set_param ( j , PhysicsServer3D : : SLIDER_JOINT_LINEAR_LIMIT_LOWER , linear_limit_lower ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " joint_constraints/linear_limit_softness " = = p_name ) {
linear_limit_softness = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > slider_joint_set_param ( j , PhysicsServer3D : : SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS , linear_limit_softness ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " joint_constraints/linear_limit_restitution " = = p_name ) {
linear_limit_restitution = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > slider_joint_set_param ( j , PhysicsServer3D : : SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION , linear_limit_restitution ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " joint_constraints/linear_limit_damping " = = p_name ) {
linear_limit_damping = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > slider_joint_set_param ( j , PhysicsServer3D : : SLIDER_JOINT_LINEAR_LIMIT_DAMPING , linear_limit_restitution ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " joint_constraints/angular_limit_upper " = = p_name ) {
angular_limit_upper = Math : : deg2rad ( real_t ( p_value ) ) ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > slider_joint_set_param ( j , PhysicsServer3D : : SLIDER_JOINT_ANGULAR_LIMIT_UPPER , angular_limit_upper ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " joint_constraints/angular_limit_lower " = = p_name ) {
angular_limit_lower = Math : : deg2rad ( real_t ( p_value ) ) ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > slider_joint_set_param ( j , PhysicsServer3D : : SLIDER_JOINT_ANGULAR_LIMIT_LOWER , angular_limit_lower ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " joint_constraints/angular_limit_softness " = = p_name ) {
angular_limit_softness = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > slider_joint_set_param ( j , PhysicsServer3D : : SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS , angular_limit_softness ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " joint_constraints/angular_limit_restitution " = = p_name ) {
angular_limit_restitution = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > slider_joint_set_param ( j , PhysicsServer3D : : SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS , angular_limit_softness ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " joint_constraints/angular_limit_damping " = = p_name ) {
angular_limit_damping = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > slider_joint_set_param ( j , PhysicsServer3D : : SLIDER_JOINT_ANGULAR_LIMIT_DAMPING , angular_limit_damping ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else {
return false ;
}
return true ;
}
2020-03-27 05:49:16 +08:00
bool PhysicalBone3D : : SliderJointData : : _get ( const StringName & p_name , Variant & r_ret ) const {
2017-10-04 00:49:32 +08:00
if ( JointData : : _get ( p_name , r_ret ) ) {
return true ;
}
if ( " joint_constraints/linear_limit_upper " = = p_name ) {
r_ret = linear_limit_upper ;
} else if ( " joint_constraints/linear_limit_lower " = = p_name ) {
r_ret = linear_limit_lower ;
} else if ( " joint_constraints/linear_limit_softness " = = p_name ) {
r_ret = linear_limit_softness ;
} else if ( " joint_constraints/linear_limit_restitution " = = p_name ) {
r_ret = linear_limit_restitution ;
} else if ( " joint_constraints/linear_limit_damping " = = p_name ) {
r_ret = linear_limit_damping ;
} else if ( " joint_constraints/angular_limit_upper " = = p_name ) {
r_ret = Math : : rad2deg ( angular_limit_upper ) ;
} else if ( " joint_constraints/angular_limit_lower " = = p_name ) {
r_ret = Math : : rad2deg ( angular_limit_lower ) ;
} else if ( " joint_constraints/angular_limit_softness " = = p_name ) {
r_ret = angular_limit_softness ;
} else if ( " joint_constraints/angular_limit_restitution " = = p_name ) {
r_ret = angular_limit_restitution ;
} else if ( " joint_constraints/angular_limit_damping " = = p_name ) {
r_ret = angular_limit_damping ;
} else {
return false ;
}
return true ;
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : SliderJointData : : _get_property_list ( List < PropertyInfo > * p_list ) const {
2017-10-04 00:49:32 +08:00
JointData : : _get_property_list ( p_list ) ;
Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
2020-02-25 02:20:53 +08:00
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/linear_limit_upper " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/linear_limit_lower " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/linear_limit_softness " , PROPERTY_HINT_RANGE , " 0.01,16.0,0.01 " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/linear_limit_restitution " , PROPERTY_HINT_RANGE , " 0.01,16.0,0.01 " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/linear_limit_damping " , PROPERTY_HINT_RANGE , " 0,16.0,0.01 " ) ) ;
2017-10-04 00:49:32 +08:00
Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
2020-02-25 02:20:53 +08:00
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/angular_limit_upper " , PROPERTY_HINT_RANGE , " -180,180,0.01 " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/angular_limit_lower " , PROPERTY_HINT_RANGE , " -180,180,0.01 " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/angular_limit_softness " , PROPERTY_HINT_RANGE , " 0.01,16.0,0.01 " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/angular_limit_restitution " , PROPERTY_HINT_RANGE , " 0.01,16.0,0.01 " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/angular_limit_damping " , PROPERTY_HINT_RANGE , " 0,16.0,0.01 " ) ) ;
2017-10-04 00:49:32 +08:00
}
2020-03-27 05:49:16 +08:00
bool PhysicalBone3D : : SixDOFJointData : : _set ( const StringName & p_name , const Variant & p_value , RID j ) {
2017-10-04 00:49:32 +08:00
if ( JointData : : _set ( p_name , p_value , j ) ) {
return true ;
}
String path = p_name ;
2021-01-18 03:25:34 +08:00
if ( ! path . begins_with ( " joint_constraints/ " ) ) {
return false ;
}
2017-10-04 00:49:32 +08:00
Vector3 : : Axis axis ;
{
const String axis_s = path . get_slicec ( ' / ' , 1 ) ;
if ( " x " = = axis_s ) {
axis = Vector3 : : AXIS_X ;
} else if ( " y " = = axis_s ) {
axis = Vector3 : : AXIS_Y ;
} else if ( " z " = = axis_s ) {
axis = Vector3 : : AXIS_Z ;
} else {
return false ;
}
}
String var_name = path . get_slicec ( ' / ' , 2 ) ;
if ( " linear_limit_enabled " = = var_name ) {
axis_data [ axis ] . linear_limit_enabled = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_flag ( j , axis , PhysicsServer3D : : G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT , axis_data [ axis ] . linear_limit_enabled ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " linear_limit_upper " = = var_name ) {
axis_data [ axis ] . linear_limit_upper = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer3D : : G6DOF_JOINT_LINEAR_UPPER_LIMIT , axis_data [ axis ] . linear_limit_upper ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " linear_limit_lower " = = var_name ) {
axis_data [ axis ] . linear_limit_lower = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer3D : : G6DOF_JOINT_LINEAR_LOWER_LIMIT , axis_data [ axis ] . linear_limit_lower ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " linear_limit_softness " = = var_name ) {
axis_data [ axis ] . linear_limit_softness = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer3D : : G6DOF_JOINT_LINEAR_LIMIT_SOFTNESS , axis_data [ axis ] . linear_limit_softness ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
2018-11-20 23:55:22 +08:00
} else if ( " linear_spring_enabled " = = var_name ) {
axis_data [ axis ] . linear_spring_enabled = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_flag ( j , axis , PhysicsServer3D : : G6DOF_JOINT_FLAG_ENABLE_LINEAR_SPRING , axis_data [ axis ] . linear_spring_enabled ) ;
2020-05-14 22:41:43 +08:00
}
2018-11-20 23:55:22 +08:00
} else if ( " linear_spring_stiffness " = = var_name ) {
axis_data [ axis ] . linear_spring_stiffness = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer3D : : G6DOF_JOINT_LINEAR_SPRING_STIFFNESS , axis_data [ axis ] . linear_spring_stiffness ) ;
2020-05-14 22:41:43 +08:00
}
2018-11-20 23:55:22 +08:00
} else if ( " linear_spring_damping " = = var_name ) {
axis_data [ axis ] . linear_spring_damping = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer3D : : G6DOF_JOINT_LINEAR_SPRING_DAMPING , axis_data [ axis ] . linear_spring_damping ) ;
2020-05-14 22:41:43 +08:00
}
2018-11-20 23:55:22 +08:00
} else if ( " linear_equilibrium_point " = = var_name ) {
axis_data [ axis ] . linear_equilibrium_point = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer3D : : G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT , axis_data [ axis ] . linear_equilibrium_point ) ;
2020-05-14 22:41:43 +08:00
}
2018-11-20 23:55:22 +08:00
2017-10-04 00:49:32 +08:00
} else if ( " linear_restitution " = = var_name ) {
axis_data [ axis ] . linear_restitution = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer3D : : G6DOF_JOINT_LINEAR_RESTITUTION , axis_data [ axis ] . linear_restitution ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " linear_damping " = = var_name ) {
axis_data [ axis ] . linear_damping = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer3D : : G6DOF_JOINT_LINEAR_DAMPING , axis_data [ axis ] . linear_damping ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " angular_limit_enabled " = = var_name ) {
axis_data [ axis ] . angular_limit_enabled = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_flag ( j , axis , PhysicsServer3D : : G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT , axis_data [ axis ] . angular_limit_enabled ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " angular_limit_upper " = = var_name ) {
axis_data [ axis ] . angular_limit_upper = Math : : deg2rad ( real_t ( p_value ) ) ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer3D : : G6DOF_JOINT_ANGULAR_UPPER_LIMIT , axis_data [ axis ] . angular_limit_upper ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " angular_limit_lower " = = var_name ) {
axis_data [ axis ] . angular_limit_lower = Math : : deg2rad ( real_t ( p_value ) ) ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer3D : : G6DOF_JOINT_ANGULAR_LOWER_LIMIT , axis_data [ axis ] . angular_limit_lower ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " angular_limit_softness " = = var_name ) {
axis_data [ axis ] . angular_limit_softness = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer3D : : G6DOF_JOINT_ANGULAR_LIMIT_SOFTNESS , axis_data [ axis ] . angular_limit_softness ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " angular_restitution " = = var_name ) {
axis_data [ axis ] . angular_restitution = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer3D : : G6DOF_JOINT_ANGULAR_RESTITUTION , axis_data [ axis ] . angular_restitution ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " angular_damping " = = var_name ) {
axis_data [ axis ] . angular_damping = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer3D : : G6DOF_JOINT_ANGULAR_DAMPING , axis_data [ axis ] . angular_damping ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
} else if ( " erp " = = var_name ) {
axis_data [ axis ] . erp = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer3D : : G6DOF_JOINT_ANGULAR_ERP , axis_data [ axis ] . erp ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
2018-11-20 23:55:22 +08:00
} else if ( " angular_spring_enabled " = = var_name ) {
axis_data [ axis ] . angular_spring_enabled = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_flag ( j , axis , PhysicsServer3D : : G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING , axis_data [ axis ] . angular_spring_enabled ) ;
2020-05-14 22:41:43 +08:00
}
2018-11-20 23:55:22 +08:00
} else if ( " angular_spring_stiffness " = = var_name ) {
axis_data [ axis ] . angular_spring_stiffness = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer3D : : G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS , axis_data [ axis ] . angular_spring_stiffness ) ;
2020-05-14 22:41:43 +08:00
}
2018-11-20 23:55:22 +08:00
} else if ( " angular_spring_damping " = = var_name ) {
axis_data [ axis ] . angular_spring_damping = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer3D : : G6DOF_JOINT_ANGULAR_SPRING_DAMPING , axis_data [ axis ] . angular_spring_damping ) ;
2020-05-14 22:41:43 +08:00
}
2018-11-20 23:55:22 +08:00
} else if ( " angular_equilibrium_point " = = var_name ) {
axis_data [ axis ] . angular_equilibrium_point = p_value ;
2020-05-14 22:41:43 +08:00
if ( j . is_valid ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer3D : : G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT , axis_data [ axis ] . angular_equilibrium_point ) ;
2020-05-14 22:41:43 +08:00
}
2018-11-20 23:55:22 +08:00
2017-10-04 00:49:32 +08:00
} else {
return false ;
}
return true ;
}
2020-03-27 05:49:16 +08:00
bool PhysicalBone3D : : SixDOFJointData : : _get ( const StringName & p_name , Variant & r_ret ) const {
2017-10-04 00:49:32 +08:00
if ( JointData : : _get ( p_name , r_ret ) ) {
return true ;
}
String path = p_name ;
2021-01-18 03:25:34 +08:00
if ( ! path . begins_with ( " joint_constraints/ " ) ) {
return false ;
}
2017-10-04 00:49:32 +08:00
int axis ;
{
const String axis_s = path . get_slicec ( ' / ' , 1 ) ;
if ( " x " = = axis_s ) {
axis = 0 ;
} else if ( " y " = = axis_s ) {
axis = 1 ;
} else if ( " z " = = axis_s ) {
axis = 2 ;
} else {
return false ;
}
}
String var_name = path . get_slicec ( ' / ' , 2 ) ;
if ( " linear_limit_enabled " = = var_name ) {
r_ret = axis_data [ axis ] . linear_limit_enabled ;
} else if ( " linear_limit_upper " = = var_name ) {
r_ret = axis_data [ axis ] . linear_limit_upper ;
} else if ( " linear_limit_lower " = = var_name ) {
r_ret = axis_data [ axis ] . linear_limit_lower ;
} else if ( " linear_limit_softness " = = var_name ) {
r_ret = axis_data [ axis ] . linear_limit_softness ;
2018-11-20 23:55:22 +08:00
} else if ( " linear_spring_enabled " = = var_name ) {
r_ret = axis_data [ axis ] . linear_spring_enabled ;
} else if ( " linear_spring_stiffness " = = var_name ) {
r_ret = axis_data [ axis ] . linear_spring_stiffness ;
} else if ( " linear_spring_damping " = = var_name ) {
r_ret = axis_data [ axis ] . linear_spring_damping ;
} else if ( " linear_equilibrium_point " = = var_name ) {
r_ret = axis_data [ axis ] . linear_equilibrium_point ;
2017-10-04 00:49:32 +08:00
} else if ( " linear_restitution " = = var_name ) {
r_ret = axis_data [ axis ] . linear_restitution ;
} else if ( " linear_damping " = = var_name ) {
r_ret = axis_data [ axis ] . linear_damping ;
} else if ( " angular_limit_enabled " = = var_name ) {
r_ret = axis_data [ axis ] . angular_limit_enabled ;
} else if ( " angular_limit_upper " = = var_name ) {
r_ret = Math : : rad2deg ( axis_data [ axis ] . angular_limit_upper ) ;
} else if ( " angular_limit_lower " = = var_name ) {
r_ret = Math : : rad2deg ( axis_data [ axis ] . angular_limit_lower ) ;
} else if ( " angular_limit_softness " = = var_name ) {
r_ret = axis_data [ axis ] . angular_limit_softness ;
} else if ( " angular_restitution " = = var_name ) {
r_ret = axis_data [ axis ] . angular_restitution ;
} else if ( " angular_damping " = = var_name ) {
r_ret = axis_data [ axis ] . angular_damping ;
} else if ( " erp " = = var_name ) {
r_ret = axis_data [ axis ] . erp ;
2018-11-20 23:55:22 +08:00
} else if ( " angular_spring_enabled " = = var_name ) {
r_ret = axis_data [ axis ] . angular_spring_enabled ;
} else if ( " angular_spring_stiffness " = = var_name ) {
r_ret = axis_data [ axis ] . angular_spring_stiffness ;
} else if ( " angular_spring_damping " = = var_name ) {
r_ret = axis_data [ axis ] . angular_spring_damping ;
} else if ( " angular_equilibrium_point " = = var_name ) {
r_ret = axis_data [ axis ] . angular_equilibrium_point ;
2017-10-04 00:49:32 +08:00
} else {
return false ;
}
return true ;
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : SixDOFJointData : : _get_property_list ( List < PropertyInfo > * p_list ) const {
2017-10-04 00:49:32 +08:00
const StringName axis_names [ ] = { " x " , " y " , " z " } ;
for ( int i = 0 ; i < 3 ; + + i ) {
p_list - > push_back ( PropertyInfo ( Variant : : BOOL , " joint_constraints/ " + axis_names [ i ] + " /linear_limit_enabled " ) ) ;
Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
2020-02-25 02:20:53 +08:00
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/ " + axis_names [ i ] + " /linear_limit_upper " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/ " + axis_names [ i ] + " /linear_limit_lower " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/ " + axis_names [ i ] + " /linear_limit_softness " , PROPERTY_HINT_RANGE , " 0.01,16,0.01 " ) ) ;
2018-11-20 23:55:22 +08:00
p_list - > push_back ( PropertyInfo ( Variant : : BOOL , " joint_constraints/ " + axis_names [ i ] + " /linear_spring_enabled " ) ) ;
Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
2020-02-25 02:20:53 +08:00
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/ " + axis_names [ i ] + " /linear_spring_stiffness " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/ " + axis_names [ i ] + " /linear_spring_damping " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/ " + axis_names [ i ] + " /linear_equilibrium_point " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/ " + axis_names [ i ] + " /linear_restitution " , PROPERTY_HINT_RANGE , " 0.01,16,0.01 " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/ " + axis_names [ i ] + " /linear_damping " , PROPERTY_HINT_RANGE , " 0.01,16,0.01 " ) ) ;
2017-10-04 00:49:32 +08:00
p_list - > push_back ( PropertyInfo ( Variant : : BOOL , " joint_constraints/ " + axis_names [ i ] + " /angular_limit_enabled " ) ) ;
Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
2020-02-25 02:20:53 +08:00
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/ " + axis_names [ i ] + " /angular_limit_upper " , PROPERTY_HINT_RANGE , " -180,180,0.01 " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/ " + axis_names [ i ] + " /angular_limit_lower " , PROPERTY_HINT_RANGE , " -180,180,0.01 " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/ " + axis_names [ i ] + " /angular_limit_softness " , PROPERTY_HINT_RANGE , " 0.01,16,0.01 " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/ " + axis_names [ i ] + " /angular_restitution " , PROPERTY_HINT_RANGE , " 0.01,16,0.01 " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/ " + axis_names [ i ] + " /angular_damping " , PROPERTY_HINT_RANGE , " 0.01,16,0.01 " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/ " + axis_names [ i ] + " /erp " ) ) ;
2018-11-20 23:55:22 +08:00
p_list - > push_back ( PropertyInfo ( Variant : : BOOL , " joint_constraints/ " + axis_names [ i ] + " /angular_spring_enabled " ) ) ;
Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
2020-02-25 02:20:53 +08:00
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/ " + axis_names [ i ] + " /angular_spring_stiffness " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/ " + axis_names [ i ] + " /angular_spring_damping " ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : FLOAT , " joint_constraints/ " + axis_names [ i ] + " /angular_equilibrium_point " ) ) ;
2017-10-04 00:49:32 +08:00
}
}
2020-03-27 05:49:16 +08:00
bool PhysicalBone3D : : _set ( const StringName & p_name , const Variant & p_value ) {
2017-10-04 00:49:32 +08:00
if ( p_name = = " bone_name " ) {
set_bone_name ( p_value ) ;
return true ;
}
if ( joint_data ) {
2020-12-21 01:39:18 +08:00
if ( joint_data - > _set ( p_name , p_value , joint ) ) {
2017-10-04 00:49:32 +08:00
# ifdef TOOLS_ENABLED
2020-05-14 22:41:43 +08:00
if ( get_gizmo ( ) . is_valid ( ) ) {
2017-10-04 00:49:32 +08:00
get_gizmo ( ) - > redraw ( ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
# endif
return true ;
}
}
return false ;
}
2020-03-27 05:49:16 +08:00
bool PhysicalBone3D : : _get ( const StringName & p_name , Variant & r_ret ) const {
2017-10-04 00:49:32 +08:00
if ( p_name = = " bone_name " ) {
r_ret = get_bone_name ( ) ;
return true ;
}
if ( joint_data ) {
return joint_data - > _get ( p_name , r_ret ) ;
}
return false ;
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : _get_property_list ( List < PropertyInfo > * p_list ) const {
Skeleton3D * parent = find_skeleton_parent ( get_parent ( ) ) ;
2017-10-04 00:49:32 +08:00
if ( parent ) {
String names ;
for ( int i = 0 ; i < parent - > get_bone_count ( ) ; i + + ) {
2020-05-14 22:41:43 +08:00
if ( i > 0 ) {
2017-10-04 00:49:32 +08:00
names + = " , " ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
names + = parent - > get_bone_name ( i ) ;
}
2020-02-21 05:58:05 +08:00
p_list - > push_back ( PropertyInfo ( Variant : : STRING_NAME , " bone_name " , PROPERTY_HINT_ENUM , names ) ) ;
2017-10-04 00:49:32 +08:00
} else {
2020-02-21 05:58:05 +08:00
p_list - > push_back ( PropertyInfo ( Variant : : STRING_NAME , " bone_name " ) ) ;
2017-10-04 00:49:32 +08:00
}
if ( joint_data ) {
joint_data - > _get_property_list ( p_list ) ;
}
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : _notification ( int p_what ) {
2017-10-04 00:49:32 +08:00
switch ( p_what ) {
case NOTIFICATION_ENTER_TREE :
parent_skeleton = find_skeleton_parent ( get_parent ( ) ) ;
update_bone_id ( ) ;
reset_to_rest_position ( ) ;
2020-02-08 16:52:58 +08:00
reset_physics_simulation_state ( ) ;
2021-02-10 00:19:03 +08:00
if ( joint_data ) {
2019-12-02 01:30:59 +08:00
_reload_joint ( ) ;
}
2017-10-04 00:49:32 +08:00
break ;
case NOTIFICATION_EXIT_TREE :
if ( parent_skeleton ) {
if ( - 1 ! = bone_id ) {
parent_skeleton - > unbind_physical_bone_from_bone ( bone_id ) ;
2021-05-19 10:22:15 +08:00
parent_skeleton - > unbind_child_node_from_bone ( bone_id , this ) ;
bone_id = - 1 ;
2017-10-04 00:49:32 +08:00
}
}
2020-04-02 07:20:12 +08:00
parent_skeleton = nullptr ;
2021-02-10 00:19:03 +08:00
PhysicsServer3D : : get_singleton ( ) - > joint_clear ( joint ) ;
2017-10-04 00:49:32 +08:00
break ;
case NOTIFICATION_TRANSFORM_CHANGED :
if ( Engine : : get_singleton ( ) - > is_editor_hint ( ) ) {
update_offset ( ) ;
}
break ;
}
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : _direct_state_changed ( Object * p_state ) {
2019-09-19 06:46:32 +08:00
if ( ! simulate_physics | | ! _internal_simulate_physics ) {
2017-10-04 00:49:32 +08:00
return ;
}
/// Update bone transform
2020-03-28 02:21:27 +08:00
PhysicsDirectBodyState3D * state ;
2017-10-04 00:49:32 +08:00
# ifdef DEBUG_ENABLED
2020-03-28 02:21:27 +08:00
state = Object : : cast_to < PhysicsDirectBodyState3D > ( p_state ) ;
2021-03-30 14:22:23 +08:00
ERR_FAIL_NULL_MSG ( state , " Method '_direct_state_changed' must receive a valid PhysicsDirectBodyState3D object as argument " ) ;
2017-10-04 00:49:32 +08:00
# else
2020-03-28 08:50:00 +08:00
state = ( PhysicsDirectBodyState3D * ) p_state ; //trust it
2017-10-04 00:49:32 +08:00
# endif
2020-10-17 13:08:21 +08:00
Transform3D global_transform ( state - > get_transform ( ) ) ;
2017-10-04 00:49:32 +08:00
set_ignore_transform_notification ( true ) ;
set_global_transform ( global_transform ) ;
set_ignore_transform_notification ( false ) ;
2021-04-25 17:27:13 +08:00
_on_transform_changed ( ) ;
2017-10-04 00:49:32 +08:00
// Update skeleton
if ( parent_skeleton ) {
if ( - 1 ! = bone_id ) {
2019-09-19 06:46:32 +08:00
parent_skeleton - > set_bone_global_pose_override ( bone_id , parent_skeleton - > get_global_transform ( ) . affine_inverse ( ) * ( global_transform * body_offset_inverse ) , 1.0 , true ) ;
2017-10-04 00:49:32 +08:00
}
}
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " apply_central_impulse " , " impulse " ) , & PhysicalBone3D : : apply_central_impulse ) ;
2020-03-26 12:23:34 +08:00
ClassDB : : bind_method ( D_METHOD ( " apply_impulse " , " impulse " , " position " ) , & PhysicalBone3D : : apply_impulse , Vector3 ( ) ) ;
2019-12-12 07:08:11 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_joint_type " , " joint_type " ) , & PhysicalBone3D : : set_joint_type ) ;
ClassDB : : bind_method ( D_METHOD ( " get_joint_type " ) , & PhysicalBone3D : : get_joint_type ) ;
2017-10-04 00:49:32 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_joint_offset " , " offset " ) , & PhysicalBone3D : : set_joint_offset ) ;
ClassDB : : bind_method ( D_METHOD ( " get_joint_offset " ) , & PhysicalBone3D : : get_joint_offset ) ;
2020-03-26 19:59:21 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_joint_rotation " , " euler " ) , & PhysicalBone3D : : set_joint_rotation ) ;
ClassDB : : bind_method ( D_METHOD ( " get_joint_rotation " ) , & PhysicalBone3D : : get_joint_rotation ) ;
ClassDB : : bind_method ( D_METHOD ( " set_joint_rotation_degrees " , " euler_degrees " ) , & PhysicalBone3D : : set_joint_rotation_degrees ) ;
ClassDB : : bind_method ( D_METHOD ( " get_joint_rotation_degrees " ) , & PhysicalBone3D : : get_joint_rotation_degrees ) ;
2017-10-04 00:49:32 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_body_offset " , " offset " ) , & PhysicalBone3D : : set_body_offset ) ;
ClassDB : : bind_method ( D_METHOD ( " get_body_offset " ) , & PhysicalBone3D : : get_body_offset ) ;
2017-10-04 00:49:32 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " get_simulate_physics " ) , & PhysicalBone3D : : get_simulate_physics ) ;
2017-10-04 00:49:32 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " is_simulating_physics " ) , & PhysicalBone3D : : is_simulating_physics ) ;
2017-10-04 00:49:32 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " get_bone_id " ) , & PhysicalBone3D : : get_bone_id ) ;
2018-08-13 01:47:21 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_mass " , " mass " ) , & PhysicalBone3D : : set_mass ) ;
ClassDB : : bind_method ( D_METHOD ( " get_mass " ) , & PhysicalBone3D : : get_mass ) ;
2017-10-04 00:49:32 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_friction " , " friction " ) , & PhysicalBone3D : : set_friction ) ;
ClassDB : : bind_method ( D_METHOD ( " get_friction " ) , & PhysicalBone3D : : get_friction ) ;
2017-10-04 00:49:32 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_bounce " , " bounce " ) , & PhysicalBone3D : : set_bounce ) ;
ClassDB : : bind_method ( D_METHOD ( " get_bounce " ) , & PhysicalBone3D : : get_bounce ) ;
2017-10-04 00:49:32 +08:00
2020-03-27 05:49:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_gravity_scale " , " gravity_scale " ) , & PhysicalBone3D : : set_gravity_scale ) ;
ClassDB : : bind_method ( D_METHOD ( " get_gravity_scale " ) , & PhysicalBone3D : : get_gravity_scale ) ;
2017-10-04 00:49:32 +08:00
2020-03-26 19:59:21 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_linear_damp " , " linear_damp " ) , & PhysicalBone3D : : set_linear_damp ) ;
ClassDB : : bind_method ( D_METHOD ( " get_linear_damp " ) , & PhysicalBone3D : : get_linear_damp ) ;
ClassDB : : bind_method ( D_METHOD ( " set_angular_damp " , " angular_damp " ) , & PhysicalBone3D : : set_angular_damp ) ;
ClassDB : : bind_method ( D_METHOD ( " get_angular_damp " ) , & PhysicalBone3D : : get_angular_damp ) ;
ClassDB : : bind_method ( D_METHOD ( " set_can_sleep " , " able_to_sleep " ) , & PhysicalBone3D : : set_can_sleep ) ;
ClassDB : : bind_method ( D_METHOD ( " is_able_to_sleep " ) , & PhysicalBone3D : : is_able_to_sleep ) ;
2017-10-04 00:49:32 +08:00
ADD_GROUP ( " Joint " , " joint_ " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " joint_type " , PROPERTY_HINT_ENUM , " None,PinJoint,ConeJoint,HingeJoint,SliderJoint,6DOFJoint " ) , " set_joint_type " , " get_joint_type " ) ;
2021-04-28 15:36:08 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : TRANSFORM3D , " joint_offset " ) , " set_joint_offset " , " get_joint_offset " ) ;
2020-03-26 19:59:21 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR3 , " joint_rotation_degrees " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_EDITOR ) , " set_joint_rotation_degrees " , " get_joint_rotation_degrees " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR3 , " joint_rotation " , PROPERTY_HINT_NONE , " " , 0 ) , " set_joint_rotation " , " get_joint_rotation " ) ;
2017-10-04 00:49:32 +08:00
2021-04-28 15:36:08 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : TRANSFORM3D , " body_offset " ) , " set_body_offset " , " get_body_offset " ) ;
2017-10-04 00:49:32 +08:00
Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
2020-02-25 02:20:53 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : FLOAT , " mass " , PROPERTY_HINT_EXP_RANGE , " 0.01,65535,0.01 " ) , " set_mass " , " get_mass " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : FLOAT , " friction " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) , " set_friction " , " get_friction " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : FLOAT , " bounce " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) , " set_bounce " , " get_bounce " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : FLOAT , " gravity_scale " , PROPERTY_HINT_RANGE , " -10,10,0.01 " ) , " set_gravity_scale " , " get_gravity_scale " ) ;
2020-03-26 19:59:21 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : FLOAT , " linear_damp " , PROPERTY_HINT_RANGE , " -1,100,0.001,or_greater " ) , " set_linear_damp " , " get_linear_damp " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : FLOAT , " angular_damp " , PROPERTY_HINT_RANGE , " -1,100,0.001,or_greater " ) , " set_angular_damp " , " get_angular_damp " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " can_sleep " ) , " set_can_sleep " , " is_able_to_sleep " ) ;
2018-05-09 08:14:31 +08:00
BIND_ENUM_CONSTANT ( JOINT_TYPE_NONE ) ;
BIND_ENUM_CONSTANT ( JOINT_TYPE_PIN ) ;
BIND_ENUM_CONSTANT ( JOINT_TYPE_CONE ) ;
BIND_ENUM_CONSTANT ( JOINT_TYPE_HINGE ) ;
BIND_ENUM_CONSTANT ( JOINT_TYPE_SLIDER ) ;
BIND_ENUM_CONSTANT ( JOINT_TYPE_6DOF ) ;
2017-10-04 00:49:32 +08:00
}
2020-03-27 05:49:16 +08:00
Skeleton3D * PhysicalBone3D : : find_skeleton_parent ( Node * p_parent ) {
2017-10-04 00:49:32 +08:00
if ( ! p_parent ) {
2020-04-02 07:20:12 +08:00
return nullptr ;
2017-10-04 00:49:32 +08:00
}
2020-03-27 05:49:16 +08:00
Skeleton3D * s = Object : : cast_to < Skeleton3D > ( p_parent ) ;
2017-10-04 00:49:32 +08:00
return s ? s : find_skeleton_parent ( p_parent - > get_parent ( ) ) ;
}
2020-03-26 19:59:21 +08:00
void PhysicalBone3D : : _update_joint_offset ( ) {
_fix_joint_offset ( ) ;
set_ignore_transform_notification ( true ) ;
reset_to_rest_position ( ) ;
set_ignore_transform_notification ( false ) ;
# ifdef TOOLS_ENABLED
2020-05-14 22:41:43 +08:00
if ( get_gizmo ( ) . is_valid ( ) ) {
2020-03-26 19:59:21 +08:00
get_gizmo ( ) - > redraw ( ) ;
2020-05-14 22:41:43 +08:00
}
2020-03-26 19:59:21 +08:00
# endif
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : _fix_joint_offset ( ) {
2017-10-04 00:49:32 +08:00
// Clamp joint origin to bone origin
if ( parent_skeleton ) {
joint_offset . origin = body_offset . affine_inverse ( ) . origin ;
}
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : _reload_joint ( ) {
2017-10-04 00:49:32 +08:00
if ( ! parent_skeleton ) {
2021-02-10 00:19:03 +08:00
PhysicsServer3D : : get_singleton ( ) - > joint_clear ( joint ) ;
2017-10-04 00:49:32 +08:00
return ;
}
2020-03-27 05:49:16 +08:00
PhysicalBone3D * body_a = parent_skeleton - > get_physical_bone_parent ( bone_id ) ;
2017-10-04 00:49:32 +08:00
if ( ! body_a ) {
2021-02-10 00:19:03 +08:00
PhysicsServer3D : : get_singleton ( ) - > joint_clear ( joint ) ;
2017-10-04 00:49:32 +08:00
return ;
}
2020-10-17 13:08:21 +08:00
Transform3D joint_transf = get_global_transform ( ) * joint_offset ;
Transform3D local_a = body_a - > get_global_transform ( ) . affine_inverse ( ) * joint_transf ;
2017-10-04 00:49:32 +08:00
local_a . orthonormalize ( ) ;
switch ( get_joint_type ( ) ) {
case JOINT_TYPE_PIN : {
2021-02-10 00:19:03 +08:00
PhysicsServer3D : : get_singleton ( ) - > joint_make_pin ( joint , body_a - > get_rid ( ) , local_a . origin , get_rid ( ) , joint_offset . origin ) ;
2017-10-04 00:49:32 +08:00
const PinJointData * pjd ( static_cast < const PinJointData * > ( joint_data ) ) ;
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > pin_joint_set_param ( joint , PhysicsServer3D : : PIN_JOINT_BIAS , pjd - > bias ) ;
PhysicsServer3D : : get_singleton ( ) - > pin_joint_set_param ( joint , PhysicsServer3D : : PIN_JOINT_DAMPING , pjd - > damping ) ;
PhysicsServer3D : : get_singleton ( ) - > pin_joint_set_param ( joint , PhysicsServer3D : : PIN_JOINT_IMPULSE_CLAMP , pjd - > impulse_clamp ) ;
2017-10-04 00:49:32 +08:00
} break ;
case JOINT_TYPE_CONE : {
2021-02-10 00:19:03 +08:00
PhysicsServer3D : : get_singleton ( ) - > joint_make_cone_twist ( joint , body_a - > get_rid ( ) , local_a , get_rid ( ) , joint_offset ) ;
2017-10-04 00:49:32 +08:00
const ConeJointData * cjd ( static_cast < const ConeJointData * > ( joint_data ) ) ;
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > cone_twist_joint_set_param ( joint , PhysicsServer3D : : CONE_TWIST_JOINT_SWING_SPAN , cjd - > swing_span ) ;
PhysicsServer3D : : get_singleton ( ) - > cone_twist_joint_set_param ( joint , PhysicsServer3D : : CONE_TWIST_JOINT_TWIST_SPAN , cjd - > twist_span ) ;
PhysicsServer3D : : get_singleton ( ) - > cone_twist_joint_set_param ( joint , PhysicsServer3D : : CONE_TWIST_JOINT_BIAS , cjd - > bias ) ;
PhysicsServer3D : : get_singleton ( ) - > cone_twist_joint_set_param ( joint , PhysicsServer3D : : CONE_TWIST_JOINT_SOFTNESS , cjd - > softness ) ;
PhysicsServer3D : : get_singleton ( ) - > cone_twist_joint_set_param ( joint , PhysicsServer3D : : CONE_TWIST_JOINT_RELAXATION , cjd - > relaxation ) ;
2017-10-04 00:49:32 +08:00
} break ;
case JOINT_TYPE_HINGE : {
2021-02-10 00:19:03 +08:00
PhysicsServer3D : : get_singleton ( ) - > joint_make_hinge ( joint , body_a - > get_rid ( ) , local_a , get_rid ( ) , joint_offset ) ;
2017-10-04 00:49:32 +08:00
const HingeJointData * hjd ( static_cast < const HingeJointData * > ( joint_data ) ) ;
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > hinge_joint_set_flag ( joint , PhysicsServer3D : : HINGE_JOINT_FLAG_USE_LIMIT , hjd - > angular_limit_enabled ) ;
PhysicsServer3D : : get_singleton ( ) - > hinge_joint_set_param ( joint , PhysicsServer3D : : HINGE_JOINT_LIMIT_UPPER , hjd - > angular_limit_upper ) ;
PhysicsServer3D : : get_singleton ( ) - > hinge_joint_set_param ( joint , PhysicsServer3D : : HINGE_JOINT_LIMIT_LOWER , hjd - > angular_limit_lower ) ;
PhysicsServer3D : : get_singleton ( ) - > hinge_joint_set_param ( joint , PhysicsServer3D : : HINGE_JOINT_LIMIT_BIAS , hjd - > angular_limit_bias ) ;
PhysicsServer3D : : get_singleton ( ) - > hinge_joint_set_param ( joint , PhysicsServer3D : : HINGE_JOINT_LIMIT_SOFTNESS , hjd - > angular_limit_softness ) ;
PhysicsServer3D : : get_singleton ( ) - > hinge_joint_set_param ( joint , PhysicsServer3D : : HINGE_JOINT_LIMIT_RELAXATION , hjd - > angular_limit_relaxation ) ;
2017-10-04 00:49:32 +08:00
} break ;
case JOINT_TYPE_SLIDER : {
2021-02-10 00:19:03 +08:00
PhysicsServer3D : : get_singleton ( ) - > joint_make_slider ( joint , body_a - > get_rid ( ) , local_a , get_rid ( ) , joint_offset ) ;
2017-10-04 00:49:32 +08:00
const SliderJointData * sjd ( static_cast < const SliderJointData * > ( joint_data ) ) ;
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > slider_joint_set_param ( joint , PhysicsServer3D : : SLIDER_JOINT_LINEAR_LIMIT_UPPER , sjd - > linear_limit_upper ) ;
PhysicsServer3D : : get_singleton ( ) - > slider_joint_set_param ( joint , PhysicsServer3D : : SLIDER_JOINT_LINEAR_LIMIT_LOWER , sjd - > linear_limit_lower ) ;
PhysicsServer3D : : get_singleton ( ) - > slider_joint_set_param ( joint , PhysicsServer3D : : SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS , sjd - > linear_limit_softness ) ;
PhysicsServer3D : : get_singleton ( ) - > slider_joint_set_param ( joint , PhysicsServer3D : : SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION , sjd - > linear_limit_restitution ) ;
PhysicsServer3D : : get_singleton ( ) - > slider_joint_set_param ( joint , PhysicsServer3D : : SLIDER_JOINT_LINEAR_LIMIT_DAMPING , sjd - > linear_limit_restitution ) ;
PhysicsServer3D : : get_singleton ( ) - > slider_joint_set_param ( joint , PhysicsServer3D : : SLIDER_JOINT_ANGULAR_LIMIT_UPPER , sjd - > angular_limit_upper ) ;
PhysicsServer3D : : get_singleton ( ) - > slider_joint_set_param ( joint , PhysicsServer3D : : SLIDER_JOINT_ANGULAR_LIMIT_LOWER , sjd - > angular_limit_lower ) ;
PhysicsServer3D : : get_singleton ( ) - > slider_joint_set_param ( joint , PhysicsServer3D : : SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS , sjd - > angular_limit_softness ) ;
PhysicsServer3D : : get_singleton ( ) - > slider_joint_set_param ( joint , PhysicsServer3D : : SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS , sjd - > angular_limit_softness ) ;
PhysicsServer3D : : get_singleton ( ) - > slider_joint_set_param ( joint , PhysicsServer3D : : SLIDER_JOINT_ANGULAR_LIMIT_DAMPING , sjd - > angular_limit_damping ) ;
2017-10-04 00:49:32 +08:00
} break ;
case JOINT_TYPE_6DOF : {
2021-02-10 00:19:03 +08:00
PhysicsServer3D : : get_singleton ( ) - > joint_make_generic_6dof ( joint , body_a - > get_rid ( ) , local_a , get_rid ( ) , joint_offset ) ;
2017-10-04 00:49:32 +08:00
const SixDOFJointData * g6dofjd ( static_cast < const SixDOFJointData * > ( joint_data ) ) ;
for ( int axis = 0 ; axis < 3 ; + + axis ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_flag ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer3D : : G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT , g6dofjd - > axis_data [ axis ] . linear_limit_enabled ) ;
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer3D : : G6DOF_JOINT_LINEAR_UPPER_LIMIT , g6dofjd - > axis_data [ axis ] . linear_limit_upper ) ;
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer3D : : G6DOF_JOINT_LINEAR_LOWER_LIMIT , g6dofjd - > axis_data [ axis ] . linear_limit_lower ) ;
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer3D : : G6DOF_JOINT_LINEAR_LIMIT_SOFTNESS , g6dofjd - > axis_data [ axis ] . linear_limit_softness ) ;
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_flag ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer3D : : G6DOF_JOINT_FLAG_ENABLE_LINEAR_SPRING , g6dofjd - > axis_data [ axis ] . linear_spring_enabled ) ;
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer3D : : G6DOF_JOINT_LINEAR_SPRING_STIFFNESS , g6dofjd - > axis_data [ axis ] . linear_spring_stiffness ) ;
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer3D : : G6DOF_JOINT_LINEAR_SPRING_DAMPING , g6dofjd - > axis_data [ axis ] . linear_spring_damping ) ;
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer3D : : G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT , g6dofjd - > axis_data [ axis ] . linear_equilibrium_point ) ;
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer3D : : G6DOF_JOINT_LINEAR_RESTITUTION , g6dofjd - > axis_data [ axis ] . linear_restitution ) ;
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer3D : : G6DOF_JOINT_LINEAR_DAMPING , g6dofjd - > axis_data [ axis ] . linear_damping ) ;
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_flag ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer3D : : G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT , g6dofjd - > axis_data [ axis ] . angular_limit_enabled ) ;
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer3D : : G6DOF_JOINT_ANGULAR_UPPER_LIMIT , g6dofjd - > axis_data [ axis ] . angular_limit_upper ) ;
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer3D : : G6DOF_JOINT_ANGULAR_LOWER_LIMIT , g6dofjd - > axis_data [ axis ] . angular_limit_lower ) ;
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer3D : : G6DOF_JOINT_ANGULAR_LIMIT_SOFTNESS , g6dofjd - > axis_data [ axis ] . angular_limit_softness ) ;
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer3D : : G6DOF_JOINT_ANGULAR_RESTITUTION , g6dofjd - > axis_data [ axis ] . angular_restitution ) ;
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer3D : : G6DOF_JOINT_ANGULAR_DAMPING , g6dofjd - > axis_data [ axis ] . angular_damping ) ;
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer3D : : G6DOF_JOINT_ANGULAR_ERP , g6dofjd - > axis_data [ axis ] . erp ) ;
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_flag ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer3D : : G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING , g6dofjd - > axis_data [ axis ] . angular_spring_enabled ) ;
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer3D : : G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS , g6dofjd - > axis_data [ axis ] . angular_spring_stiffness ) ;
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer3D : : G6DOF_JOINT_ANGULAR_SPRING_DAMPING , g6dofjd - > axis_data [ axis ] . angular_spring_damping ) ;
PhysicsServer3D : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer3D : : G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT , g6dofjd - > axis_data [ axis ] . angular_equilibrium_point ) ;
2017-10-04 00:49:32 +08:00
}
} break ;
2018-09-26 19:13:56 +08:00
case JOINT_TYPE_NONE : {
} break ;
2017-10-04 00:49:32 +08:00
}
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : _on_bone_parent_changed ( ) {
2017-10-04 00:49:32 +08:00
_reload_joint ( ) ;
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : _set_gizmo_move_joint ( bool p_move_joint ) {
2017-10-04 00:49:32 +08:00
# ifdef TOOLS_ENABLED
gizmo_move_joint = p_move_joint ;
2020-03-27 05:49:16 +08:00
Node3DEditor : : get_singleton ( ) - > update_transform_gizmo ( ) ;
2017-10-04 00:49:32 +08:00
# endif
}
# ifdef TOOLS_ENABLED
2020-10-17 13:08:21 +08:00
Transform3D PhysicalBone3D : : get_global_gizmo_transform ( ) const {
2017-10-04 00:49:32 +08:00
return gizmo_move_joint ? get_global_transform ( ) * joint_offset : get_global_transform ( ) ;
}
2020-10-17 13:08:21 +08:00
Transform3D PhysicalBone3D : : get_local_gizmo_transform ( ) const {
2017-10-04 00:49:32 +08:00
return gizmo_move_joint ? get_transform ( ) * joint_offset : get_transform ( ) ;
}
# endif
2020-03-27 05:49:16 +08:00
const PhysicalBone3D : : JointData * PhysicalBone3D : : get_joint_data ( ) const {
2017-10-04 00:49:32 +08:00
return joint_data ;
}
2020-03-27 05:49:16 +08:00
Skeleton3D * PhysicalBone3D : : find_skeleton_parent ( ) {
2017-10-04 00:49:32 +08:00
return find_skeleton_parent ( this ) ;
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : set_joint_type ( JointType p_joint_type ) {
2020-05-14 22:41:43 +08:00
if ( p_joint_type = = get_joint_type ( ) ) {
2017-10-04 00:49:32 +08:00
return ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
2020-05-14 22:41:43 +08:00
if ( joint_data ) {
2018-11-01 16:46:46 +08:00
memdelete ( joint_data ) ;
2020-05-14 22:41:43 +08:00
}
2020-04-02 07:20:12 +08:00
joint_data = nullptr ;
2017-10-04 00:49:32 +08:00
switch ( p_joint_type ) {
case JOINT_TYPE_PIN :
joint_data = memnew ( PinJointData ) ;
break ;
case JOINT_TYPE_CONE :
joint_data = memnew ( ConeJointData ) ;
break ;
case JOINT_TYPE_HINGE :
joint_data = memnew ( HingeJointData ) ;
break ;
case JOINT_TYPE_SLIDER :
joint_data = memnew ( SliderJointData ) ;
break ;
case JOINT_TYPE_6DOF :
joint_data = memnew ( SixDOFJointData ) ;
break ;
2018-09-26 19:13:56 +08:00
case JOINT_TYPE_NONE :
break ;
2017-10-04 00:49:32 +08:00
}
_reload_joint ( ) ;
# ifdef TOOLS_ENABLED
2021-02-11 04:18:45 +08:00
notify_property_list_changed ( ) ;
2020-05-14 22:41:43 +08:00
if ( get_gizmo ( ) . is_valid ( ) ) {
2017-10-04 00:49:32 +08:00
get_gizmo ( ) - > redraw ( ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
# endif
}
2020-03-27 05:49:16 +08:00
PhysicalBone3D : : JointType PhysicalBone3D : : get_joint_type ( ) const {
2017-10-04 00:49:32 +08:00
return joint_data ? joint_data - > get_joint_type ( ) : JOINT_TYPE_NONE ;
}
2020-10-17 13:08:21 +08:00
void PhysicalBone3D : : set_joint_offset ( const Transform3D & p_offset ) {
2017-10-04 00:49:32 +08:00
joint_offset = p_offset ;
2020-03-26 19:59:21 +08:00
_update_joint_offset ( ) ;
}
2017-10-04 00:49:32 +08:00
2020-10-17 13:08:21 +08:00
const Transform3D & PhysicalBone3D : : get_joint_offset ( ) const {
2020-03-26 19:59:21 +08:00
return joint_offset ;
}
2017-10-04 00:49:32 +08:00
2020-03-26 19:59:21 +08:00
void PhysicalBone3D : : set_joint_rotation ( const Vector3 & p_euler_rad ) {
joint_offset . basis . set_euler_scale ( p_euler_rad , joint_offset . basis . get_scale ( ) ) ;
_update_joint_offset ( ) ;
}
Vector3 PhysicalBone3D : : get_joint_rotation ( ) const {
return joint_offset . basis . get_rotation ( ) ;
}
void PhysicalBone3D : : set_joint_rotation_degrees ( const Vector3 & p_euler_deg ) {
2020-04-03 17:50:40 +08:00
set_joint_rotation ( p_euler_deg * ( Math_PI / 180.0 ) ) ;
2020-03-26 19:59:21 +08:00
}
Vector3 PhysicalBone3D : : get_joint_rotation_degrees ( ) const {
2020-04-03 17:50:40 +08:00
return get_joint_rotation ( ) * ( 180.0 / Math_PI ) ;
2017-10-04 00:49:32 +08:00
}
2020-10-17 13:08:21 +08:00
const Transform3D & PhysicalBone3D : : get_body_offset ( ) const {
2017-10-04 00:49:32 +08:00
return body_offset ;
}
2020-10-17 13:08:21 +08:00
void PhysicalBone3D : : set_body_offset ( const Transform3D & p_offset ) {
2017-10-04 00:49:32 +08:00
body_offset = p_offset ;
body_offset_inverse = body_offset . affine_inverse ( ) ;
2020-03-26 19:59:21 +08:00
_update_joint_offset ( ) ;
2017-10-04 00:49:32 +08:00
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : set_simulate_physics ( bool p_simulate ) {
2017-10-04 00:49:32 +08:00
if ( simulate_physics = = p_simulate ) {
return ;
}
simulate_physics = p_simulate ;
2020-02-08 16:52:58 +08:00
reset_physics_simulation_state ( ) ;
2017-10-04 00:49:32 +08:00
}
2020-03-27 05:49:16 +08:00
bool PhysicalBone3D : : get_simulate_physics ( ) {
2017-10-04 00:49:32 +08:00
return simulate_physics ;
}
2020-03-27 05:49:16 +08:00
bool PhysicalBone3D : : is_simulating_physics ( ) {
2020-02-08 16:52:58 +08:00
return _internal_simulate_physics ;
2017-10-04 00:49:32 +08:00
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : set_bone_name ( const String & p_name ) {
2017-10-04 00:49:32 +08:00
bone_name = p_name ;
bone_id = - 1 ;
update_bone_id ( ) ;
reset_to_rest_position ( ) ;
}
2020-03-27 05:49:16 +08:00
const String & PhysicalBone3D : : get_bone_name ( ) const {
2017-10-04 00:49:32 +08:00
return bone_name ;
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : set_mass ( real_t p_mass ) {
2017-10-04 00:49:32 +08:00
ERR_FAIL_COND ( p_mass < = 0 ) ;
mass = p_mass ;
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer3D : : BODY_PARAM_MASS , mass ) ;
2017-10-04 00:49:32 +08:00
}
2020-03-27 05:49:16 +08:00
real_t PhysicalBone3D : : get_mass ( ) const {
2017-10-04 00:49:32 +08:00
return mass ;
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : set_friction ( real_t p_friction ) {
2017-10-04 00:49:32 +08:00
ERR_FAIL_COND ( p_friction < 0 | | p_friction > 1 ) ;
friction = p_friction ;
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer3D : : BODY_PARAM_FRICTION , friction ) ;
2017-10-04 00:49:32 +08:00
}
2020-03-27 05:49:16 +08:00
real_t PhysicalBone3D : : get_friction ( ) const {
2017-10-04 00:49:32 +08:00
return friction ;
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : set_bounce ( real_t p_bounce ) {
2017-10-04 00:49:32 +08:00
ERR_FAIL_COND ( p_bounce < 0 | | p_bounce > 1 ) ;
bounce = p_bounce ;
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer3D : : BODY_PARAM_BOUNCE , bounce ) ;
2017-10-04 00:49:32 +08:00
}
2017-10-25 00:10:30 +08:00
2020-03-27 05:49:16 +08:00
real_t PhysicalBone3D : : get_bounce ( ) const {
2017-10-04 00:49:32 +08:00
return bounce ;
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : set_gravity_scale ( real_t p_gravity_scale ) {
2017-10-04 00:49:32 +08:00
gravity_scale = p_gravity_scale ;
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer3D : : BODY_PARAM_GRAVITY_SCALE , gravity_scale ) ;
2017-10-04 00:49:32 +08:00
}
2020-03-27 05:49:16 +08:00
real_t PhysicalBone3D : : get_gravity_scale ( ) const {
2017-10-04 00:49:32 +08:00
return gravity_scale ;
}
2020-03-26 19:59:21 +08:00
void PhysicalBone3D : : set_linear_damp ( real_t p_linear_damp ) {
ERR_FAIL_COND ( p_linear_damp < - 1 ) ;
linear_damp = p_linear_damp ;
PhysicsServer3D : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer3D : : BODY_PARAM_LINEAR_DAMP , linear_damp ) ;
}
real_t PhysicalBone3D : : get_linear_damp ( ) const {
return linear_damp ;
}
void PhysicalBone3D : : set_angular_damp ( real_t p_angular_damp ) {
ERR_FAIL_COND ( p_angular_damp < - 1 ) ;
angular_damp = p_angular_damp ;
PhysicsServer3D : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer3D : : BODY_PARAM_ANGULAR_DAMP , angular_damp ) ;
}
real_t PhysicalBone3D : : get_angular_damp ( ) const {
return angular_damp ;
}
void PhysicalBone3D : : set_can_sleep ( bool p_active ) {
can_sleep = p_active ;
PhysicsServer3D : : get_singleton ( ) - > body_set_state ( get_rid ( ) , PhysicsServer3D : : BODY_STATE_CAN_SLEEP , p_active ) ;
}
bool PhysicalBone3D : : is_able_to_sleep ( ) const {
return can_sleep ;
}
2020-03-27 05:49:16 +08:00
PhysicalBone3D : : PhysicalBone3D ( ) :
2020-05-12 23:01:17 +08:00
PhysicsBody3D ( PhysicsServer3D : : BODY_MODE_STATIC ) {
2021-02-10 00:19:03 +08:00
joint = PhysicsServer3D : : get_singleton ( ) - > joint_create ( ) ;
2020-02-08 16:52:58 +08:00
reset_physics_simulation_state ( ) ;
2017-10-04 00:49:32 +08:00
}
2020-03-27 05:49:16 +08:00
PhysicalBone3D : : ~ PhysicalBone3D ( ) {
2020-05-14 22:41:43 +08:00
if ( joint_data ) {
2018-11-01 16:46:46 +08:00
memdelete ( joint_data ) ;
2020-05-14 22:41:43 +08:00
}
2021-02-10 00:19:03 +08:00
PhysicsServer3D : : get_singleton ( ) - > free ( joint ) ;
2017-10-04 00:49:32 +08:00
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : update_bone_id ( ) {
2017-10-04 00:49:32 +08:00
if ( ! parent_skeleton ) {
return ;
}
const int new_bone_id = parent_skeleton - > find_bone ( bone_name ) ;
if ( new_bone_id ! = bone_id ) {
if ( - 1 ! = bone_id ) {
// Assert the unbind from old node
parent_skeleton - > unbind_physical_bone_from_bone ( bone_id ) ;
parent_skeleton - > unbind_child_node_from_bone ( bone_id , this ) ;
}
bone_id = new_bone_id ;
parent_skeleton - > bind_physical_bone_to_bone ( bone_id , this ) ;
_fix_joint_offset ( ) ;
2020-02-08 16:52:58 +08:00
reset_physics_simulation_state ( ) ;
2017-10-04 00:49:32 +08:00
}
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : update_offset ( ) {
2017-10-04 00:49:32 +08:00
# ifdef TOOLS_ENABLED
if ( parent_skeleton ) {
2020-10-17 13:08:21 +08:00
Transform3D bone_transform ( parent_skeleton - > get_global_transform ( ) ) ;
2020-05-14 22:41:43 +08:00
if ( - 1 ! = bone_id ) {
2017-10-04 00:49:32 +08:00
bone_transform * = parent_skeleton - > get_bone_global_pose ( bone_id ) ;
2020-05-14 22:41:43 +08:00
}
2017-10-04 00:49:32 +08:00
if ( gizmo_move_joint ) {
bone_transform * = body_offset ;
set_joint_offset ( bone_transform . affine_inverse ( ) * get_global_transform ( ) ) ;
} else {
set_body_offset ( bone_transform . affine_inverse ( ) * get_global_transform ( ) ) ;
}
}
# endif
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : _start_physics_simulation ( ) {
2017-10-04 00:49:32 +08:00
if ( _internal_simulate_physics | | ! parent_skeleton ) {
return ;
}
reset_to_rest_position ( ) ;
2021-05-20 09:15:07 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_mode ( get_rid ( ) , PhysicsServer3D : : BODY_MODE_DYNAMIC ) ;
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_collision_layer ( get_rid ( ) , get_collision_layer ( ) ) ;
PhysicsServer3D : : get_singleton ( ) - > body_set_collision_mask ( get_rid ( ) , get_collision_mask ( ) ) ;
2021-03-30 14:22:23 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_force_integration_callback ( get_rid ( ) , callable_mp ( this , & PhysicalBone3D : : _direct_state_changed ) ) ;
2020-10-01 15:17:33 +08:00
set_as_top_level ( true ) ;
2017-10-04 00:49:32 +08:00
_internal_simulate_physics = true ;
}
2020-03-27 05:49:16 +08:00
void PhysicalBone3D : : _stop_physics_simulation ( ) {
2020-02-08 16:52:58 +08:00
if ( ! parent_skeleton ) {
2017-10-04 00:49:32 +08:00
return ;
}
2020-02-08 16:52:58 +08:00
if ( parent_skeleton - > get_animate_physical_bones ( ) ) {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_mode ( get_rid ( ) , PhysicsServer3D : : BODY_MODE_KINEMATIC ) ;
PhysicsServer3D : : get_singleton ( ) - > body_set_collision_layer ( get_rid ( ) , get_collision_layer ( ) ) ;
PhysicsServer3D : : get_singleton ( ) - > body_set_collision_mask ( get_rid ( ) , get_collision_mask ( ) ) ;
2020-02-08 16:52:58 +08:00
} else {
2020-03-28 02:21:27 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_mode ( get_rid ( ) , PhysicsServer3D : : BODY_MODE_STATIC ) ;
PhysicsServer3D : : get_singleton ( ) - > body_set_collision_layer ( get_rid ( ) , 0 ) ;
PhysicsServer3D : : get_singleton ( ) - > body_set_collision_mask ( get_rid ( ) , 0 ) ;
2020-02-08 16:52:58 +08:00
}
if ( _internal_simulate_physics ) {
2021-03-30 14:22:23 +08:00
PhysicsServer3D : : get_singleton ( ) - > body_set_force_integration_callback ( get_rid ( ) , Callable ( ) ) ;
2020-10-17 13:08:21 +08:00
parent_skeleton - > set_bone_global_pose_override ( bone_id , Transform3D ( ) , 0.0 , false ) ;
2020-10-01 15:17:33 +08:00
set_as_top_level ( false ) ;
2020-02-08 16:52:58 +08:00
_internal_simulate_physics = false ;
}
2017-10-04 00:49:32 +08:00
}