1 /*************************************************************************/ 2 /* physics_body_2d.h */ 3 /*************************************************************************/ 4 /* This file is part of: */ 5 /* GODOT ENGINE */ 6 /* https://godotengine.org */ 7 /*************************************************************************/ 8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ 9 /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ 10 /* */ 11 /* Permission is hereby granted, free of charge, to any person obtaining */ 12 /* a copy of this software and associated documentation files (the */ 13 /* "Software"), to deal in the Software without restriction, including */ 14 /* without limitation the rights to use, copy, modify, merge, publish, */ 15 /* distribute, sublicense, and/or sell copies of the Software, and to */ 16 /* permit persons to whom the Software is furnished to do so, subject to */ 17 /* the following conditions: */ 18 /* */ 19 /* The above copyright notice and this permission notice shall be */ 20 /* included in all copies or substantial portions of the Software. */ 21 /* */ 22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 29 /*************************************************************************/ 30 #ifndef PHYSICS_BODY_2D_H 31 #define PHYSICS_BODY_2D_H 32 33 #include "scene/2d/collision_object_2d.h" 34 #include "servers/physics_2d_server.h" 35 #include "vset.h" 36 37 class PhysicsBody2D : public CollisionObject2D { 38 39 OBJ_TYPE(PhysicsBody2D, CollisionObject2D); 40 41 uint32_t mask; 42 uint32_t collision_mask; 43 Vector2 one_way_collision_direction; 44 float one_way_collision_max_depth; 45 46 void _set_layers(uint32_t p_mask); 47 uint32_t _get_layers() const; 48 49 protected: 50 // So this flag can be set at startup and cached for every body 51 friend void register_scene_types(); 52 static bool motion_fix_enabled; 53 54 void _notification(int p_what); 55 PhysicsBody2D(Physics2DServer::BodyMode p_mode); 56 57 static void _bind_methods(); 58 59 public: 60 void set_layer_mask(uint32_t p_mask); 61 uint32_t get_layer_mask() const; 62 63 void set_collision_mask(uint32_t p_mask); 64 uint32_t get_collision_mask() const; 65 66 void set_collision_mask_bit(int p_bit, bool p_value); 67 bool get_collision_mask_bit(int p_bit) const; 68 69 void set_layer_mask_bit(int p_bit, bool p_value); 70 bool get_layer_mask_bit(int p_bit) const; 71 72 void add_collision_exception_with(Node *p_node); //must be physicsbody 73 void remove_collision_exception_with(Node *p_node); 74 75 void set_one_way_collision_direction(const Vector2 &p_dir); 76 Vector2 get_one_way_collision_direction() const; 77 78 void set_one_way_collision_max_depth(float p_dir); 79 float get_one_way_collision_max_depth() const; 80 81 PhysicsBody2D(); 82 }; 83 84 class StaticBody2D : public PhysicsBody2D { 85 86 OBJ_TYPE(StaticBody2D, PhysicsBody2D); 87 88 Vector2 constant_linear_velocity; 89 real_t constant_angular_velocity; 90 91 real_t bounce; 92 real_t friction; 93 94 protected: 95 static void _bind_methods(); 96 97 public: 98 void set_friction(real_t p_friction); 99 real_t get_friction() const; 100 101 void set_bounce(real_t p_bounce); 102 real_t get_bounce() const; 103 104 void set_constant_linear_velocity(const Vector2 &p_vel); 105 void set_constant_angular_velocity(real_t p_vel); 106 107 Vector2 get_constant_linear_velocity() const; 108 real_t get_constant_angular_velocity() const; 109 110 StaticBody2D(); 111 ~StaticBody2D(); 112 }; 113 114 class RigidBody2D : public PhysicsBody2D { 115 116 OBJ_TYPE(RigidBody2D, PhysicsBody2D); 117 118 public: 119 enum Mode { 120 MODE_RIGID, 121 MODE_STATIC, 122 MODE_CHARACTER, 123 MODE_KINEMATIC, 124 }; 125 126 enum CCDMode { 127 CCD_MODE_DISABLED, 128 CCD_MODE_CAST_RAY, 129 CCD_MODE_CAST_SHAPE, 130 }; 131 132 private: 133 bool can_sleep; 134 Physics2DDirectBodyState *state; 135 Mode mode; 136 137 real_t bounce; 138 real_t mass; 139 real_t friction; 140 real_t gravity_scale; 141 real_t linear_damp; 142 real_t angular_damp; 143 144 Vector2 linear_velocity; 145 real_t angular_velocity; 146 bool sleeping; 147 148 int max_contacts_reported; 149 150 bool custom_integrator; 151 152 CCDMode ccd_mode; 153 154 struct ShapePair { 155 156 int body_shape; 157 int local_shape; 158 bool tagged; 159 bool operator<(const ShapePair &p_sp) const { 160 if (body_shape == p_sp.body_shape) 161 return local_shape < p_sp.local_shape; 162 else 163 return body_shape < p_sp.body_shape; 164 } 165 ShapePairShapePair166 ShapePair() {} ShapePairShapePair167 ShapePair(int p_bs, int p_ls) { 168 body_shape = p_bs; 169 local_shape = p_ls; 170 } 171 }; 172 struct RigidBody2D_RemoveAction { 173 174 ObjectID body_id; 175 ShapePair pair; 176 }; 177 struct BodyState { 178 179 //int rc; 180 bool in_scene; 181 VSet<ShapePair> shapes; 182 }; 183 184 struct ContactMonitor { 185 186 bool locked; 187 Map<ObjectID, BodyState> body_map; 188 }; 189 190 ContactMonitor *contact_monitor; 191 void _body_enter_tree(ObjectID p_id); 192 void _body_exit_tree(ObjectID p_id); 193 194 void _body_inout(int p_status, ObjectID p_instance, int p_body_shape, int p_local_shape); 195 void _direct_state_changed(Object *p_state); 196 197 bool _test_motion(const Vector2 &p_motion, float p_margin = 0.08, const Ref<Physics2DTestMotionResult> &p_result = Ref<Physics2DTestMotionResult>()); 198 199 protected: 200 void _notification(int p_what); 201 static void _bind_methods(); 202 203 public: 204 void set_mode(Mode p_mode); 205 Mode get_mode() const; 206 207 void set_mass(real_t p_mass); 208 real_t get_mass() const; 209 210 void set_inertia(real_t p_inertia); 211 real_t get_inertia() const; 212 213 void set_weight(real_t p_weight); 214 real_t get_weight() const; 215 216 void set_friction(real_t p_friction); 217 real_t get_friction() const; 218 219 void set_bounce(real_t p_bounce); 220 real_t get_bounce() const; 221 222 void set_gravity_scale(real_t p_gravity_scale); 223 real_t get_gravity_scale() const; 224 225 void set_linear_damp(real_t p_linear_damp); 226 real_t get_linear_damp() const; 227 228 void set_angular_damp(real_t p_angular_damp); 229 real_t get_angular_damp() const; 230 231 void set_linear_velocity(const Vector2 &p_velocity); 232 Vector2 get_linear_velocity() const; 233 234 void set_axis_velocity(const Vector2 &p_axis); 235 236 void set_angular_velocity(real_t p_velocity); 237 real_t get_angular_velocity() const; 238 239 void set_use_custom_integrator(bool p_enable); 240 bool is_using_custom_integrator(); 241 242 void set_sleeping(bool p_sleeping); 243 bool is_sleeping() const; 244 245 void set_can_sleep(bool p_active); 246 bool is_able_to_sleep() const; 247 248 void set_contact_monitor(bool p_enabled); 249 bool is_contact_monitor_enabled() const; 250 251 void set_max_contacts_reported(int p_amount); 252 int get_max_contacts_reported() const; 253 254 void set_continuous_collision_detection_mode(CCDMode p_mode); 255 CCDMode get_continuous_collision_detection_mode() const; 256 257 void apply_impulse(const Vector2 &p_offset, const Vector2 &p_impulse); 258 259 void set_applied_force(const Vector2 &p_force); 260 Vector2 get_applied_force() const; 261 262 void set_applied_torque(const float p_torque); 263 float get_applied_torque() const; 264 265 void add_force(const Vector2 &p_offset, const Vector2 &p_force); 266 267 Array get_colliding_bodies() const; //function for script 268 269 virtual String get_configuration_warning() const; 270 271 RigidBody2D(); 272 ~RigidBody2D(); 273 }; 274 275 VARIANT_ENUM_CAST(RigidBody2D::Mode); 276 VARIANT_ENUM_CAST(RigidBody2D::CCDMode); 277 278 class KinematicBody2D : public PhysicsBody2D { 279 280 OBJ_TYPE(KinematicBody2D, PhysicsBody2D); 281 282 float margin; 283 bool colliding; 284 Vector2 collision; 285 Vector2 normal; 286 Vector2 collider_vel; 287 ObjectID collider; 288 int collider_shape; 289 Variant collider_metadata; 290 Vector2 travel; 291 292 Vector2 move_and_slide_floor_velocity; 293 bool move_and_slide_on_floor; 294 bool move_and_slide_on_ceiling; 295 bool move_and_slide_on_wall; 296 Array move_and_slide_colliders; 297 298 Variant _get_collider() const; 299 300 _FORCE_INLINE_ bool _ignores_mode(Physics2DServer::BodyMode) const; 301 302 protected: 303 static void _bind_methods(); 304 305 public: 306 Vector2 move(const Vector2 &p_motion); 307 Vector2 move_to(const Vector2 &p_position); 308 309 bool test_move(const Vector2 &p_motion); 310 bool test_move_from(const Matrix32 &p_from, const Vector2 &p_motion); 311 bool is_colliding() const; 312 313 Vector2 get_travel() const; 314 void revert_motion(); 315 316 Vector2 get_collision_pos() const; 317 Vector2 get_collision_normal() const; 318 Vector2 get_collider_velocity() const; 319 ObjectID get_collider() const; 320 int get_collider_shape() const; 321 Variant get_collider_metadata() const; 322 323 void set_collision_margin(float p_margin); 324 float get_collision_margin() const; 325 326 Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction = Vector2(0, 0), float p_slope_stop_min_velocity = 5, int p_max_bounces = 4, float p_floor_max_angle = Math::deg2rad((float)45)); 327 bool is_move_and_slide_on_floor() const; 328 bool is_move_and_slide_on_wall() const; 329 bool is_move_and_slide_on_ceiling() const; 330 Array get_move_and_slide_colliders() const; 331 332 KinematicBody2D(); 333 ~KinematicBody2D(); 334 }; 335 336 #endif // PHYSICS_BODY_2D_H 337