diff options
Diffstat (limited to 'scene/3d/physics_body.cpp')
-rw-r--r-- | scene/3d/physics_body.cpp | 88 |
1 files changed, 61 insertions, 27 deletions
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp index 4e06b272e2..c5f817d317 100644 --- a/scene/3d/physics_body.cpp +++ b/scene/3d/physics_body.cpp @@ -166,8 +166,8 @@ void PhysicsBody::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); } -PhysicsBody::PhysicsBody(PhysicsServer::BodyMode p_mode) - : CollisionObject(PhysicsServer::get_singleton()->body_create(p_mode), false) { +PhysicsBody::PhysicsBody(PhysicsServer::BodyMode p_mode) : + CollisionObject(PhysicsServer::get_singleton()->body_create(p_mode), false) { collision_layer = 1; collision_mask = 1; @@ -241,8 +241,8 @@ void StaticBody::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_angular_velocity"), "set_constant_angular_velocity", "get_constant_angular_velocity"); } -StaticBody::StaticBody() - : PhysicsBody(PhysicsServer::BODY_MODE_STATIC) { +StaticBody::StaticBody() : + PhysicsBody(PhysicsServer::BODY_MODE_STATIC) { bounce = 0; friction = 1; @@ -734,15 +734,12 @@ bool RigidBody::is_contact_monitor_enabled() const { return contact_monitor != NULL; } -void RigidBody::set_axis_lock(AxisLock p_lock) { - - axis_lock = p_lock; - PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), PhysicsServer::BodyAxisLock(axis_lock)); +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); } -RigidBody::AxisLock RigidBody::get_axis_lock() const { - - return axis_lock; +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 { @@ -837,8 +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", "axis_lock"), &RigidBody::set_axis_lock); - ClassDB::bind_method(D_METHOD("get_axis_lock"), &RigidBody::get_axis_lock); + 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); @@ -856,7 +853,13 @@ void RigidBody::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "contact_monitor"), "set_contact_monitor", "is_contact_monitor_enabled"); 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_PROPERTY(PropertyInfo(Variant::INT, "axis_lock", PROPERTY_HINT_ENUM, "Disabled,Lock X,Lock Y,Lock Z"), "set_axis_lock", "get_axis_lock"); + ADD_GROUP("Axis Lock", "axis_lock_"); + 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"); @@ -874,15 +877,10 @@ void RigidBody::_bind_methods() { BIND_ENUM_CONSTANT(MODE_STATIC); BIND_ENUM_CONSTANT(MODE_CHARACTER); BIND_ENUM_CONSTANT(MODE_KINEMATIC); - - BIND_ENUM_CONSTANT(AXIS_LOCK_DISABLED); - BIND_ENUM_CONSTANT(AXIS_LOCK_X); - BIND_ENUM_CONSTANT(AXIS_LOCK_Y); - BIND_ENUM_CONSTANT(AXIS_LOCK_Z); } -RigidBody::RigidBody() - : PhysicsBody(PhysicsServer::BODY_MODE_RIGID) { +RigidBody::RigidBody() : + PhysicsBody(PhysicsServer::BODY_MODE_RIGID) { mode = MODE_RIGID; @@ -904,8 +902,6 @@ RigidBody::RigidBody() contact_monitor = NULL; can_sleep = true; - axis_lock = AXIS_LOCK_DISABLED; - PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed"); } @@ -952,6 +948,12 @@ bool KinematicBody::move_and_collide(const Vector3 &p_motion, Collision &r_colli r_collision.local_shape = result.collision_local_shape; } + for (int i = 0; i < 3; i++) { + if (locked_axis & (1 << i)) { + result.motion[i] = 0; + } + } + gt.origin += result.motion; set_global_transform(gt); @@ -960,9 +962,16 @@ bool KinematicBody::move_and_collide(const Vector3 &p_motion, Collision &r_colli Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle) { - Vector3 motion = (floor_velocity + p_linear_velocity) * get_physics_process_delta_time(); Vector3 lv = p_linear_velocity; + for (int i = 0; i < 3; i++) { + if (locked_axis & (1 << i)) { + lv[i] = 0; + } + } + + Vector3 motion = (floor_velocity + lv) * get_physics_process_delta_time(); + on_floor = false; on_ceiling = false; on_wall = false; @@ -1008,6 +1017,12 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve motion = motion.slide(n); lv = lv.slide(n); + for (int i = 0; i < 3; i++) { + if (locked_axis & (1 << i)) { + lv[i] = 0; + } + } + colliders.push_back(collision); } else { @@ -1047,6 +1062,14 @@ 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(PhysicsServer::BodyAxis p_axis, bool p_lock) { + PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock); +} + +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) { margin = p_margin; @@ -1095,20 +1118,31 @@ 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", "axis", "lock"), &KinematicBody::set_axis_lock); + ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &KinematicBody::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); ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody::get_slide_count); ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody::_get_slide_collision); + ADD_GROUP("Axis Lock", "axis_lock_"); + 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"); } -KinematicBody::KinematicBody() - : PhysicsBody(PhysicsServer::BODY_MODE_KINEMATIC) { +KinematicBody::KinematicBody() : + PhysicsBody(PhysicsServer::BODY_MODE_KINEMATIC) { margin = 0.001; - + locked_axis = 0; on_floor = false; on_ceiling = false; on_wall = false; |