2014-02-10 02:10:30 +01:00
/*************************************************************************/
/* physics_body.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 14:16:55 +02:00
/* https://godotengine.org */
2014-02-10 02:10:30 +01:00
/*************************************************************************/
2020-01-01 11:16:22 +01:00
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
2014-02-10 02:10:30 +01:00
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
2018-01-05 00:50:27 +01:00
2014-02-10 02:10:30 +01:00
# include "physics_body.h"
2017-08-19 01:02:56 +02:00
2017-10-24 18:10:30 +02:00
# include "core/core_string_names.h"
2018-09-11 18:13:45 +02:00
# include "core/engine.h"
2018-10-24 21:32:55 +02:00
# include "core/list.h"
2018-09-11 18:13:45 +02:00
# include "core/method_bind_ext.gen.inc"
2018-10-24 21:32:55 +02:00
# include "core/object.h"
# include "core/rid.h"
2020-01-10 12:22:34 +01:00
# include "scene/3d/collision_shape.h"
2014-02-10 02:10:30 +01:00
# include "scene/scene_string_names.h"
2020-01-10 12:22:34 +01:00
# include "servers/navigation_server.h"
2014-02-10 02:10:30 +01:00
2017-10-03 18:49:32 +02:00
# ifdef TOOLS_ENABLED
# include "editor/plugins/spatial_editor_plugin.h"
# endif
2014-08-14 15:31:38 +02:00
Vector3 PhysicsBody : : get_linear_velocity ( ) const {
return Vector3 ( ) ;
}
Vector3 PhysicsBody : : get_angular_velocity ( ) const {
return Vector3 ( ) ;
}
float PhysicsBody : : get_inverse_mass ( ) const {
return 0 ;
}
2017-06-13 17:45:01 +02:00
void PhysicsBody : : set_collision_layer ( uint32_t p_layer ) {
2014-02-10 02:10:30 +01:00
2017-06-13 17:45:01 +02:00
collision_layer = p_layer ;
PhysicsServer : : get_singleton ( ) - > body_set_collision_layer ( get_rid ( ) , p_layer ) ;
2014-02-10 02:10:30 +01:00
}
2017-01-13 15:01:19 +01:00
uint32_t PhysicsBody : : get_collision_layer ( ) const {
2014-02-10 02:10:30 +01:00
2017-06-13 17:45:01 +02:00
return collision_layer ;
2014-02-10 02:10:30 +01:00
}
2016-04-09 20:54:09 +02:00
void PhysicsBody : : set_collision_mask ( uint32_t p_mask ) {
2017-03-05 16:44:50 +01:00
collision_mask = p_mask ;
PhysicsServer : : get_singleton ( ) - > body_set_collision_mask ( get_rid ( ) , p_mask ) ;
2016-04-09 20:54:09 +02:00
}
uint32_t PhysicsBody : : get_collision_mask ( ) const {
return collision_mask ;
}
void PhysicsBody : : set_collision_mask_bit ( int p_bit , bool p_value ) {
uint32_t mask = get_collision_mask ( ) ;
if ( p_value )
2017-03-05 16:44:50 +01:00
mask | = 1 < < p_bit ;
2016-04-09 20:54:09 +02:00
else
2017-03-05 16:44:50 +01:00
mask & = ~ ( 1 < < p_bit ) ;
2016-04-09 20:54:09 +02:00
set_collision_mask ( mask ) ;
}
2017-03-05 16:44:50 +01:00
bool PhysicsBody : : get_collision_mask_bit ( int p_bit ) const {
2016-04-09 20:54:09 +02:00
2017-03-05 16:44:50 +01:00
return get_collision_mask ( ) & ( 1 < < p_bit ) ;
2016-04-09 20:54:09 +02:00
}
2017-01-13 15:01:19 +01:00
void PhysicsBody : : set_collision_layer_bit ( int p_bit , bool p_value ) {
2016-04-09 20:54:09 +02:00
2017-01-13 15:01:19 +01:00
uint32_t mask = get_collision_layer ( ) ;
2016-04-09 20:54:09 +02:00
if ( p_value )
2017-03-05 16:44:50 +01:00
mask | = 1 < < p_bit ;
2016-04-09 20:54:09 +02:00
else
2017-03-05 16:44:50 +01:00
mask & = ~ ( 1 < < p_bit ) ;
2017-01-13 15:01:19 +01:00
set_collision_layer ( mask ) ;
2016-04-09 20:54:09 +02:00
}
2017-03-05 16:44:50 +01:00
bool PhysicsBody : : get_collision_layer_bit ( int p_bit ) const {
2016-04-09 20:54:09 +02:00
2017-03-05 16:44:50 +01:00
return get_collision_layer ( ) & ( 1 < < p_bit ) ;
2016-04-09 20:54:09 +02:00
}
2018-10-24 21:32:55 +02:00
Array PhysicsBody : : get_collision_exceptions ( ) {
List < RID > exceptions ;
PhysicsServer : : get_singleton ( ) - > body_get_collision_exceptions ( get_rid ( ) , & exceptions ) ;
Array ret ;
for ( List < RID > : : Element * E = exceptions . front ( ) ; E ; E = E - > next ( ) ) {
RID body = E - > get ( ) ;
ObjectID instance_id = PhysicsServer : : get_singleton ( ) - > body_get_object_instance_id ( body ) ;
Object * obj = ObjectDB : : get_instance ( instance_id ) ;
PhysicsBody * physics_body = Object : : cast_to < PhysicsBody > ( obj ) ;
ret . append ( physics_body ) ;
}
return ret ;
}
2017-03-05 16:44:50 +01:00
void PhysicsBody : : add_collision_exception_with ( Node * p_node ) {
2014-09-22 06:03:56 +02:00
ERR_FAIL_NULL ( p_node ) ;
2017-11-21 01:36:32 +01:00
CollisionObject * collision_object = Object : : cast_to < CollisionObject > ( p_node ) ;
2019-08-08 22:11:48 +02:00
ERR_FAIL_COND_MSG ( ! collision_object , " Collision exception only works between two CollisionObject. " ) ;
2017-11-21 01:36:32 +01:00
PhysicsServer : : get_singleton ( ) - > body_add_collision_exception ( get_rid ( ) , collision_object - > get_rid ( ) ) ;
2014-09-22 06:03:56 +02:00
}
2017-03-05 16:44:50 +01:00
void PhysicsBody : : remove_collision_exception_with ( Node * p_node ) {
2014-09-22 06:03:56 +02:00
ERR_FAIL_NULL ( p_node ) ;
2017-11-21 01:36:32 +01:00
CollisionObject * collision_object = Object : : cast_to < CollisionObject > ( p_node ) ;
2019-08-08 22:11:48 +02:00
ERR_FAIL_COND_MSG ( ! collision_object , " Collision exception only works between two CollisionObject. " ) ;
2017-11-21 01:36:32 +01:00
PhysicsServer : : get_singleton ( ) - > body_remove_collision_exception ( get_rid ( ) , collision_object - > get_rid ( ) ) ;
2014-09-22 06:03:56 +02:00
}
2016-04-09 20:54:09 +02:00
void PhysicsBody : : _set_layers ( uint32_t p_mask ) {
2017-01-13 15:01:19 +01:00
set_collision_layer ( p_mask ) ;
2016-04-09 20:54:09 +02:00
set_collision_mask ( p_mask ) ;
}
2017-03-05 16:44:50 +01:00
uint32_t PhysicsBody : : _get_layers ( ) const {
2016-04-09 20:54:09 +02:00
2017-01-13 15:01:19 +01:00
return get_collision_layer ( ) ;
2016-04-09 20:54:09 +02:00
}
2015-01-13 14:49:26 +01:00
2014-09-03 04:13:40 +02:00
void PhysicsBody : : _bind_methods ( ) {
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_collision_layer " , " layer " ) , & PhysicsBody : : set_collision_layer ) ;
ClassDB : : bind_method ( D_METHOD ( " get_collision_layer " ) , & PhysicsBody : : get_collision_layer ) ;
2016-04-09 20:54:09 +02:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_collision_mask " , " mask " ) , & PhysicsBody : : set_collision_mask ) ;
ClassDB : : bind_method ( D_METHOD ( " get_collision_mask " ) , & PhysicsBody : : get_collision_mask ) ;
2016-04-09 20:54:09 +02:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_collision_mask_bit " , " bit " , " value " ) , & PhysicsBody : : set_collision_mask_bit ) ;
ClassDB : : bind_method ( D_METHOD ( " get_collision_mask_bit " , " bit " ) , & PhysicsBody : : get_collision_mask_bit ) ;
2016-04-09 20:54:09 +02:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_collision_layer_bit " , " bit " , " value " ) , & PhysicsBody : : set_collision_layer_bit ) ;
ClassDB : : bind_method ( D_METHOD ( " get_collision_layer_bit " , " bit " ) , & PhysicsBody : : get_collision_layer_bit ) ;
2016-04-09 20:54:09 +02:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " _set_layers " , " mask " ) , & PhysicsBody : : _set_layers ) ;
ClassDB : : bind_method ( D_METHOD ( " _get_layers " ) , & PhysicsBody : : _get_layers ) ;
2016-04-09 20:54:09 +02:00
2017-03-05 16:44:50 +01:00
ADD_GROUP ( " Collision " , " collision_ " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " collision_layer " , PROPERTY_HINT_LAYERS_3D_PHYSICS ) , " set_collision_layer " , " get_collision_layer " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " collision_mask " , PROPERTY_HINT_LAYERS_3D_PHYSICS ) , " set_collision_mask " , " get_collision_mask " ) ;
2014-02-10 02:10:30 +01:00
}
2017-12-06 21:36:34 +01:00
PhysicsBody : : PhysicsBody ( PhysicsServer : : BodyMode p_mode ) :
CollisionObject ( PhysicsServer : : get_singleton ( ) - > body_create ( p_mode ) , false ) {
2014-02-10 02:10:30 +01:00
2017-06-13 17:45:01 +02:00
collision_layer = 1 ;
2017-03-05 16:44:50 +01:00
collision_mask = 1 ;
2014-09-03 04:13:40 +02:00
}
2014-02-10 02:10:30 +01:00
2017-10-24 18:10:30 +02:00
void StaticBody : : set_physics_material_override ( const Ref < PhysicsMaterial > & p_physics_material_override ) {
if ( physics_material_override . is_valid ( ) ) {
2020-02-21 23:26:13 +01:00
if ( physics_material_override - > is_connected ( CoreStringNames : : get_singleton ( ) - > changed , callable_mp ( this , & StaticBody : : _reload_physics_characteristics ) ) ) {
physics_material_override - > disconnect ( CoreStringNames : : get_singleton ( ) - > changed , callable_mp ( this , & StaticBody : : _reload_physics_characteristics ) ) ;
}
2017-10-24 18:10:30 +02:00
}
physics_material_override = p_physics_material_override ;
if ( physics_material_override . is_valid ( ) ) {
2020-02-21 23:26:13 +01:00
physics_material_override - > connect ( CoreStringNames : : get_singleton ( ) - > changed , callable_mp ( this , & StaticBody : : _reload_physics_characteristics ) ) ;
2017-10-24 18:10:30 +02:00
}
_reload_physics_characteristics ( ) ;
}
Ref < PhysicsMaterial > StaticBody : : get_physics_material_override ( ) const {
return physics_material_override ;
2014-09-03 04:13:40 +02:00
}
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
void StaticBody : : set_constant_linear_velocity ( const Vector3 & p_vel ) {
2015-08-30 23:57:17 +02:00
2017-03-05 16:44:50 +01:00
constant_linear_velocity = p_vel ;
PhysicsServer : : get_singleton ( ) - > body_set_state ( get_rid ( ) , PhysicsServer : : BODY_STATE_LINEAR_VELOCITY , constant_linear_velocity ) ;
2014-09-03 04:13:40 +02:00
}
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
void StaticBody : : set_constant_angular_velocity ( const Vector3 & p_vel ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
constant_angular_velocity = p_vel ;
PhysicsServer : : get_singleton ( ) - > body_set_state ( get_rid ( ) , PhysicsServer : : BODY_STATE_ANGULAR_VELOCITY , constant_angular_velocity ) ;
2014-02-10 02:10:30 +01:00
}
2014-09-03 04:13:40 +02:00
Vector3 StaticBody : : get_constant_linear_velocity ( ) const {
2014-02-10 02:10:30 +01:00
2014-09-03 04:13:40 +02:00
return constant_linear_velocity ;
}
Vector3 StaticBody : : get_constant_angular_velocity ( ) const {
2014-02-10 02:10:30 +01:00
2014-09-03 04:13:40 +02:00
return constant_angular_velocity ;
2014-02-10 02:10:30 +01:00
}
void StaticBody : : _bind_methods ( ) {
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_constant_linear_velocity " , " vel " ) , & StaticBody : : set_constant_linear_velocity ) ;
ClassDB : : bind_method ( D_METHOD ( " set_constant_angular_velocity " , " vel " ) , & StaticBody : : set_constant_angular_velocity ) ;
ClassDB : : bind_method ( D_METHOD ( " get_constant_linear_velocity " ) , & StaticBody : : get_constant_linear_velocity ) ;
ClassDB : : bind_method ( D_METHOD ( " get_constant_angular_velocity " ) , & StaticBody : : get_constant_angular_velocity ) ;
2014-02-10 02:10:30 +01:00
2017-10-24 18:10:30 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_physics_material_override " , " physics_material_override " ) , & StaticBody : : set_physics_material_override ) ;
ClassDB : : bind_method ( D_METHOD ( " get_physics_material_override " ) , & StaticBody : : get_physics_material_override ) ;
2018-10-24 21:32:55 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_collision_exceptions " ) , & PhysicsBody : : get_collision_exceptions ) ;
2017-08-09 13:19:41 +02:00
ClassDB : : bind_method ( D_METHOD ( " add_collision_exception_with " , " body " ) , & PhysicsBody : : add_collision_exception_with ) ;
ClassDB : : bind_method ( D_METHOD ( " remove_collision_exception_with " , " body " ) , & PhysicsBody : : remove_collision_exception_with ) ;
2014-09-22 06:03:56 +02:00
2018-11-08 15:30:02 +01: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 16:44:50 +01: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 " ) ;
2014-02-10 02:10:30 +01:00
}
2017-12-06 21:36:34 +01:00
StaticBody : : StaticBody ( ) :
PhysicsBody ( PhysicsServer : : BODY_MODE_STATIC ) {
2014-02-10 02:10:30 +01:00
}
2017-10-24 18:10:30 +02:00
StaticBody : : ~ StaticBody ( ) { }
void StaticBody : : _reload_physics_characteristics ( ) {
if ( physics_material_override . is_null ( ) ) {
PhysicsServer : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer : : BODY_PARAM_BOUNCE , 0 ) ;
PhysicsServer : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer : : BODY_PARAM_FRICTION , 1 ) ;
} else {
2018-07-23 16:37:07 +02:00
PhysicsServer : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer : : BODY_PARAM_BOUNCE , physics_material_override - > computed_bounce ( ) ) ;
PhysicsServer : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer : : BODY_PARAM_FRICTION , physics_material_override - > computed_friction ( ) ) ;
2017-10-24 18:10:30 +02:00
}
2014-02-10 02:10:30 +01:00
}
2014-11-06 01:20:42 +01:00
void RigidBody : : _body_enter_tree ( ObjectID p_id ) {
2014-02-10 02:10:30 +01:00
Object * obj = ObjectDB : : get_instance ( p_id ) ;
2017-08-24 22:58:51 +02:00
Node * node = Object : : cast_to < Node > ( obj ) ;
2014-02-10 02:10:30 +01:00
ERR_FAIL_COND ( ! node ) ;
2018-01-21 12:46:13 +01:00
ERR_FAIL_COND ( ! contact_monitor ) ;
2017-03-05 16:44:50 +01:00
Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . find ( p_id ) ;
2014-02-10 02:10:30 +01:00
ERR_FAIL_COND ( ! E ) ;
2014-11-06 01:20:42 +01:00
ERR_FAIL_COND ( E - > get ( ) . in_tree ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
E - > get ( ) . in_tree = true ;
2016-01-12 10:14:15 +01:00
2017-03-05 16:44:50 +01:00
contact_monitor - > locked = true ;
2016-01-12 10:14:15 +01:00
2017-03-05 16:44:50 +01:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_entered , node ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < E - > get ( ) . shapes . size ( ) ; i + + ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_shape_entered , p_id , node , E - > get ( ) . shapes [ i ] . body_shape , E - > get ( ) . shapes [ i ] . local_shape ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
contact_monitor - > locked = false ;
2014-02-10 02:10:30 +01:00
}
2014-11-06 01:20:42 +01:00
void RigidBody : : _body_exit_tree ( ObjectID p_id ) {
2014-02-10 02:10:30 +01:00
Object * obj = ObjectDB : : get_instance ( p_id ) ;
2017-08-24 22:58:51 +02:00
Node * node = Object : : cast_to < Node > ( obj ) ;
2014-02-10 02:10:30 +01:00
ERR_FAIL_COND ( ! node ) ;
2018-01-21 12:46:13 +01:00
ERR_FAIL_COND ( ! contact_monitor ) ;
2017-03-05 16:44:50 +01:00
Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . find ( p_id ) ;
2014-02-10 02:10:30 +01:00
ERR_FAIL_COND ( ! E ) ;
2014-11-06 01:20:42 +01:00
ERR_FAIL_COND ( ! E - > get ( ) . in_tree ) ;
2017-03-05 16:44:50 +01:00
E - > get ( ) . in_tree = false ;
2016-01-12 10:14:15 +01:00
2017-03-05 16:44:50 +01:00
contact_monitor - > locked = true ;
2016-01-12 10:14:15 +01:00
2017-03-05 16:44:50 +01:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_exited , node ) ;
2016-01-12 10:14:15 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < E - > get ( ) . shapes . size ( ) ; i + + ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_shape_exited , p_id , node , E - > get ( ) . shapes [ i ] . body_shape , E - > get ( ) . shapes [ i ] . local_shape ) ;
2014-02-10 02:10:30 +01:00
}
2016-01-12 10:14:15 +01:00
2017-03-05 16:44:50 +01:00
contact_monitor - > locked = false ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
void RigidBody : : _body_inout ( int p_status , ObjectID p_instance , int p_body_shape , int p_local_shape ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
bool body_in = p_status = = 1 ;
ObjectID objid = p_instance ;
2014-02-10 02:10:30 +01:00
Object * obj = ObjectDB : : get_instance ( objid ) ;
2017-08-24 22:58:51 +02:00
Node * node = Object : : cast_to < Node > ( obj ) ;
2014-02-10 02:10:30 +01:00
2018-01-21 12:46:13 +01:00
ERR_FAIL_COND ( ! contact_monitor ) ;
2017-03-05 16:44:50 +01:00
Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . find ( objid ) ;
2014-02-10 02:10:30 +01:00
ERR_FAIL_COND ( ! body_in & & ! E ) ;
if ( body_in ) {
if ( ! E ) {
2017-03-05 16:44:50 +01:00
E = contact_monitor - > body_map . insert ( objid , BodyState ( ) ) ;
2014-10-03 13:58:41 +02:00
//E->get().rc=0;
2017-03-05 16:44:50 +01:00
E - > get ( ) . in_tree = node & & node - > is_inside_tree ( ) ;
2014-02-10 02:10:30 +01:00
if ( node ) {
2020-02-21 23:26:13 +01:00
node - > connect ( SceneStringNames : : get_singleton ( ) - > tree_entered , callable_mp ( this , & RigidBody : : _body_enter_tree ) , make_binds ( objid ) ) ;
node - > connect ( SceneStringNames : : get_singleton ( ) - > tree_exiting , callable_mp ( this , & RigidBody : : _body_exit_tree ) , make_binds ( objid ) ) ;
2014-11-06 01:20:42 +01:00
if ( E - > get ( ) . in_tree ) {
2017-03-05 16:44:50 +01:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_entered , node ) ;
2014-02-10 02:10:30 +01:00
}
}
}
2014-10-03 13:58:41 +02:00
//E->get().rc++;
2014-02-10 02:10:30 +01:00
if ( node )
2017-03-05 16:44:50 +01:00
E - > get ( ) . shapes . insert ( ShapePair ( p_body_shape , p_local_shape ) ) ;
2014-02-10 02:10:30 +01:00
2014-11-06 01:20:42 +01:00
if ( E - > get ( ) . in_tree ) {
2017-03-05 16:44:50 +01:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_shape_entered , objid , node , p_body_shape , p_local_shape ) ;
2014-02-10 02:10:30 +01:00
}
} else {
2014-10-03 13:58:41 +02:00
//E->get().rc--;
2014-02-10 02:10:30 +01:00
if ( node )
2017-03-05 16:44:50 +01:00
E - > get ( ) . shapes . erase ( ShapePair ( p_body_shape , p_local_shape ) ) ;
2014-02-10 02:10:30 +01:00
2014-11-06 01:20:42 +01:00
bool in_tree = E - > get ( ) . in_tree ;
2014-10-03 13:58:41 +02:00
if ( E - > get ( ) . shapes . empty ( ) ) {
2014-02-10 02:10:30 +01:00
if ( node ) {
2020-02-21 23:26:13 +01:00
node - > disconnect ( SceneStringNames : : get_singleton ( ) - > tree_entered , callable_mp ( this , & RigidBody : : _body_enter_tree ) ) ;
node - > disconnect ( SceneStringNames : : get_singleton ( ) - > tree_exiting , callable_mp ( this , & RigidBody : : _body_exit_tree ) ) ;
2014-11-06 01:20:42 +01:00
if ( in_tree )
2018-09-01 12:05:51 +02:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_exited , node ) ;
2014-02-10 02:10:30 +01:00
}
contact_monitor - > body_map . erase ( E ) ;
}
2014-11-06 01:20:42 +01:00
if ( node & & in_tree ) {
2017-03-05 16:44:50 +01:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_shape_exited , objid , obj , p_body_shape , p_local_shape ) ;
2014-02-10 02:10:30 +01:00
}
}
}
struct _RigidBodyInOut {
ObjectID id ;
int shape ;
int local_shape ;
} ;
void RigidBody : : _direct_state_changed ( Object * p_state ) {
# ifdef DEBUG_ENABLED
2017-08-24 22:58:51 +02:00
state = Object : : cast_to < PhysicsDirectBodyState > ( p_state ) ;
2014-02-10 02:10:30 +01:00
# else
2017-03-05 16:44:50 +01:00
state = ( PhysicsDirectBodyState * ) p_state ; //trust it
2014-02-10 02:10:30 +01:00
# endif
2016-06-17 21:45:10 +02:00
set_ignore_transform_notification ( true ) ;
set_global_transform ( state - > get_transform ( ) ) ;
2017-03-05 16:44:50 +01:00
linear_velocity = state - > get_linear_velocity ( ) ;
angular_velocity = state - > get_angular_velocity ( ) ;
if ( sleeping ! = state - > is_sleeping ( ) ) {
sleeping = state - > is_sleeping ( ) ;
2016-06-17 21:45:10 +02:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > sleeping_state_changed ) ;
}
if ( get_script_instance ( ) )
2017-03-05 16:44:50 +01:00
get_script_instance ( ) - > call ( " _integrate_forces " , state ) ;
2016-06-17 21:45:10 +02:00
set_ignore_transform_notification ( false ) ;
2014-02-10 02:10:30 +01:00
if ( contact_monitor ) {
2017-03-05 16:44:50 +01:00
contact_monitor - > locked = true ;
2016-01-12 10:14:15 +01:00
2014-02-10 02:10:30 +01:00
//untag all
2017-03-05 16:44:50 +01:00
int rc = 0 ;
for ( Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < E - > get ( ) . shapes . size ( ) ; i + + ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
E - > get ( ) . shapes [ i ] . tagged = false ;
2014-02-10 02:10:30 +01:00
rc + + ;
}
}
2017-03-05 16:44:50 +01:00
_RigidBodyInOut * toadd = ( _RigidBodyInOut * ) alloca ( state - > get_contact_count ( ) * sizeof ( _RigidBodyInOut ) ) ;
int toadd_count = 0 ; //state->get_contact_count();
RigidBody_RemoveAction * toremove = ( RigidBody_RemoveAction * ) alloca ( rc * sizeof ( RigidBody_RemoveAction ) ) ;
int toremove_count = 0 ;
2014-02-10 02:10:30 +01:00
//put the ones to add
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < state - > get_contact_count ( ) ; i + + ) {
2014-02-10 02:10:30 +01: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 12:26:56 +01:00
//bool found=false;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . find ( obj ) ;
2014-02-10 02:10:30 +01:00
if ( ! E ) {
2017-03-05 16:44:50 +01:00
toadd [ toadd_count ] . local_shape = local_shape ;
toadd [ toadd_count ] . id = obj ;
toadd [ toadd_count ] . shape = shape ;
2014-02-10 02:10:30 +01:00
toadd_count + + ;
continue ;
}
2017-03-05 16:44:50 +01:00
ShapePair sp ( shape , local_shape ) ;
2014-02-10 02:10:30 +01:00
int idx = E - > get ( ) . shapes . find ( sp ) ;
2017-03-05 16:44:50 +01:00
if ( idx = = - 1 ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
toadd [ toadd_count ] . local_shape = local_shape ;
toadd [ toadd_count ] . id = obj ;
toadd [ toadd_count ] . shape = shape ;
2014-02-10 02:10:30 +01:00
toadd_count + + ;
continue ;
}
2017-03-05 16:44:50 +01:00
E - > get ( ) . shapes [ idx ] . tagged = true ;
2014-02-10 02:10:30 +01:00
}
//put the ones to remove
2017-03-05 16:44:50 +01:00
for ( Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < E - > get ( ) . shapes . size ( ) ; i + + ) {
2014-02-10 02:10:30 +01:00
if ( ! E - > get ( ) . shapes [ i ] . tagged ) {
2017-03-05 16:44:50 +01:00
toremove [ toremove_count ] . body_id = E - > key ( ) ;
toremove [ toremove_count ] . pair = E - > get ( ) . shapes [ i ] ;
2014-02-10 02:10:30 +01:00
toremove_count + + ;
}
}
}
//process remotions
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < toremove_count ; i + + ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
_body_inout ( 0 , toremove [ i ] . body_id , toremove [ i ] . pair . body_shape , toremove [ i ] . pair . local_shape ) ;
2014-02-10 02:10:30 +01:00
}
//process aditions
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < toadd_count ; i + + ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
_body_inout ( 1 , toadd [ i ] . id , toadd [ i ] . shape , toadd [ i ] . local_shape ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
contact_monitor - > locked = false ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
state = NULL ;
2014-02-10 02:10:30 +01:00
}
void RigidBody : : _notification ( int p_what ) {
2017-08-05 21:06:15 +02:00
# ifdef TOOLS_ENABLED
if ( p_what = = NOTIFICATION_ENTER_TREE ) {
2017-08-19 01:02:56 +02:00
if ( Engine : : get_singleton ( ) - > is_editor_hint ( ) ) {
2017-08-05 21:06:15 +02:00
set_notify_local_transform ( true ) ; //used for warnings and only in editor
}
}
if ( p_what = = NOTIFICATION_LOCAL_TRANSFORM_CHANGED ) {
2017-08-19 01:02:56 +02:00
if ( Engine : : get_singleton ( ) - > is_editor_hint ( ) ) {
2017-08-05 21:06:15 +02:00
update_configuration_warning ( ) ;
}
}
# endif
2014-02-10 02:10:30 +01:00
}
void RigidBody : : set_mode ( Mode p_mode ) {
2017-03-05 16:44:50 +01:00
mode = p_mode ;
switch ( p_mode ) {
2014-02-10 02:10:30 +01:00
case MODE_RIGID : {
2017-03-05 16:44:50 +01:00
PhysicsServer : : get_singleton ( ) - > body_set_mode ( get_rid ( ) , PhysicsServer : : BODY_MODE_RIGID ) ;
2014-02-10 02:10:30 +01:00
} break ;
case MODE_STATIC : {
2017-03-05 16:44:50 +01:00
PhysicsServer : : get_singleton ( ) - > body_set_mode ( get_rid ( ) , PhysicsServer : : BODY_MODE_STATIC ) ;
2014-02-10 02:10:30 +01:00
} break ;
case MODE_CHARACTER : {
2017-03-05 16:44:50 +01:00
PhysicsServer : : get_singleton ( ) - > body_set_mode ( get_rid ( ) , PhysicsServer : : BODY_MODE_CHARACTER ) ;
2014-02-10 02:10:30 +01:00
} break ;
2014-02-19 15:57:14 +01:00
case MODE_KINEMATIC : {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
PhysicsServer : : get_singleton ( ) - > body_set_mode ( get_rid ( ) , PhysicsServer : : BODY_MODE_KINEMATIC ) ;
2014-02-10 02:10:30 +01:00
} break ;
}
2020-03-03 17:05:10 +01:00
update_configuration_warning ( ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
RigidBody : : Mode RigidBody : : get_mode ( ) const {
2014-02-10 02:10:30 +01:00
return mode ;
}
2017-03-05 16:44:50 +01:00
void RigidBody : : set_mass ( real_t p_mass ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ERR_FAIL_COND ( p_mass < = 0 ) ;
mass = p_mass ;
2014-02-10 02:10:30 +01:00
_change_notify ( " mass " ) ;
_change_notify ( " weight " ) ;
2017-03-05 16:44:50 +01:00
PhysicsServer : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer : : BODY_PARAM_MASS , mass ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
real_t RigidBody : : get_mass ( ) const {
2014-02-10 02:10:30 +01:00
return mass ;
}
2017-03-05 16:44:50 +01:00
void RigidBody : : set_weight ( real_t p_weight ) {
2014-02-10 02:10:30 +01:00
2017-07-04 14:57:15 +02:00
set_mass ( p_weight / real_t ( GLOBAL_DEF ( " physics/3d/default_gravity " , 9.8 ) ) ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
real_t RigidBody : : get_weight ( ) const {
2014-02-10 02:10:30 +01:00
2017-07-04 14:57:15 +02:00
return mass * real_t ( GLOBAL_DEF ( " physics/3d/default_gravity " , 9.8 ) ) ;
2014-02-10 02:10:30 +01:00
}
2017-10-24 18:10:30 +02:00
void RigidBody : : set_physics_material_override ( const Ref < PhysicsMaterial > & p_physics_material_override ) {
if ( physics_material_override . is_valid ( ) ) {
2020-02-21 23:26:13 +01:00
if ( physics_material_override - > is_connected ( CoreStringNames : : get_singleton ( ) - > changed , callable_mp ( this , & RigidBody : : _reload_physics_characteristics ) ) ) {
physics_material_override - > disconnect ( CoreStringNames : : get_singleton ( ) - > changed , callable_mp ( this , & RigidBody : : _reload_physics_characteristics ) ) ;
}
2017-10-24 18:10:30 +02:00
}
physics_material_override = p_physics_material_override ;
if ( physics_material_override . is_valid ( ) ) {
2020-02-21 23:26:13 +01:00
physics_material_override - > connect ( CoreStringNames : : get_singleton ( ) - > changed , callable_mp ( this , & RigidBody : : _reload_physics_characteristics ) ) ;
2017-10-24 18:10:30 +02:00
}
_reload_physics_characteristics ( ) ;
}
Ref < PhysicsMaterial > RigidBody : : get_physics_material_override ( ) const {
return physics_material_override ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
void RigidBody : : set_gravity_scale ( real_t p_gravity_scale ) {
2015-08-30 23:57:17 +02:00
2017-03-05 16:44:50 +01:00
gravity_scale = p_gravity_scale ;
PhysicsServer : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer : : BODY_PARAM_GRAVITY_SCALE , gravity_scale ) ;
2015-08-30 23:57:17 +02:00
}
2017-03-05 16:44:50 +01:00
real_t RigidBody : : get_gravity_scale ( ) const {
2015-08-30 23:57:17 +02:00
return gravity_scale ;
}
2017-03-05 16:44:50 +01:00
void RigidBody : : set_linear_damp ( real_t p_linear_damp ) {
2015-08-30 23:57:17 +02:00
2017-03-05 16:44:50 +01:00
ERR_FAIL_COND ( p_linear_damp < - 1 ) ;
linear_damp = p_linear_damp ;
PhysicsServer : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer : : BODY_PARAM_LINEAR_DAMP , linear_damp ) ;
2015-08-30 23:57:17 +02:00
}
2017-03-05 16:44:50 +01:00
real_t RigidBody : : get_linear_damp ( ) const {
2015-08-30 23:57:17 +02:00
return linear_damp ;
}
2017-03-05 16:44:50 +01:00
void RigidBody : : set_angular_damp ( real_t p_angular_damp ) {
2015-08-30 23:57:17 +02:00
2017-03-05 16:44:50 +01:00
ERR_FAIL_COND ( p_angular_damp < - 1 ) ;
angular_damp = p_angular_damp ;
PhysicsServer : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer : : BODY_PARAM_ANGULAR_DAMP , angular_damp ) ;
2015-08-30 23:57:17 +02:00
}
2017-03-05 16:44:50 +01:00
real_t RigidBody : : get_angular_damp ( ) const {
2015-08-30 23:57:17 +02:00
return angular_damp ;
}
2017-03-05 16:44:50 +01:00
void RigidBody : : set_axis_velocity ( const Vector3 & p_axis ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Vector3 v = state ? state - > get_linear_velocity ( ) : linear_velocity ;
2014-02-10 02:10:30 +01:00
Vector3 axis = p_axis . normalized ( ) ;
2017-03-05 16:44:50 +01:00
v - = axis * axis . dot ( v ) ;
v + = p_axis ;
2014-02-10 02:10:30 +01:00
if ( state ) {
set_linear_velocity ( v ) ;
} else {
2017-03-05 16:44:50 +01:00
PhysicsServer : : get_singleton ( ) - > body_set_axis_velocity ( get_rid ( ) , p_axis ) ;
linear_velocity = v ;
2014-02-10 02:10:30 +01:00
}
}
2017-03-05 16:44:50 +01:00
void RigidBody : : set_linear_velocity ( const Vector3 & p_velocity ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
linear_velocity = p_velocity ;
2014-02-10 02:10:30 +01:00
if ( state )
state - > set_linear_velocity ( linear_velocity ) ;
else
2017-03-05 16:44:50 +01:00
PhysicsServer : : get_singleton ( ) - > body_set_state ( get_rid ( ) , PhysicsServer : : BODY_STATE_LINEAR_VELOCITY , linear_velocity ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
Vector3 RigidBody : : get_linear_velocity ( ) const {
2014-02-10 02:10:30 +01:00
return linear_velocity ;
}
2017-03-05 16:44:50 +01:00
void RigidBody : : set_angular_velocity ( const Vector3 & p_velocity ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
angular_velocity = p_velocity ;
2014-02-10 02:10:30 +01:00
if ( state )
state - > set_angular_velocity ( angular_velocity ) ;
else
2017-03-05 16:44:50 +01:00
PhysicsServer : : get_singleton ( ) - > body_set_state ( get_rid ( ) , PhysicsServer : : BODY_STATE_ANGULAR_VELOCITY , angular_velocity ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
Vector3 RigidBody : : get_angular_velocity ( ) const {
2014-02-10 02:10:30 +01:00
return angular_velocity ;
}
2017-03-05 16:44:50 +01:00
void RigidBody : : set_use_custom_integrator ( bool p_enable ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( custom_integrator = = p_enable )
2014-02-10 02:10:30 +01:00
return ;
2017-03-05 16:44:50 +01:00
custom_integrator = p_enable ;
PhysicsServer : : get_singleton ( ) - > body_set_omit_force_integration ( get_rid ( ) , p_enable ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
bool RigidBody : : is_using_custom_integrator ( ) {
2014-02-10 02:10:30 +01:00
return custom_integrator ;
}
2014-09-22 05:50:48 +02:00
void RigidBody : : set_sleeping ( bool p_sleeping ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
sleeping = p_sleeping ;
PhysicsServer : : get_singleton ( ) - > body_set_state ( get_rid ( ) , PhysicsServer : : BODY_STATE_SLEEPING , sleeping ) ;
2014-02-10 02:10:30 +01:00
}
void RigidBody : : set_can_sleep ( bool p_active ) {
2017-03-05 16:44:50 +01:00
can_sleep = p_active ;
PhysicsServer : : get_singleton ( ) - > body_set_state ( get_rid ( ) , PhysicsServer : : BODY_STATE_CAN_SLEEP , p_active ) ;
2014-02-10 02:10:30 +01:00
}
bool RigidBody : : is_able_to_sleep ( ) const {
return can_sleep ;
}
2014-09-22 05:50:48 +02:00
bool RigidBody : : is_sleeping ( ) const {
2014-02-10 02:10:30 +01:00
2014-09-22 05:50:48 +02:00
return sleeping ;
2014-02-10 02:10:30 +01:00
}
void RigidBody : : set_max_contacts_reported ( int p_amount ) {
2017-03-05 16:44:50 +01:00
max_contacts_reported = p_amount ;
PhysicsServer : : get_singleton ( ) - > body_set_max_contacts_reported ( get_rid ( ) , p_amount ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
int RigidBody : : get_max_contacts_reported ( ) const {
2014-02-10 02:10:30 +01:00
return max_contacts_reported ;
}
2018-07-24 09:49:12 +02:00
void RigidBody : : add_central_force ( const Vector3 & p_force ) {
PhysicsServer : : get_singleton ( ) - > body_add_central_force ( get_rid ( ) , p_force ) ;
}
void RigidBody : : add_force ( const Vector3 & p_force , const Vector3 & p_pos ) {
PhysicsServer : : get_singleton ( ) - > body_add_force ( get_rid ( ) , p_force , p_pos ) ;
}
void RigidBody : : add_torque ( const Vector3 & p_torque ) {
PhysicsServer : : get_singleton ( ) - > body_add_torque ( get_rid ( ) , p_torque ) ;
}
void RigidBody : : apply_central_impulse ( const Vector3 & p_impulse ) {
PhysicsServer : : get_singleton ( ) - > body_apply_central_impulse ( get_rid ( ) , p_impulse ) ;
}
2017-03-05 16:44:50 +01:00
void RigidBody : : apply_impulse ( const Vector3 & p_pos , const Vector3 & p_impulse ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
PhysicsServer : : get_singleton ( ) - > body_apply_impulse ( get_rid ( ) , p_pos , p_impulse ) ;
2014-02-10 02:10:30 +01:00
}
2018-01-25 09:45:00 +01:00
void RigidBody : : apply_torque_impulse ( const Vector3 & p_impulse ) {
PhysicsServer : : get_singleton ( ) - > body_apply_torque_impulse ( get_rid ( ) , p_impulse ) ;
}
2014-02-10 02:10:30 +01:00
void RigidBody : : set_use_continuous_collision_detection ( bool p_enable ) {
2017-03-05 16:44:50 +01:00
ccd = p_enable ;
PhysicsServer : : get_singleton ( ) - > body_set_enable_continuous_collision_detection ( get_rid ( ) , p_enable ) ;
2014-02-10 02:10:30 +01:00
}
bool RigidBody : : is_using_continuous_collision_detection ( ) const {
return ccd ;
}
void RigidBody : : set_contact_monitor ( bool p_enabled ) {
2017-03-05 16:44:50 +01:00
if ( p_enabled = = is_contact_monitor_enabled ( ) )
2014-02-10 02:10:30 +01:00
return ;
if ( ! p_enabled ) {
2019-08-08 22:11:48 +02: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 10:14:15 +01:00
2017-03-05 16:44:50 +01:00
for ( Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 02:10:30 +01:00
//clean up mess
2018-01-21 12:46:13 +01:00
Object * obj = ObjectDB : : get_instance ( E - > key ( ) ) ;
Node * node = Object : : cast_to < Node > ( obj ) ;
if ( node ) {
2020-02-21 23:26:13 +01:00
node - > disconnect ( SceneStringNames : : get_singleton ( ) - > tree_entered , callable_mp ( this , & RigidBody : : _body_enter_tree ) ) ;
node - > disconnect ( SceneStringNames : : get_singleton ( ) - > tree_exiting , callable_mp ( this , & RigidBody : : _body_exit_tree ) ) ;
2018-01-21 12:46:13 +01:00
}
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
memdelete ( contact_monitor ) ;
contact_monitor = NULL ;
2014-02-10 02:10:30 +01:00
} else {
2017-03-05 16:44:50 +01:00
contact_monitor = memnew ( ContactMonitor ) ;
contact_monitor - > locked = false ;
2014-02-10 02:10:30 +01:00
}
}
bool RigidBody : : is_contact_monitor_enabled ( ) const {
2017-03-05 16:44:50 +01:00
return contact_monitor ! = NULL ;
2014-02-10 02:10:30 +01:00
}
2017-12-10 17:21:14 +01:00
void RigidBody : : set_axis_lock ( PhysicsServer : : BodyAxis p_axis , bool p_lock ) {
PhysicsServer : : get_singleton ( ) - > body_set_axis_lock ( get_rid ( ) , p_axis , p_lock ) ;
2017-11-08 22:35:47 +01:00
}
2017-12-10 17:21:14 +01:00
bool RigidBody : : get_axis_lock ( PhysicsServer : : BodyAxis p_axis ) const {
return PhysicsServer : : get_singleton ( ) - > body_is_axis_locked ( get_rid ( ) , p_axis ) ;
2014-05-14 06:22:15 +02:00
}
2014-02-10 02:10:30 +01:00
2014-11-13 04:53:12 +01:00
Array RigidBody : : get_colliding_bodies ( ) const {
2017-03-05 16:44:50 +01:00
ERR_FAIL_COND_V ( ! contact_monitor , Array ( ) ) ;
2014-11-13 04:53:12 +01:00
Array ret ;
ret . resize ( contact_monitor - > body_map . size ( ) ) ;
2017-03-05 16:44:50 +01:00
int idx = 0 ;
for ( const Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . front ( ) ; E ; E = E - > next ( ) ) {
2014-11-13 04:53:12 +01:00
Object * obj = ObjectDB : : get_instance ( E - > key ( ) ) ;
if ( ! obj ) {
2017-03-05 16:44:50 +01:00
ret . resize ( ret . size ( ) - 1 ) ; //ops
2014-11-13 04:53:12 +01:00
} else {
2017-03-05 16:44:50 +01:00
ret [ idx + + ] = obj ;
2014-11-13 04:53:12 +01:00
}
}
return ret ;
}
2017-08-05 21:06:15 +02:00
String RigidBody : : get_configuration_warning ( ) const {
Transform t = get_transform ( ) ;
String warning = CollisionObject : : get_configuration_warning ( ) ;
2018-04-09 08:28:31 +02:00
if ( ( get_mode ( ) = = MODE_RIGID | | get_mode ( ) = = MODE_CHARACTER ) & & ( 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 ) ) {
2017-08-05 21:06:15 +02:00
if ( warning ! = String ( ) ) {
2019-07-09 00:17:04 +02:00
warning + = " \n \n " ;
2017-08-05 21:06:15 +02:00
}
2018-01-18 21:37:17 +01:00
warning + = TTR ( " Size changes to RigidBody (in character or rigid modes) will be overridden by the physics engine when running. \n Change the size in children collision shapes instead. " ) ;
2017-08-05 21:06:15 +02:00
}
return warning ;
}
2014-02-10 02:10:30 +01:00
void RigidBody : : _bind_methods ( ) {
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_mode " , " mode " ) , & RigidBody : : set_mode ) ;
ClassDB : : bind_method ( D_METHOD ( " get_mode " ) , & RigidBody : : get_mode ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_mass " , " mass " ) , & RigidBody : : set_mass ) ;
ClassDB : : bind_method ( D_METHOD ( " get_mass " ) , & RigidBody : : get_mass ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_weight " , " weight " ) , & RigidBody : : set_weight ) ;
ClassDB : : bind_method ( D_METHOD ( " get_weight " ) , & RigidBody : : get_weight ) ;
2014-02-10 02:10:30 +01:00
2017-10-24 18:10:30 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_physics_material_override " , " physics_material_override " ) , & RigidBody : : set_physics_material_override ) ;
ClassDB : : bind_method ( D_METHOD ( " get_physics_material_override " ) , & RigidBody : : get_physics_material_override ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_linear_velocity " , " linear_velocity " ) , & RigidBody : : set_linear_velocity ) ;
ClassDB : : bind_method ( D_METHOD ( " get_linear_velocity " ) , & RigidBody : : get_linear_velocity ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_angular_velocity " , " angular_velocity " ) , & RigidBody : : set_angular_velocity ) ;
ClassDB : : bind_method ( D_METHOD ( " get_angular_velocity " ) , & RigidBody : : get_angular_velocity ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_gravity_scale " , " gravity_scale " ) , & RigidBody : : set_gravity_scale ) ;
ClassDB : : bind_method ( D_METHOD ( " get_gravity_scale " ) , & RigidBody : : get_gravity_scale ) ;
2015-08-30 23:57:17 +02:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_linear_damp " , " linear_damp " ) , & RigidBody : : set_linear_damp ) ;
ClassDB : : bind_method ( D_METHOD ( " get_linear_damp " ) , & RigidBody : : get_linear_damp ) ;
2015-08-30 23:57:17 +02:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_angular_damp " , " angular_damp " ) , & RigidBody : : set_angular_damp ) ;
ClassDB : : bind_method ( D_METHOD ( " get_angular_damp " ) , & RigidBody : : get_angular_damp ) ;
2015-08-30 23:57:17 +02:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_max_contacts_reported " , " amount " ) , & RigidBody : : set_max_contacts_reported ) ;
ClassDB : : bind_method ( D_METHOD ( " get_max_contacts_reported " ) , & RigidBody : : get_max_contacts_reported ) ;
2015-08-30 23:57:17 +02:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_use_custom_integrator " , " enable " ) , & RigidBody : : set_use_custom_integrator ) ;
ClassDB : : bind_method ( D_METHOD ( " is_using_custom_integrator " ) , & RigidBody : : is_using_custom_integrator ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_contact_monitor " , " enabled " ) , & RigidBody : : set_contact_monitor ) ;
ClassDB : : bind_method ( D_METHOD ( " is_contact_monitor_enabled " ) , & RigidBody : : is_contact_monitor_enabled ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_use_continuous_collision_detection " , " enable " ) , & RigidBody : : set_use_continuous_collision_detection ) ;
ClassDB : : bind_method ( D_METHOD ( " is_using_continuous_collision_detection " ) , & RigidBody : : is_using_continuous_collision_detection ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_axis_velocity " , " axis_velocity " ) , & RigidBody : : set_axis_velocity ) ;
2018-07-24 09:49:12 +02:00
ClassDB : : bind_method ( D_METHOD ( " add_central_force " , " force " ) , & RigidBody : : add_central_force ) ;
ClassDB : : bind_method ( D_METHOD ( " add_force " , " force " , " position " ) , & RigidBody : : add_force ) ;
ClassDB : : bind_method ( D_METHOD ( " add_torque " , " torque " ) , & RigidBody : : add_torque ) ;
ClassDB : : bind_method ( D_METHOD ( " apply_central_impulse " , " impulse " ) , & RigidBody : : apply_central_impulse ) ;
2017-09-10 15:37:49 +02:00
ClassDB : : bind_method ( D_METHOD ( " apply_impulse " , " position " , " impulse " ) , & RigidBody : : apply_impulse ) ;
2018-01-25 09:45:00 +01:00
ClassDB : : bind_method ( D_METHOD ( " apply_torque_impulse " , " impulse " ) , & RigidBody : : apply_torque_impulse ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_sleeping " , " sleeping " ) , & RigidBody : : set_sleeping ) ;
ClassDB : : bind_method ( D_METHOD ( " is_sleeping " ) , & RigidBody : : is_sleeping ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_can_sleep " , " able_to_sleep " ) , & RigidBody : : set_can_sleep ) ;
ClassDB : : bind_method ( D_METHOD ( " is_able_to_sleep " ) , & RigidBody : : is_able_to_sleep ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " _direct_state_changed " ) , & RigidBody : : _direct_state_changed ) ;
2014-02-10 02:10:30 +01:00
2017-12-10 17:21:14 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_axis_lock " , " axis " , " lock " ) , & RigidBody : : set_axis_lock ) ;
ClassDB : : bind_method ( D_METHOD ( " get_axis_lock " , " axis " ) , & RigidBody : : get_axis_lock ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_colliding_bodies " ) , & RigidBody : : get_colliding_bodies ) ;
2014-05-14 06:22:15 +02:00
2017-08-29 07:15:46 +02:00
BIND_VMETHOD ( MethodInfo ( " _integrate_forces " , PropertyInfo ( Variant : : OBJECT , " state " , PROPERTY_HINT_RESOURCE_TYPE , " PhysicsDirectBodyState " ) ) ) ;
2014-11-13 04:53:12 +01:00
2017-03-05 16:44:50 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " mode " , PROPERTY_HINT_ENUM , " Rigid,Static,Character,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-24 19:20:53 +01: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 , " weight " , PROPERTY_HINT_EXP_RANGE , " 0.01,65535,0.01 " , PROPERTY_USAGE_EDITOR ) , " set_weight " , " get_weight " ) ;
2018-11-08 15:30:02 +01: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-24 19:20:53 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : FLOAT , " gravity_scale " , PROPERTY_HINT_RANGE , " -128,128,0.01 " ) , " set_gravity_scale " , " get_gravity_scale " ) ;
2017-03-05 16:44:50 +01: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-21 22:25:01 +01: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 16:44:50 +01: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 " ) ;
2017-11-08 22:35:47 +01:00
ADD_GROUP ( " Axis Lock " , " axis_lock_ " ) ;
2017-12-10 17:21:14 +01:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : BOOL , " axis_lock_linear_x " ) , " set_axis_lock " , " get_axis_lock " , PhysicsServer : : BODY_AXIS_LINEAR_X ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : BOOL , " axis_lock_linear_y " ) , " set_axis_lock " , " get_axis_lock " , PhysicsServer : : BODY_AXIS_LINEAR_Y ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : BOOL , " axis_lock_linear_z " ) , " set_axis_lock " , " get_axis_lock " , PhysicsServer : : BODY_AXIS_LINEAR_Z ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : BOOL , " axis_lock_angular_x " ) , " set_axis_lock " , " get_axis_lock " , PhysicsServer : : BODY_AXIS_ANGULAR_X ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : BOOL , " axis_lock_angular_y " ) , " set_axis_lock " , " get_axis_lock " , PhysicsServer : : BODY_AXIS_ANGULAR_Y ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : BOOL , " axis_lock_angular_z " ) , " set_axis_lock " , " get_axis_lock " , PhysicsServer : : BODY_AXIS_ANGULAR_Z ) ;
2017-03-05 16:44:50 +01:00
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-24 19:20:53 +01: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 16:44:50 +01: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-24 19:20:53 +01: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 02:10:30 +01:00
2018-09-01 12:05:51 +02:00
ADD_SIGNAL ( MethodInfo ( " body_shape_entered " , PropertyInfo ( Variant : : INT , " body_id " ) , 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 : : INT , " body_id " ) , PropertyInfo ( Variant : : OBJECT , " body " , PROPERTY_HINT_RESOURCE_TYPE , " Node " ) , PropertyInfo ( Variant : : INT , " body_shape " ) , PropertyInfo ( Variant : : INT , " local_shape " ) ) ) ;
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 16:44:50 +01:00
ADD_SIGNAL ( MethodInfo ( " sleeping_state_changed " ) ) ;
2014-02-10 02:10:30 +01:00
2017-08-20 17:45:01 +02:00
BIND_ENUM_CONSTANT ( MODE_RIGID ) ;
2017-10-21 20:58:02 +02:00
BIND_ENUM_CONSTANT ( MODE_STATIC ) ;
2017-08-20 17:45:01 +02:00
BIND_ENUM_CONSTANT ( MODE_CHARACTER ) ;
2017-10-21 20:58:02 +02:00
BIND_ENUM_CONSTANT ( MODE_KINEMATIC ) ;
2014-02-10 02:10:30 +01:00
}
2017-12-06 21:36:34 +01:00
RigidBody : : RigidBody ( ) :
PhysicsBody ( PhysicsServer : : BODY_MODE_RIGID ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
mode = MODE_RIGID ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
mass = 1 ;
max_contacts_reported = 0 ;
state = NULL ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
gravity_scale = 1 ;
linear_damp = - 1 ;
angular_damp = - 1 ;
2015-08-30 23:57:17 +02:00
2014-02-10 02:10:30 +01:00
//angular_velocity=0;
2017-03-05 16:44:50 +01:00
sleeping = false ;
ccd = false ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
custom_integrator = false ;
contact_monitor = NULL ;
can_sleep = true ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
PhysicsServer : : get_singleton ( ) - > body_set_force_integration_callback ( get_rid ( ) , this , " _direct_state_changed " ) ;
2014-02-10 02:10:30 +01:00
}
RigidBody : : ~ RigidBody ( ) {
if ( contact_monitor )
2017-03-05 16:44:50 +01:00
memdelete ( contact_monitor ) ;
2014-02-10 02:10:30 +01:00
}
2017-10-24 18:10:30 +02:00
void RigidBody : : _reload_physics_characteristics ( ) {
if ( physics_material_override . is_null ( ) ) {
PhysicsServer : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer : : BODY_PARAM_BOUNCE , 0 ) ;
PhysicsServer : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer : : BODY_PARAM_FRICTION , 1 ) ;
} else {
2018-07-23 16:37:07 +02:00
PhysicsServer : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer : : BODY_PARAM_BOUNCE , physics_material_override - > computed_bounce ( ) ) ;
PhysicsServer : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer : : BODY_PARAM_FRICTION , physics_material_override - > computed_friction ( ) ) ;
2017-10-24 18:10:30 +02:00
}
}
2014-09-03 04:13:40 +02:00
//////////////////////////////////////////////////////
//////////////////////////
2019-03-03 20:10:10 +01:00
Ref < KinematicCollision > KinematicBody : : _move ( const Vector3 & p_motion , bool p_infinite_inertia , bool p_exclude_raycast_shapes , bool p_test_only ) {
2017-07-15 06:23:10 +02:00
Collision col ;
2019-03-03 20:10:10 +01:00
if ( move_and_collide ( p_motion , p_infinite_inertia , col , p_exclude_raycast_shapes , p_test_only ) ) {
2017-09-04 12:48:14 +02:00
if ( motion_cache . is_null ( ) ) {
motion_cache . instance ( ) ;
motion_cache - > owner = this ;
2017-07-15 06:23:10 +02:00
}
2014-09-03 04:13:40 +02:00
2017-09-04 12:48:14 +02:00
motion_cache - > collision = col ;
2014-09-03 04:13:40 +02:00
2017-09-04 12:48:14 +02:00
return motion_cache ;
2014-09-03 04:13:40 +02:00
}
2017-09-04 12:48:14 +02:00
return Ref < KinematicCollision > ( ) ;
2014-09-03 04:13:40 +02:00
}
2020-01-10 12:22:34 +01:00
Vector3 KinematicBody : : get_linear_velocity ( ) const {
return linear_velocity ;
}
Vector3 KinematicBody : : get_angular_velocity ( ) const {
return angular_velocity ;
}
2019-03-03 20:10:10 +01:00
bool KinematicBody : : move_and_collide ( const Vector3 & p_motion , bool p_infinite_inertia , Collision & r_collision , bool p_exclude_raycast_shapes , bool p_test_only ) {
2017-04-13 20:37:17 +02:00
Transform gt = get_global_transform ( ) ;
2017-07-15 06:23:10 +02:00
PhysicsServer : : MotionResult result ;
2019-03-03 20:10:10 +01:00
bool colliding = PhysicsServer : : get_singleton ( ) - > body_test_motion ( get_rid ( ) , gt , p_motion , p_infinite_inertia , & result , p_exclude_raycast_shapes ) ;
2017-07-15 06:23:10 +02:00
if ( colliding ) {
r_collision . collider_metadata = result . collider_metadata ;
r_collision . collider_shape = result . collider_shape ;
r_collision . collider_vel = result . collider_velocity ;
r_collision . collision = result . collision_point ;
r_collision . normal = result . collision_normal ;
r_collision . collider = result . collider_id ;
2018-08-14 19:20:48 +02:00
r_collision . collider_rid = result . collider ;
2017-07-15 06:23:10 +02:00
r_collision . travel = result . motion ;
r_collision . remainder = result . remainder ;
r_collision . local_shape = result . collision_local_shape ;
2014-09-03 04:13:40 +02:00
}
2017-11-08 22:35:47 +01:00
for ( int i = 0 ; i < 3 ; i + + ) {
2017-12-10 17:21:14 +01:00
if ( locked_axis & ( 1 < < i ) ) {
2017-11-08 22:35:47 +01:00
result . motion [ i ] = 0 ;
}
}
2018-08-14 19:20:48 +02:00
if ( ! p_test_only ) {
gt . origin + = result . motion ;
set_global_transform ( gt ) ;
}
2014-09-03 04:13:40 +02:00
2017-07-15 06:23:10 +02:00
return colliding ;
2014-09-03 04:13:40 +02:00
}
Fix misc. source comment typos
Found using `codespell -q 3 -S ./thirdparty,*.po -L ang,ba,cas,dof,doubleclick,fave,hist,leapyear,lod,nd,numer,ois,paket,seeked,sinc,switchs,te,uint -D ~/Projects/codespell/codespell_lib/data/dictionary.txt `
2019-09-19 20:36:39 +02:00
//so, if you pass 45 as limit, avoid numerical precision errors when angle is 45.
2018-08-10 18:06:34 +02:00
# define FLOOR_ANGLE_THRESHOLD 0.01
2020-01-10 14:58:19 +01:00
Vector3 KinematicBody : : move_and_slide ( const Vector3 & p_linear_velocity , const Vector3 & p_up_direction , bool p_stop_on_slope , int p_max_slides , float p_floor_max_angle , bool p_infinite_inertia ) {
2017-04-13 20:37:17 +02:00
2019-11-25 00:10:36 +01:00
Vector3 body_velocity = p_linear_velocity ;
Vector3 body_velocity_normal = body_velocity . normalized ( ) ;
2017-04-13 20:37:17 +02:00
2017-11-08 22:35:47 +01:00
for ( int i = 0 ; i < 3 ; i + + ) {
2017-12-10 17:21:14 +01:00
if ( locked_axis & ( 1 < < i ) ) {
2019-11-25 00:10:36 +01:00
body_velocity [ i ] = 0 ;
}
}
2018-03-15 13:29:22 +01:00
// Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky
2020-01-05 17:15:51 +01: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-08 22:35:47 +01:00
2017-07-15 06:23:10 +02:00
on_floor = false ;
2019-11-25 00:10:36 +01:00
on_floor_body = RID ( ) ;
2017-07-15 06:23:10 +02:00
on_ceiling = false ;
on_wall = false ;
colliders . clear ( ) ;
2020-01-15 08:04:02 +01:00
floor_normal = Vector3 ( ) ;
2017-07-15 06:23:10 +02:00
floor_velocity = Vector3 ( ) ;
2017-04-13 20:37:17 +02:00
2017-09-04 12:48:14 +02:00
while ( p_max_slides ) {
2017-04-13 20:37:17 +02:00
2017-07-15 06:23:10 +02:00
Collision collision ;
2018-08-14 19:20:48 +02:00
bool found_collision = false ;
2017-04-13 20:37:17 +02:00
2019-03-25 22:46:26 +01:00
for ( int i = 0 ; i < 2 ; + + i ) {
2018-08-14 19:20:48 +02:00
bool collided ;
2019-03-25 22:46:26 +01:00
if ( i = = 0 ) { //collide
2018-08-14 19:20:48 +02:00
collided = move_and_collide ( motion , p_infinite_inertia , collision ) ;
if ( ! collided ) {
motion = Vector3 ( ) ; //clear because no collision happened and motion completed
}
2019-03-25 22:46:26 +01:00
} else { //separate raycasts (if any)
2018-08-14 19:20:48 +02:00
collided = separate_raycast_shapes ( p_infinite_inertia , collision ) ;
if ( collided ) {
collision . remainder = motion ; //keep
collision . travel = Vector3 ( ) ;
}
}
2017-04-13 20:37:17 +02:00
2018-08-14 19:20:48 +02:00
if ( collided ) {
found_collision = true ;
2018-08-11 10:25:56 +02:00
2018-08-14 19:20:48 +02:00
colliders . push_back ( collision ) ;
motion = collision . remainder ;
2018-08-11 10:25:56 +02:00
2020-01-10 14:58:19 +01:00
if ( p_up_direction = = Vector3 ( ) ) {
2018-08-14 19:20:48 +02:00
//all is a wall
2017-07-15 06:23:10 +02:00
on_wall = true ;
2018-08-14 19:20:48 +02:00
} else {
2020-01-10 14:58:19 +01:00
if ( Math : : acos ( collision . normal . dot ( p_up_direction ) ) < = p_floor_max_angle + FLOOR_ANGLE_THRESHOLD ) { //floor
2018-08-14 19:20:48 +02:00
on_floor = true ;
2020-01-10 14:58:19 +01:00
floor_normal = collision . normal ;
2018-08-14 19:20:48 +02:00
on_floor_body = collision . collider_rid ;
floor_velocity = collision . collider_vel ;
if ( p_stop_on_slope ) {
2020-01-10 14:58:19 +01:00
if ( ( body_velocity_normal + p_up_direction ) . length ( ) < 0.01 & & collision . travel . length ( ) < 1 ) {
2018-08-14 19:20:48 +02:00
Transform gt = get_global_transform ( ) ;
2020-01-10 14:58:19 +01:00
gt . origin - = collision . travel . slide ( p_up_direction ) ;
2018-08-14 19:20:48 +02:00
set_global_transform ( gt ) ;
return Vector3 ( ) ;
}
}
2020-01-10 14:58:19 +01:00
} else if ( Math : : acos ( collision . normal . dot ( - p_up_direction ) ) < = p_floor_max_angle + FLOOR_ANGLE_THRESHOLD ) { //ceiling
2018-08-14 19:20:48 +02:00
on_ceiling = true ;
} else {
on_wall = true ;
}
2017-04-13 20:37:17 +02:00
}
2019-11-25 00:10:36 +01:00
motion = motion . slide ( collision . normal ) ;
body_velocity = body_velocity . slide ( collision . normal ) ;
2017-07-15 06:23:10 +02:00
2019-03-25 22:46:26 +01:00
for ( int j = 0 ; j < 3 ; j + + ) {
if ( locked_axis & ( 1 < < j ) ) {
2019-11-25 00:10:36 +01:00
body_velocity [ j ] = 0 ;
2018-08-14 19:20:48 +02:00
}
2017-11-08 22:35:47 +01:00
}
}
2019-03-25 22:46:26 +01:00
}
2017-04-13 20:37:17 +02:00
2018-08-14 19:20:48 +02:00
if ( ! found_collision | | motion = = Vector3 ( ) )
2017-04-13 20:37:17 +02:00
break ;
2018-08-14 19:20:48 +02:00
- - p_max_slides ;
2017-04-13 20:37:17 +02:00
}
2019-11-25 00:10:36 +01:00
return body_velocity ;
2017-04-13 20:37:17 +02:00
}
2020-01-10 14:58:19 +01:00
Vector3 KinematicBody : : move_and_slide_with_snap ( const Vector3 & p_linear_velocity , const Vector3 & p_snap , const Vector3 & p_up_direction , bool p_stop_on_slope , int p_max_slides , float p_floor_max_angle , bool p_infinite_inertia ) {
2018-08-14 19:20:48 +02:00
bool was_on_floor = on_floor ;
2020-01-10 14:58:19 +01:00
Vector3 ret = move_and_slide ( p_linear_velocity , p_up_direction , p_stop_on_slope , p_max_slides , p_floor_max_angle , p_infinite_inertia ) ;
2018-08-14 19:20:48 +02:00
if ( ! was_on_floor | | p_snap = = Vector3 ( ) ) {
return ret ;
}
Collision col ;
Transform gt = get_global_transform ( ) ;
2019-03-03 20:10:10 +01:00
if ( move_and_collide ( p_snap , p_infinite_inertia , col , false , true ) ) {
2019-02-16 19:49:55 +01:00
bool apply = true ;
2020-01-10 14:58:19 +01:00
if ( p_up_direction ! = Vector3 ( ) ) {
if ( Math : : acos ( p_up_direction . normalized ( ) . dot ( col . normal ) ) < p_floor_max_angle ) {
2019-02-16 19:49:55 +01:00
on_floor = true ;
2020-01-10 14:58:19 +01:00
floor_normal = col . normal ;
2019-02-16 19:49:55 +01:00
on_floor_body = col . collider_rid ;
floor_velocity = col . collider_vel ;
2019-02-23 14:23:38 +01:00
if ( p_stop_on_slope ) {
// 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.
2020-01-10 14:58:19 +01:00
col . travel = col . travel . project ( p_up_direction ) ;
2019-02-23 14:23:38 +01:00
}
2019-02-16 19:49:55 +01:00
} else {
apply = false ; //snapped with floor direction, but did not snap to a floor, do not snap.
}
}
if ( apply ) {
gt . origin + = col . travel ;
set_global_transform ( gt ) ;
2018-08-14 19:20:48 +02:00
}
}
return ret ;
}
2017-07-15 06:23:10 +02:00
bool KinematicBody : : is_on_floor ( ) const {
2017-04-13 20:37:17 +02:00
2017-07-15 06:23:10 +02:00
return on_floor ;
2017-04-13 20:37:17 +02:00
}
2018-08-14 19:20:48 +02:00
2017-07-15 06:23:10 +02:00
bool KinematicBody : : is_on_wall ( ) const {
2017-04-13 20:37:17 +02:00
2017-07-15 06:23:10 +02:00
return on_wall ;
2017-04-13 20:37:17 +02:00
}
2017-07-15 06:23:10 +02:00
bool KinematicBody : : is_on_ceiling ( ) const {
2017-04-13 20:37:17 +02:00
2017-07-15 06:23:10 +02:00
return on_ceiling ;
2017-04-13 20:37:17 +02:00
}
2020-01-10 14:58:19 +01:00
Vector3 KinematicBody : : get_floor_normal ( ) const {
return floor_normal ;
}
2017-07-15 06:23:10 +02:00
Vector3 KinematicBody : : get_floor_velocity ( ) const {
2014-09-03 04:13:40 +02:00
2017-07-15 06:23:10 +02:00
return floor_velocity ;
2014-09-03 04:13:40 +02:00
}
2018-02-16 19:06:00 +01:00
bool KinematicBody : : test_move ( const Transform & p_from , const Vector3 & p_motion , bool p_infinite_inertia ) {
2014-09-03 04:13:40 +02:00
2017-03-05 16:44:50 +01:00
ERR_FAIL_COND_V ( ! is_inside_tree ( ) , false ) ;
2014-09-03 04:13:40 +02:00
2018-02-16 19:06:00 +01:00
return PhysicsServer : : get_singleton ( ) - > body_test_motion ( get_rid ( ) , p_from , p_motion , p_infinite_inertia ) ;
2014-09-03 04:13:40 +02:00
}
2018-08-14 19:20:48 +02:00
bool KinematicBody : : separate_raycast_shapes ( bool p_infinite_inertia , Collision & r_collision ) {
PhysicsServer : : SeparationResult sep_res [ 8 ] ; //max 8 rays
Transform gt = get_global_transform ( ) ;
Vector3 recover ;
int hits = PhysicsServer : : get_singleton ( ) - > body_test_ray_separation ( get_rid ( ) , gt , p_infinite_inertia , recover , sep_res , 8 , margin ) ;
int deepest = - 1 ;
float deepest_depth ;
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 ) {
r_collision . collider = sep_res [ deepest ] . collider_id ;
r_collision . collider_metadata = sep_res [ deepest ] . collider_metadata ;
r_collision . collider_shape = sep_res [ deepest ] . collider_shape ;
r_collision . collider_vel = sep_res [ deepest ] . collider_velocity ;
r_collision . collision = sep_res [ deepest ] . collision_point ;
r_collision . normal = sep_res [ deepest ] . collision_normal ;
r_collision . local_shape = sep_res [ deepest ] . collision_local_shape ;
r_collision . travel = recover ;
r_collision . remainder = Vector3 ( ) ;
return true ;
} else {
return false ;
}
}
2017-12-10 17:21:14 +01:00
void KinematicBody : : set_axis_lock ( PhysicsServer : : BodyAxis p_axis , bool p_lock ) {
PhysicsServer : : get_singleton ( ) - > body_set_axis_lock ( get_rid ( ) , p_axis , p_lock ) ;
2017-11-08 22:35:47 +01:00
}
2017-12-10 17:21:14 +01:00
bool KinematicBody : : get_axis_lock ( PhysicsServer : : BodyAxis p_axis ) const {
return PhysicsServer : : get_singleton ( ) - > body_is_axis_locked ( get_rid ( ) , p_axis ) ;
2017-11-08 22:35:47 +01:00
}
2017-07-15 06:23:10 +02:00
void KinematicBody : : set_safe_margin ( float p_margin ) {
2014-09-03 04:13:40 +02:00
2017-07-15 06:23:10 +02:00
margin = p_margin ;
2017-11-07 15:22:09 +01:00
PhysicsServer : : get_singleton ( ) - > body_set_kinematic_safe_margin ( get_rid ( ) , margin ) ;
2014-09-03 04:13:40 +02:00
}
2017-07-15 06:23:10 +02:00
float KinematicBody : : get_safe_margin ( ) const {
2014-09-03 04:13:40 +02:00
2017-07-15 06:23:10 +02:00
return margin ;
2014-09-03 04:13:40 +02:00
}
2017-09-04 12:48:14 +02:00
int KinematicBody : : get_slide_count ( ) const {
2014-09-03 04:13:40 +02:00
2017-07-15 06:23:10 +02:00
return colliders . size ( ) ;
2014-09-03 04:13:40 +02:00
}
2017-09-04 12:48:14 +02:00
KinematicBody : : Collision KinematicBody : : get_slide_collision ( int p_bounce ) const {
ERR_FAIL_INDEX_V ( p_bounce , colliders . size ( ) , Collision ( ) ) ;
return colliders [ p_bounce ] ;
2014-09-03 04:13:40 +02:00
}
2017-09-04 12:48:14 +02:00
Ref < KinematicCollision > KinematicBody : : _get_slide_collision ( int p_bounce ) {
2014-09-03 04:13:40 +02:00
2017-09-04 12:48:14 +02:00
ERR_FAIL_INDEX_V ( p_bounce , colliders . size ( ) , Ref < KinematicCollision > ( ) ) ;
2017-09-10 18:07:47 +02:00
if ( p_bounce > = slide_colliders . size ( ) ) {
2017-09-04 12:48:14 +02:00
slide_colliders . resize ( p_bounce + 1 ) ;
2017-07-15 06:23:10 +02:00
}
2014-09-03 04:13:40 +02:00
2017-09-04 12:48:14 +02:00
if ( slide_colliders [ p_bounce ] . is_null ( ) ) {
2018-07-25 03:11:03 +02:00
slide_colliders . write [ p_bounce ] . instance ( ) ;
slide_colliders . write [ p_bounce ] - > owner = this ;
2017-07-15 06:23:10 +02:00
}
2014-09-03 04:13:40 +02:00
2018-07-25 03:11:03 +02:00
slide_colliders . write [ p_bounce ] - > collision = colliders [ p_bounce ] ;
2017-09-04 12:48:14 +02:00
return slide_colliders [ p_bounce ] ;
2014-09-03 04:13:40 +02:00
}
2019-08-19 11:11:14 +02:00
void KinematicBody : : _notification ( int p_what ) {
if ( p_what = = NOTIFICATION_ENTER_TREE ) {
// Reset move_and_slide() data.
on_floor = false ;
on_floor_body = RID ( ) ;
on_ceiling = false ;
on_wall = false ;
colliders . clear ( ) ;
floor_velocity = Vector3 ( ) ;
}
}
2014-09-03 04:13:40 +02:00
void KinematicBody : : _bind_methods ( ) {
2020-01-10 12:22:34 +01:00
ClassDB : : bind_method ( D_METHOD ( " _direct_state_changed " ) , & KinematicBody : : _direct_state_changed ) ;
2019-03-03 20:10:10 +01:00
ClassDB : : bind_method ( D_METHOD ( " move_and_collide " , " rel_vec " , " infinite_inertia " , " exclude_raycast_shapes " , " test_only " ) , & KinematicBody : : _move , DEFVAL ( true ) , DEFVAL ( true ) , DEFVAL ( false ) ) ;
2020-01-10 14:58:19 +01:00
ClassDB : : bind_method ( D_METHOD ( " move_and_slide " , " linear_velocity " , " up_direction " , " stop_on_slope " , " max_slides " , " floor_max_angle " , " infinite_inertia " ) , & KinematicBody : : move_and_slide , DEFVAL ( Vector3 ( 0 , 0 , 0 ) ) , DEFVAL ( false ) , DEFVAL ( 4 ) , DEFVAL ( Math : : deg2rad ( ( float ) 45 ) ) , DEFVAL ( true ) ) ;
2020-01-15 08:04:02 +01:00
ClassDB : : bind_method ( D_METHOD ( " move_and_slide_with_snap " , " linear_velocity " , " snap " , " up_direction " , " stop_on_slope " , " max_slides " , " floor_max_angle " , " infinite_inertia " ) , & KinematicBody : : move_and_slide_with_snap , DEFVAL ( Vector3 ( 0 , 0 , 0 ) ) , DEFVAL ( false ) , DEFVAL ( 4 ) , DEFVAL ( Math : : deg2rad ( ( float ) 45 ) ) , DEFVAL ( true ) ) ;
2014-09-03 04:13:40 +02:00
2018-10-17 10:22:48 +02:00
ClassDB : : bind_method ( D_METHOD ( " test_move " , " from " , " rel_vec " , " infinite_inertia " ) , & KinematicBody : : test_move , DEFVAL ( true ) ) ;
2014-09-03 04:13:40 +02:00
2017-07-15 06:23:10 +02:00
ClassDB : : bind_method ( D_METHOD ( " is_on_floor " ) , & KinematicBody : : is_on_floor ) ;
ClassDB : : bind_method ( D_METHOD ( " is_on_ceiling " ) , & KinematicBody : : is_on_ceiling ) ;
ClassDB : : bind_method ( D_METHOD ( " is_on_wall " ) , & KinematicBody : : is_on_wall ) ;
2020-01-10 14:58:19 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_floor_normal " ) , & KinematicBody : : get_floor_normal ) ;
2017-07-15 06:23:10 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_floor_velocity " ) , & KinematicBody : : get_floor_velocity ) ;
2014-09-03 04:13:40 +02:00
2017-12-11 01:42:16 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_axis_lock " , " axis " , " lock " ) , & KinematicBody : : set_axis_lock ) ;
ClassDB : : bind_method ( D_METHOD ( " get_axis_lock " , " axis " ) , & KinematicBody : : get_axis_lock ) ;
2017-11-08 22:35:47 +01:00
2017-07-15 06:23:10 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_safe_margin " , " pixels " ) , & KinematicBody : : set_safe_margin ) ;
2017-08-09 13:54:55 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_safe_margin " ) , & KinematicBody : : get_safe_margin ) ;
2014-09-03 04:13:40 +02:00
2017-09-04 12:48:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_slide_count " ) , & KinematicBody : : get_slide_count ) ;
ClassDB : : bind_method ( D_METHOD ( " get_slide_collision " , " slide_idx " ) , & KinematicBody : : _get_slide_collision ) ;
2014-09-03 04:13:40 +02:00
2018-08-20 18:38:18 +02:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : BOOL , " move_lock_x " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NOEDITOR ) , " set_axis_lock " , " get_axis_lock " , PhysicsServer : : BODY_AXIS_LINEAR_X ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : BOOL , " move_lock_y " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NOEDITOR ) , " set_axis_lock " , " get_axis_lock " , PhysicsServer : : BODY_AXIS_LINEAR_Y ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : BOOL , " move_lock_z " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NOEDITOR ) , " set_axis_lock " , " get_axis_lock " , PhysicsServer : : BODY_AXIS_LINEAR_Z ) ;
2017-11-08 22:35:47 +01: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-24 19:20:53 +01: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 04:13:40 +02:00
}
2020-01-10 12:22:34 +01:00
void KinematicBody : : _direct_state_changed ( Object * p_state ) {
# ifdef DEBUG_ENABLED
PhysicsDirectBodyState * state = Object : : cast_to < PhysicsDirectBodyState > ( p_state ) ;
# else
PhysicsDirectBodyState * state = ( PhysicsDirectBodyState * ) p_state ; //trust it
# endif
linear_velocity = state - > get_linear_velocity ( ) ;
angular_velocity = state - > get_angular_velocity ( ) ;
}
2017-12-06 21:36:34 +01:00
KinematicBody : : KinematicBody ( ) :
PhysicsBody ( PhysicsServer : : BODY_MODE_KINEMATIC ) {
2014-09-03 04:13:40 +02:00
2017-03-05 16:44:50 +01:00
margin = 0.001 ;
2017-12-10 17:21:14 +01:00
locked_axis = 0 ;
2017-07-15 06:23:10 +02:00
on_floor = false ;
on_ceiling = false ;
on_wall = false ;
2020-01-10 12:22:34 +01:00
PhysicsServer : : get_singleton ( ) - > body_set_force_integration_callback ( get_rid ( ) , this , " _direct_state_changed " ) ;
2014-09-03 04:13:40 +02:00
}
2017-03-05 16:44:50 +01:00
KinematicBody : : ~ KinematicBody ( ) {
2017-09-04 12:48:14 +02:00
if ( motion_cache . is_valid ( ) ) {
motion_cache - > owner = NULL ;
}
for ( int i = 0 ; i < slide_colliders . size ( ) ; i + + ) {
if ( slide_colliders [ i ] . is_valid ( ) ) {
2018-07-25 03:11:03 +02:00
slide_colliders . write [ i ] - > owner = NULL ;
2017-09-04 12:48:14 +02:00
}
}
}
///////////////////////////////////////
Vector3 KinematicCollision : : get_position ( ) const {
return collision . collision ;
}
Vector3 KinematicCollision : : get_normal ( ) const {
return collision . normal ;
}
Vector3 KinematicCollision : : get_travel ( ) const {
return collision . travel ;
}
Vector3 KinematicCollision : : get_remainder ( ) const {
return collision . remainder ;
}
Object * KinematicCollision : : get_local_shape ( ) const {
2019-06-01 15:42:22 +02:00
if ( ! owner ) return NULL ;
2017-09-04 12:48:14 +02:00
uint32_t ownerid = owner - > shape_find_owner ( collision . local_shape ) ;
return owner - > shape_owner_get_owner ( ownerid ) ;
}
Object * KinematicCollision : : get_collider ( ) const {
2020-02-12 18:24:06 +01:00
if ( collision . collider . is_valid ( ) ) {
2017-09-04 12:48:14 +02:00
return ObjectDB : : get_instance ( collision . collider ) ;
}
return NULL ;
}
ObjectID KinematicCollision : : get_collider_id ( ) const {
return collision . collider ;
}
Object * KinematicCollision : : get_collider_shape ( ) const {
Object * collider = get_collider ( ) ;
if ( collider ) {
CollisionObject * obj2d = Object : : cast_to < CollisionObject > ( collider ) ;
if ( obj2d ) {
uint32_t ownerid = obj2d - > shape_find_owner ( collision . collider_shape ) ;
return obj2d - > shape_owner_get_owner ( ownerid ) ;
}
}
return NULL ;
}
int KinematicCollision : : get_collider_shape_index ( ) const {
return collision . collider_shape ;
}
Vector3 KinematicCollision : : get_collider_velocity ( ) const {
return collision . collider_vel ;
}
Variant KinematicCollision : : get_collider_metadata ( ) const {
return Variant ( ) ;
}
void KinematicCollision : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " get_position " ) , & KinematicCollision : : get_position ) ;
ClassDB : : bind_method ( D_METHOD ( " get_normal " ) , & KinematicCollision : : get_normal ) ;
ClassDB : : bind_method ( D_METHOD ( " get_travel " ) , & KinematicCollision : : get_travel ) ;
ClassDB : : bind_method ( D_METHOD ( " get_remainder " ) , & KinematicCollision : : get_remainder ) ;
ClassDB : : bind_method ( D_METHOD ( " get_local_shape " ) , & KinematicCollision : : get_local_shape ) ;
ClassDB : : bind_method ( D_METHOD ( " get_collider " ) , & KinematicCollision : : get_collider ) ;
ClassDB : : bind_method ( D_METHOD ( " get_collider_id " ) , & KinematicCollision : : get_collider_id ) ;
ClassDB : : bind_method ( D_METHOD ( " get_collider_shape " ) , & KinematicCollision : : get_collider_shape ) ;
ClassDB : : bind_method ( D_METHOD ( " get_collider_shape_index " ) , & KinematicCollision : : get_collider_shape_index ) ;
ClassDB : : bind_method ( D_METHOD ( " get_collider_velocity " ) , & KinematicCollision : : get_collider_velocity ) ;
ClassDB : : bind_method ( D_METHOD ( " get_collider_metadata " ) , & KinematicCollision : : get_collider_metadata ) ;
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 " ) ;
}
KinematicCollision : : KinematicCollision ( ) {
2020-02-12 18:24:06 +01:00
2017-09-04 12:48:14 +02:00
collision . collider_shape = 0 ;
collision . local_shape = 0 ;
owner = NULL ;
2014-09-03 04:13:40 +02:00
}
2017-10-03 18:49:32 +02:00
///////////////////////////////////////
bool PhysicalBone : : JointData : : _set ( const StringName & p_name , const Variant & p_value , RID j ) {
return false ;
}
bool PhysicalBone : : JointData : : _get ( const StringName & p_name , Variant & r_ret ) const {
return false ;
}
void PhysicalBone : : JointData : : _get_property_list ( List < PropertyInfo > * p_list ) const {
}
2019-12-12 00:08:11 +01:00
void PhysicalBone : : apply_central_impulse ( const Vector3 & p_impulse ) {
PhysicsServer : : get_singleton ( ) - > body_apply_central_impulse ( get_rid ( ) , p_impulse ) ;
}
void PhysicalBone : : apply_impulse ( const Vector3 & p_pos , const Vector3 & p_impulse ) {
PhysicsServer : : get_singleton ( ) - > body_apply_impulse ( get_rid ( ) , p_pos , p_impulse ) ;
}
2020-02-08 09:52:58 +01:00
void PhysicalBone : : reset_physics_simulation_state ( ) {
if ( simulate_physics ) {
_start_physics_simulation ( ) ;
} else {
_stop_physics_simulation ( ) ;
}
}
void PhysicalBone : : reset_to_rest_position ( ) {
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 ) ;
}
}
}
2017-10-03 18:49:32 +02:00
bool PhysicalBone : : PinJointData : : _set ( const StringName & p_name , const Variant & p_value , RID j ) {
if ( JointData : : _set ( p_name , p_value , j ) ) {
return true ;
}
if ( " joint_constraints/bias " = = p_name ) {
bias = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > pin_joint_set_param ( j , PhysicsServer : : PIN_JOINT_BIAS , bias ) ;
} else if ( " joint_constraints/damping " = = p_name ) {
damping = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > pin_joint_set_param ( j , PhysicsServer : : PIN_JOINT_DAMPING , damping ) ;
} else if ( " joint_constraints/impulse_clamp " = = p_name ) {
impulse_clamp = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > pin_joint_set_param ( j , PhysicsServer : : PIN_JOINT_IMPULSE_CLAMP , impulse_clamp ) ;
} else {
return false ;
}
return true ;
}
bool PhysicalBone : : PinJointData : : _get ( const StringName & p_name , Variant & r_ret ) const {
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 ;
}
void PhysicalBone : : PinJointData : : _get_property_list ( List < PropertyInfo > * p_list ) const {
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-24 19:20:53 +01: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-03 18:49:32 +02:00
}
bool PhysicalBone : : ConeJointData : : _set ( const StringName & p_name , const Variant & p_value , RID j ) {
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 ) ) ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > cone_twist_joint_set_param ( j , PhysicsServer : : CONE_TWIST_JOINT_SWING_SPAN , swing_span ) ;
} else if ( " joint_constraints/twist_span " = = p_name ) {
twist_span = Math : : deg2rad ( real_t ( p_value ) ) ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > cone_twist_joint_set_param ( j , PhysicsServer : : CONE_TWIST_JOINT_TWIST_SPAN , twist_span ) ;
} else if ( " joint_constraints/bias " = = p_name ) {
bias = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > cone_twist_joint_set_param ( j , PhysicsServer : : CONE_TWIST_JOINT_BIAS , bias ) ;
} else if ( " joint_constraints/softness " = = p_name ) {
softness = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > cone_twist_joint_set_param ( j , PhysicsServer : : CONE_TWIST_JOINT_SOFTNESS , softness ) ;
} else if ( " joint_constraints/relaxation " = = p_name ) {
relaxation = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > cone_twist_joint_set_param ( j , PhysicsServer : : CONE_TWIST_JOINT_RELAXATION , relaxation ) ;
} else {
return false ;
}
return true ;
}
bool PhysicalBone : : ConeJointData : : _get ( const StringName & p_name , Variant & r_ret ) const {
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 ;
}
void PhysicalBone : : ConeJointData : : _get_property_list ( List < PropertyInfo > * p_list ) const {
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-24 19:20:53 +01: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-03 18:49:32 +02:00
}
bool PhysicalBone : : HingeJointData : : _set ( const StringName & p_name , const Variant & p_value , RID j ) {
if ( JointData : : _set ( p_name , p_value , j ) ) {
return true ;
}
if ( " joint_constraints/angular_limit_enabled " = = p_name ) {
angular_limit_enabled = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > hinge_joint_set_flag ( j , PhysicsServer : : HINGE_JOINT_FLAG_USE_LIMIT , angular_limit_enabled ) ;
} else if ( " joint_constraints/angular_limit_upper " = = p_name ) {
angular_limit_upper = Math : : deg2rad ( real_t ( p_value ) ) ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > hinge_joint_set_param ( j , PhysicsServer : : HINGE_JOINT_LIMIT_UPPER , angular_limit_upper ) ;
} else if ( " joint_constraints/angular_limit_lower " = = p_name ) {
angular_limit_lower = Math : : deg2rad ( real_t ( p_value ) ) ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > hinge_joint_set_param ( j , PhysicsServer : : HINGE_JOINT_LIMIT_LOWER , angular_limit_lower ) ;
} else if ( " joint_constraints/angular_limit_bias " = = p_name ) {
angular_limit_bias = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > hinge_joint_set_param ( j , PhysicsServer : : HINGE_JOINT_LIMIT_BIAS , angular_limit_bias ) ;
} else if ( " joint_constraints/angular_limit_softness " = = p_name ) {
angular_limit_softness = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > hinge_joint_set_param ( j , PhysicsServer : : HINGE_JOINT_LIMIT_SOFTNESS , angular_limit_softness ) ;
} else if ( " joint_constraints/angular_limit_relaxation " = = p_name ) {
angular_limit_relaxation = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > hinge_joint_set_param ( j , PhysicsServer : : HINGE_JOINT_LIMIT_RELAXATION , angular_limit_relaxation ) ;
} else {
return false ;
}
return true ;
}
bool PhysicalBone : : HingeJointData : : _get ( const StringName & p_name , Variant & r_ret ) const {
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 ;
}
void PhysicalBone : : HingeJointData : : _get_property_list ( List < PropertyInfo > * p_list ) const {
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-24 19:20:53 +01: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-03 18:49:32 +02:00
}
bool PhysicalBone : : SliderJointData : : _set ( const StringName & p_name , const Variant & p_value , RID j ) {
if ( JointData : : _set ( p_name , p_value , j ) ) {
return true ;
}
if ( " joint_constraints/linear_limit_upper " = = p_name ) {
linear_limit_upper = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > slider_joint_set_param ( j , PhysicsServer : : SLIDER_JOINT_LINEAR_LIMIT_UPPER , linear_limit_upper ) ;
} else if ( " joint_constraints/linear_limit_lower " = = p_name ) {
linear_limit_lower = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > slider_joint_set_param ( j , PhysicsServer : : SLIDER_JOINT_LINEAR_LIMIT_LOWER , linear_limit_lower ) ;
} else if ( " joint_constraints/linear_limit_softness " = = p_name ) {
linear_limit_softness = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > slider_joint_set_param ( j , PhysicsServer : : SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS , linear_limit_softness ) ;
} else if ( " joint_constraints/linear_limit_restitution " = = p_name ) {
linear_limit_restitution = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > slider_joint_set_param ( j , PhysicsServer : : SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION , linear_limit_restitution ) ;
} else if ( " joint_constraints/linear_limit_damping " = = p_name ) {
linear_limit_damping = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > slider_joint_set_param ( j , PhysicsServer : : SLIDER_JOINT_LINEAR_LIMIT_DAMPING , linear_limit_restitution ) ;
} else if ( " joint_constraints/angular_limit_upper " = = p_name ) {
angular_limit_upper = Math : : deg2rad ( real_t ( p_value ) ) ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > slider_joint_set_param ( j , PhysicsServer : : SLIDER_JOINT_ANGULAR_LIMIT_UPPER , angular_limit_upper ) ;
} else if ( " joint_constraints/angular_limit_lower " = = p_name ) {
angular_limit_lower = Math : : deg2rad ( real_t ( p_value ) ) ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > slider_joint_set_param ( j , PhysicsServer : : SLIDER_JOINT_ANGULAR_LIMIT_LOWER , angular_limit_lower ) ;
} else if ( " joint_constraints/angular_limit_softness " = = p_name ) {
angular_limit_softness = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > slider_joint_set_param ( j , PhysicsServer : : SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS , angular_limit_softness ) ;
} else if ( " joint_constraints/angular_limit_restitution " = = p_name ) {
angular_limit_restitution = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > slider_joint_set_param ( j , PhysicsServer : : SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS , angular_limit_softness ) ;
} else if ( " joint_constraints/angular_limit_damping " = = p_name ) {
angular_limit_damping = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > slider_joint_set_param ( j , PhysicsServer : : SLIDER_JOINT_ANGULAR_LIMIT_DAMPING , angular_limit_damping ) ;
} else {
return false ;
}
return true ;
}
bool PhysicalBone : : SliderJointData : : _get ( const StringName & p_name , Variant & r_ret ) const {
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 ;
}
void PhysicalBone : : SliderJointData : : _get_property_list ( List < PropertyInfo > * p_list ) const {
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-24 19:20:53 +01: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-03 18:49:32 +02: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-24 19:20:53 +01: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-03 18:49:32 +02:00
}
bool PhysicalBone : : SixDOFJointData : : _set ( const StringName & p_name , const Variant & p_value , RID j ) {
if ( JointData : : _set ( p_name , p_value , j ) ) {
return true ;
}
String path = p_name ;
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 ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_flag ( j , axis , PhysicsServer : : G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT , axis_data [ axis ] . linear_limit_enabled ) ;
} else if ( " linear_limit_upper " = = var_name ) {
axis_data [ axis ] . linear_limit_upper = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer : : G6DOF_JOINT_LINEAR_UPPER_LIMIT , axis_data [ axis ] . linear_limit_upper ) ;
} else if ( " linear_limit_lower " = = var_name ) {
axis_data [ axis ] . linear_limit_lower = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer : : G6DOF_JOINT_LINEAR_LOWER_LIMIT , axis_data [ axis ] . linear_limit_lower ) ;
} else if ( " linear_limit_softness " = = var_name ) {
axis_data [ axis ] . linear_limit_softness = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer : : G6DOF_JOINT_LINEAR_LIMIT_SOFTNESS , axis_data [ axis ] . linear_limit_softness ) ;
2018-11-20 16:55:22 +01:00
} else if ( " linear_spring_enabled " = = var_name ) {
axis_data [ axis ] . linear_spring_enabled = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_flag ( j , axis , PhysicsServer : : G6DOF_JOINT_FLAG_ENABLE_LINEAR_SPRING , axis_data [ axis ] . linear_spring_enabled ) ;
} else if ( " linear_spring_stiffness " = = var_name ) {
axis_data [ axis ] . linear_spring_stiffness = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer : : G6DOF_JOINT_LINEAR_SPRING_STIFFNESS , axis_data [ axis ] . linear_spring_stiffness ) ;
} else if ( " linear_spring_damping " = = var_name ) {
axis_data [ axis ] . linear_spring_damping = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer : : G6DOF_JOINT_LINEAR_SPRING_DAMPING , axis_data [ axis ] . linear_spring_damping ) ;
} else if ( " linear_equilibrium_point " = = var_name ) {
axis_data [ axis ] . linear_equilibrium_point = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer : : G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT , axis_data [ axis ] . linear_equilibrium_point ) ;
2017-10-03 18:49:32 +02:00
} else if ( " linear_restitution " = = var_name ) {
axis_data [ axis ] . linear_restitution = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer : : G6DOF_JOINT_LINEAR_RESTITUTION , axis_data [ axis ] . linear_restitution ) ;
} else if ( " linear_damping " = = var_name ) {
axis_data [ axis ] . linear_damping = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer : : G6DOF_JOINT_LINEAR_DAMPING , axis_data [ axis ] . linear_damping ) ;
} else if ( " angular_limit_enabled " = = var_name ) {
axis_data [ axis ] . angular_limit_enabled = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_flag ( j , axis , PhysicsServer : : G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT , axis_data [ axis ] . angular_limit_enabled ) ;
} else if ( " angular_limit_upper " = = var_name ) {
axis_data [ axis ] . angular_limit_upper = Math : : deg2rad ( real_t ( p_value ) ) ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer : : G6DOF_JOINT_ANGULAR_UPPER_LIMIT , axis_data [ axis ] . angular_limit_upper ) ;
} else if ( " angular_limit_lower " = = var_name ) {
axis_data [ axis ] . angular_limit_lower = Math : : deg2rad ( real_t ( p_value ) ) ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer : : G6DOF_JOINT_ANGULAR_LOWER_LIMIT , axis_data [ axis ] . angular_limit_lower ) ;
} else if ( " angular_limit_softness " = = var_name ) {
axis_data [ axis ] . angular_limit_softness = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer : : G6DOF_JOINT_ANGULAR_LIMIT_SOFTNESS , axis_data [ axis ] . angular_limit_softness ) ;
} else if ( " angular_restitution " = = var_name ) {
axis_data [ axis ] . angular_restitution = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer : : G6DOF_JOINT_ANGULAR_RESTITUTION , axis_data [ axis ] . angular_restitution ) ;
} else if ( " angular_damping " = = var_name ) {
axis_data [ axis ] . angular_damping = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer : : G6DOF_JOINT_ANGULAR_DAMPING , axis_data [ axis ] . angular_damping ) ;
} else if ( " erp " = = var_name ) {
axis_data [ axis ] . erp = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer : : G6DOF_JOINT_ANGULAR_ERP , axis_data [ axis ] . erp ) ;
2018-11-20 16:55:22 +01:00
} else if ( " angular_spring_enabled " = = var_name ) {
axis_data [ axis ] . angular_spring_enabled = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_flag ( j , axis , PhysicsServer : : G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING , axis_data [ axis ] . angular_spring_enabled ) ;
} else if ( " angular_spring_stiffness " = = var_name ) {
axis_data [ axis ] . angular_spring_stiffness = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer : : G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS , axis_data [ axis ] . angular_spring_stiffness ) ;
} else if ( " angular_spring_damping " = = var_name ) {
axis_data [ axis ] . angular_spring_damping = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer : : G6DOF_JOINT_ANGULAR_SPRING_DAMPING , axis_data [ axis ] . angular_spring_damping ) ;
} else if ( " angular_equilibrium_point " = = var_name ) {
axis_data [ axis ] . angular_equilibrium_point = p_value ;
if ( j . is_valid ( ) )
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( j , axis , PhysicsServer : : G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT , axis_data [ axis ] . angular_equilibrium_point ) ;
2017-10-03 18:49:32 +02:00
} else {
return false ;
}
return true ;
}
bool PhysicalBone : : SixDOFJointData : : _get ( const StringName & p_name , Variant & r_ret ) const {
if ( JointData : : _get ( p_name , r_ret ) ) {
return true ;
}
String path = p_name ;
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 16:55:22 +01: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-03 18:49:32 +02: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 16:55:22 +01: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-03 18:49:32 +02:00
} else {
return false ;
}
return true ;
}
void PhysicalBone : : SixDOFJointData : : _get_property_list ( List < PropertyInfo > * p_list ) const {
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-24 19:20:53 +01: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 16:55:22 +01: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-24 19:20:53 +01: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-03 18:49:32 +02: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-24 19:20:53 +01: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 16:55:22 +01: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-24 19:20:53 +01: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-03 18:49:32 +02:00
}
}
bool PhysicalBone : : _set ( const StringName & p_name , const Variant & p_value ) {
if ( p_name = = " bone_name " ) {
set_bone_name ( p_value ) ;
return true ;
}
if ( joint_data ) {
if ( joint_data - > _set ( p_name , p_value ) ) {
# ifdef TOOLS_ENABLED
if ( get_gizmo ( ) . is_valid ( ) )
get_gizmo ( ) - > redraw ( ) ;
# endif
return true ;
}
}
return false ;
}
bool PhysicalBone : : _get ( const StringName & p_name , Variant & r_ret ) const {
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 ;
}
void PhysicalBone : : _get_property_list ( List < PropertyInfo > * p_list ) const {
Skeleton * parent = find_skeleton_parent ( get_parent ( ) ) ;
if ( parent ) {
String names ;
for ( int i = 0 ; i < parent - > get_bone_count ( ) ; i + + ) {
if ( i > 0 )
names + = " , " ;
names + = parent - > get_bone_name ( i ) ;
}
2020-02-20 22:58:05 +01:00
p_list - > push_back ( PropertyInfo ( Variant : : STRING_NAME , " bone_name " , PROPERTY_HINT_ENUM , names ) ) ;
2017-10-03 18:49:32 +02:00
} else {
2020-02-20 22:58:05 +01:00
p_list - > push_back ( PropertyInfo ( Variant : : STRING_NAME , " bone_name " ) ) ;
2017-10-03 18:49:32 +02:00
}
if ( joint_data ) {
joint_data - > _get_property_list ( p_list ) ;
}
}
void PhysicalBone : : _notification ( int p_what ) {
switch ( p_what ) {
case NOTIFICATION_ENTER_TREE :
parent_skeleton = find_skeleton_parent ( get_parent ( ) ) ;
update_bone_id ( ) ;
reset_to_rest_position ( ) ;
2020-02-08 09:52:58 +01:00
reset_physics_simulation_state ( ) ;
2019-12-01 18:30:59 +01:00
if ( ! joint . is_valid ( ) & & joint_data ) {
_reload_joint ( ) ;
}
2017-10-03 18:49:32 +02:00
break ;
case NOTIFICATION_EXIT_TREE :
if ( parent_skeleton ) {
if ( - 1 ! = bone_id ) {
parent_skeleton - > unbind_physical_bone_from_bone ( bone_id ) ;
}
}
parent_skeleton = NULL ;
2019-12-01 18:30:59 +01:00
if ( joint . is_valid ( ) ) {
PhysicsServer : : get_singleton ( ) - > free ( joint ) ;
joint = RID ( ) ;
}
2017-10-03 18:49:32 +02:00
break ;
case NOTIFICATION_TRANSFORM_CHANGED :
if ( Engine : : get_singleton ( ) - > is_editor_hint ( ) ) {
update_offset ( ) ;
}
break ;
}
}
void PhysicalBone : : _direct_state_changed ( Object * p_state ) {
2019-09-19 00:46:32 +02:00
if ( ! simulate_physics | | ! _internal_simulate_physics ) {
2017-10-03 18:49:32 +02:00
return ;
}
/// Update bone transform
PhysicsDirectBodyState * state ;
# ifdef DEBUG_ENABLED
state = Object : : cast_to < PhysicsDirectBodyState > ( p_state ) ;
# else
state = ( PhysicsDirectBodyState * ) p_state ; //trust it
# endif
Transform global_transform ( state - > get_transform ( ) ) ;
set_ignore_transform_notification ( true ) ;
set_global_transform ( global_transform ) ;
set_ignore_transform_notification ( false ) ;
// Update skeleton
if ( parent_skeleton ) {
if ( - 1 ! = bone_id ) {
2019-09-19 00:46:32 +02: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-03 18:49:32 +02:00
}
}
}
void PhysicalBone : : _bind_methods ( ) {
2019-12-12 00:08:11 +01:00
ClassDB : : bind_method ( D_METHOD ( " apply_central_impulse " , " impulse " ) , & PhysicalBone : : apply_central_impulse ) ;
ClassDB : : bind_method ( D_METHOD ( " apply_impulse " , " position " , " impulse " ) , & PhysicalBone : : apply_impulse ) ;
2017-10-03 18:49:32 +02:00
ClassDB : : bind_method ( D_METHOD ( " _direct_state_changed " ) , & PhysicalBone : : _direct_state_changed ) ;
ClassDB : : bind_method ( D_METHOD ( " set_joint_type " , " joint_type " ) , & PhysicalBone : : set_joint_type ) ;
ClassDB : : bind_method ( D_METHOD ( " get_joint_type " ) , & PhysicalBone : : get_joint_type ) ;
ClassDB : : bind_method ( D_METHOD ( " set_joint_offset " , " offset " ) , & PhysicalBone : : set_joint_offset ) ;
ClassDB : : bind_method ( D_METHOD ( " get_joint_offset " ) , & PhysicalBone : : get_joint_offset ) ;
ClassDB : : bind_method ( D_METHOD ( " set_body_offset " , " offset " ) , & PhysicalBone : : set_body_offset ) ;
ClassDB : : bind_method ( D_METHOD ( " get_body_offset " ) , & PhysicalBone : : get_body_offset ) ;
ClassDB : : bind_method ( D_METHOD ( " get_simulate_physics " ) , & PhysicalBone : : get_simulate_physics ) ;
ClassDB : : bind_method ( D_METHOD ( " is_simulating_physics " ) , & PhysicalBone : : is_simulating_physics ) ;
2018-08-12 19:47:21 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_bone_id " ) , & PhysicalBone : : get_bone_id ) ;
2017-10-03 18:49:32 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_mass " , " mass " ) , & PhysicalBone : : set_mass ) ;
ClassDB : : bind_method ( D_METHOD ( " get_mass " ) , & PhysicalBone : : get_mass ) ;
ClassDB : : bind_method ( D_METHOD ( " set_weight " , " weight " ) , & PhysicalBone : : set_weight ) ;
ClassDB : : bind_method ( D_METHOD ( " get_weight " ) , & PhysicalBone : : get_weight ) ;
ClassDB : : bind_method ( D_METHOD ( " set_friction " , " friction " ) , & PhysicalBone : : set_friction ) ;
ClassDB : : bind_method ( D_METHOD ( " get_friction " ) , & PhysicalBone : : get_friction ) ;
ClassDB : : bind_method ( D_METHOD ( " set_bounce " , " bounce " ) , & PhysicalBone : : set_bounce ) ;
ClassDB : : bind_method ( D_METHOD ( " get_bounce " ) , & PhysicalBone : : get_bounce ) ;
ClassDB : : bind_method ( D_METHOD ( " set_gravity_scale " , " gravity_scale " ) , & PhysicalBone : : set_gravity_scale ) ;
ClassDB : : bind_method ( D_METHOD ( " get_gravity_scale " ) , & PhysicalBone : : get_gravity_scale ) ;
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 " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : TRANSFORM , " joint_offset " ) , " set_joint_offset " , " get_joint_offset " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : TRANSFORM , " body_offset " ) , " set_body_offset " , " get_body_offset " ) ;
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-24 19:20:53 +01: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 , " weight " , PROPERTY_HINT_EXP_RANGE , " 0.01,65535,0.01 " ) , " set_weight " , " get_weight " ) ;
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 " ) ;
2018-05-09 02:14:31 +02: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-03 18:49:32 +02:00
}
Skeleton * PhysicalBone : : find_skeleton_parent ( Node * p_parent ) {
if ( ! p_parent ) {
return NULL ;
}
Skeleton * s = Object : : cast_to < Skeleton > ( p_parent ) ;
return s ? s : find_skeleton_parent ( p_parent - > get_parent ( ) ) ;
}
void PhysicalBone : : _fix_joint_offset ( ) {
// Clamp joint origin to bone origin
if ( parent_skeleton ) {
joint_offset . origin = body_offset . affine_inverse ( ) . origin ;
}
}
void PhysicalBone : : _reload_joint ( ) {
if ( joint . is_valid ( ) ) {
PhysicsServer : : get_singleton ( ) - > free ( joint ) ;
joint = RID ( ) ;
}
if ( ! parent_skeleton ) {
return ;
}
PhysicalBone * body_a = parent_skeleton - > get_physical_bone_parent ( bone_id ) ;
if ( ! body_a ) {
return ;
}
Transform joint_transf = get_global_transform ( ) * joint_offset ;
Transform local_a = body_a - > get_global_transform ( ) . affine_inverse ( ) * joint_transf ;
local_a . orthonormalize ( ) ;
switch ( get_joint_type ( ) ) {
case JOINT_TYPE_PIN : {
joint = PhysicsServer : : get_singleton ( ) - > joint_create_pin ( body_a - > get_rid ( ) , local_a . origin , get_rid ( ) , joint_offset . origin ) ;
const PinJointData * pjd ( static_cast < const PinJointData * > ( joint_data ) ) ;
PhysicsServer : : get_singleton ( ) - > pin_joint_set_param ( joint , PhysicsServer : : PIN_JOINT_BIAS , pjd - > bias ) ;
PhysicsServer : : get_singleton ( ) - > pin_joint_set_param ( joint , PhysicsServer : : PIN_JOINT_DAMPING , pjd - > damping ) ;
PhysicsServer : : get_singleton ( ) - > pin_joint_set_param ( joint , PhysicsServer : : PIN_JOINT_IMPULSE_CLAMP , pjd - > impulse_clamp ) ;
} break ;
case JOINT_TYPE_CONE : {
joint = PhysicsServer : : get_singleton ( ) - > joint_create_cone_twist ( body_a - > get_rid ( ) , local_a , get_rid ( ) , joint_offset ) ;
const ConeJointData * cjd ( static_cast < const ConeJointData * > ( joint_data ) ) ;
PhysicsServer : : get_singleton ( ) - > cone_twist_joint_set_param ( joint , PhysicsServer : : CONE_TWIST_JOINT_SWING_SPAN , cjd - > swing_span ) ;
PhysicsServer : : get_singleton ( ) - > cone_twist_joint_set_param ( joint , PhysicsServer : : CONE_TWIST_JOINT_TWIST_SPAN , cjd - > twist_span ) ;
PhysicsServer : : get_singleton ( ) - > cone_twist_joint_set_param ( joint , PhysicsServer : : CONE_TWIST_JOINT_BIAS , cjd - > bias ) ;
PhysicsServer : : get_singleton ( ) - > cone_twist_joint_set_param ( joint , PhysicsServer : : CONE_TWIST_JOINT_SOFTNESS , cjd - > softness ) ;
PhysicsServer : : get_singleton ( ) - > cone_twist_joint_set_param ( joint , PhysicsServer : : CONE_TWIST_JOINT_RELAXATION , cjd - > relaxation ) ;
} break ;
case JOINT_TYPE_HINGE : {
joint = PhysicsServer : : get_singleton ( ) - > joint_create_hinge ( body_a - > get_rid ( ) , local_a , get_rid ( ) , joint_offset ) ;
const HingeJointData * hjd ( static_cast < const HingeJointData * > ( joint_data ) ) ;
PhysicsServer : : get_singleton ( ) - > hinge_joint_set_flag ( joint , PhysicsServer : : HINGE_JOINT_FLAG_USE_LIMIT , hjd - > angular_limit_enabled ) ;
PhysicsServer : : get_singleton ( ) - > hinge_joint_set_param ( joint , PhysicsServer : : HINGE_JOINT_LIMIT_UPPER , hjd - > angular_limit_upper ) ;
PhysicsServer : : get_singleton ( ) - > hinge_joint_set_param ( joint , PhysicsServer : : HINGE_JOINT_LIMIT_LOWER , hjd - > angular_limit_lower ) ;
PhysicsServer : : get_singleton ( ) - > hinge_joint_set_param ( joint , PhysicsServer : : HINGE_JOINT_LIMIT_BIAS , hjd - > angular_limit_bias ) ;
PhysicsServer : : get_singleton ( ) - > hinge_joint_set_param ( joint , PhysicsServer : : HINGE_JOINT_LIMIT_SOFTNESS , hjd - > angular_limit_softness ) ;
PhysicsServer : : get_singleton ( ) - > hinge_joint_set_param ( joint , PhysicsServer : : HINGE_JOINT_LIMIT_RELAXATION , hjd - > angular_limit_relaxation ) ;
} break ;
case JOINT_TYPE_SLIDER : {
joint = PhysicsServer : : get_singleton ( ) - > joint_create_slider ( body_a - > get_rid ( ) , local_a , get_rid ( ) , joint_offset ) ;
const SliderJointData * sjd ( static_cast < const SliderJointData * > ( joint_data ) ) ;
PhysicsServer : : get_singleton ( ) - > slider_joint_set_param ( joint , PhysicsServer : : SLIDER_JOINT_LINEAR_LIMIT_UPPER , sjd - > linear_limit_upper ) ;
PhysicsServer : : get_singleton ( ) - > slider_joint_set_param ( joint , PhysicsServer : : SLIDER_JOINT_LINEAR_LIMIT_LOWER , sjd - > linear_limit_lower ) ;
PhysicsServer : : get_singleton ( ) - > slider_joint_set_param ( joint , PhysicsServer : : SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS , sjd - > linear_limit_softness ) ;
PhysicsServer : : get_singleton ( ) - > slider_joint_set_param ( joint , PhysicsServer : : SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION , sjd - > linear_limit_restitution ) ;
PhysicsServer : : get_singleton ( ) - > slider_joint_set_param ( joint , PhysicsServer : : SLIDER_JOINT_LINEAR_LIMIT_DAMPING , sjd - > linear_limit_restitution ) ;
PhysicsServer : : get_singleton ( ) - > slider_joint_set_param ( joint , PhysicsServer : : SLIDER_JOINT_ANGULAR_LIMIT_UPPER , sjd - > angular_limit_upper ) ;
PhysicsServer : : get_singleton ( ) - > slider_joint_set_param ( joint , PhysicsServer : : SLIDER_JOINT_ANGULAR_LIMIT_LOWER , sjd - > angular_limit_lower ) ;
PhysicsServer : : get_singleton ( ) - > slider_joint_set_param ( joint , PhysicsServer : : SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS , sjd - > angular_limit_softness ) ;
PhysicsServer : : get_singleton ( ) - > slider_joint_set_param ( joint , PhysicsServer : : SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS , sjd - > angular_limit_softness ) ;
PhysicsServer : : get_singleton ( ) - > slider_joint_set_param ( joint , PhysicsServer : : SLIDER_JOINT_ANGULAR_LIMIT_DAMPING , sjd - > angular_limit_damping ) ;
} break ;
case JOINT_TYPE_6DOF : {
joint = PhysicsServer : : get_singleton ( ) - > joint_create_generic_6dof ( body_a - > get_rid ( ) , local_a , get_rid ( ) , joint_offset ) ;
const SixDOFJointData * g6dofjd ( static_cast < const SixDOFJointData * > ( joint_data ) ) ;
for ( int axis = 0 ; axis < 3 ; + + axis ) {
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_flag ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer : : G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT , g6dofjd - > axis_data [ axis ] . linear_limit_enabled ) ;
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer : : G6DOF_JOINT_LINEAR_UPPER_LIMIT , g6dofjd - > axis_data [ axis ] . linear_limit_upper ) ;
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer : : G6DOF_JOINT_LINEAR_LOWER_LIMIT , g6dofjd - > axis_data [ axis ] . linear_limit_lower ) ;
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer : : G6DOF_JOINT_LINEAR_LIMIT_SOFTNESS , g6dofjd - > axis_data [ axis ] . linear_limit_softness ) ;
2018-11-20 16:55:22 +01:00
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_flag ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer : : G6DOF_JOINT_FLAG_ENABLE_LINEAR_SPRING , g6dofjd - > axis_data [ axis ] . linear_spring_enabled ) ;
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer : : G6DOF_JOINT_LINEAR_SPRING_STIFFNESS , g6dofjd - > axis_data [ axis ] . linear_spring_stiffness ) ;
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer : : G6DOF_JOINT_LINEAR_SPRING_DAMPING , g6dofjd - > axis_data [ axis ] . linear_spring_damping ) ;
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer : : G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT , g6dofjd - > axis_data [ axis ] . linear_equilibrium_point ) ;
2017-10-03 18:49:32 +02:00
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer : : G6DOF_JOINT_LINEAR_RESTITUTION , g6dofjd - > axis_data [ axis ] . linear_restitution ) ;
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer : : G6DOF_JOINT_LINEAR_DAMPING , g6dofjd - > axis_data [ axis ] . linear_damping ) ;
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_flag ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer : : G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT , g6dofjd - > axis_data [ axis ] . angular_limit_enabled ) ;
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer : : G6DOF_JOINT_ANGULAR_UPPER_LIMIT , g6dofjd - > axis_data [ axis ] . angular_limit_upper ) ;
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer : : G6DOF_JOINT_ANGULAR_LOWER_LIMIT , g6dofjd - > axis_data [ axis ] . angular_limit_lower ) ;
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer : : G6DOF_JOINT_ANGULAR_LIMIT_SOFTNESS , g6dofjd - > axis_data [ axis ] . angular_limit_softness ) ;
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer : : G6DOF_JOINT_ANGULAR_RESTITUTION , g6dofjd - > axis_data [ axis ] . angular_restitution ) ;
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer : : G6DOF_JOINT_ANGULAR_DAMPING , g6dofjd - > axis_data [ axis ] . angular_damping ) ;
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer : : G6DOF_JOINT_ANGULAR_ERP , g6dofjd - > axis_data [ axis ] . erp ) ;
2018-11-20 16:55:22 +01:00
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_flag ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer : : G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING , g6dofjd - > axis_data [ axis ] . angular_spring_enabled ) ;
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer : : G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS , g6dofjd - > axis_data [ axis ] . angular_spring_stiffness ) ;
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer : : G6DOF_JOINT_ANGULAR_SPRING_DAMPING , g6dofjd - > axis_data [ axis ] . angular_spring_damping ) ;
PhysicsServer : : get_singleton ( ) - > generic_6dof_joint_set_param ( joint , static_cast < Vector3 : : Axis > ( axis ) , PhysicsServer : : G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT , g6dofjd - > axis_data [ axis ] . angular_equilibrium_point ) ;
2017-10-03 18:49:32 +02:00
}
} break ;
2018-09-26 13:13:56 +02:00
case JOINT_TYPE_NONE : {
} break ;
2017-10-03 18:49:32 +02:00
}
}
void PhysicalBone : : _on_bone_parent_changed ( ) {
_reload_joint ( ) ;
}
void PhysicalBone : : _set_gizmo_move_joint ( bool p_move_joint ) {
# ifdef TOOLS_ENABLED
gizmo_move_joint = p_move_joint ;
SpatialEditor : : get_singleton ( ) - > update_transform_gizmo ( ) ;
# endif
}
# ifdef TOOLS_ENABLED
Transform PhysicalBone : : get_global_gizmo_transform ( ) const {
return gizmo_move_joint ? get_global_transform ( ) * joint_offset : get_global_transform ( ) ;
}
Transform PhysicalBone : : get_local_gizmo_transform ( ) const {
return gizmo_move_joint ? get_transform ( ) * joint_offset : get_transform ( ) ;
}
# endif
const PhysicalBone : : JointData * PhysicalBone : : get_joint_data ( ) const {
return joint_data ;
}
Skeleton * PhysicalBone : : find_skeleton_parent ( ) {
return find_skeleton_parent ( this ) ;
}
void PhysicalBone : : set_joint_type ( JointType p_joint_type ) {
if ( p_joint_type = = get_joint_type ( ) )
return ;
2018-11-01 09:46:46 +01:00
if ( joint_data )
memdelete ( joint_data ) ;
2017-10-03 18:49:32 +02:00
joint_data = NULL ;
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 13:13:56 +02:00
case JOINT_TYPE_NONE :
break ;
2017-10-03 18:49:32 +02:00
}
_reload_joint ( ) ;
# ifdef TOOLS_ENABLED
_change_notify ( ) ;
if ( get_gizmo ( ) . is_valid ( ) )
get_gizmo ( ) - > redraw ( ) ;
# endif
}
PhysicalBone : : JointType PhysicalBone : : get_joint_type ( ) const {
return joint_data ? joint_data - > get_joint_type ( ) : JOINT_TYPE_NONE ;
}
void PhysicalBone : : set_joint_offset ( const Transform & p_offset ) {
joint_offset = p_offset ;
_fix_joint_offset ( ) ;
set_ignore_transform_notification ( true ) ;
reset_to_rest_position ( ) ;
set_ignore_transform_notification ( false ) ;
# ifdef TOOLS_ENABLED
if ( get_gizmo ( ) . is_valid ( ) )
get_gizmo ( ) - > redraw ( ) ;
# endif
}
const Transform & PhysicalBone : : get_body_offset ( ) const {
return body_offset ;
}
void PhysicalBone : : set_body_offset ( const Transform & p_offset ) {
body_offset = p_offset ;
body_offset_inverse = body_offset . affine_inverse ( ) ;
_fix_joint_offset ( ) ;
set_ignore_transform_notification ( true ) ;
reset_to_rest_position ( ) ;
set_ignore_transform_notification ( false ) ;
# ifdef TOOLS_ENABLED
if ( get_gizmo ( ) . is_valid ( ) )
get_gizmo ( ) - > redraw ( ) ;
# endif
}
const Transform & PhysicalBone : : get_joint_offset ( ) const {
return joint_offset ;
}
void PhysicalBone : : set_simulate_physics ( bool p_simulate ) {
if ( simulate_physics = = p_simulate ) {
return ;
}
simulate_physics = p_simulate ;
2020-02-08 09:52:58 +01:00
reset_physics_simulation_state ( ) ;
2017-10-03 18:49:32 +02:00
}
bool PhysicalBone : : get_simulate_physics ( ) {
return simulate_physics ;
}
bool PhysicalBone : : is_simulating_physics ( ) {
2020-02-08 09:52:58 +01:00
return _internal_simulate_physics ;
2017-10-03 18:49:32 +02:00
}
void PhysicalBone : : set_bone_name ( const String & p_name ) {
bone_name = p_name ;
bone_id = - 1 ;
update_bone_id ( ) ;
reset_to_rest_position ( ) ;
}
const String & PhysicalBone : : get_bone_name ( ) const {
return bone_name ;
}
void PhysicalBone : : set_mass ( real_t p_mass ) {
ERR_FAIL_COND ( p_mass < = 0 ) ;
mass = p_mass ;
PhysicsServer : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer : : BODY_PARAM_MASS , mass ) ;
}
real_t PhysicalBone : : get_mass ( ) const {
return mass ;
}
void PhysicalBone : : set_weight ( real_t p_weight ) {
set_mass ( p_weight / real_t ( GLOBAL_DEF ( " physics/3d/default_gravity " , 9.8 ) ) ) ;
}
real_t PhysicalBone : : get_weight ( ) const {
return mass * real_t ( GLOBAL_DEF ( " physics/3d/default_gravity " , 9.8 ) ) ;
}
void PhysicalBone : : set_friction ( real_t p_friction ) {
ERR_FAIL_COND ( p_friction < 0 | | p_friction > 1 ) ;
friction = p_friction ;
PhysicsServer : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer : : BODY_PARAM_FRICTION , friction ) ;
}
real_t PhysicalBone : : get_friction ( ) const {
return friction ;
}
void PhysicalBone : : set_bounce ( real_t p_bounce ) {
ERR_FAIL_COND ( p_bounce < 0 | | p_bounce > 1 ) ;
bounce = p_bounce ;
PhysicsServer : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer : : BODY_PARAM_BOUNCE , bounce ) ;
}
2017-10-24 18:10:30 +02:00
2017-10-03 18:49:32 +02:00
real_t PhysicalBone : : get_bounce ( ) const {
return bounce ;
}
void PhysicalBone : : set_gravity_scale ( real_t p_gravity_scale ) {
gravity_scale = p_gravity_scale ;
PhysicsServer : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer : : BODY_PARAM_GRAVITY_SCALE , gravity_scale ) ;
}
real_t PhysicalBone : : get_gravity_scale ( ) const {
return gravity_scale ;
}
PhysicalBone : : PhysicalBone ( ) :
PhysicsBody ( PhysicsServer : : BODY_MODE_STATIC ) ,
# ifdef TOOLS_ENABLED
gizmo_move_joint ( false ) ,
# endif
joint_data ( NULL ) ,
2018-09-28 17:17:38 +02:00
parent_skeleton ( NULL ) ,
simulate_physics ( false ) ,
2018-05-10 13:23:05 +02:00
_internal_simulate_physics ( false ) ,
2017-10-03 18:49:32 +02:00
bone_id ( - 1 ) ,
bone_name ( " " ) ,
bounce ( 0 ) ,
mass ( 1 ) ,
friction ( 1 ) ,
gravity_scale ( 1 ) {
2020-02-08 09:52:58 +01:00
reset_physics_simulation_state ( ) ;
2017-10-03 18:49:32 +02:00
}
PhysicalBone : : ~ PhysicalBone ( ) {
2018-11-01 09:46:46 +01:00
if ( joint_data )
memdelete ( joint_data ) ;
2017-10-03 18:49:32 +02:00
}
void PhysicalBone : : update_bone_id ( ) {
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 09:52:58 +01:00
reset_physics_simulation_state ( ) ;
2017-10-03 18:49:32 +02:00
}
}
void PhysicalBone : : update_offset ( ) {
# ifdef TOOLS_ENABLED
if ( parent_skeleton ) {
Transform bone_transform ( parent_skeleton - > get_global_transform ( ) ) ;
if ( - 1 ! = bone_id )
bone_transform * = parent_skeleton - > get_bone_global_pose ( bone_id ) ;
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
}
void PhysicalBone : : _start_physics_simulation ( ) {
if ( _internal_simulate_physics | | ! parent_skeleton ) {
return ;
}
reset_to_rest_position ( ) ;
PhysicsServer : : get_singleton ( ) - > body_set_mode ( get_rid ( ) , PhysicsServer : : BODY_MODE_RIGID ) ;
PhysicsServer : : get_singleton ( ) - > body_set_collision_layer ( get_rid ( ) , get_collision_layer ( ) ) ;
PhysicsServer : : get_singleton ( ) - > body_set_collision_mask ( get_rid ( ) , get_collision_mask ( ) ) ;
PhysicsServer : : get_singleton ( ) - > body_set_force_integration_callback ( get_rid ( ) , this , " _direct_state_changed " ) ;
2020-02-08 09:52:58 +01:00
set_as_toplevel ( true ) ;
2017-10-03 18:49:32 +02:00
_internal_simulate_physics = true ;
}
void PhysicalBone : : _stop_physics_simulation ( ) {
2020-02-08 09:52:58 +01:00
if ( ! parent_skeleton ) {
2017-10-03 18:49:32 +02:00
return ;
}
2020-02-08 09:52:58 +01:00
if ( parent_skeleton - > get_animate_physical_bones ( ) ) {
PhysicsServer : : get_singleton ( ) - > body_set_mode ( get_rid ( ) , PhysicsServer : : BODY_MODE_KINEMATIC ) ;
PhysicsServer : : get_singleton ( ) - > body_set_collision_layer ( get_rid ( ) , get_collision_layer ( ) ) ;
PhysicsServer : : get_singleton ( ) - > body_set_collision_mask ( get_rid ( ) , get_collision_mask ( ) ) ;
} else {
PhysicsServer : : get_singleton ( ) - > body_set_mode ( get_rid ( ) , PhysicsServer : : BODY_MODE_STATIC ) ;
PhysicsServer : : get_singleton ( ) - > body_set_collision_layer ( get_rid ( ) , 0 ) ;
PhysicsServer : : get_singleton ( ) - > body_set_collision_mask ( get_rid ( ) , 0 ) ;
}
if ( _internal_simulate_physics ) {
PhysicsServer : : get_singleton ( ) - > body_set_force_integration_callback ( get_rid ( ) , NULL , " " ) ;
parent_skeleton - > set_bone_global_pose_override ( bone_id , Transform ( ) , 0.0 , false ) ;
set_as_toplevel ( false ) ;
_internal_simulate_physics = false ;
}
2017-10-03 18:49:32 +02:00
}