2023-01-10 15:26:54 +01:00
/**************************************************************************/
/* collision_object_sw.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* 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
# ifndef COLLISION_OBJECT_SW_H
# define COLLISION_OBJECT_SW_H
# include "broad_phase_sw.h"
2018-09-11 18:13:45 +02:00
# include "core/self_list.h"
2017-03-05 16:44:50 +01:00
# include "servers/physics_server.h"
# include "shape_sw.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
2014-02-10 02:10:30 +01:00
class SpaceSW ;
class CollisionObjectSW : public ShapeOwnerSW {
public :
enum Type {
TYPE_AREA ,
TYPE_BODY
} ;
2017-03-05 16:44:50 +01:00
private :
2014-02-10 02:10:30 +01:00
Type type ;
RID self ;
ObjectID instance_id ;
2017-06-13 17:45:01 +02:00
uint32_t collision_layer ;
2016-04-09 20:54:09 +02:00
uint32_t collision_mask ;
2014-02-10 02:10:30 +01:00
struct Shape {
Transform xform ;
Transform xform_inv ;
BroadPhaseSW : : ID bpid ;
2017-11-17 03:09:00 +01:00
AABB aabb_cache ; //for rayqueries
2016-12-31 15:39:25 +01:00
real_t area_cache ;
2014-02-10 02:10:30 +01:00
ShapeSW * shape ;
2017-07-15 06:23:10 +02:00
bool disabled ;
2014-10-03 13:58:41 +02:00
2017-07-15 06:23:10 +02:00
Shape ( ) { disabled = false ; }
2014-02-10 02:10:30 +01:00
} ;
Vector < Shape > shapes ;
SpaceSW * space ;
Transform transform ;
Transform inv_transform ;
bool _static ;
2017-09-03 19:53:17 +02:00
SelfList < CollisionObjectSW > pending_shape_update_list ;
2014-02-10 02:10:30 +01:00
void _update_shapes ( ) ;
2021-10-21 21:06:09 +02:00
void _recheck_shapes ( ) ;
2014-02-10 02:10:30 +01:00
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 ( ) ;
2017-03-05 16:44:50 +01:00
_FORCE_INLINE_ void _set_transform ( const Transform & 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 ;
2021-05-05 12:44:11 +02:00
if ( p_update_shapes ) {
2021-05-04 14:28:27 +02:00
_update_shapes ( ) ;
2021-05-05 12:44:11 +02:00
}
2014-09-19 23:39:50 +02:00
}
2017-03-05 16:44:50 +01:00
_FORCE_INLINE_ void _set_inv_transform ( const Transform & 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 ;
2017-08-11 21:10:05 +02:00
void _set_space ( SpaceSW * p_space ) ;
2014-02-10 02:10:30 +01:00
2014-10-03 05:10:51 +02:00
bool ray_pickable ;
2014-02-10 02:10:30 +01:00
CollisionObjectSW ( Type p_type ) ;
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 ; }
void _shape_changed ( ) ;
_FORCE_INLINE_ Type get_type ( ) const { return type ; }
2019-03-24 10:38:31 +01:00
void add_shape ( ShapeSW * p_shape , const Transform & p_transform = Transform ( ) , bool p_disabled = false ) ;
2017-03-05 16:44:50 +01:00
void set_shape ( int p_index , ShapeSW * p_shape ) ;
void set_shape_transform ( int p_index , const Transform & p_transform ) ;
2014-02-10 02:10:30 +01:00
_FORCE_INLINE_ int get_shape_count ( ) const { return shapes . size ( ) ; }
2021-06-23 01:19:15 +02:00
_FORCE_INLINE_ ShapeSW * 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:19:15 +02:00
return shapes [ p_index ] . shape ;
}
_FORCE_INLINE_ const Transform & get_shape_transform ( int p_index ) const {
CRASH_BAD_INDEX ( p_index , shapes . size ( ) ) ;
return shapes [ p_index ] . xform ;
}
_FORCE_INLINE_ const Transform & 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
_FORCE_INLINE_ Transform get_transform ( ) const { return transform ; }
_FORCE_INLINE_ Transform get_inv_transform ( ) const { return inv_transform ; }
2017-03-05 16:44:50 +01:00
_FORCE_INLINE_ SpaceSW * 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:19:15 +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 11:57:47 +02:00
_FORCE_INLINE_ void set_collision_layer ( uint32_t p_layer ) {
collision_layer = p_layer ;
2021-10-21 21:06:09 +02:00
_recheck_shapes ( ) ;
_shapes_changed ( ) ;
2020-06-27 11:57:47 +02:00
}
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 11:57:47 +02:00
_FORCE_INLINE_ void set_collision_mask ( uint32_t p_mask ) {
collision_mask = p_mask ;
2021-10-21 21:06:09 +02:00
_recheck_shapes ( ) ;
_shapes_changed ( ) ;
2020-06-27 11:57:47 +02:00
}
2016-04-09 20:54:09 +02:00
_FORCE_INLINE_ uint32_t get_collision_mask ( ) const { return collision_mask ; }
2021-12-03 12:36:39 +01:00
_FORCE_INLINE_ bool test_collision_mask ( const CollisionObjectSW * 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
}
2014-02-10 02:10:30 +01:00
void remove_shape ( ShapeSW * p_shape ) ;
void remove_shape ( int p_index ) ;
2017-03-05 16:44:50 +01:00
virtual void set_space ( SpaceSW * 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
virtual ~ CollisionObjectSW ( ) { }
} ;
# endif // COLLISION_OBJECT_SW_H