2014-02-10 02:10:30 +01:00
/*************************************************************************/
2021-10-18 21:24:30 +02:00
/* godot_collision_object_3d.h */
2014-02-10 02:10:30 +01:00
/*************************************************************************/
/* 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
/*************************************************************************/
2022-01-03 21:27:34 +01:00
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
2014-02-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
2021-10-18 21:24:30 +02:00
# ifndef GODOT_COLLISION_OBJECT_3D_H
# define GODOT_COLLISION_OBJECT_3D_H
# include "godot_broad_phase_3d.h"
# include "godot_shape_3d.h"
2014-02-10 02:10:30 +01:00
2020-11-07 23:33:38 +01:00
# include "core/templates/self_list.h"
2020-03-27 19:21:27 +01:00
# include "servers/physics_server_3d.h"
2014-02-10 02:10:30 +01:00
2015-05-06 00:56:59 +02:00
# ifdef DEBUG_ENABLED
2018-03-17 23:32:07 +01:00
# define MAX_OBJECT_DISTANCE 3.1622776601683791e+18
2017-03-05 16:44:50 +01:00
# define MAX_OBJECT_DISTANCE_X2 (MAX_OBJECT_DISTANCE * MAX_OBJECT_DISTANCE)
2015-05-06 00:56:59 +02:00
# endif
2014-09-19 23:39:50 +02:00
2021-10-18 21:24:30 +02:00
class GodotSpace3D ;
2014-02-10 02:10:30 +01:00
2021-10-18 21:24:30 +02:00
class GodotCollisionObject3D : public GodotShapeOwner3D {
2014-02-10 02:10:30 +01:00
public :
enum Type {
TYPE_AREA ,
2021-03-12 04:33:46 +01:00
TYPE_BODY ,
TYPE_SOFT_BODY ,
2014-02-10 02:10:30 +01:00
} ;
2017-03-05 16:44:50 +01:00
private :
2014-02-10 02:10:30 +01:00
Type type ;
RID self ;
ObjectID instance_id ;
2021-09-14 11:01:49 +02:00
uint32_t collision_layer = 1 ;
uint32_t collision_mask = 1 ;
2022-08-10 18:45:36 +02:00
real_t collision_priority = 1.0 ;
2014-02-10 02:10:30 +01:00
struct Shape {
2020-10-17 07:08:21 +02:00
Transform3D xform ;
Transform3D xform_inv ;
2021-10-18 21:24:30 +02:00
GodotBroadPhase3D : : ID bpid ;
2017-11-17 03:09:00 +01:00
AABB aabb_cache ; //for rayqueries
2021-09-14 11:01:49 +02:00
real_t area_cache = 0.0 ;
2021-10-18 21:24:30 +02:00
GodotShape3D * shape = nullptr ;
2021-09-14 11:01:49 +02:00
bool disabled = false ;
2014-02-10 02:10:30 +01:00
} ;
Vector < Shape > shapes ;
2021-10-18 21:24:30 +02:00
GodotSpace3D * space = nullptr ;
2020-10-17 07:08:21 +02:00
Transform3D transform ;
Transform3D inv_transform ;
2021-09-14 11:01:49 +02:00
bool _static = true ;
2014-02-10 02:10:30 +01:00
2021-10-18 21:24:30 +02:00
SelfList < GodotCollisionObject3D > pending_shape_update_list ;
2017-09-03 19:53:17 +02:00
2014-02-10 02:10:30 +01:00
void _update_shapes ( ) ;
protected :
2017-03-05 16:44:50 +01:00
void _update_shapes_with_motion ( const Vector3 & p_motion ) ;
2014-02-10 02:10:30 +01:00
void _unregister_shapes ( ) ;
2020-10-17 07:08:21 +02:00
_FORCE_INLINE_ void _set_transform ( const Transform3D & p_transform , bool p_update_shapes = true ) {
2014-09-19 23:39:50 +02:00
# ifdef DEBUG_ENABLED
2019-09-25 10:28:50 +02:00
ERR_FAIL_COND_MSG ( p_transform . origin . length_squared ( ) > MAX_OBJECT_DISTANCE_X2 , " Object went too far away (more than ' " + itos ( MAX_OBJECT_DISTANCE ) + " ' units from origin). " ) ;
2014-09-19 23:39:50 +02:00
# endif
2017-03-05 16:44:50 +01:00
transform = p_transform ;
2020-05-14 16:41:43 +02:00
if ( p_update_shapes ) {
2020-05-10 12:56:01 +02:00
_update_shapes ( ) ;
2020-05-14 16:41:43 +02:00
}
2014-09-19 23:39:50 +02:00
}
2020-10-17 07:08:21 +02:00
_FORCE_INLINE_ void _set_inv_transform ( const Transform3D & p_transform ) { inv_transform = p_transform ; }
2014-02-10 02:10:30 +01:00
void _set_static ( bool p_static ) ;
2017-03-05 16:44:50 +01:00
virtual void _shapes_changed ( ) = 0 ;
2021-10-18 21:24:30 +02:00
void _set_space ( GodotSpace3D * p_space ) ;
2014-02-10 02:10:30 +01:00
2021-09-14 11:01:49 +02:00
bool ray_pickable = true ;
2014-10-03 05:10:51 +02:00
2021-10-18 21:24:30 +02:00
GodotCollisionObject3D ( Type p_type ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
public :
_FORCE_INLINE_ void set_self ( const RID & p_self ) { self = p_self ; }
2014-02-10 02:10:30 +01:00
_FORCE_INLINE_ RID get_self ( ) const { return self ; }
2017-03-05 16:44:50 +01:00
_FORCE_INLINE_ void set_instance_id ( const ObjectID & p_instance_id ) { instance_id = p_instance_id ; }
2014-02-10 02:10:30 +01:00
_FORCE_INLINE_ ObjectID get_instance_id ( ) const { return instance_id ; }
2022-04-05 12:40:26 +02:00
void _shape_changed ( ) override ;
2014-02-10 02:10:30 +01:00
_FORCE_INLINE_ Type get_type ( ) const { return type ; }
2021-10-18 21:24:30 +02:00
void add_shape ( GodotShape3D * p_shape , const Transform3D & p_transform = Transform3D ( ) , bool p_disabled = false ) ;
void set_shape ( int p_index , GodotShape3D * p_shape ) ;
2020-10-17 07:08:21 +02:00
void set_shape_transform ( int p_index , const Transform3D & p_transform ) ;
2014-02-10 02:10:30 +01:00
_FORCE_INLINE_ int get_shape_count ( ) const { return shapes . size ( ) ; }
2021-10-18 21:24:30 +02:00
_FORCE_INLINE_ GodotShape3D * get_shape ( int p_index ) const {
2018-12-07 22:09:39 +01:00
CRASH_BAD_INDEX ( p_index , shapes . size ( ) ) ;
2021-06-23 01:36:43 +02:00
return shapes [ p_index ] . shape ;
}
_FORCE_INLINE_ const Transform3D & get_shape_transform ( int p_index ) const {
CRASH_BAD_INDEX ( p_index , shapes . size ( ) ) ;
return shapes [ p_index ] . xform ;
}
_FORCE_INLINE_ const Transform3D & get_shape_inv_transform ( int p_index ) const {
CRASH_BAD_INDEX ( p_index , shapes . size ( ) ) ;
return shapes [ p_index ] . xform_inv ;
}
_FORCE_INLINE_ const AABB & get_shape_aabb ( int p_index ) const {
CRASH_BAD_INDEX ( p_index , shapes . size ( ) ) ;
return shapes [ p_index ] . aabb_cache ;
}
_FORCE_INLINE_ real_t get_shape_area ( int p_index ) const {
CRASH_BAD_INDEX ( p_index , shapes . size ( ) ) ;
return shapes [ p_index ] . area_cache ;
2018-12-07 22:09:39 +01:00
}
2014-02-10 02:10:30 +01:00
2020-10-17 07:08:21 +02:00
_FORCE_INLINE_ const Transform3D & get_transform ( ) const { return transform ; }
_FORCE_INLINE_ const Transform3D & get_inv_transform ( ) const { return inv_transform ; }
2021-10-18 21:24:30 +02:00
_FORCE_INLINE_ GodotSpace3D * get_space ( ) const { return space ; }
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
_FORCE_INLINE_ void set_ray_pickable ( bool p_enable ) { ray_pickable = p_enable ; }
2014-10-03 05:10:51 +02:00
_FORCE_INLINE_ bool is_ray_pickable ( ) const { return ray_pickable ; }
2021-06-23 01:36:43 +02:00
void set_shape_disabled ( int p_idx , bool p_disabled ) ;
_FORCE_INLINE_ bool is_shape_disabled ( int p_idx ) const {
ERR_FAIL_INDEX_V ( p_idx , shapes . size ( ) , false ) ;
2019-06-21 13:33:01 +02:00
return shapes [ p_idx ] . disabled ;
}
2014-02-10 02:10:30 +01:00
2020-06-27 19:34:16 +02:00
_FORCE_INLINE_ void set_collision_layer ( uint32_t p_layer ) {
collision_layer = p_layer ;
_shape_changed ( ) ;
}
2017-06-13 17:45:01 +02:00
_FORCE_INLINE_ uint32_t get_collision_layer ( ) const { return collision_layer ; }
2014-02-10 02:10:30 +01:00
2020-06-27 19:34:16 +02:00
_FORCE_INLINE_ void set_collision_mask ( uint32_t p_mask ) {
collision_mask = p_mask ;
_shape_changed ( ) ;
}
2016-04-09 20:54:09 +02:00
_FORCE_INLINE_ uint32_t get_collision_mask ( ) const { return collision_mask ; }
2022-08-10 18:45:36 +02:00
_FORCE_INLINE_ void set_collision_priority ( real_t p_priority ) {
ERR_FAIL_COND_MSG ( p_priority < = 0 , " Priority must be greater than 0. " ) ;
collision_priority = p_priority ;
_shape_changed ( ) ;
}
_FORCE_INLINE_ real_t get_collision_priority ( ) const { return collision_priority ; }
2021-10-18 21:24:30 +02:00
_FORCE_INLINE_ bool collides_with ( GodotCollisionObject3D * p_other ) const {
2021-07-15 21:38:48 +02:00
return p_other - > collision_layer & collision_mask ;
2020-10-08 13:45:03 +02:00
}
2022-02-04 17:46:10 +01:00
_FORCE_INLINE_ bool interacts_with ( const GodotCollisionObject3D * p_other ) const {
2017-06-13 17:45:01 +02:00
return collision_layer & p_other - > collision_mask | | p_other - > collision_layer & collision_mask ;
2016-04-09 20:54:09 +02:00
}
2022-04-05 12:40:26 +02:00
void remove_shape ( GodotShape3D * p_shape ) override ;
2014-02-10 02:10:30 +01:00
void remove_shape ( int p_index ) ;
2021-10-18 21:24:30 +02:00
virtual void set_space ( GodotSpace3D * p_space ) = 0 ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
_FORCE_INLINE_ bool is_static ( ) const { return _static ; }
2014-02-10 02:10:30 +01:00
2021-10-18 21:24:30 +02:00
virtual ~ GodotCollisionObject3D ( ) { }
2014-02-10 02:10:30 +01:00
} ;
2021-10-18 21:24:30 +02:00
# endif // GODOT_COLLISION_OBJECT_3D_H