2014-02-10 01:10:30 +00:00
/*************************************************************************/
/* physics_body.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
2017-01-01 21:01:57 +00:00
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
2017-04-07 22:45:00 +00:00
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
2014-02-10 01:10:30 +00:00
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
# include "physics_body.h"
# include "scene/scene_string_names.h"
void PhysicsBody : : _notification ( int p_what ) {
2017-03-18 23:36:26 +00:00
/*
2014-02-10 01:10:30 +00:00
switch ( p_what ) {
case NOTIFICATION_TRANSFORM_CHANGED : {
PhysicsServer : : get_singleton ( ) - > body_set_state ( get_rid ( ) , PhysicsServer : : BODY_STATE_TRANSFORM , get_global_transform ( ) ) ;
} break ;
}
*/
}
2014-08-14 13:31:38 +00: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 ;
}
2014-09-03 02:13:40 +00:00
void PhysicsBody : : set_layer_mask ( uint32_t p_mask ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
layer_mask = p_mask ;
PhysicsServer : : get_singleton ( ) - > body_set_layer_mask ( get_rid ( ) , p_mask ) ;
2014-02-10 01:10:30 +00:00
}
2014-09-03 02:13:40 +00:00
uint32_t PhysicsBody : : get_layer_mask ( ) const {
2014-02-10 01:10:30 +00:00
2014-09-03 02:13:40 +00:00
return layer_mask ;
2014-02-10 01:10:30 +00:00
}
2016-04-09 18:54:09 +00:00
void PhysicsBody : : set_collision_mask ( uint32_t p_mask ) {
2017-03-18 23:36:26 +00:00
collision_mask = p_mask ;
PhysicsServer : : get_singleton ( ) - > body_set_collision_mask ( get_rid ( ) , p_mask ) ;
2016-04-09 18:54:09 +00: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-18 23:36:26 +00:00
mask | = 1 < < p_bit ;
2016-04-09 18:54:09 +00:00
else
2017-03-18 23:36:26 +00:00
mask & = ~ ( 1 < < p_bit ) ;
2016-04-09 18:54:09 +00:00
set_collision_mask ( mask ) ;
}
2017-03-18 23:36:26 +00:00
bool PhysicsBody : : get_collision_mask_bit ( int p_bit ) const {
2016-04-09 18:54:09 +00:00
2017-03-18 23:36:26 +00:00
return get_collision_mask ( ) & ( 1 < < p_bit ) ;
2016-04-09 18:54:09 +00:00
}
void PhysicsBody : : set_layer_mask_bit ( int p_bit , bool p_value ) {
uint32_t mask = get_layer_mask ( ) ;
if ( p_value )
2017-03-18 23:36:26 +00:00
mask | = 1 < < p_bit ;
2016-04-09 18:54:09 +00:00
else
2017-03-18 23:36:26 +00:00
mask & = ~ ( 1 < < p_bit ) ;
2016-04-09 18:54:09 +00:00
set_layer_mask ( mask ) ;
}
2017-03-18 23:36:26 +00:00
bool PhysicsBody : : get_layer_mask_bit ( int p_bit ) const {
2016-04-09 18:54:09 +00:00
2017-03-18 23:36:26 +00:00
return get_layer_mask ( ) & ( 1 < < p_bit ) ;
2016-04-09 18:54:09 +00:00
}
2017-03-18 23:36:26 +00:00
void PhysicsBody : : add_collision_exception_with ( Node * p_node ) {
2014-09-22 04:03:56 +00:00
ERR_FAIL_NULL ( p_node ) ;
PhysicsBody * physics_body = p_node - > cast_to < PhysicsBody > ( ) ;
if ( ! physics_body ) {
ERR_EXPLAIN ( " Collision exception only works between two objects of PhysicsBody type " ) ;
}
ERR_FAIL_COND ( ! physics_body ) ;
2017-03-18 23:36:26 +00:00
PhysicsServer : : get_singleton ( ) - > body_add_collision_exception ( get_rid ( ) , physics_body - > get_rid ( ) ) ;
2014-09-22 04:03:56 +00:00
}
2017-03-18 23:36:26 +00:00
void PhysicsBody : : remove_collision_exception_with ( Node * p_node ) {
2014-09-22 04:03:56 +00:00
ERR_FAIL_NULL ( p_node ) ;
PhysicsBody * physics_body = p_node - > cast_to < PhysicsBody > ( ) ;
if ( ! physics_body ) {
ERR_EXPLAIN ( " Collision exception only works between two objects of PhysicsBody type " ) ;
}
ERR_FAIL_COND ( ! physics_body ) ;
2017-03-18 23:36:26 +00:00
PhysicsServer : : get_singleton ( ) - > body_remove_collision_exception ( get_rid ( ) , physics_body - > get_rid ( ) ) ;
2014-09-22 04:03:56 +00:00
}
2016-04-09 18:54:09 +00:00
void PhysicsBody : : _set_layers ( uint32_t p_mask ) {
set_layer_mask ( p_mask ) ;
set_collision_mask ( p_mask ) ;
}
2017-03-18 23:36:26 +00:00
uint32_t PhysicsBody : : _get_layers ( ) const {
2016-04-09 18:54:09 +00:00
return get_layer_mask ( ) ;
}
2015-01-13 13:49:26 +00:00
2014-09-03 02:13:40 +00:00
void PhysicsBody : : _bind_methods ( ) {
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_layer_mask " , " mask " ) , & PhysicsBody : : set_layer_mask ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_layer_mask " ) , & PhysicsBody : : get_layer_mask ) ;
2016-04-09 18:54:09 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_collision_mask " , " mask " ) , & PhysicsBody : : set_collision_mask ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_collision_mask " ) , & PhysicsBody : : get_collision_mask ) ;
2016-04-09 18:54:09 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_collision_mask_bit " , " bit " , " value " ) , & PhysicsBody : : set_collision_mask_bit ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_collision_mask_bit " , " bit " ) , & PhysicsBody : : get_collision_mask_bit ) ;
2016-04-09 18:54:09 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_layer_mask_bit " , " bit " , " value " ) , & PhysicsBody : : set_layer_mask_bit ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_layer_mask_bit " , " bit " ) , & PhysicsBody : : get_layer_mask_bit ) ;
2016-04-09 18:54:09 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " _set_layers " , " mask " ) , & PhysicsBody : : _set_layers ) ;
ObjectTypeDB : : bind_method ( _MD ( " _get_layers " ) , & PhysicsBody : : _get_layers ) ;
2016-04-09 18:54:09 +00:00
2017-03-18 23:36:26 +00:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " layers " , PROPERTY_HINT_ALL_FLAGS , " " , 0 ) , _SCS ( " _set_layers " ) , _SCS ( " _get_layers " ) ) ; //for backwards compat
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " collision/layers " , PROPERTY_HINT_ALL_FLAGS ) , _SCS ( " set_layer_mask " ) , _SCS ( " get_layer_mask " ) ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " collision/mask " , PROPERTY_HINT_ALL_FLAGS ) , _SCS ( " set_collision_mask " ) , _SCS ( " get_collision_mask " ) ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-18 23:36:26 +00:00
PhysicsBody : : PhysicsBody ( PhysicsServer : : BodyMode p_mode )
: CollisionObject ( PhysicsServer : : get_singleton ( ) - > body_create ( p_mode ) , false ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
layer_mask = 1 ;
collision_mask = 1 ;
2014-09-03 02:13:40 +00:00
}
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
void StaticBody : : set_friction ( real_t p_friction ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
ERR_FAIL_COND ( p_friction < 0 | | p_friction > 1 ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
friction = p_friction ;
PhysicsServer : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer : : BODY_PARAM_FRICTION , friction ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-18 23:36:26 +00:00
real_t StaticBody : : get_friction ( ) const {
2014-02-10 01:10:30 +00:00
2014-09-03 02:13:40 +00:00
return friction ;
}
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
void StaticBody : : set_bounce ( real_t p_bounce ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
ERR_FAIL_COND ( p_bounce < 0 | | p_bounce > 1 ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
bounce = p_bounce ;
PhysicsServer : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer : : BODY_PARAM_BOUNCE , bounce ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-18 23:36:26 +00:00
real_t StaticBody : : get_bounce ( ) const {
2014-02-10 01:10:30 +00:00
2014-09-03 02:13:40 +00:00
return bounce ;
}
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
void StaticBody : : set_constant_linear_velocity ( const Vector3 & p_vel ) {
2015-08-30 21:57:17 +00:00
2017-03-18 23:36:26 +00: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 02:13:40 +00:00
}
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
void StaticBody : : set_constant_angular_velocity ( const Vector3 & p_vel ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00: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 01:10:30 +00:00
}
2014-09-03 02:13:40 +00:00
Vector3 StaticBody : : get_constant_linear_velocity ( ) const {
2014-02-10 01:10:30 +00:00
2014-09-03 02:13:40 +00:00
return constant_linear_velocity ;
}
Vector3 StaticBody : : get_constant_angular_velocity ( ) const {
2014-02-10 01:10:30 +00:00
2014-09-03 02:13:40 +00:00
return constant_angular_velocity ;
2014-02-10 01:10:30 +00:00
}
void StaticBody : : _bind_methods ( ) {
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_constant_linear_velocity " , " vel " ) , & StaticBody : : set_constant_linear_velocity ) ;
ObjectTypeDB : : bind_method ( _MD ( " set_constant_angular_velocity " , " vel " ) , & StaticBody : : set_constant_angular_velocity ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_constant_linear_velocity " ) , & StaticBody : : get_constant_linear_velocity ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_constant_angular_velocity " ) , & StaticBody : : get_constant_angular_velocity ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_friction " , " friction " ) , & StaticBody : : set_friction ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_friction " ) , & StaticBody : : get_friction ) ;
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_bounce " , " bounce " ) , & StaticBody : : set_bounce ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_bounce " ) , & StaticBody : : get_bounce ) ;
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " add_collision_exception_with " , " body:PhysicsBody " ) , & PhysicsBody : : add_collision_exception_with ) ;
ObjectTypeDB : : bind_method ( _MD ( " remove_collision_exception_with " , " body:PhysicsBody " ) , & PhysicsBody : : remove_collision_exception_with ) ;
2014-09-22 04:03:56 +00:00
2017-03-18 23:36:26 +00:00
ADD_PROPERTY ( PropertyInfo ( Variant : : REAL , " friction " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) , _SCS ( " set_friction " ) , _SCS ( " get_friction " ) ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : REAL , " bounce " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) , _SCS ( " set_bounce " ) , _SCS ( " get_bounce " ) ) ;
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR3 , " constant_linear_velocity " ) , _SCS ( " set_constant_linear_velocity " ) , _SCS ( " get_constant_linear_velocity " ) ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR3 , " constant_angular_velocity " ) , _SCS ( " set_constant_angular_velocity " ) , _SCS ( " get_constant_angular_velocity " ) ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-18 23:36:26 +00:00
StaticBody : : StaticBody ( )
: PhysicsBody ( PhysicsServer : : BODY_MODE_STATIC ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
bounce = 0 ;
friction = 1 ;
2014-02-10 01:10:30 +00:00
}
StaticBody : : ~ StaticBody ( ) {
}
2014-11-06 00:20:42 +00:00
void RigidBody : : _body_enter_tree ( ObjectID p_id ) {
2014-02-10 01:10:30 +00:00
Object * obj = ObjectDB : : get_instance ( p_id ) ;
Node * node = obj ? obj - > cast_to < Node > ( ) : NULL ;
ERR_FAIL_COND ( ! node ) ;
2017-03-18 23:36:26 +00:00
Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . find ( p_id ) ;
2014-02-10 01:10:30 +00:00
ERR_FAIL_COND ( ! E ) ;
2014-11-06 00:20:42 +00:00
ERR_FAIL_COND ( E - > get ( ) . in_tree ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
E - > get ( ) . in_tree = true ;
2016-01-12 09:14:15 +00:00
2017-03-18 23:36:26 +00:00
contact_monitor - > locked = true ;
2016-01-12 09:14:15 +00:00
2017-03-18 23:36:26 +00:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_enter , node ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
for ( int i = 0 ; i < E - > get ( ) . shapes . size ( ) ; i + + ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_enter_shape , p_id , node , E - > get ( ) . shapes [ i ] . body_shape , E - > get ( ) . shapes [ i ] . local_shape ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-18 23:36:26 +00:00
contact_monitor - > locked = false ;
2014-02-10 01:10:30 +00:00
}
2014-11-06 00:20:42 +00:00
void RigidBody : : _body_exit_tree ( ObjectID p_id ) {
2014-02-10 01:10:30 +00:00
Object * obj = ObjectDB : : get_instance ( p_id ) ;
Node * node = obj ? obj - > cast_to < Node > ( ) : NULL ;
ERR_FAIL_COND ( ! node ) ;
2017-03-18 23:36:26 +00:00
Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . find ( p_id ) ;
2014-02-10 01:10:30 +00:00
ERR_FAIL_COND ( ! E ) ;
2014-11-06 00:20:42 +00:00
ERR_FAIL_COND ( ! E - > get ( ) . in_tree ) ;
2017-03-18 23:36:26 +00:00
E - > get ( ) . in_tree = false ;
2016-01-12 09:14:15 +00:00
2017-03-18 23:36:26 +00:00
contact_monitor - > locked = true ;
2016-01-12 09:14:15 +00:00
2017-03-18 23:36:26 +00:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_exit , node ) ;
2016-01-12 09:14:15 +00:00
2017-03-18 23:36:26 +00:00
for ( int i = 0 ; i < E - > get ( ) . shapes . size ( ) ; i + + ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_exit_shape , p_id , node , E - > get ( ) . shapes [ i ] . body_shape , E - > get ( ) . shapes [ i ] . local_shape ) ;
2014-02-10 01:10:30 +00:00
}
2016-01-12 09:14:15 +00:00
2017-03-18 23:36:26 +00:00
contact_monitor - > locked = false ;
2014-02-10 01:10:30 +00:00
}
2017-03-18 23:36:26 +00:00
void RigidBody : : _body_inout ( int p_status , ObjectID p_instance , int p_body_shape , int p_local_shape ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
bool body_in = p_status = = 1 ;
ObjectID objid = p_instance ;
2014-02-10 01:10:30 +00:00
Object * obj = ObjectDB : : get_instance ( objid ) ;
Node * node = obj ? obj - > cast_to < Node > ( ) : NULL ;
2017-03-18 23:36:26 +00:00
Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . find ( objid ) ;
2014-02-10 01:10:30 +00:00
ERR_FAIL_COND ( ! body_in & & ! E ) ;
if ( body_in ) {
if ( ! E ) {
2017-03-18 23:36:26 +00:00
E = contact_monitor - > body_map . insert ( objid , BodyState ( ) ) ;
2014-10-03 11:58:41 +00:00
//E->get().rc=0;
2017-03-18 23:36:26 +00:00
E - > get ( ) . in_tree = node & & node - > is_inside_tree ( ) ;
2014-02-10 01:10:30 +00:00
if ( node ) {
2017-03-18 23:36:26 +00:00
node - > connect ( SceneStringNames : : get_singleton ( ) - > enter_tree , this , SceneStringNames : : get_singleton ( ) - > _body_enter_tree , make_binds ( objid ) ) ;
node - > connect ( SceneStringNames : : get_singleton ( ) - > exit_tree , this , SceneStringNames : : get_singleton ( ) - > _body_exit_tree , make_binds ( objid ) ) ;
2014-11-06 00:20:42 +00:00
if ( E - > get ( ) . in_tree ) {
2017-03-18 23:36:26 +00:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_enter , node ) ;
2014-02-10 01:10:30 +00:00
}
}
}
2014-10-03 11:58:41 +00:00
//E->get().rc++;
2014-02-10 01:10:30 +00:00
if ( node )
2017-03-18 23:36:26 +00:00
E - > get ( ) . shapes . insert ( ShapePair ( p_body_shape , p_local_shape ) ) ;
2014-02-10 01:10:30 +00:00
2014-11-06 00:20:42 +00:00
if ( E - > get ( ) . in_tree ) {
2017-03-18 23:36:26 +00:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_enter_shape , objid , node , p_body_shape , p_local_shape ) ;
2014-02-10 01:10:30 +00:00
}
} else {
2014-10-03 11:58:41 +00:00
//E->get().rc--;
2014-02-10 01:10:30 +00:00
if ( node )
2017-03-18 23:36:26 +00:00
E - > get ( ) . shapes . erase ( ShapePair ( p_body_shape , p_local_shape ) ) ;
2014-02-10 01:10:30 +00:00
2014-11-06 00:20:42 +00:00
bool in_tree = E - > get ( ) . in_tree ;
2014-10-03 11:58:41 +00:00
if ( E - > get ( ) . shapes . empty ( ) ) {
2014-02-10 01:10:30 +00:00
if ( node ) {
2017-03-18 23:36:26 +00:00
node - > disconnect ( SceneStringNames : : get_singleton ( ) - > enter_tree , this , SceneStringNames : : get_singleton ( ) - > _body_enter_tree ) ;
node - > disconnect ( SceneStringNames : : get_singleton ( ) - > exit_tree , this , SceneStringNames : : get_singleton ( ) - > _body_exit_tree ) ;
2014-11-06 00:20:42 +00:00
if ( in_tree )
2017-03-18 23:36:26 +00:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_exit , obj ) ;
2014-02-10 01:10:30 +00:00
}
contact_monitor - > body_map . erase ( E ) ;
}
2014-11-06 00:20:42 +00:00
if ( node & & in_tree ) {
2017-03-18 23:36:26 +00:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > body_exit_shape , objid , obj , p_body_shape , p_local_shape ) ;
2014-02-10 01:10:30 +00:00
}
}
}
struct _RigidBodyInOut {
ObjectID id ;
int shape ;
int local_shape ;
} ;
void RigidBody : : _direct_state_changed ( Object * p_state ) {
2017-03-18 23:36:26 +00:00
//eh.. fuck
2014-02-10 01:10:30 +00:00
# ifdef DEBUG_ENABLED
2017-03-18 23:36:26 +00:00
state = p_state - > cast_to < PhysicsDirectBodyState > ( ) ;
2014-02-10 01:10:30 +00:00
# else
2017-03-18 23:36:26 +00:00
state = ( PhysicsDirectBodyState * ) p_state ; //trust it
2014-02-10 01:10:30 +00:00
# endif
2016-06-17 19:45:10 +00:00
set_ignore_transform_notification ( true ) ;
set_global_transform ( state - > get_transform ( ) ) ;
2017-03-18 23:36:26 +00: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 19:45:10 +00:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > sleeping_state_changed ) ;
}
if ( get_script_instance ( ) )
2017-03-18 23:36:26 +00:00
get_script_instance ( ) - > call ( " _integrate_forces " , state ) ;
2016-06-17 19:45:10 +00:00
set_ignore_transform_notification ( false ) ;
2014-02-10 01:10:30 +00:00
if ( contact_monitor ) {
2017-03-18 23:36:26 +00:00
contact_monitor - > locked = true ;
2016-01-12 09:14:15 +00:00
2014-02-10 01:10:30 +00:00
//untag all
2017-03-18 23:36:26 +00:00
int rc = 0 ;
for ( Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
for ( int i = 0 ; i < E - > get ( ) . shapes . size ( ) ; i + + ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
E - > get ( ) . shapes [ i ] . tagged = false ;
2014-02-10 01:10:30 +00:00
rc + + ;
}
}
2017-03-18 23:36:26 +00: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 01:10:30 +00:00
//put the ones to add
2017-03-18 23:36:26 +00:00
for ( int i = 0 ; i < state - > get_contact_count ( ) ; i + + ) {
2014-02-10 01:10:30 +00: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-03-18 23:36:26 +00:00
// bool found=false;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . find ( obj ) ;
2014-02-10 01:10:30 +00:00
if ( ! E ) {
2017-03-18 23:36:26 +00:00
toadd [ toadd_count ] . local_shape = local_shape ;
toadd [ toadd_count ] . id = obj ;
toadd [ toadd_count ] . shape = shape ;
2014-02-10 01:10:30 +00:00
toadd_count + + ;
continue ;
}
2017-03-18 23:36:26 +00:00
ShapePair sp ( shape , local_shape ) ;
2014-02-10 01:10:30 +00:00
int idx = E - > get ( ) . shapes . find ( sp ) ;
2017-03-18 23:36:26 +00:00
if ( idx = = - 1 ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
toadd [ toadd_count ] . local_shape = local_shape ;
toadd [ toadd_count ] . id = obj ;
toadd [ toadd_count ] . shape = shape ;
2014-02-10 01:10:30 +00:00
toadd_count + + ;
continue ;
}
2017-03-18 23:36:26 +00:00
E - > get ( ) . shapes [ idx ] . tagged = true ;
2014-02-10 01:10:30 +00:00
}
//put the ones to remove
2017-03-18 23:36:26 +00:00
for ( Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
for ( int i = 0 ; i < E - > get ( ) . shapes . size ( ) ; i + + ) {
2014-02-10 01:10:30 +00:00
if ( ! E - > get ( ) . shapes [ i ] . tagged ) {
2017-03-18 23:36:26 +00:00
toremove [ toremove_count ] . body_id = E - > key ( ) ;
toremove [ toremove_count ] . pair = E - > get ( ) . shapes [ i ] ;
2014-02-10 01:10:30 +00:00
toremove_count + + ;
}
}
}
//process remotions
2017-03-18 23:36:26 +00:00
for ( int i = 0 ; i < toremove_count ; i + + ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
_body_inout ( 0 , toremove [ i ] . body_id , toremove [ i ] . pair . body_shape , toremove [ i ] . pair . local_shape ) ;
2014-02-10 01:10:30 +00:00
}
//process aditions
2017-03-18 23:36:26 +00:00
for ( int i = 0 ; i < toadd_count ; i + + ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
_body_inout ( 1 , toadd [ i ] . id , toadd [ i ] . shape , toadd [ i ] . local_shape ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-18 23:36:26 +00:00
contact_monitor - > locked = false ;
2014-02-10 01:10:30 +00:00
}
2017-03-18 23:36:26 +00:00
state = NULL ;
2014-02-10 01:10:30 +00:00
}
void RigidBody : : _notification ( int p_what ) {
2017-08-05 19:06:15 +00:00
# ifdef TOOLS_ENABLED
if ( p_what = = NOTIFICATION_ENTER_TREE ) {
if ( get_tree ( ) - > is_editor_hint ( ) ) {
set_notify_local_transform ( true ) ; //used for warnings and only in editor
}
}
if ( p_what = = NOTIFICATION_LOCAL_TRANSFORM_CHANGED ) {
if ( get_tree ( ) - > is_editor_hint ( ) ) {
update_configuration_warning ( ) ;
}
}
# endif
2014-02-10 01:10:30 +00:00
}
void RigidBody : : set_mode ( Mode p_mode ) {
2017-03-18 23:36:26 +00:00
mode = p_mode ;
switch ( p_mode ) {
2014-02-10 01:10:30 +00:00
case MODE_RIGID : {
2017-03-18 23:36:26 +00:00
PhysicsServer : : get_singleton ( ) - > body_set_mode ( get_rid ( ) , PhysicsServer : : BODY_MODE_RIGID ) ;
2014-02-10 01:10:30 +00:00
} break ;
case MODE_STATIC : {
2017-03-18 23:36:26 +00:00
PhysicsServer : : get_singleton ( ) - > body_set_mode ( get_rid ( ) , PhysicsServer : : BODY_MODE_STATIC ) ;
2014-02-10 01:10:30 +00:00
} break ;
case MODE_CHARACTER : {
2017-03-18 23:36:26 +00:00
PhysicsServer : : get_singleton ( ) - > body_set_mode ( get_rid ( ) , PhysicsServer : : BODY_MODE_CHARACTER ) ;
2014-02-10 01:10:30 +00:00
} break ;
2014-02-19 14:57:14 +00:00
case MODE_KINEMATIC : {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
PhysicsServer : : get_singleton ( ) - > body_set_mode ( get_rid ( ) , PhysicsServer : : BODY_MODE_KINEMATIC ) ;
2014-02-10 01:10:30 +00:00
} break ;
}
}
2017-03-18 23:36:26 +00:00
RigidBody : : Mode RigidBody : : get_mode ( ) const {
2014-02-10 01:10:30 +00:00
return mode ;
}
2017-03-18 23:36:26 +00:00
void RigidBody : : set_mass ( real_t p_mass ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
ERR_FAIL_COND ( p_mass < = 0 ) ;
mass = p_mass ;
2014-02-10 01:10:30 +00:00
_change_notify ( " mass " ) ;
_change_notify ( " weight " ) ;
2017-03-18 23:36:26 +00:00
PhysicsServer : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer : : BODY_PARAM_MASS , mass ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-18 23:36:26 +00:00
real_t RigidBody : : get_mass ( ) const {
2014-02-10 01:10:30 +00:00
return mass ;
}
2017-03-18 23:36:26 +00:00
void RigidBody : : set_weight ( real_t p_weight ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
set_mass ( p_weight / 9.8 ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-18 23:36:26 +00:00
real_t RigidBody : : get_weight ( ) const {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
return mass * 9.8 ;
2014-02-10 01:10:30 +00:00
}
2017-03-18 23:36:26 +00:00
void RigidBody : : set_friction ( real_t p_friction ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
ERR_FAIL_COND ( p_friction < 0 | | p_friction > 1 ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
friction = p_friction ;
PhysicsServer : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer : : BODY_PARAM_FRICTION , friction ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-18 23:36:26 +00:00
real_t RigidBody : : get_friction ( ) const {
2014-02-10 01:10:30 +00:00
return friction ;
}
2017-03-18 23:36:26 +00:00
void RigidBody : : set_bounce ( real_t p_bounce ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
ERR_FAIL_COND ( p_bounce < 0 | | p_bounce > 1 ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
bounce = p_bounce ;
PhysicsServer : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer : : BODY_PARAM_BOUNCE , bounce ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-18 23:36:26 +00:00
real_t RigidBody : : get_bounce ( ) const {
2014-02-10 01:10:30 +00:00
return bounce ;
}
2017-03-18 23:36:26 +00:00
void RigidBody : : set_gravity_scale ( real_t p_gravity_scale ) {
2015-08-30 21:57:17 +00:00
2017-03-18 23:36:26 +00:00
gravity_scale = p_gravity_scale ;
PhysicsServer : : get_singleton ( ) - > body_set_param ( get_rid ( ) , PhysicsServer : : BODY_PARAM_GRAVITY_SCALE , gravity_scale ) ;
2015-08-30 21:57:17 +00:00
}
2017-03-18 23:36:26 +00:00
real_t RigidBody : : get_gravity_scale ( ) const {
2015-08-30 21:57:17 +00:00
return gravity_scale ;
}
2017-03-18 23:36:26 +00:00
void RigidBody : : set_linear_damp ( real_t p_linear_damp ) {
2015-08-30 21:57:17 +00:00
2017-03-18 23:36:26 +00: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 21:57:17 +00:00
}
2017-03-18 23:36:26 +00:00
real_t RigidBody : : get_linear_damp ( ) const {
2015-08-30 21:57:17 +00:00
return linear_damp ;
}
2017-03-18 23:36:26 +00:00
void RigidBody : : set_angular_damp ( real_t p_angular_damp ) {
2015-08-30 21:57:17 +00:00
2017-03-18 23:36:26 +00: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 21:57:17 +00:00
}
2017-03-18 23:36:26 +00:00
real_t RigidBody : : get_angular_damp ( ) const {
2015-08-30 21:57:17 +00:00
return angular_damp ;
}
2017-03-18 23:36:26 +00:00
void RigidBody : : set_axis_velocity ( const Vector3 & p_axis ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
Vector3 v = state ? state - > get_linear_velocity ( ) : linear_velocity ;
2014-02-10 01:10:30 +00:00
Vector3 axis = p_axis . normalized ( ) ;
2017-03-18 23:36:26 +00:00
v - = axis * axis . dot ( v ) ;
v + = p_axis ;
2014-02-10 01:10:30 +00:00
if ( state ) {
set_linear_velocity ( v ) ;
} else {
2017-03-18 23:36:26 +00:00
PhysicsServer : : get_singleton ( ) - > body_set_axis_velocity ( get_rid ( ) , p_axis ) ;
linear_velocity = v ;
2014-02-10 01:10:30 +00:00
}
}
2017-03-18 23:36:26 +00:00
void RigidBody : : set_linear_velocity ( const Vector3 & p_velocity ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
linear_velocity = p_velocity ;
2014-02-10 01:10:30 +00:00
if ( state )
state - > set_linear_velocity ( linear_velocity ) ;
else
2017-03-18 23:36:26 +00:00
PhysicsServer : : get_singleton ( ) - > body_set_state ( get_rid ( ) , PhysicsServer : : BODY_STATE_LINEAR_VELOCITY , linear_velocity ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-18 23:36:26 +00:00
Vector3 RigidBody : : get_linear_velocity ( ) const {
2014-02-10 01:10:30 +00:00
return linear_velocity ;
}
2017-03-18 23:36:26 +00:00
void RigidBody : : set_angular_velocity ( const Vector3 & p_velocity ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
angular_velocity = p_velocity ;
2014-02-10 01:10:30 +00:00
if ( state )
state - > set_angular_velocity ( angular_velocity ) ;
else
2017-03-18 23:36:26 +00:00
PhysicsServer : : get_singleton ( ) - > body_set_state ( get_rid ( ) , PhysicsServer : : BODY_STATE_ANGULAR_VELOCITY , angular_velocity ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-18 23:36:26 +00:00
Vector3 RigidBody : : get_angular_velocity ( ) const {
2014-02-10 01:10:30 +00:00
return angular_velocity ;
}
2017-03-18 23:36:26 +00:00
void RigidBody : : set_use_custom_integrator ( bool p_enable ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
if ( custom_integrator = = p_enable )
2014-02-10 01:10:30 +00:00
return ;
2017-03-18 23:36:26 +00:00
custom_integrator = p_enable ;
PhysicsServer : : get_singleton ( ) - > body_set_omit_force_integration ( get_rid ( ) , p_enable ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-18 23:36:26 +00:00
bool RigidBody : : is_using_custom_integrator ( ) {
2014-02-10 01:10:30 +00:00
return custom_integrator ;
}
2014-09-22 03:50:48 +00:00
void RigidBody : : set_sleeping ( bool p_sleeping ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
sleeping = p_sleeping ;
PhysicsServer : : get_singleton ( ) - > body_set_state ( get_rid ( ) , PhysicsServer : : BODY_STATE_SLEEPING , sleeping ) ;
2014-02-10 01:10:30 +00:00
}
void RigidBody : : set_can_sleep ( bool p_active ) {
2017-03-18 23:36:26 +00:00
can_sleep = p_active ;
PhysicsServer : : get_singleton ( ) - > body_set_state ( get_rid ( ) , PhysicsServer : : BODY_STATE_CAN_SLEEP , p_active ) ;
2014-02-10 01:10:30 +00:00
}
bool RigidBody : : is_able_to_sleep ( ) const {
return can_sleep ;
}
2014-09-22 03:50:48 +00:00
bool RigidBody : : is_sleeping ( ) const {
2014-02-10 01:10:30 +00:00
2014-09-22 03:50:48 +00:00
return sleeping ;
2014-02-10 01:10:30 +00:00
}
void RigidBody : : set_max_contacts_reported ( int p_amount ) {
2017-03-18 23:36:26 +00:00
max_contacts_reported = p_amount ;
PhysicsServer : : get_singleton ( ) - > body_set_max_contacts_reported ( get_rid ( ) , p_amount ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-18 23:36:26 +00:00
int RigidBody : : get_max_contacts_reported ( ) const {
2014-02-10 01:10:30 +00:00
return max_contacts_reported ;
}
2017-03-18 23:36:26 +00:00
void RigidBody : : apply_impulse ( const Vector3 & p_pos , const Vector3 & p_impulse ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
PhysicsServer : : get_singleton ( ) - > body_apply_impulse ( get_rid ( ) , p_pos , p_impulse ) ;
2014-02-10 01:10:30 +00:00
}
void RigidBody : : set_use_continuous_collision_detection ( bool p_enable ) {
2017-03-18 23:36:26 +00:00
ccd = p_enable ;
PhysicsServer : : get_singleton ( ) - > body_set_enable_continuous_collision_detection ( get_rid ( ) , p_enable ) ;
2014-02-10 01:10:30 +00:00
}
bool RigidBody : : is_using_continuous_collision_detection ( ) const {
return ccd ;
}
void RigidBody : : set_contact_monitor ( bool p_enabled ) {
2017-03-18 23:36:26 +00:00
if ( p_enabled = = is_contact_monitor_enabled ( ) )
2014-02-10 01:10:30 +00:00
return ;
if ( ! p_enabled ) {
2016-01-12 09:14:15 +00:00
if ( contact_monitor - > locked ) {
ERR_EXPLAIN ( " Can't disable contact monitoring during in/out callback. Use call_deferred( \" set_contact_monitor \" ,false) instead " ) ;
}
ERR_FAIL_COND ( contact_monitor - > locked ) ;
2017-03-18 23:36:26 +00:00
for ( Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 01:10:30 +00:00
//clean up mess
}
2017-03-18 23:36:26 +00:00
memdelete ( contact_monitor ) ;
contact_monitor = NULL ;
2014-02-10 01:10:30 +00:00
} else {
2017-03-18 23:36:26 +00:00
contact_monitor = memnew ( ContactMonitor ) ;
contact_monitor - > locked = false ;
2014-02-10 01:10:30 +00:00
}
}
bool RigidBody : : is_contact_monitor_enabled ( ) const {
2017-03-18 23:36:26 +00:00
return contact_monitor ! = NULL ;
2014-02-10 01:10:30 +00:00
}
2014-05-14 04:22:15 +00:00
void RigidBody : : set_axis_lock ( AxisLock p_lock ) {
2017-03-18 23:36:26 +00:00
axis_lock = p_lock ;
PhysicsServer : : get_singleton ( ) - > body_set_axis_lock ( get_rid ( ) , PhysicsServer : : BodyAxisLock ( axis_lock ) ) ;
2014-05-14 04:22:15 +00:00
}
RigidBody : : AxisLock RigidBody : : get_axis_lock ( ) const {
return axis_lock ;
}
2014-02-10 01:10:30 +00:00
2014-11-13 03:53:12 +00:00
Array RigidBody : : get_colliding_bodies ( ) const {
2017-03-18 23:36:26 +00:00
ERR_FAIL_COND_V ( ! contact_monitor , Array ( ) ) ;
2014-11-13 03:53:12 +00:00
Array ret ;
ret . resize ( contact_monitor - > body_map . size ( ) ) ;
2017-03-18 23:36:26 +00:00
int idx = 0 ;
for ( const Map < ObjectID , BodyState > : : Element * E = contact_monitor - > body_map . front ( ) ; E ; E = E - > next ( ) ) {
2014-11-13 03:53:12 +00:00
Object * obj = ObjectDB : : get_instance ( E - > key ( ) ) ;
if ( ! obj ) {
2017-03-18 23:36:26 +00:00
ret . resize ( ret . size ( ) - 1 ) ; //ops
2014-11-13 03:53:12 +00:00
} else {
2017-03-18 23:36:26 +00:00
ret [ idx + + ] = obj ;
2014-11-13 03:53:12 +00:00
}
}
return ret ;
}
2017-08-05 19:06:15 +00:00
String RigidBody : : get_configuration_warning ( ) const {
Transform t = get_transform ( ) ;
String warning = CollisionObject : : get_configuration_warning ( ) ;
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 ( 0 ) . length ( ) - 1.0 ) > 0.05 ) ) {
if ( warning ! = String ( ) ) {
warning + = " \n " ;
}
warning + = TTR ( " Size changes to RigidBody (in character or rigid modes) will be overriden by the physics engine when running. \n Change the size in children collision shapes instead. " ) ;
}
return warning ;
}
2014-02-10 01:10:30 +00:00
void RigidBody : : _bind_methods ( ) {
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_mode " , " mode " ) , & RigidBody : : set_mode ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_mode " ) , & RigidBody : : get_mode ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_mass " , " mass " ) , & RigidBody : : set_mass ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_mass " ) , & RigidBody : : get_mass ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_weight " , " weight " ) , & RigidBody : : set_weight ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_weight " ) , & RigidBody : : get_weight ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_friction " , " friction " ) , & RigidBody : : set_friction ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_friction " ) , & RigidBody : : get_friction ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_bounce " , " bounce " ) , & RigidBody : : set_bounce ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_bounce " ) , & RigidBody : : get_bounce ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_linear_velocity " , " linear_velocity " ) , & RigidBody : : set_linear_velocity ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_linear_velocity " ) , & RigidBody : : get_linear_velocity ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_angular_velocity " , " angular_velocity " ) , & RigidBody : : set_angular_velocity ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_angular_velocity " ) , & RigidBody : : get_angular_velocity ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_gravity_scale " , " gravity_scale " ) , & RigidBody : : set_gravity_scale ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_gravity_scale " ) , & RigidBody : : get_gravity_scale ) ;
2015-08-30 21:57:17 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_linear_damp " , " linear_damp " ) , & RigidBody : : set_linear_damp ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_linear_damp " ) , & RigidBody : : get_linear_damp ) ;
2015-08-30 21:57:17 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_angular_damp " , " angular_damp " ) , & RigidBody : : set_angular_damp ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_angular_damp " ) , & RigidBody : : get_angular_damp ) ;
2015-08-30 21:57:17 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_max_contacts_reported " , " amount " ) , & RigidBody : : set_max_contacts_reported ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_max_contacts_reported " ) , & RigidBody : : get_max_contacts_reported ) ;
2015-08-30 21:57:17 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_use_custom_integrator " , " enable " ) , & RigidBody : : set_use_custom_integrator ) ;
ObjectTypeDB : : bind_method ( _MD ( " is_using_custom_integrator " ) , & RigidBody : : is_using_custom_integrator ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_contact_monitor " , " enabled " ) , & RigidBody : : set_contact_monitor ) ;
ObjectTypeDB : : bind_method ( _MD ( " is_contact_monitor_enabled " ) , & RigidBody : : is_contact_monitor_enabled ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_use_continuous_collision_detection " , " enable " ) , & RigidBody : : set_use_continuous_collision_detection ) ;
ObjectTypeDB : : bind_method ( _MD ( " is_using_continuous_collision_detection " ) , & RigidBody : : is_using_continuous_collision_detection ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_axis_velocity " , " axis_velocity " ) , & RigidBody : : set_axis_velocity ) ;
ObjectTypeDB : : bind_method ( _MD ( " apply_impulse " , " pos " , " impulse " ) , & RigidBody : : apply_impulse ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_sleeping " , " sleeping " ) , & RigidBody : : set_sleeping ) ;
ObjectTypeDB : : bind_method ( _MD ( " is_sleeping " ) , & RigidBody : : is_sleeping ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_can_sleep " , " able_to_sleep " ) , & RigidBody : : set_can_sleep ) ;
ObjectTypeDB : : bind_method ( _MD ( " is_able_to_sleep " ) , & RigidBody : : is_able_to_sleep ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " _direct_state_changed " ) , & RigidBody : : _direct_state_changed ) ;
ObjectTypeDB : : bind_method ( _MD ( " _body_enter_tree " ) , & RigidBody : : _body_enter_tree ) ;
ObjectTypeDB : : bind_method ( _MD ( " _body_exit_tree " ) , & RigidBody : : _body_exit_tree ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_axis_lock " , " axis_lock " ) , & RigidBody : : set_axis_lock ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_axis_lock " ) , & RigidBody : : get_axis_lock ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " get_colliding_bodies " ) , & RigidBody : : get_colliding_bodies ) ;
2014-05-14 04:22:15 +00:00
2017-03-18 23:36:26 +00:00
BIND_VMETHOD ( MethodInfo ( " _integrate_forces " , PropertyInfo ( Variant : : OBJECT , " state:PhysicsDirectBodyState " ) ) ) ;
2014-11-13 03:53:12 +00:00
2017-03-18 23:36:26 +00:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " mode " , PROPERTY_HINT_ENUM , " Rigid,Static,Character,Kinematic " ) , _SCS ( " set_mode " ) , _SCS ( " get_mode " ) ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : REAL , " mass " , PROPERTY_HINT_EXP_RANGE , " 0.01,65535,0.01 " ) , _SCS ( " set_mass " ) , _SCS ( " get_mass " ) ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : REAL , " weight " , PROPERTY_HINT_EXP_RANGE , " 0.01,65535,0.01 " , PROPERTY_USAGE_EDITOR ) , _SCS ( " set_weight " ) , _SCS ( " get_weight " ) ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : REAL , " friction " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) , _SCS ( " set_friction " ) , _SCS ( " get_friction " ) ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : REAL , " bounce " , PROPERTY_HINT_RANGE , " 0,1,0.01 " ) , _SCS ( " set_bounce " ) , _SCS ( " get_bounce " ) ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : REAL , " gravity_scale " , PROPERTY_HINT_RANGE , " -128,128,0.01 " ) , _SCS ( " set_gravity_scale " ) , _SCS ( " get_gravity_scale " ) ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " custom_integrator " ) , _SCS ( " set_use_custom_integrator " ) , _SCS ( " is_using_custom_integrator " ) ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " continuous_cd " ) , _SCS ( " set_use_continuous_collision_detection " ) , _SCS ( " is_using_continuous_collision_detection " ) ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " contacts_reported " ) , _SCS ( " set_max_contacts_reported " ) , _SCS ( " get_max_contacts_reported " ) ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " contact_monitor " ) , _SCS ( " set_contact_monitor " ) , _SCS ( " is_contact_monitor_enabled " ) ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " sleeping " ) , _SCS ( " set_sleeping " ) , _SCS ( " is_sleeping " ) ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " can_sleep " ) , _SCS ( " set_can_sleep " ) , _SCS ( " is_able_to_sleep " ) ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " axis_lock " , PROPERTY_HINT_ENUM , " Disabled,Lock X,Lock Y,Lock Z " ) , _SCS ( " set_axis_lock " ) , _SCS ( " get_axis_lock " ) ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR3 , " velocity/linear " ) , _SCS ( " set_linear_velocity " ) , _SCS ( " get_linear_velocity " ) ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR3 , " velocity/angular " ) , _SCS ( " set_angular_velocity " ) , _SCS ( " get_angular_velocity " ) ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : REAL , " damp_override/linear " , PROPERTY_HINT_RANGE , " -1,128,0.01 " ) , _SCS ( " set_linear_damp " ) , _SCS ( " get_linear_damp " ) ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : REAL , " damp_override/angular " , PROPERTY_HINT_RANGE , " -1,128,0.01 " ) , _SCS ( " set_angular_damp " ) , _SCS ( " get_angular_damp " ) ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
ADD_SIGNAL ( MethodInfo ( " body_enter_shape " , PropertyInfo ( Variant : : INT , " body_id " ) , PropertyInfo ( Variant : : OBJECT , " body " ) , PropertyInfo ( Variant : : INT , " body_shape " ) , PropertyInfo ( Variant : : INT , " local_shape " ) ) ) ;
ADD_SIGNAL ( MethodInfo ( " body_exit_shape " , PropertyInfo ( Variant : : INT , " body_id " ) , PropertyInfo ( Variant : : OBJECT , " body " ) , PropertyInfo ( Variant : : INT , " body_shape " ) , PropertyInfo ( Variant : : INT , " local_shape " ) ) ) ;
ADD_SIGNAL ( MethodInfo ( " body_enter " , PropertyInfo ( Variant : : OBJECT , " body " ) ) ) ;
ADD_SIGNAL ( MethodInfo ( " body_exit " , PropertyInfo ( Variant : : OBJECT , " body " ) ) ) ;
ADD_SIGNAL ( MethodInfo ( " sleeping_state_changed " ) ) ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
BIND_CONSTANT ( MODE_STATIC ) ;
BIND_CONSTANT ( MODE_KINEMATIC ) ;
BIND_CONSTANT ( MODE_RIGID ) ;
BIND_CONSTANT ( MODE_CHARACTER ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-18 23:36:26 +00:00
RigidBody : : RigidBody ( )
: PhysicsBody ( PhysicsServer : : BODY_MODE_RIGID ) {
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
mode = MODE_RIGID ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
bounce = 0 ;
mass = 1 ;
friction = 1 ;
max_contacts_reported = 0 ;
state = NULL ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
gravity_scale = 1 ;
linear_damp = - 1 ;
angular_damp = - 1 ;
2015-08-30 21:57:17 +00:00
2014-02-10 01:10:30 +00:00
//angular_velocity=0;
2017-03-18 23:36:26 +00:00
sleeping = false ;
ccd = false ;
2014-02-10 01:10:30 +00:00
2017-03-18 23:36:26 +00:00
custom_integrator = false ;
contact_monitor = NULL ;
can_sleep = true ;
2014-02-10 01:10:30 +00:00
2014-05-14 04:22:15 +00:00
axis_lock = AXIS_LOCK_DISABLED ;
2017-03-18 23:36:26 +00:00
PhysicsServer : : get_singleton ( ) - > body_set_force_integration_callback ( get_rid ( ) , this , " _direct_state_changed " ) ;
2014-02-10 01:10:30 +00:00
}
RigidBody : : ~ RigidBody ( ) {
if ( contact_monitor )
2017-03-18 23:36:26 +00:00
memdelete ( contact_monitor ) ;
2014-02-10 01:10:30 +00:00
}
2014-09-03 02:13:40 +00:00
//////////////////////////////////////////////////////
//////////////////////////
Variant KinematicBody : : _get_collider ( ) const {
2017-03-18 23:36:26 +00:00
ObjectID oid = get_collider ( ) ;
if ( oid = = 0 )
2014-09-03 02:13:40 +00:00
return Variant ( ) ;
Object * obj = ObjectDB : : get_instance ( oid ) ;
if ( ! obj )
return Variant ( ) ;
Reference * ref = obj - > cast_to < Reference > ( ) ;
if ( ref ) {
return Ref < Reference > ( ref ) ;
}
return obj ;
}
bool KinematicBody : : _ignores_mode ( PhysicsServer : : BodyMode p_mode ) const {
2017-03-18 23:36:26 +00:00
switch ( p_mode ) {
2014-09-03 02:13:40 +00:00
case PhysicsServer : : BODY_MODE_STATIC : return ! collide_static ;
case PhysicsServer : : BODY_MODE_KINEMATIC : return ! collide_kinematic ;
case PhysicsServer : : BODY_MODE_RIGID : return ! collide_rigid ;
case PhysicsServer : : BODY_MODE_CHARACTER : return ! collide_character ;
}
return true ;
}
2017-03-18 23:36:26 +00:00
Vector3 KinematicBody : : move ( const Vector3 & p_motion ) {
2014-09-03 02:13:40 +00:00
//give me back regular physics engine logic
//this is madness
//and most people using this function will think
//what it does is simpler than using physics
//this took about a week to get right..
//but is it right? who knows at this point..
2017-03-18 23:36:26 +00:00
colliding = false ;
ERR_FAIL_COND_V ( ! is_inside_tree ( ) , Vector3 ( ) ) ;
2014-09-03 02:13:40 +00:00
PhysicsDirectSpaceState * dss = PhysicsServer : : get_singleton ( ) - > space_get_direct_state ( get_world ( ) - > get_space ( ) ) ;
2017-03-18 23:36:26 +00:00
ERR_FAIL_COND_V ( ! dss , Vector3 ( ) ) ;
const int max_shapes = 32 ;
Vector3 sr [ max_shapes * 2 ] ;
2014-09-03 02:13:40 +00:00
int res_shapes ;
Set < RID > exclude ;
exclude . insert ( get_rid ( ) ) ;
//recover first
2017-03-18 23:36:26 +00:00
int recover_attempts = 4 ;
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
bool collided = false ;
uint32_t mask = 0 ;
2014-09-03 02:13:40 +00:00
if ( collide_static )
2017-03-18 23:36:26 +00:00
mask | = PhysicsDirectSpaceState : : TYPE_MASK_STATIC_BODY ;
2014-09-03 02:13:40 +00:00
if ( collide_kinematic )
2017-03-18 23:36:26 +00:00
mask | = PhysicsDirectSpaceState : : TYPE_MASK_KINEMATIC_BODY ;
2014-09-03 02:13:40 +00:00
if ( collide_rigid )
2017-03-18 23:36:26 +00:00
mask | = PhysicsDirectSpaceState : : TYPE_MASK_RIGID_BODY ;
2014-09-03 02:13:40 +00:00
if ( collide_character )
2017-03-18 23:36:26 +00:00
mask | = PhysicsDirectSpaceState : : TYPE_MASK_CHARACTER_BODY ;
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
// print_line("motion: "+p_motion+" margin: "+rtos(margin));
2014-09-03 02:13:40 +00:00
//print_line("margin: "+rtos(margin));
float m = margin ;
//m=0.001;
do {
//motion recover
2017-03-18 23:36:26 +00:00
for ( int i = 0 ; i < get_shape_count ( ) ; i + + ) {
2014-09-03 02:13:40 +00:00
2015-01-02 16:30:59 +00:00
if ( is_shape_set_as_trigger ( i ) )
continue ;
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
if ( dss - > collide_shape ( get_shape ( i ) - > get_rid ( ) , get_global_transform ( ) * get_shape_transform ( i ) , m , sr , max_shapes , res_shapes , exclude , get_layer_mask ( ) , mask ) ) {
collided = true ;
2014-09-03 02:13:40 +00:00
}
}
if ( ! collided )
break ;
//print_line("have to recover");
Vector3 recover_motion ;
2017-03-18 23:36:26 +00:00
bool all_outside = true ;
for ( int j = 0 ; j < 8 ; j + + ) {
for ( int i = 0 ; i < res_shapes ; i + + ) {
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
Vector3 a = sr [ i * 2 + 0 ] ;
Vector3 b = sr [ i * 2 + 1 ] ;
//print_line(String()+a+" -> "+b);
2014-09-03 02:13:40 +00:00
#if 0
float d = a . distance_to ( b ) ;
//if (d<margin)
/// continue;
///
///
recover_motion + = ( b - a ) * 0.2 ;
# else
float dist = a . distance_to ( b ) ;
2017-03-18 23:36:26 +00:00
if ( dist > CMP_EPSILON ) {
Vector3 norm = ( b - a ) . normalized ( ) ;
if ( dist > margin * 0.5 )
all_outside = false ;
2014-09-03 02:13:40 +00:00
float adv = norm . dot ( recover_motion ) ;
//print_line(itos(i)+" dist: "+rtos(dist)+" adv: "+rtos(adv));
2017-03-18 23:36:26 +00:00
recover_motion + = norm * MAX ( dist - adv , 0 ) * 0.4 ;
2014-09-03 02:13:40 +00:00
}
# endif
}
}
2017-03-18 23:36:26 +00:00
if ( recover_motion = = Vector3 ( ) ) {
collided = false ;
2014-09-03 02:13:40 +00:00
break ;
}
//print_line("**** RECOVER: "+recover_motion);
Transform gt = get_global_transform ( ) ;
2017-03-18 23:36:26 +00:00
gt . origin + = recover_motion ;
2014-09-03 02:13:40 +00:00
set_global_transform ( gt ) ;
recover_attempts - - ;
if ( all_outside )
break ;
} while ( recover_attempts ) ;
//move second
float safe = 1.0 ;
float unsafe = 1.0 ;
2017-03-18 23:36:26 +00:00
int best_shape = - 1 ;
2014-09-03 02:13:40 +00:00
PhysicsDirectSpaceState : : ShapeRestInfo rest ;
//print_line("pos: "+get_global_transform().origin);
//print_line("motion: "+p_motion);
2017-03-18 23:36:26 +00:00
for ( int i = 0 ; i < get_shape_count ( ) ; i + + ) {
2014-09-03 02:13:40 +00:00
2014-12-20 18:30:06 +00:00
if ( is_shape_set_as_trigger ( i ) )
continue ;
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
float lsafe , lunsafe ;
2014-09-03 02:13:40 +00:00
PhysicsDirectSpaceState : : ShapeRestInfo lrest ;
2017-03-18 23:36:26 +00:00
bool valid = dss - > cast_motion ( get_shape ( i ) - > get_rid ( ) , get_global_transform ( ) * get_shape_transform ( i ) , p_motion , 0 , lsafe , lunsafe , exclude , get_layer_mask ( ) , mask , & lrest ) ;
2014-09-03 02:13:40 +00:00
//print_line("shape: "+itos(i)+" travel:"+rtos(ltravel));
if ( ! valid ) {
2017-03-18 23:36:26 +00:00
safe = 0 ;
unsafe = 0 ;
best_shape = i ; //sadly it's the best
2014-09-03 02:13:40 +00:00
//print_line("initial stuck");
break ;
}
2017-03-18 23:36:26 +00:00
if ( lsafe = = 1.0 ) {
2014-09-03 02:13:40 +00:00
//print_line("initial free");
continue ;
}
if ( lsafe < safe ) {
//print_line("initial at "+rtos(lsafe));
2017-03-18 23:36:26 +00:00
safe = lsafe ;
safe = MAX ( 0 , lsafe - 0.01 ) ;
unsafe = lunsafe ;
best_shape = i ;
rest = lrest ;
2014-09-03 02:13:40 +00:00
}
}
//print_line("best shape: "+itos(best_shape)+" motion "+p_motion);
2017-03-18 23:36:26 +00:00
if ( safe > = 1 ) {
2014-09-03 02:13:40 +00:00
//not collided
2017-03-18 23:36:26 +00:00
colliding = false ;
2014-09-03 02:13:40 +00:00
} else {
2017-03-18 23:36:26 +00:00
colliding = true ;
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
if ( true | | ( safe = = 0 & & unsafe = = 0 ) ) { //use it always because it's more precise than GJK
2014-09-03 02:13:40 +00:00
//no advance, use rest info from collision
Transform ugt = get_global_transform ( ) ;
2017-03-18 23:36:26 +00:00
ugt . origin + = p_motion * unsafe ;
2014-09-03 02:13:40 +00:00
PhysicsDirectSpaceState : : ShapeRestInfo rest_info ;
2017-03-18 23:36:26 +00:00
bool c2 = dss - > rest_info ( get_shape ( best_shape ) - > get_rid ( ) , ugt * get_shape_transform ( best_shape ) , m , & rest , exclude , get_layer_mask ( ) , mask ) ;
2014-09-03 02:13:40 +00:00
if ( ! c2 ) {
//should not happen, but floating point precision is so weird..
2017-03-18 23:36:26 +00:00
colliding = false ;
2014-09-03 02:13:40 +00:00
}
2017-03-18 23:36:26 +00:00
// print_line("Rest Travel: "+rest.normal);
2014-09-03 02:13:40 +00:00
}
if ( colliding ) {
2017-03-18 23:36:26 +00:00
collision = rest . point ;
normal = rest . normal ;
collider = rest . collider_id ;
collider_vel = rest . linear_velocity ;
collider_shape = rest . shape ;
2014-09-03 02:13:40 +00:00
}
}
2017-03-18 23:36:26 +00:00
Vector3 motion = p_motion * safe ;
2014-09-03 02:13:40 +00:00
//if (colliding)
// motion+=normal*0.001;
Transform gt = get_global_transform ( ) ;
2017-03-18 23:36:26 +00:00
gt . origin + = motion ;
2014-09-03 02:13:40 +00:00
set_global_transform ( gt ) ;
2017-03-18 23:36:26 +00:00
return p_motion - motion ;
2014-09-03 02:13:40 +00:00
}
2017-03-18 23:36:26 +00:00
Vector3 KinematicBody : : move_to ( const Vector3 & p_position ) {
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
return move ( p_position - get_global_transform ( ) . origin ) ;
2014-09-03 02:13:40 +00:00
}
2017-03-18 23:36:26 +00:00
bool KinematicBody : : can_teleport_to ( const Vector3 & p_position ) {
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
ERR_FAIL_COND_V ( ! is_inside_tree ( ) , false ) ;
2014-09-03 02:13:40 +00:00
PhysicsDirectSpaceState * dss = PhysicsServer : : get_singleton ( ) - > space_get_direct_state ( get_world ( ) - > get_space ( ) ) ;
2017-03-18 23:36:26 +00:00
ERR_FAIL_COND_V ( ! dss , false ) ;
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
uint32_t mask = 0 ;
2014-09-03 02:13:40 +00:00
if ( collide_static )
2017-03-18 23:36:26 +00:00
mask | = PhysicsDirectSpaceState : : TYPE_MASK_STATIC_BODY ;
2014-09-03 02:13:40 +00:00
if ( collide_kinematic )
2017-03-18 23:36:26 +00:00
mask | = PhysicsDirectSpaceState : : TYPE_MASK_KINEMATIC_BODY ;
2014-09-03 02:13:40 +00:00
if ( collide_rigid )
2017-03-18 23:36:26 +00:00
mask | = PhysicsDirectSpaceState : : TYPE_MASK_RIGID_BODY ;
2014-09-03 02:13:40 +00:00
if ( collide_character )
2017-03-18 23:36:26 +00:00
mask | = PhysicsDirectSpaceState : : TYPE_MASK_CHARACTER_BODY ;
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
Transform xform = get_global_transform ( ) ;
xform . origin = p_position ;
2014-09-03 02:13:40 +00:00
Set < RID > exclude ;
exclude . insert ( get_rid ( ) ) ;
2017-03-18 23:36:26 +00:00
for ( int i = 0 ; i < get_shape_count ( ) ; i + + ) {
2014-09-03 02:13:40 +00:00
2014-12-20 18:30:06 +00:00
if ( is_shape_set_as_trigger ( i ) )
continue ;
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
bool col = dss - > intersect_shape ( get_shape ( i ) - > get_rid ( ) , xform * get_shape_transform ( i ) , 0 , NULL , 1 , exclude , get_layer_mask ( ) , mask ) ;
2014-09-03 02:13:40 +00:00
if ( col )
return false ;
}
return true ;
}
bool KinematicBody : : is_colliding ( ) const {
2017-03-18 23:36:26 +00:00
ERR_FAIL_COND_V ( ! is_inside_tree ( ) , false ) ;
2014-09-03 02:13:40 +00:00
return colliding ;
}
Vector3 KinematicBody : : get_collision_pos ( ) const {
2017-03-18 23:36:26 +00:00
ERR_FAIL_COND_V ( ! colliding , Vector3 ( ) ) ;
2014-09-03 02:13:40 +00:00
return collision ;
}
Vector3 KinematicBody : : get_collision_normal ( ) const {
2017-03-18 23:36:26 +00:00
ERR_FAIL_COND_V ( ! colliding , Vector3 ( ) ) ;
2014-09-03 02:13:40 +00:00
return normal ;
}
Vector3 KinematicBody : : get_collider_velocity ( ) const {
return collider_vel ;
}
ObjectID KinematicBody : : get_collider ( ) const {
2017-03-18 23:36:26 +00:00
ERR_FAIL_COND_V ( ! colliding , 0 ) ;
2014-09-03 02:13:40 +00:00
return collider ;
}
2014-10-14 04:01:25 +00:00
int KinematicBody : : get_collider_shape ( ) const {
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
ERR_FAIL_COND_V ( ! colliding , - 1 ) ;
2014-10-14 04:01:25 +00:00
return collider_shape ;
}
2014-09-03 02:13:40 +00:00
void KinematicBody : : set_collide_with_static_bodies ( bool p_enable ) {
2017-03-18 23:36:26 +00:00
collide_static = p_enable ;
2014-09-03 02:13:40 +00:00
}
bool KinematicBody : : can_collide_with_static_bodies ( ) const {
return collide_static ;
}
void KinematicBody : : set_collide_with_rigid_bodies ( bool p_enable ) {
2017-03-18 23:36:26 +00:00
collide_rigid = p_enable ;
2014-09-03 02:13:40 +00:00
}
bool KinematicBody : : can_collide_with_rigid_bodies ( ) const {
return collide_rigid ;
}
void KinematicBody : : set_collide_with_kinematic_bodies ( bool p_enable ) {
2017-03-18 23:36:26 +00:00
collide_kinematic = p_enable ;
2014-09-03 02:13:40 +00:00
}
bool KinematicBody : : can_collide_with_kinematic_bodies ( ) const {
return collide_kinematic ;
}
void KinematicBody : : set_collide_with_character_bodies ( bool p_enable ) {
2017-03-18 23:36:26 +00:00
collide_character = p_enable ;
2014-09-03 02:13:40 +00:00
}
bool KinematicBody : : can_collide_with_character_bodies ( ) const {
return collide_character ;
}
void KinematicBody : : set_collision_margin ( float p_margin ) {
2017-03-18 23:36:26 +00:00
margin = p_margin ;
2014-09-03 02:13:40 +00:00
}
2017-03-18 23:36:26 +00:00
float KinematicBody : : get_collision_margin ( ) const {
2014-09-03 02:13:40 +00:00
return margin ;
}
void KinematicBody : : _bind_methods ( ) {
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " move " , " rel_vec " ) , & KinematicBody : : move ) ;
ObjectTypeDB : : bind_method ( _MD ( " move_to " , " position " ) , & KinematicBody : : move_to ) ;
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " can_teleport_to " , " position " ) , & KinematicBody : : can_teleport_to ) ;
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " is_colliding " ) , & KinematicBody : : is_colliding ) ;
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " get_collision_pos " ) , & KinematicBody : : get_collision_pos ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_collision_normal " ) , & KinematicBody : : get_collision_normal ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_collider_velocity " ) , & KinematicBody : : get_collider_velocity ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_collider:Variant " ) , & KinematicBody : : _get_collider ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_collider_shape " ) , & KinematicBody : : get_collider_shape ) ;
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_collide_with_static_bodies " , " enable " ) , & KinematicBody : : set_collide_with_static_bodies ) ;
ObjectTypeDB : : bind_method ( _MD ( " can_collide_with_static_bodies " ) , & KinematicBody : : can_collide_with_static_bodies ) ;
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_collide_with_kinematic_bodies " , " enable " ) , & KinematicBody : : set_collide_with_kinematic_bodies ) ;
ObjectTypeDB : : bind_method ( _MD ( " can_collide_with_kinematic_bodies " ) , & KinematicBody : : can_collide_with_kinematic_bodies ) ;
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_collide_with_rigid_bodies " , " enable " ) , & KinematicBody : : set_collide_with_rigid_bodies ) ;
ObjectTypeDB : : bind_method ( _MD ( " can_collide_with_rigid_bodies " ) , & KinematicBody : : can_collide_with_rigid_bodies ) ;
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_collide_with_character_bodies " , " enable " ) , & KinematicBody : : set_collide_with_character_bodies ) ;
ObjectTypeDB : : bind_method ( _MD ( " can_collide_with_character_bodies " ) , & KinematicBody : : can_collide_with_character_bodies ) ;
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
ObjectTypeDB : : bind_method ( _MD ( " set_collision_margin " , " pixels " ) , & KinematicBody : : set_collision_margin ) ;
ObjectTypeDB : : bind_method ( _MD ( " get_collision_margin " , " pixels " ) , & KinematicBody : : get_collision_margin ) ;
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " collide_with/static " ) , _SCS ( " set_collide_with_static_bodies " ) , _SCS ( " can_collide_with_static_bodies " ) ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " collide_with/kinematic " ) , _SCS ( " set_collide_with_kinematic_bodies " ) , _SCS ( " can_collide_with_kinematic_bodies " ) ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " collide_with/rigid " ) , _SCS ( " set_collide_with_rigid_bodies " ) , _SCS ( " can_collide_with_rigid_bodies " ) ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " collide_with/character " ) , _SCS ( " set_collide_with_character_bodies " ) , _SCS ( " can_collide_with_character_bodies " ) ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : REAL , " collision/margin " , PROPERTY_HINT_RANGE , " 0.001,256,0.001 " ) , _SCS ( " set_collision_margin " ) , _SCS ( " get_collision_margin " ) ) ;
2014-09-03 02:13:40 +00:00
}
2017-03-18 23:36:26 +00:00
KinematicBody : : KinematicBody ( )
: PhysicsBody ( PhysicsServer : : BODY_MODE_KINEMATIC ) {
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
collide_static = true ;
collide_rigid = true ;
collide_kinematic = true ;
collide_character = true ;
2014-09-03 02:13:40 +00:00
2017-03-18 23:36:26 +00:00
colliding = false ;
collider = 0 ;
margin = 0.001 ;
collider_shape = 0 ;
2014-09-03 02:13:40 +00:00
}
2017-03-18 23:36:26 +00:00
KinematicBody : : ~ KinematicBody ( ) {
2014-09-03 02:13:40 +00:00
}