diff options
author | AndreaCatania <info@andreacatania.com> | 2017-12-10 17:21:14 +0100 |
---|---|---|
committer | AndreaCatania <info@andreacatania.com> | 2017-12-10 17:21:14 +0100 |
commit | 5dee44bbc13605348b65bc74878a5a8be2b50cbd (patch) | |
tree | 18015df53d04b296c58702d5375c5c43cf0eab27 | |
parent | a5b3c9cae010c98ec692bc08463cde25f8f9ac67 (diff) |
Implemented physics linear and angular lock
-rw-r--r-- | modules/bullet/bullet_physics_server.cpp | 8 | ||||
-rw-r--r-- | modules/bullet/bullet_physics_server.h | 4 | ||||
-rw-r--r-- | modules/bullet/rigid_body_bullet.cpp | 41 | ||||
-rw-r--r-- | modules/bullet/rigid_body_bullet.h | 7 | ||||
-rw-r--r-- | scene/3d/physics_body.cpp | 96 | ||||
-rw-r--r-- | scene/3d/physics_body.h | 20 | ||||
-rw-r--r-- | servers/physics/body_sw.cpp | 39 | ||||
-rw-r--r-- | servers/physics/body_sw.h | 6 | ||||
-rw-r--r-- | servers/physics/physics_server_sw.cpp | 8 | ||||
-rw-r--r-- | servers/physics/physics_server_sw.h | 4 | ||||
-rw-r--r-- | servers/physics_server.cpp | 8 | ||||
-rw-r--r-- | servers/physics_server.h | 14 |
12 files changed, 122 insertions, 133 deletions
diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp index 339dccce33..b233edc0d4 100644 --- a/modules/bullet/bullet_physics_server.cpp +++ b/modules/bullet/bullet_physics_server.cpp @@ -723,16 +723,16 @@ void BulletPhysicsServer::body_set_axis_velocity(RID p_body, const Vector3 &p_ax body->set_linear_velocity(v); } -void BulletPhysicsServer::body_set_axis_lock(RID p_body, int axis, bool p_lock) { +void BulletPhysicsServer::body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_lock) { RigidBodyBullet *body = rigid_body_owner.get(p_body); ERR_FAIL_COND(!body); - body->set_axis_lock(axis, p_lock); + body->set_axis_lock(p_axis, p_lock); } -bool BulletPhysicsServer::body_get_axis_lock(RID p_body) const { +bool BulletPhysicsServer::body_is_axis_locked(RID p_body, BodyAxis p_axis) const { const RigidBodyBullet *body = rigid_body_owner.get(p_body); ERR_FAIL_COND_V(!body, 0); - return body->get_axis_lock(); + return body->is_axis_locked(p_axis); } void BulletPhysicsServer::body_add_collision_exception(RID p_body, RID p_body_b) { diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h index ed5acb9041..8a10c87fc6 100644 --- a/modules/bullet/bullet_physics_server.h +++ b/modules/bullet/bullet_physics_server.h @@ -226,8 +226,8 @@ public: virtual void body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse); virtual void body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity); - virtual void body_set_axis_lock(RID p_body, int axis, bool p_lock); - virtual bool body_get_axis_lock(RID p_body) const; + virtual void body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_lock); + virtual bool body_is_axis_locked(RID p_body, BodyAxis p_axis) const; virtual void body_add_collision_exception(RID p_body, RID p_body_b); virtual void body_remove_collision_exception(RID p_body, RID p_body_b); diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp index 843bdab31f..dd2e17c110 100644 --- a/modules/bullet/rigid_body_bullet.cpp +++ b/modules/bullet/rigid_body_bullet.cpp @@ -253,6 +253,7 @@ void RigidBodyBullet::KinematicUtilities::just_delete_shapes(int new_size) { RigidBodyBullet::RigidBodyBullet() : RigidCollisionObjectBullet(CollisionObjectBullet::TYPE_RIGID_BODY), kinematic_utilities(NULL), + locked_axis(0), gravity_scale(1), mass(1), linearDamp(0), @@ -277,7 +278,7 @@ RigidBodyBullet::RigidBodyBullet() : setupBulletCollisionObject(btBody); set_mode(PhysicsServer::BODY_MODE_RIGID); - set_axis_lock(0, locked_axis[0]); + reload_axis_lock(); areasWhereIam.resize(maxAreasWhereIam); for (int i = areasWhereIam.size() - 1; 0 <= i; --i) { @@ -498,25 +499,25 @@ void RigidBodyBullet::set_mode(PhysicsServer::BodyMode p_mode) { switch (p_mode) { case PhysicsServer::BODY_MODE_KINEMATIC: mode = PhysicsServer::BODY_MODE_KINEMATIC; - set_axis_lock(0, locked_axis[0]); // Reload axis lock + reload_axis_lock(); _internal_set_mass(0); init_kinematic_utilities(); break; case PhysicsServer::BODY_MODE_STATIC: mode = PhysicsServer::BODY_MODE_STATIC; - set_axis_lock(0, locked_axis[0]); // Reload axis lock + reload_axis_lock(); _internal_set_mass(0); break; case PhysicsServer::BODY_MODE_RIGID: { mode = PhysicsServer::BODY_MODE_RIGID; - set_axis_lock(0, locked_axis[0]); // Reload axis lock + reload_axis_lock(); _internal_set_mass(0 == mass ? 1 : mass); scratch_space_override_modificator(); break; } case PhysicsServer::BODY_MODE_CHARACTER: { mode = PhysicsServer::BODY_MODE_CHARACTER; - set_axis_lock(0, locked_axis[0]); // Reload axis lock + reload_axis_lock(); _internal_set_mass(0 == mass ? 1 : mass); scratch_space_override_modificator(); break; @@ -655,25 +656,31 @@ Vector3 RigidBodyBullet::get_applied_torque() const { return gTotTorq; } -void RigidBodyBullet::set_axis_lock(int axis, bool p_lock) { - locked_axis[axis] = p_lock; +void RigidBodyBullet::set_axis_lock(PhysicsServer::BodyAxis p_axis, bool lock) { + if (lock) { + locked_axis |= p_axis; + } else { + locked_axis &= ~p_axis; + } - btBody->setLinearFactor(btVector3(locked_axis[0] ? 0 : 1., locked_axis[1] ? 0 : 1., locked_axis[2] ? 0 : 1.)); - if (locked_axis[0] || locked_axis[1] || locked_axis[2]) - btBody->setAngularFactor(btVector3(locked_axis[0] ? 1. : 0, locked_axis[1] ? 1. : 0, locked_axis[2] ? 1. : 0)); - else - btBody->setAngularFactor(btVector3(1., 1., 1.)); + reload_axis_lock(); +} + +bool RigidBodyBullet::is_axis_locked(PhysicsServer::BodyAxis p_axis) const { + return locked_axis & p_axis; +} +void RigidBodyBullet::reload_axis_lock() { + + btBody->setLinearFactor(btVector3(!is_axis_locked(PhysicsServer::BODY_AXIS_LINEAR_X), !is_axis_locked(PhysicsServer::BODY_AXIS_LINEAR_Y), !is_axis_locked(PhysicsServer::BODY_AXIS_LINEAR_Z))); if (PhysicsServer::BODY_MODE_CHARACTER == mode) { - /// When character lock angular + /// When character angular is always locked btBody->setAngularFactor(btVector3(0., 0., 0.)); + } else { + btBody->setAngularFactor(btVector3(!is_axis_locked(PhysicsServer::BODY_AXIS_ANGULAR_X), !is_axis_locked(PhysicsServer::BODY_AXIS_ANGULAR_Y), !is_axis_locked(PhysicsServer::BODY_AXIS_ANGULAR_Z))); } } -bool RigidBodyBullet::get_axis_lock() const { - return locked_axis; -} - void RigidBodyBullet::set_continuous_collision_detection(bool p_enable) { if (p_enable) { // This threshold enable CCD if the object moves more than diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h index fde8b21e17..c0eb148e24 100644 --- a/modules/bullet/rigid_body_bullet.h +++ b/modules/bullet/rigid_body_bullet.h @@ -184,9 +184,9 @@ private: KinematicUtilities *kinematic_utilities; PhysicsServer::BodyMode mode; - bool locked_axis[3] = { false, false, false }; GodotMotionState *godotMotionState; btRigidBody *btBody; + uint16_t locked_axis; real_t mass; real_t gravity_scale; real_t linearDamp; @@ -269,8 +269,9 @@ public: void set_applied_torque(const Vector3 &p_torque); Vector3 get_applied_torque() const; - void set_axis_lock(int axis, bool p_lock); - bool get_axis_lock() const; + void set_axis_lock(PhysicsServer::BodyAxis p_axis, bool lock); + bool is_axis_locked(PhysicsServer::BodyAxis p_axis) const; + void reload_axis_lock(); /// Doc: /// http://www.bulletphysics.org/mediawiki-1.5.8/index.php?title=Anti_tunneling_by_Motion_Clamping diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp index 8c9f59e267..0b7c2fbe81 100644 --- a/scene/3d/physics_body.cpp +++ b/scene/3d/physics_body.cpp @@ -734,31 +734,12 @@ bool RigidBody::is_contact_monitor_enabled() const { return contact_monitor != NULL; } -void RigidBody::set_axis_lock_x(bool p_lock) { - RigidBody::locked_axis[0] = p_lock; - PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 0, locked_axis[0]); +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); } -void RigidBody::set_axis_lock_y(bool p_lock) { - RigidBody::locked_axis[1] = p_lock; - PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 1, locked_axis[1]); -} - -void RigidBody::set_axis_lock_z(bool p_lock) { - RigidBody::locked_axis[2] = p_lock; - PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 2, locked_axis[2]); -} - -bool RigidBody::get_axis_lock_x() const { - return RigidBody::locked_axis[0]; -} - -bool RigidBody::get_axis_lock_y() const { - return RigidBody::locked_axis[1]; -} - -bool RigidBody::get_axis_lock_z() const { - return RigidBody::locked_axis[2]; +bool RigidBody::get_axis_lock(PhysicsServer::BodyAxis p_axis) const { + return PhysicsServer::get_singleton()->body_is_axis_locked(get_rid(), p_axis); } Array RigidBody::get_colliding_bodies() const { @@ -853,12 +834,8 @@ void RigidBody::_bind_methods() { ClassDB::bind_method(D_METHOD("_body_enter_tree"), &RigidBody::_body_enter_tree); ClassDB::bind_method(D_METHOD("_body_exit_tree"), &RigidBody::_body_exit_tree); - ClassDB::bind_method(D_METHOD("set_axis_lock_x", "axis_lock_x"), &RigidBody::set_axis_lock_x); - ClassDB::bind_method(D_METHOD("set_axis_lock_y", "axis_lock_y"), &RigidBody::set_axis_lock_y); - ClassDB::bind_method(D_METHOD("set_axis_lock_z", "axis_lock_z"), &RigidBody::set_axis_lock_z); - ClassDB::bind_method(D_METHOD("get_axis_lock_x"), &RigidBody::get_axis_lock_x); - ClassDB::bind_method(D_METHOD("get_axis_lock_y"), &RigidBody::get_axis_lock_y); - ClassDB::bind_method(D_METHOD("get_axis_lock_z"), &RigidBody::get_axis_lock_z); + 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); ClassDB::bind_method(D_METHOD("get_colliding_bodies"), &RigidBody::get_colliding_bodies); @@ -877,9 +854,12 @@ void RigidBody::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sleeping"), "set_sleeping", "is_sleeping"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep"); ADD_GROUP("Axis Lock", "axis_lock_"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_x"), "set_axis_lock_x", "get_axis_lock_x"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_y"), "set_axis_lock_y", "get_axis_lock_y"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_z"), "set_axis_lock_z", "get_axis_lock_z"); + 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); ADD_GROUP("Linear", "linear_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "-1,128,0.01"), "set_linear_damp", "get_linear_damp"); @@ -969,7 +949,7 @@ bool KinematicBody::move_and_collide(const Vector3 &p_motion, Collision &r_colli } for (int i = 0; i < 3; i++) { - if (locked_axis[i]) { + if (locked_axis & (1 << i)) { result.motion[i] = 0; } } @@ -985,7 +965,7 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve Vector3 lv = p_linear_velocity; for (int i = 0; i < 3; i++) { - if (locked_axis[i]) { + if (locked_axis & (1 << i)) { lv[i] = 0; } } @@ -1038,7 +1018,7 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve lv = lv.slide(n); for (int i = 0; i < 3; i++) { - if (locked_axis[i]) { + if (locked_axis & (1 << i)) { lv[i] = 0; } } @@ -1082,31 +1062,12 @@ bool KinematicBody::test_move(const Transform &p_from, const Vector3 &p_motion) return PhysicsServer::get_singleton()->body_test_motion(get_rid(), p_from, p_motion); } -void KinematicBody::set_axis_lock_x(bool p_lock) { - KinematicBody::locked_axis[0] = p_lock; - PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 0, locked_axis[0]); +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); } -void KinematicBody::set_axis_lock_y(bool p_lock) { - KinematicBody::locked_axis[1] = p_lock; - PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 1, locked_axis[1]); -} - -void KinematicBody::set_axis_lock_z(bool p_lock) { - KinematicBody::locked_axis[2] = p_lock; - PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 2, locked_axis[2]); -} - -bool KinematicBody::get_axis_lock_x() const { - return KinematicBody::locked_axis[0]; -} - -bool KinematicBody::get_axis_lock_y() const { - return KinematicBody::locked_axis[1]; -} - -bool KinematicBody::get_axis_lock_z() const { - return KinematicBody::locked_axis[2]; +bool KinematicBody::get_axis_lock(PhysicsServer::BodyAxis p_axis) const { + return PhysicsServer::get_singleton()->body_is_axis_locked(get_rid(), p_axis); } void KinematicBody::set_safe_margin(float p_margin) { @@ -1157,12 +1118,8 @@ void KinematicBody::_bind_methods() { ClassDB::bind_method(D_METHOD("is_on_wall"), &KinematicBody::is_on_wall); ClassDB::bind_method(D_METHOD("get_floor_velocity"), &KinematicBody::get_floor_velocity); - ClassDB::bind_method(D_METHOD("set_axis_lock_x", "axis_lock_x"), &KinematicBody::set_axis_lock_x); - ClassDB::bind_method(D_METHOD("set_axis_lock_y", "axis_lock_y"), &KinematicBody::set_axis_lock_y); - ClassDB::bind_method(D_METHOD("set_axis_lock_z", "axis_lock_z"), &KinematicBody::set_axis_lock_z); - ClassDB::bind_method(D_METHOD("get_axis_lock_x"), &KinematicBody::get_axis_lock_x); - ClassDB::bind_method(D_METHOD("get_axis_lock_y"), &KinematicBody::get_axis_lock_y); - ClassDB::bind_method(D_METHOD("get_axis_lock_z"), &KinematicBody::get_axis_lock_z); + 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); ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody::set_safe_margin); ClassDB::bind_method(D_METHOD("get_safe_margin"), &KinematicBody::get_safe_margin); @@ -1171,9 +1128,12 @@ void KinematicBody::_bind_methods() { ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody::_get_slide_collision); ADD_GROUP("Axis Lock", "axis_lock_"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_x"), "set_axis_lock_x", "get_axis_lock_x"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_y"), "set_axis_lock_y", "get_axis_lock_y"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_z"), "set_axis_lock_z", "get_axis_lock_z"); + 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); ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin"); } @@ -1182,7 +1142,7 @@ KinematicBody::KinematicBody() : PhysicsBody(PhysicsServer::BODY_MODE_KINEMATIC) { margin = 0.001; - + locked_axis = 0; on_floor = false; on_ceiling = false; on_wall = false; diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h index 57b120ef63..9d9feda0b2 100644 --- a/scene/3d/physics_body.h +++ b/scene/3d/physics_body.h @@ -132,8 +132,6 @@ private: bool sleeping; bool ccd; - bool locked_axis[3] = { false, false, false }; - int max_contacts_reported; bool custom_integrator; @@ -238,12 +236,8 @@ public: void set_use_continuous_collision_detection(bool p_enable); bool is_using_continuous_collision_detection() const; - void set_axis_lock_x(bool p_lock); - void set_axis_lock_y(bool p_lock); - void set_axis_lock_z(bool p_lock); - bool get_axis_lock_x() const; - bool get_axis_lock_y() const; - bool get_axis_lock_z() const; + void set_axis_lock(PhysicsServer::BodyAxis p_axis, bool p_lock); + bool get_axis_lock(PhysicsServer::BodyAxis p_axis) const; Array get_colliding_bodies() const; @@ -277,7 +271,7 @@ public: }; private: - bool locked_axis[3] = { false, false, false }; + uint16_t locked_axis; float margin; @@ -301,12 +295,8 @@ public: bool move_and_collide(const Vector3 &p_motion, Collision &r_collision); bool test_move(const Transform &p_from, const Vector3 &p_motion); - void set_axis_lock_x(bool p_lock); - void set_axis_lock_y(bool p_lock); - void set_axis_lock_z(bool p_lock); - bool get_axis_lock_x() const; - bool get_axis_lock_y() const; - bool get_axis_lock_z() const; + void set_axis_lock(PhysicsServer::BodyAxis p_axis, bool p_lock); + bool get_axis_lock(PhysicsServer::BodyAxis p_axis) const; void set_safe_margin(float p_margin); float get_safe_margin() const; diff --git a/servers/physics/body_sw.cpp b/servers/physics/body_sw.cpp index bba4d7a147..7fa7f0a45d 100644 --- a/servers/physics/body_sw.cpp +++ b/servers/physics/body_sw.cpp @@ -422,6 +422,18 @@ void BodySW::_compute_area_gravity_and_dampenings(const AreaSW *p_area) { area_angular_damp += p_area->get_angular_damp(); } +void BodySW::set_axis_lock(PhysicsServer::BodyAxis p_axis, bool lock) { + if (lock) { + locked_axis |= p_axis; + } else { + locked_axis &= ~p_axis; + } +} + +bool BodySW::is_axis_locked(PhysicsServer::BodyAxis p_axis) const { + return locked_axis & p_axis; +} + void BodySW::integrate_forces(real_t p_step) { if (mode == PhysicsServer::BODY_MODE_STATIC) @@ -559,17 +571,19 @@ void BodySW::integrate_velocities(real_t p_step) { if (fi_callback) get_space()->body_add_to_state_query_list(&direct_state_query_list); - //apply axis lock - if (locked_axis[0] || locked_axis[1] || locked_axis[2]) { - for (int i = 0; i < 3; i++) { - if (locked_axis[i]) { - linear_velocity[i] = 0; - biased_linear_velocity[i] = 0; - new_transform.origin[i] = get_transform().origin[i]; - } else { - angular_velocity[i] = 0; - biased_angular_velocity[i] = 0; - } + //apply axis lock linear + for (int i = 0; i < 3; i++) { + if (is_axis_locked((PhysicsServer::BodyAxis)(1 << i))) { + linear_velocity[i] = 0; + biased_linear_velocity[i] = 0; + new_transform.origin[i] = get_transform().origin[i]; + } + } + //apply axis lock angular + for (int i = 0; i < 3; i++) { + if (is_axis_locked((PhysicsServer::BodyAxis)(1 << (i + 3)))) { + angular_velocity[i] = 0; + biased_angular_velocity[i] = 0; } } @@ -742,7 +756,8 @@ BodySW::BodySW() : CollisionObjectSW(TYPE_BODY), active_list(this), inertia_update_list(this), - direct_state_query_list(this) { + direct_state_query_list(this), + locked_axis(0) { mode = PhysicsServer::BODY_MODE_RIGID; active = true; diff --git a/servers/physics/body_sw.h b/servers/physics/body_sw.h index aab6def1a9..b6aa76c70a 100644 --- a/servers/physics/body_sw.h +++ b/servers/physics/body_sw.h @@ -53,7 +53,7 @@ class BodySW : public CollisionObjectSW { real_t angular_damp; real_t gravity_scale; - bool locked_axis[3] = { false, false, false }; + uint16_t locked_axis; real_t kinematic_safe_margin; real_t _inv_mass; @@ -288,8 +288,8 @@ public: _FORCE_INLINE_ Vector3 get_gravity() const { return gravity; } _FORCE_INLINE_ real_t get_bounce() const { return bounce; } - _FORCE_INLINE_ void set_axis_lock(int axis, bool lock) { locked_axis[axis] = lock; } - _FORCE_INLINE_ bool get_axis_lock() const { return locked_axis; } + void set_axis_lock(PhysicsServer::BodyAxis p_axis, bool lock); + bool is_axis_locked(PhysicsServer::BodyAxis p_axis) const; void integrate_forces(real_t p_step); void integrate_velocities(real_t p_step); diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp index 2909308366..0a1d524839 100644 --- a/servers/physics/physics_server_sw.cpp +++ b/servers/physics/physics_server_sw.cpp @@ -794,20 +794,20 @@ void PhysicsServerSW::body_set_axis_velocity(RID p_body, const Vector3 &p_axis_v body->wakeup(); }; -void PhysicsServerSW::body_set_axis_lock(RID p_body, int axis, bool lock) { +void PhysicsServerSW::body_set_axis_lock(RID p_body, BodyAxis p_axis, bool lock) { BodySW *body = body_owner.get(p_body); ERR_FAIL_COND(!body); - body->set_axis_lock(axis, lock); + body->set_axis_lock(p_axis, lock); body->wakeup(); } -bool PhysicsServerSW::body_get_axis_lock(RID p_body) const { +bool PhysicsServerSW::body_is_axis_locked(RID p_body, BodyAxis p_axis) const { const BodySW *body = body_owner.get(p_body); ERR_FAIL_COND_V(!body, 0); - return body->get_axis_lock(); + return body->is_axis_locked(p_axis); } void PhysicsServerSW::body_add_collision_exception(RID p_body, RID p_body_b) { diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h index fea6e34ebd..71547f24c8 100644 --- a/servers/physics/physics_server_sw.h +++ b/servers/physics/physics_server_sw.h @@ -203,8 +203,8 @@ public: virtual void body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse); virtual void body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity); - virtual void body_set_axis_lock(RID p_body, int axis, bool p_lock); - virtual bool body_get_axis_lock(RID p_body) const; + virtual void body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_lock); + virtual bool body_is_axis_locked(RID p_body, BodyAxis p_axis) const; virtual void body_add_collision_exception(RID p_body, RID p_body_b); virtual void body_remove_collision_exception(RID p_body, RID p_body_b); diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp index 9a9b20bf28..2aef12f04c 100644 --- a/servers/physics_server.cpp +++ b/servers/physics_server.cpp @@ -473,7 +473,7 @@ void PhysicsServer::_bind_methods() { ClassDB::bind_method(D_METHOD("body_set_axis_velocity", "body", "axis_velocity"), &PhysicsServer::body_set_axis_velocity); ClassDB::bind_method(D_METHOD("body_set_axis_lock", "body", "axis", "lock"), &PhysicsServer::body_set_axis_lock); - ClassDB::bind_method(D_METHOD("body_get_axis_lock", "body"), &PhysicsServer::body_get_axis_lock); + ClassDB::bind_method(D_METHOD("body_is_axis_locked", "body", "axis"), &PhysicsServer::body_is_axis_locked); ClassDB::bind_method(D_METHOD("body_add_collision_exception", "body", "excepted_body"), &PhysicsServer::body_add_collision_exception); ClassDB::bind_method(D_METHOD("body_remove_collision_exception", "body", "excepted_body"), &PhysicsServer::body_remove_collision_exception); @@ -702,6 +702,12 @@ void PhysicsServer::_bind_methods() { BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_TIME_TO_SLEEP); BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO); BIND_ENUM_CONSTANT(SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS); + BIND_ENUM_CONSTANT(BODY_AXIS_LINEAR_X); + BIND_ENUM_CONSTANT(BODY_AXIS_LINEAR_Y); + BIND_ENUM_CONSTANT(BODY_AXIS_LINEAR_Z); + BIND_ENUM_CONSTANT(BODY_AXIS_ANGULAR_X); + BIND_ENUM_CONSTANT(BODY_AXIS_ANGULAR_Y); + BIND_ENUM_CONSTANT(BODY_AXIS_ANGULAR_Z); } PhysicsServer::PhysicsServer() { diff --git a/servers/physics_server.h b/servers/physics_server.h index 66c3a0afc4..341d02eb87 100644 --- a/servers/physics_server.h +++ b/servers/physics_server.h @@ -421,8 +421,17 @@ public: virtual void body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse) = 0; virtual void body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity) = 0; - virtual void body_set_axis_lock(RID p_body, int axis, bool lock) = 0; - virtual bool body_get_axis_lock(RID p_body) const = 0; + enum BodyAxis { + BODY_AXIS_LINEAR_X = 1 << 0, + BODY_AXIS_LINEAR_Y = 1 << 1, + BODY_AXIS_LINEAR_Z = 1 << 2, + BODY_AXIS_ANGULAR_X = 1 << 3, + BODY_AXIS_ANGULAR_Y = 1 << 4, + BODY_AXIS_ANGULAR_Z = 1 << 5 + }; + + virtual void body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_lock) = 0; + virtual bool body_is_axis_locked(RID p_body, BodyAxis p_axis) const = 0; //fix virtual void body_add_collision_exception(RID p_body, RID p_body_b) = 0; @@ -685,6 +694,7 @@ VARIANT_ENUM_CAST(PhysicsServer::AreaSpaceOverrideMode); VARIANT_ENUM_CAST(PhysicsServer::BodyMode); VARIANT_ENUM_CAST(PhysicsServer::BodyParameter); VARIANT_ENUM_CAST(PhysicsServer::BodyState); +VARIANT_ENUM_CAST(PhysicsServer::BodyAxis); VARIANT_ENUM_CAST(PhysicsServer::PinJointParam); VARIANT_ENUM_CAST(PhysicsServer::JointType); VARIANT_ENUM_CAST(PhysicsServer::HingeJointParam); |