diff options
Diffstat (limited to 'scene/3d/physics_body_3d.cpp')
-rw-r--r-- | scene/3d/physics_body_3d.cpp | 547 |
1 files changed, 286 insertions, 261 deletions
diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index 37981f914c..de8f1eea2e 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -45,72 +45,64 @@ #endif Vector3 PhysicsBody3D::get_linear_velocity() const { - return Vector3(); } -Vector3 PhysicsBody3D::get_angular_velocity() const { +Vector3 PhysicsBody3D::get_angular_velocity() const { return Vector3(); } float PhysicsBody3D::get_inverse_mass() const { - return 0; } void PhysicsBody3D::set_collision_layer(uint32_t p_layer) { - collision_layer = p_layer; PhysicsServer3D::get_singleton()->body_set_collision_layer(get_rid(), p_layer); } uint32_t PhysicsBody3D::get_collision_layer() const { - return collision_layer; } void PhysicsBody3D::set_collision_mask(uint32_t p_mask) { - collision_mask = p_mask; PhysicsServer3D::get_singleton()->body_set_collision_mask(get_rid(), p_mask); } uint32_t PhysicsBody3D::get_collision_mask() const { - return collision_mask; } void PhysicsBody3D::set_collision_mask_bit(int p_bit, bool p_value) { - uint32_t mask = get_collision_mask(); - if (p_value) + if (p_value) { mask |= 1 << p_bit; - else + } else { mask &= ~(1 << p_bit); + } set_collision_mask(mask); } bool PhysicsBody3D::get_collision_mask_bit(int p_bit) const { - return get_collision_mask() & (1 << p_bit); } void PhysicsBody3D::set_collision_layer_bit(int p_bit, bool p_value) { - uint32_t mask = get_collision_layer(); - if (p_value) + if (p_value) { mask |= 1 << p_bit; - else + } else { mask &= ~(1 << p_bit); + } set_collision_layer(mask); } bool PhysicsBody3D::get_collision_layer_bit(int p_bit) const { - return get_collision_layer() & (1 << p_bit); } -Array PhysicsBody3D::get_collision_exceptions() { +TypedArray<PhysicsBody3D> PhysicsBody3D::get_collision_exceptions() { List<RID> exceptions; PhysicsServer3D::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions); Array ret; @@ -125,7 +117,6 @@ Array PhysicsBody3D::get_collision_exceptions() { } void PhysicsBody3D::add_collision_exception_with(Node *p_node) { - ERR_FAIL_NULL(p_node); CollisionObject3D *collision_object = Object::cast_to<CollisionObject3D>(p_node); ERR_FAIL_COND_MSG(!collision_object, "Collision exception only works between two CollisionObject3Ds."); @@ -133,7 +124,6 @@ void PhysicsBody3D::add_collision_exception_with(Node *p_node) { } void PhysicsBody3D::remove_collision_exception_with(Node *p_node) { - ERR_FAIL_NULL(p_node); CollisionObject3D *collision_object = Object::cast_to<CollisionObject3D>(p_node); ERR_FAIL_COND_MSG(!collision_object, "Collision exception only works between two CollisionObject3Ds."); @@ -146,7 +136,6 @@ void PhysicsBody3D::_set_layers(uint32_t p_mask) { } uint32_t PhysicsBody3D::_get_layers() const { - return get_collision_layer(); } @@ -173,7 +162,6 @@ void PhysicsBody3D::_bind_methods() { PhysicsBody3D::PhysicsBody3D(PhysicsServer3D::BodyMode p_mode) : CollisionObject3D(PhysicsServer3D::get_singleton()->body_create(p_mode), false) { - collision_layer = 1; collision_mask = 1; } @@ -198,28 +186,24 @@ Ref<PhysicsMaterial> StaticBody3D::get_physics_material_override() const { } void StaticBody3D::set_constant_linear_velocity(const Vector3 &p_vel) { - constant_linear_velocity = p_vel; PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY, constant_linear_velocity); } void StaticBody3D::set_constant_angular_velocity(const Vector3 &p_vel) { - constant_angular_velocity = p_vel; PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_ANGULAR_VELOCITY, constant_angular_velocity); } Vector3 StaticBody3D::get_constant_linear_velocity() const { - return constant_linear_velocity; } -Vector3 StaticBody3D::get_constant_angular_velocity() const { +Vector3 StaticBody3D::get_constant_angular_velocity() const { return constant_angular_velocity; } void StaticBody3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_constant_linear_velocity", "vel"), &StaticBody3D::set_constant_linear_velocity); ClassDB::bind_method(D_METHOD("set_constant_angular_velocity", "vel"), &StaticBody3D::set_constant_angular_velocity); ClassDB::bind_method(D_METHOD("get_constant_linear_velocity"), &StaticBody3D::get_constant_linear_velocity); @@ -254,7 +238,6 @@ void StaticBody3D::_reload_physics_characteristics() { } void RigidBody3D::_body_enter_tree(ObjectID p_id) { - Object *obj = ObjectDB::get_instance(p_id); Node *node = Object::cast_to<Node>(obj); ERR_FAIL_COND(!node); @@ -271,7 +254,6 @@ void RigidBody3D::_body_enter_tree(ObjectID p_id) { emit_signal(SceneStringNames::get_singleton()->body_entered, node); for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].local_shape); } @@ -279,7 +261,6 @@ void RigidBody3D::_body_enter_tree(ObjectID p_id) { } void RigidBody3D::_body_exit_tree(ObjectID p_id) { - Object *obj = ObjectDB::get_instance(p_id); Node *node = Object::cast_to<Node>(obj); ERR_FAIL_COND(!node); @@ -294,7 +275,6 @@ void RigidBody3D::_body_exit_tree(ObjectID p_id) { emit_signal(SceneStringNames::get_singleton()->body_exited, node); for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].local_shape); } @@ -302,7 +282,6 @@ void RigidBody3D::_body_exit_tree(ObjectID p_id) { } void RigidBody3D::_body_inout(int p_status, ObjectID p_instance, int p_body_shape, int p_local_shape) { - bool body_in = p_status == 1; ObjectID objid = p_instance; @@ -316,7 +295,6 @@ void RigidBody3D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap if (body_in) { if (!E) { - E = contact_monitor->body_map.insert(objid, BodyState()); //E->get().rc=0; E->get().in_tree = node && node->is_inside_tree(); @@ -329,29 +307,30 @@ void RigidBody3D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap } } //E->get().rc++; - if (node) + if (node) { E->get().shapes.insert(ShapePair(p_body_shape, p_local_shape)); + } if (E->get().in_tree) { emit_signal(SceneStringNames::get_singleton()->body_shape_entered, objid, node, p_body_shape, p_local_shape); } } else { - //E->get().rc--; - if (node) + if (node) { E->get().shapes.erase(ShapePair(p_body_shape, p_local_shape)); + } bool in_tree = E->get().in_tree; if (E->get().shapes.empty()) { - if (node) { node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody3D::_body_enter_tree)); node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody3D::_body_exit_tree)); - if (in_tree) + if (in_tree) { emit_signal(SceneStringNames::get_singleton()->body_exited, node); + } } contact_monitor->body_map.erase(E); @@ -363,14 +342,12 @@ void RigidBody3D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap } struct _RigidBodyInOut { - ObjectID id; int shape; int local_shape; }; void RigidBody3D::_direct_state_changed(Object *p_state) { - #ifdef DEBUG_ENABLED state = Object::cast_to<PhysicsDirectBodyState3D>(p_state); #else @@ -385,20 +362,18 @@ void RigidBody3D::_direct_state_changed(Object *p_state) { sleeping = state->is_sleeping(); emit_signal(SceneStringNames::get_singleton()->sleeping_state_changed); } - if (get_script_instance()) + if (get_script_instance()) { get_script_instance()->call("_integrate_forces", state); + } set_ignore_transform_notification(false); if (contact_monitor) { - contact_monitor->locked = true; //untag all int rc = 0; for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) { - for (int i = 0; i < E->get().shapes.size(); i++) { - E->get().shapes[i].tagged = false; rc++; } @@ -412,7 +387,6 @@ void RigidBody3D::_direct_state_changed(Object *p_state) { //put the ones to add for (int i = 0; i < state->get_contact_count(); i++) { - ObjectID obj = state->get_contact_collider_id(i); int local_shape = state->get_contact_local_shape(i); int shape = state->get_contact_collider_shape(i); @@ -431,7 +405,6 @@ void RigidBody3D::_direct_state_changed(Object *p_state) { ShapePair sp(shape, local_shape); int idx = E->get().shapes.find(sp); if (idx == -1) { - toadd[toadd_count].local_shape = local_shape; toadd[toadd_count].id = obj; toadd[toadd_count].shape = shape; @@ -445,11 +418,8 @@ void RigidBody3D::_direct_state_changed(Object *p_state) { //put the ones to remove for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) { - for (int i = 0; i < E->get().shapes.size(); i++) { - if (!E->get().shapes[i].tagged) { - toremove[toremove_count].body_id = E->key(); toremove[toremove_count].pair = E->get().shapes[i]; toremove_count++; @@ -460,25 +430,22 @@ void RigidBody3D::_direct_state_changed(Object *p_state) { //process remotions for (int i = 0; i < toremove_count; i++) { - _body_inout(0, toremove[i].body_id, toremove[i].pair.body_shape, toremove[i].pair.local_shape); } //process aditions for (int i = 0; i < toadd_count; i++) { - _body_inout(1, toadd[i].id, toadd[i].shape, toadd[i].local_shape); } contact_monitor->locked = false; } - state = NULL; + state = nullptr; } void RigidBody3D::_notification(int p_what) { - #ifdef TOOLS_ENABLED if (p_what == NOTIFICATION_ENTER_TREE) { if (Engine::get_singleton()->is_editor_hint()) { @@ -496,16 +463,12 @@ void RigidBody3D::_notification(int p_what) { } void RigidBody3D::set_mode(Mode p_mode) { - mode = p_mode; switch (p_mode) { - case MODE_RIGID: { - PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_RIGID); } break; case MODE_STATIC: { - PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_STATIC); } break; @@ -514,7 +477,6 @@ void RigidBody3D::set_mode(Mode p_mode) { } break; case MODE_KINEMATIC: { - PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_KINEMATIC); } break; } @@ -522,29 +484,26 @@ void RigidBody3D::set_mode(Mode p_mode) { } RigidBody3D::Mode RigidBody3D::get_mode() const { - return mode; } void RigidBody3D::set_mass(real_t p_mass) { - ERR_FAIL_COND(p_mass <= 0); mass = p_mass; _change_notify("mass"); _change_notify("weight"); PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_MASS, mass); } -real_t RigidBody3D::get_mass() const { +real_t RigidBody3D::get_mass() const { return mass; } void RigidBody3D::set_weight(real_t p_weight) { - set_mass(p_weight / real_t(GLOBAL_DEF("physics/3d/default_gravity", 9.8))); } -real_t RigidBody3D::get_weight() const { +real_t RigidBody3D::get_weight() const { return mass * real_t(GLOBAL_DEF("physics/3d/default_gravity", 9.8)); } @@ -568,39 +527,35 @@ Ref<PhysicsMaterial> RigidBody3D::get_physics_material_override() const { } void RigidBody3D::set_gravity_scale(real_t p_gravity_scale) { - gravity_scale = p_gravity_scale; PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_GRAVITY_SCALE, gravity_scale); } -real_t RigidBody3D::get_gravity_scale() const { +real_t RigidBody3D::get_gravity_scale() const { return gravity_scale; } void RigidBody3D::set_linear_damp(real_t p_linear_damp) { - ERR_FAIL_COND(p_linear_damp < -1); linear_damp = p_linear_damp; PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_LINEAR_DAMP, linear_damp); } -real_t RigidBody3D::get_linear_damp() const { +real_t RigidBody3D::get_linear_damp() const { return linear_damp; } void RigidBody3D::set_angular_damp(real_t p_angular_damp) { - ERR_FAIL_COND(p_angular_damp < -1); angular_damp = p_angular_damp; PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP, angular_damp); } -real_t RigidBody3D::get_angular_damp() const { +real_t RigidBody3D::get_angular_damp() const { return angular_damp; } void RigidBody3D::set_axis_velocity(const Vector3 &p_axis) { - Vector3 v = state ? state->get_linear_velocity() : linear_velocity; Vector3 axis = p_axis.normalized(); v -= axis * axis.dot(v); @@ -614,75 +569,68 @@ void RigidBody3D::set_axis_velocity(const Vector3 &p_axis) { } void RigidBody3D::set_linear_velocity(const Vector3 &p_velocity) { - linear_velocity = p_velocity; - if (state) + if (state) { state->set_linear_velocity(linear_velocity); - else + } else { PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY, linear_velocity); + } } Vector3 RigidBody3D::get_linear_velocity() const { - return linear_velocity; } void RigidBody3D::set_angular_velocity(const Vector3 &p_velocity) { - angular_velocity = p_velocity; - if (state) + if (state) { state->set_angular_velocity(angular_velocity); - else + } else { PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_ANGULAR_VELOCITY, angular_velocity); + } } -Vector3 RigidBody3D::get_angular_velocity() const { +Vector3 RigidBody3D::get_angular_velocity() const { return angular_velocity; } void RigidBody3D::set_use_custom_integrator(bool p_enable) { - - if (custom_integrator == p_enable) + if (custom_integrator == p_enable) { return; + } custom_integrator = p_enable; PhysicsServer3D::get_singleton()->body_set_omit_force_integration(get_rid(), p_enable); } -bool RigidBody3D::is_using_custom_integrator() { +bool RigidBody3D::is_using_custom_integrator() { return custom_integrator; } void RigidBody3D::set_sleeping(bool p_sleeping) { - sleeping = p_sleeping; PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_SLEEPING, sleeping); } void RigidBody3D::set_can_sleep(bool p_active) { - can_sleep = p_active; PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_CAN_SLEEP, p_active); } bool RigidBody3D::is_able_to_sleep() const { - return can_sleep; } bool RigidBody3D::is_sleeping() const { - return sleeping; } void RigidBody3D::set_max_contacts_reported(int p_amount) { - max_contacts_reported = p_amount; PhysicsServer3D::get_singleton()->body_set_max_contacts_reported(get_rid(), p_amount); } int RigidBody3D::get_max_contacts_reported() const { - return max_contacts_reported; } @@ -703,7 +651,6 @@ void RigidBody3D::apply_central_impulse(const Vector3 &p_impulse) { } void RigidBody3D::apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse) { - PhysicsServer3D::get_singleton()->body_apply_impulse(get_rid(), p_pos, p_impulse); } @@ -712,27 +659,23 @@ void RigidBody3D::apply_torque_impulse(const Vector3 &p_impulse) { } void RigidBody3D::set_use_continuous_collision_detection(bool p_enable) { - ccd = p_enable; PhysicsServer3D::get_singleton()->body_set_enable_continuous_collision_detection(get_rid(), p_enable); } bool RigidBody3D::is_using_continuous_collision_detection() const { - return ccd; } void RigidBody3D::set_contact_monitor(bool p_enabled) { - - if (p_enabled == is_contact_monitor_enabled()) + if (p_enabled == is_contact_monitor_enabled()) { return; + } if (!p_enabled) { - ERR_FAIL_COND_MSG(contact_monitor->locked, "Can't disable contact monitoring during in/out callback. Use call_deferred(\"set_contact_monitor\", false) instead."); for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) { - //clean up mess Object *obj = ObjectDB::get_instance(E->key()); Node *node = Object::cast_to<Node>(obj); @@ -744,17 +687,15 @@ void RigidBody3D::set_contact_monitor(bool p_enabled) { } memdelete(contact_monitor); - contact_monitor = NULL; + contact_monitor = nullptr; } else { - contact_monitor = memnew(ContactMonitor); contact_monitor->locked = false; } } bool RigidBody3D::is_contact_monitor_enabled() const { - - return contact_monitor != NULL; + return contact_monitor != nullptr; } void RigidBody3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) { @@ -766,7 +707,6 @@ bool RigidBody3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const { } Array RigidBody3D::get_colliding_bodies() const { - ERR_FAIL_COND_V(!contact_monitor, Array()); Array ret; @@ -785,7 +725,6 @@ Array RigidBody3D::get_colliding_bodies() const { } String RigidBody3D::get_configuration_warning() const { - Transform t = get_transform(); String warning = CollisionObject3D::get_configuration_warning(); @@ -801,7 +740,6 @@ String RigidBody3D::get_configuration_warning() const { } void RigidBody3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_mode", "mode"), &RigidBody3D::set_mode); ClassDB::bind_method(D_METHOD("get_mode"), &RigidBody3D::get_mode); @@ -905,12 +843,11 @@ void RigidBody3D::_bind_methods() { RigidBody3D::RigidBody3D() : PhysicsBody3D(PhysicsServer3D::BODY_MODE_RIGID) { - mode = MODE_RIGID; mass = 1; max_contacts_reported = 0; - state = NULL; + state = nullptr; gravity_scale = 1; linear_damp = -1; @@ -921,16 +858,16 @@ RigidBody3D::RigidBody3D() : ccd = false; custom_integrator = false; - contact_monitor = NULL; + contact_monitor = nullptr; can_sleep = true; PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed"); } RigidBody3D::~RigidBody3D() { - - if (contact_monitor) + if (contact_monitor) { memdelete(contact_monitor); + } } void RigidBody3D::_reload_physics_characteristics() { @@ -947,7 +884,6 @@ void RigidBody3D::_reload_physics_characteristics() { ////////////////////////// Ref<KinematicCollision3D> KinematicBody3D::_move(const Vector3 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, bool p_test_only) { - Collision col; if (move_and_collide(p_motion, p_infinite_inertia, col, p_exclude_raycast_shapes, p_test_only)) { if (motion_cache.is_null()) { @@ -972,7 +908,6 @@ Vector3 KinematicBody3D::get_angular_velocity() const { } bool KinematicBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes, bool p_test_only) { - Transform gt = get_global_transform(); PhysicsServer3D::MotionResult result; bool colliding = PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, &result, p_exclude_raycast_shapes); @@ -1008,7 +943,6 @@ bool KinematicBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_ #define FLOOR_ANGLE_THRESHOLD 0.01 Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { - Vector3 body_velocity = p_linear_velocity; Vector3 body_velocity_normal = body_velocity.normalized(); @@ -1030,7 +964,6 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const floor_velocity = Vector3(); while (p_max_slides) { - Collision collision; bool found_collision = false; @@ -1092,8 +1025,9 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const } } - if (!found_collision || motion == Vector3()) + if (!found_collision || motion == Vector3()) { break; + } --p_max_slides; } @@ -1102,7 +1036,6 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const } Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { - bool was_on_floor = on_floor; Vector3 ret = move_and_slide(p_linear_velocity, p_up_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia); @@ -1114,7 +1047,6 @@ Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_veloci Transform gt = get_global_transform(); if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) { - bool apply = true; if (p_up_direction != Vector3()) { if (Math::acos(p_up_direction.normalized().dot(col.normal)) < p_floor_max_angle) { @@ -1141,38 +1073,32 @@ Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_veloci } bool KinematicBody3D::is_on_floor() const { - return on_floor; } bool KinematicBody3D::is_on_wall() const { - return on_wall; } -bool KinematicBody3D::is_on_ceiling() const { +bool KinematicBody3D::is_on_ceiling() const { return on_ceiling; } Vector3 KinematicBody3D::get_floor_normal() const { - return floor_normal; } Vector3 KinematicBody3D::get_floor_velocity() const { - return floor_velocity; } bool KinematicBody3D::test_move(const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia) { - ERR_FAIL_COND_V(!is_inside_tree(), false); return PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia); } bool KinematicBody3D::separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision) { - PhysicsServer3D::SeparationResult sep_res[8]; //max 8 rays Transform gt = get_global_transform(); @@ -1209,6 +1135,11 @@ bool KinematicBody3D::separate_raycast_shapes(bool p_infinite_inertia, Collision } void KinematicBody3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) { + if (p_lock) { + locked_axis |= p_axis; + } else { + locked_axis &= (~p_axis); + } PhysicsServer3D::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock); } @@ -1217,17 +1148,15 @@ bool KinematicBody3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const { } void KinematicBody3D::set_safe_margin(float p_margin) { - margin = p_margin; PhysicsServer3D::get_singleton()->body_set_kinematic_safe_margin(get_rid(), margin); } float KinematicBody3D::get_safe_margin() const { - return margin; } -int KinematicBody3D::get_slide_count() const { +int KinematicBody3D::get_slide_count() const { return colliders.size(); } @@ -1237,7 +1166,6 @@ KinematicBody3D::Collision KinematicBody3D::get_slide_collision(int p_bounce) co } Ref<KinematicCollision3D> KinematicBody3D::_get_slide_collision(int p_bounce) { - ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Ref<KinematicCollision3D>()); if (p_bounce >= slide_colliders.size()) { slide_colliders.resize(p_bounce + 1); @@ -1265,7 +1193,6 @@ void KinematicBody3D::_notification(int p_what) { } void KinematicBody3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("_direct_state_changed"), &KinematicBody3D::_direct_state_changed); ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody3D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false)); @@ -1289,9 +1216,10 @@ void KinematicBody3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody3D::get_slide_count); ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody3D::_get_slide_collision); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "move_lock_x", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_X); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "move_lock_y", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Y); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "move_lock_z", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Z); + ADD_GROUP("Axis Lock", "axis_lock_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_motion_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_X); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_motion_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Y); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_motion_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Z); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin"); } @@ -1309,7 +1237,6 @@ void KinematicBody3D::_direct_state_changed(Object *p_state) { KinematicBody3D::KinematicBody3D() : PhysicsBody3D(PhysicsServer3D::BODY_MODE_KINEMATIC) { - margin = 0.001; locked_axis = 0; on_floor = false; @@ -1318,53 +1245,58 @@ KinematicBody3D::KinematicBody3D() : PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed"); } -KinematicBody3D::~KinematicBody3D() { +KinematicBody3D::~KinematicBody3D() { if (motion_cache.is_valid()) { - motion_cache->owner = NULL; + motion_cache->owner = nullptr; } for (int i = 0; i < slide_colliders.size(); i++) { if (slide_colliders[i].is_valid()) { - slide_colliders.write[i]->owner = NULL; + slide_colliders.write[i]->owner = nullptr; } } } + /////////////////////////////////////// Vector3 KinematicCollision3D::get_position() const { - return collision.collision; } + Vector3 KinematicCollision3D::get_normal() const { return collision.normal; } + Vector3 KinematicCollision3D::get_travel() const { return collision.travel; } + Vector3 KinematicCollision3D::get_remainder() const { return collision.remainder; } + Object *KinematicCollision3D::get_local_shape() const { - if (!owner) return NULL; + if (!owner) { + return nullptr; + } uint32_t ownerid = owner->shape_find_owner(collision.local_shape); return owner->shape_owner_get_owner(ownerid); } Object *KinematicCollision3D::get_collider() const { - if (collision.collider.is_valid()) { return ObjectDB::get_instance(collision.collider); } - return NULL; + return nullptr; } -ObjectID KinematicCollision3D::get_collider_id() const { +ObjectID KinematicCollision3D::get_collider_id() const { return collision.collider; } -Object *KinematicCollision3D::get_collider_shape() const { +Object *KinematicCollision3D::get_collider_shape() const { Object *collider = get_collider(); if (collider) { CollisionObject3D *obj2d = Object::cast_to<CollisionObject3D>(collider); @@ -1374,23 +1306,22 @@ Object *KinematicCollision3D::get_collider_shape() const { } } - return NULL; + return nullptr; } -int KinematicCollision3D::get_collider_shape_index() const { +int KinematicCollision3D::get_collider_shape_index() const { return collision.collider_shape; } -Vector3 KinematicCollision3D::get_collider_velocity() const { +Vector3 KinematicCollision3D::get_collider_velocity() const { return collision.collider_vel; } -Variant KinematicCollision3D::get_collider_metadata() const { +Variant KinematicCollision3D::get_collider_metadata() const { return Variant(); } void KinematicCollision3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_position"), &KinematicCollision3D::get_position); ClassDB::bind_method(D_METHOD("get_normal"), &KinematicCollision3D::get_normal); ClassDB::bind_method(D_METHOD("get_travel"), &KinematicCollision3D::get_travel); @@ -1417,10 +1348,9 @@ void KinematicCollision3D::_bind_methods() { } KinematicCollision3D::KinematicCollision3D() { - collision.collider_shape = 0; collision.local_shape = 0; - owner = NULL; + owner = nullptr; } /////////////////////////////////////// @@ -1469,18 +1399,21 @@ bool PhysicalBone3D::PinJointData::_set(const StringName &p_name, const Variant if ("joint_constraints/bias" == p_name) { bias = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->pin_joint_set_param(j, PhysicsServer3D::PIN_JOINT_BIAS, bias); + } } else if ("joint_constraints/damping" == p_name) { damping = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->pin_joint_set_param(j, PhysicsServer3D::PIN_JOINT_DAMPING, damping); + } } else if ("joint_constraints/impulse_clamp" == p_name) { impulse_clamp = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->pin_joint_set_param(j, PhysicsServer3D::PIN_JOINT_IMPULSE_CLAMP, impulse_clamp); + } } else { return false; @@ -1522,28 +1455,33 @@ bool PhysicalBone3D::ConeJointData::_set(const StringName &p_name, const Variant if ("joint_constraints/swing_span" == p_name) { swing_span = Math::deg2rad(real_t(p_value)); - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(j, PhysicsServer3D::CONE_TWIST_JOINT_SWING_SPAN, swing_span); + } } else if ("joint_constraints/twist_span" == p_name) { twist_span = Math::deg2rad(real_t(p_value)); - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(j, PhysicsServer3D::CONE_TWIST_JOINT_TWIST_SPAN, twist_span); + } } else if ("joint_constraints/bias" == p_name) { bias = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(j, PhysicsServer3D::CONE_TWIST_JOINT_BIAS, bias); + } } else if ("joint_constraints/softness" == p_name) { softness = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(j, PhysicsServer3D::CONE_TWIST_JOINT_SOFTNESS, softness); + } } else if ("joint_constraints/relaxation" == p_name) { relaxation = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(j, PhysicsServer3D::CONE_TWIST_JOINT_RELAXATION, relaxation); + } } else { return false; @@ -1591,33 +1529,39 @@ bool PhysicalBone3D::HingeJointData::_set(const StringName &p_name, const Varian if ("joint_constraints/angular_limit_enabled" == p_name) { angular_limit_enabled = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->hinge_joint_set_flag(j, PhysicsServer3D::HINGE_JOINT_FLAG_USE_LIMIT, angular_limit_enabled); + } } else if ("joint_constraints/angular_limit_upper" == p_name) { angular_limit_upper = Math::deg2rad(real_t(p_value)); - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->hinge_joint_set_param(j, PhysicsServer3D::HINGE_JOINT_LIMIT_UPPER, angular_limit_upper); + } } else if ("joint_constraints/angular_limit_lower" == p_name) { angular_limit_lower = Math::deg2rad(real_t(p_value)); - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->hinge_joint_set_param(j, PhysicsServer3D::HINGE_JOINT_LIMIT_LOWER, angular_limit_lower); + } } else if ("joint_constraints/angular_limit_bias" == p_name) { angular_limit_bias = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->hinge_joint_set_param(j, PhysicsServer3D::HINGE_JOINT_LIMIT_BIAS, angular_limit_bias); + } } else if ("joint_constraints/angular_limit_softness" == p_name) { angular_limit_softness = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->hinge_joint_set_param(j, PhysicsServer3D::HINGE_JOINT_LIMIT_SOFTNESS, angular_limit_softness); + } } else if ("joint_constraints/angular_limit_relaxation" == p_name) { angular_limit_relaxation = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->hinge_joint_set_param(j, PhysicsServer3D::HINGE_JOINT_LIMIT_RELAXATION, angular_limit_relaxation); + } } else { return false; @@ -1668,53 +1612,63 @@ bool PhysicalBone3D::SliderJointData::_set(const StringName &p_name, const Varia if ("joint_constraints/linear_limit_upper" == p_name) { linear_limit_upper = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER, linear_limit_upper); + } } else if ("joint_constraints/linear_limit_lower" == p_name) { linear_limit_lower = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_LOWER, linear_limit_lower); + } } else if ("joint_constraints/linear_limit_softness" == p_name) { linear_limit_softness = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS, linear_limit_softness); + } } else if ("joint_constraints/linear_limit_restitution" == p_name) { linear_limit_restitution = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION, linear_limit_restitution); + } } else if ("joint_constraints/linear_limit_damping" == p_name) { linear_limit_damping = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_DAMPING, linear_limit_restitution); + } } else if ("joint_constraints/angular_limit_upper" == p_name) { angular_limit_upper = Math::deg2rad(real_t(p_value)); - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_UPPER, angular_limit_upper); + } } else if ("joint_constraints/angular_limit_lower" == p_name) { angular_limit_lower = Math::deg2rad(real_t(p_value)); - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_LOWER, angular_limit_lower); + } } else if ("joint_constraints/angular_limit_softness" == p_name) { angular_limit_softness = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS, angular_limit_softness); + } } else if ("joint_constraints/angular_limit_restitution" == p_name) { angular_limit_restitution = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS, angular_limit_softness); + } } else if ("joint_constraints/angular_limit_damping" == p_name) { angular_limit_damping = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING, angular_limit_damping); + } } else { return false; @@ -1796,108 +1750,129 @@ bool PhysicalBone3D::SixDOFJointData::_set(const StringName &p_name, const Varia if ("linear_limit_enabled" == var_name) { axis_data[axis].linear_limit_enabled = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(j, axis, PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT, axis_data[axis].linear_limit_enabled); + } } else if ("linear_limit_upper" == var_name) { axis_data[axis].linear_limit_upper = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_LINEAR_UPPER_LIMIT, axis_data[axis].linear_limit_upper); + } } else if ("linear_limit_lower" == var_name) { axis_data[axis].linear_limit_lower = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_LINEAR_LOWER_LIMIT, axis_data[axis].linear_limit_lower); + } } else if ("linear_limit_softness" == var_name) { axis_data[axis].linear_limit_softness = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_LINEAR_LIMIT_SOFTNESS, axis_data[axis].linear_limit_softness); + } } else if ("linear_spring_enabled" == var_name) { axis_data[axis].linear_spring_enabled = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(j, axis, PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_SPRING, axis_data[axis].linear_spring_enabled); + } } else if ("linear_spring_stiffness" == var_name) { axis_data[axis].linear_spring_stiffness = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_STIFFNESS, axis_data[axis].linear_spring_stiffness); + } } else if ("linear_spring_damping" == var_name) { axis_data[axis].linear_spring_damping = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_DAMPING, axis_data[axis].linear_spring_damping); + } } else if ("linear_equilibrium_point" == var_name) { axis_data[axis].linear_equilibrium_point = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT, axis_data[axis].linear_equilibrium_point); + } } else if ("linear_restitution" == var_name) { axis_data[axis].linear_restitution = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_LINEAR_RESTITUTION, axis_data[axis].linear_restitution); + } } else if ("linear_damping" == var_name) { axis_data[axis].linear_damping = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_LINEAR_DAMPING, axis_data[axis].linear_damping); + } } else if ("angular_limit_enabled" == var_name) { axis_data[axis].angular_limit_enabled = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(j, axis, PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT, axis_data[axis].angular_limit_enabled); + } } else if ("angular_limit_upper" == var_name) { axis_data[axis].angular_limit_upper = Math::deg2rad(real_t(p_value)); - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_ANGULAR_UPPER_LIMIT, axis_data[axis].angular_limit_upper); + } } else if ("angular_limit_lower" == var_name) { axis_data[axis].angular_limit_lower = Math::deg2rad(real_t(p_value)); - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_ANGULAR_LOWER_LIMIT, axis_data[axis].angular_limit_lower); + } } else if ("angular_limit_softness" == var_name) { axis_data[axis].angular_limit_softness = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_ANGULAR_LIMIT_SOFTNESS, axis_data[axis].angular_limit_softness); + } } else if ("angular_restitution" == var_name) { axis_data[axis].angular_restitution = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_ANGULAR_RESTITUTION, axis_data[axis].angular_restitution); + } } else if ("angular_damping" == var_name) { axis_data[axis].angular_damping = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_ANGULAR_DAMPING, axis_data[axis].angular_damping); + } } else if ("erp" == var_name) { axis_data[axis].erp = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_ANGULAR_ERP, axis_data[axis].erp); + } } else if ("angular_spring_enabled" == var_name) { axis_data[axis].angular_spring_enabled = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(j, axis, PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING, axis_data[axis].angular_spring_enabled); + } } else if ("angular_spring_stiffness" == var_name) { axis_data[axis].angular_spring_stiffness = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS, axis_data[axis].angular_spring_stiffness); + } } else if ("angular_spring_damping" == var_name) { axis_data[axis].angular_spring_damping = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_DAMPING, axis_data[axis].angular_spring_damping); + } } else if ("angular_equilibrium_point" == var_name) { axis_data[axis].angular_equilibrium_point = p_value; - if (j.is_valid()) + if (j.is_valid()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT, axis_data[axis].angular_equilibrium_point); + } } else { return false; @@ -2014,8 +1989,9 @@ bool PhysicalBone3D::_set(const StringName &p_name, const Variant &p_value) { if (joint_data) { if (joint_data->_set(p_name, p_value)) { #ifdef TOOLS_ENABLED - if (get_gizmo().is_valid()) + if (get_gizmo().is_valid()) { get_gizmo()->redraw(); + } #endif return true; } @@ -2038,21 +2014,19 @@ bool PhysicalBone3D::_get(const StringName &p_name, Variant &r_ret) const { } void PhysicalBone3D::_get_property_list(List<PropertyInfo> *p_list) const { - Skeleton3D *parent = find_skeleton_parent(get_parent()); if (parent) { - String names; for (int i = 0; i < parent->get_bone_count(); i++) { - if (i > 0) + if (i > 0) { names += ","; + } names += parent->get_bone_name(i); } p_list->push_back(PropertyInfo(Variant::STRING_NAME, "bone_name", PROPERTY_HINT_ENUM, names)); } else { - p_list->push_back(PropertyInfo(Variant::STRING_NAME, "bone_name")); } @@ -2078,7 +2052,7 @@ void PhysicalBone3D::_notification(int p_what) { parent_skeleton->unbind_physical_bone_from_bone(bone_id); } } - parent_skeleton = NULL; + parent_skeleton = nullptr; if (joint.is_valid()) { PhysicsServer3D::get_singleton()->free(joint); joint = RID(); @@ -2086,7 +2060,6 @@ void PhysicalBone3D::_notification(int p_what) { break; case NOTIFICATION_TRANSFORM_CHANGED: if (Engine::get_singleton()->is_editor_hint()) { - update_offset(); } break; @@ -2094,7 +2067,6 @@ void PhysicalBone3D::_notification(int p_what) { } void PhysicalBone3D::_direct_state_changed(Object *p_state) { - if (!simulate_physics || !_internal_simulate_physics) { return; } @@ -2134,6 +2106,10 @@ void PhysicalBone3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_joint_offset", "offset"), &PhysicalBone3D::set_joint_offset); ClassDB::bind_method(D_METHOD("get_joint_offset"), &PhysicalBone3D::get_joint_offset); + ClassDB::bind_method(D_METHOD("set_joint_rotation", "euler"), &PhysicalBone3D::set_joint_rotation); + ClassDB::bind_method(D_METHOD("get_joint_rotation"), &PhysicalBone3D::get_joint_rotation); + ClassDB::bind_method(D_METHOD("set_joint_rotation_degrees", "euler_degrees"), &PhysicalBone3D::set_joint_rotation_degrees); + ClassDB::bind_method(D_METHOD("get_joint_rotation_degrees"), &PhysicalBone3D::get_joint_rotation_degrees); ClassDB::bind_method(D_METHOD("set_body_offset", "offset"), &PhysicalBone3D::set_body_offset); ClassDB::bind_method(D_METHOD("get_body_offset"), &PhysicalBone3D::get_body_offset); @@ -2159,9 +2135,23 @@ void PhysicalBone3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_gravity_scale", "gravity_scale"), &PhysicalBone3D::set_gravity_scale); ClassDB::bind_method(D_METHOD("get_gravity_scale"), &PhysicalBone3D::get_gravity_scale); + ClassDB::bind_method(D_METHOD("set_linear_damp", "linear_damp"), &PhysicalBone3D::set_linear_damp); + ClassDB::bind_method(D_METHOD("get_linear_damp"), &PhysicalBone3D::get_linear_damp); + + ClassDB::bind_method(D_METHOD("set_angular_damp", "angular_damp"), &PhysicalBone3D::set_angular_damp); + ClassDB::bind_method(D_METHOD("get_angular_damp"), &PhysicalBone3D::get_angular_damp); + + ClassDB::bind_method(D_METHOD("set_can_sleep", "able_to_sleep"), &PhysicalBone3D::set_can_sleep); + ClassDB::bind_method(D_METHOD("is_able_to_sleep"), &PhysicalBone3D::is_able_to_sleep); + + ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &PhysicalBone3D::set_axis_lock); + ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &PhysicalBone3D::get_axis_lock); + ADD_GROUP("Joint", "joint_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "joint_type", PROPERTY_HINT_ENUM, "None,PinJoint,ConeJoint,HingeJoint,SliderJoint,6DOFJoint"), "set_joint_type", "get_joint_type"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "joint_offset"), "set_joint_offset", "get_joint_offset"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_joint_rotation_degrees", "get_joint_rotation_degrees"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation", PROPERTY_HINT_NONE, "", 0), "set_joint_rotation", "get_joint_rotation"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "body_offset"), "set_body_offset", "get_body_offset"); @@ -2170,6 +2160,17 @@ void PhysicalBone3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_friction", "get_friction"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_bounce", "get_bounce"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_scale", PROPERTY_HINT_RANGE, "-10,10,0.01"), "set_gravity_scale", "get_gravity_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep"); + + ADD_GROUP("Axis Lock", "axis_lock_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_X); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Y); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Z); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_X); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Y); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Z); BIND_ENUM_CONSTANT(JOINT_TYPE_NONE); BIND_ENUM_CONSTANT(JOINT_TYPE_PIN); @@ -2181,12 +2182,26 @@ void PhysicalBone3D::_bind_methods() { Skeleton3D *PhysicalBone3D::find_skeleton_parent(Node *p_parent) { if (!p_parent) { - return NULL; + return nullptr; } Skeleton3D *s = Object::cast_to<Skeleton3D>(p_parent); return s ? s : find_skeleton_parent(p_parent->get_parent()); } +void PhysicalBone3D::_update_joint_offset() { + _fix_joint_offset(); + + set_ignore_transform_notification(true); + reset_to_rest_position(); + set_ignore_transform_notification(false); + +#ifdef TOOLS_ENABLED + if (get_gizmo().is_valid()) { + get_gizmo()->redraw(); + } +#endif +} + void PhysicalBone3D::_fix_joint_offset() { // Clamp joint origin to bone origin if (parent_skeleton) { @@ -2195,7 +2210,6 @@ void PhysicalBone3D::_fix_joint_offset() { } void PhysicalBone3D::_reload_joint() { - if (joint.is_valid()) { PhysicsServer3D::get_singleton()->free(joint); joint = RID(); @@ -2216,7 +2230,6 @@ void PhysicalBone3D::_reload_joint() { switch (get_joint_type()) { case JOINT_TYPE_PIN: { - joint = PhysicsServer3D::get_singleton()->joint_create_pin(body_a->get_rid(), local_a.origin, get_rid(), joint_offset.origin); const PinJointData *pjd(static_cast<const PinJointData *>(joint_data)); PhysicsServer3D::get_singleton()->pin_joint_set_param(joint, PhysicsServer3D::PIN_JOINT_BIAS, pjd->bias); @@ -2225,7 +2238,6 @@ void PhysicalBone3D::_reload_joint() { } break; case JOINT_TYPE_CONE: { - joint = PhysicsServer3D::get_singleton()->joint_create_cone_twist(body_a->get_rid(), local_a, get_rid(), joint_offset); const ConeJointData *cjd(static_cast<const ConeJointData *>(joint_data)); PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(joint, PhysicsServer3D::CONE_TWIST_JOINT_SWING_SPAN, cjd->swing_span); @@ -2236,7 +2248,6 @@ void PhysicalBone3D::_reload_joint() { } break; case JOINT_TYPE_HINGE: { - joint = PhysicsServer3D::get_singleton()->joint_create_hinge(body_a->get_rid(), local_a, get_rid(), joint_offset); const HingeJointData *hjd(static_cast<const HingeJointData *>(joint_data)); PhysicsServer3D::get_singleton()->hinge_joint_set_flag(joint, PhysicsServer3D::HINGE_JOINT_FLAG_USE_LIMIT, hjd->angular_limit_enabled); @@ -2248,7 +2259,6 @@ void PhysicalBone3D::_reload_joint() { } break; case JOINT_TYPE_SLIDER: { - joint = PhysicsServer3D::get_singleton()->joint_create_slider(body_a->get_rid(), local_a, get_rid(), joint_offset); const SliderJointData *sjd(static_cast<const SliderJointData *>(joint_data)); PhysicsServer3D::get_singleton()->slider_joint_set_param(joint, PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER, sjd->linear_limit_upper); @@ -2264,7 +2274,6 @@ void PhysicalBone3D::_reload_joint() { } break; case JOINT_TYPE_6DOF: { - joint = PhysicsServer3D::get_singleton()->joint_create_generic_6dof(body_a->get_rid(), local_a, get_rid(), joint_offset); const SixDOFJointData *g6dofjd(static_cast<const SixDOFJointData *>(joint_data)); for (int axis = 0; axis < 3; ++axis) { @@ -2327,13 +2336,14 @@ Skeleton3D *PhysicalBone3D::find_skeleton_parent() { } void PhysicalBone3D::set_joint_type(JointType p_joint_type) { - - if (p_joint_type == get_joint_type()) + if (p_joint_type == get_joint_type()) { return; + } - if (joint_data) + if (joint_data) { memdelete(joint_data); - joint_data = NULL; + } + joint_data = nullptr; switch (p_joint_type) { case JOINT_TYPE_PIN: joint_data = memnew(PinJointData); @@ -2358,8 +2368,9 @@ void PhysicalBone3D::set_joint_type(JointType p_joint_type) { #ifdef TOOLS_ENABLED _change_notify(); - if (get_gizmo().is_valid()) + if (get_gizmo().is_valid()) { get_gizmo()->redraw(); + } #endif } @@ -2370,16 +2381,31 @@ PhysicalBone3D::JointType PhysicalBone3D::get_joint_type() const { void PhysicalBone3D::set_joint_offset(const Transform &p_offset) { joint_offset = p_offset; - _fix_joint_offset(); + _update_joint_offset(); + _change_notify("joint_rotation_degrees"); +} - set_ignore_transform_notification(true); - reset_to_rest_position(); - set_ignore_transform_notification(false); +const Transform &PhysicalBone3D::get_joint_offset() const { + return joint_offset; +} -#ifdef TOOLS_ENABLED - if (get_gizmo().is_valid()) - get_gizmo()->redraw(); -#endif +void PhysicalBone3D::set_joint_rotation(const Vector3 &p_euler_rad) { + joint_offset.basis.set_euler_scale(p_euler_rad, joint_offset.basis.get_scale()); + + _update_joint_offset(); + _change_notify("joint_offset"); +} + +Vector3 PhysicalBone3D::get_joint_rotation() const { + return joint_offset.basis.get_rotation(); +} + +void PhysicalBone3D::set_joint_rotation_degrees(const Vector3 &p_euler_deg) { + set_joint_rotation(p_euler_deg * Math_PI / 180.0); +} + +Vector3 PhysicalBone3D::get_joint_rotation_degrees() const { + return get_joint_rotation() * 180.0 / Math_PI; } const Transform &PhysicalBone3D::get_body_offset() const { @@ -2390,20 +2416,7 @@ void PhysicalBone3D::set_body_offset(const Transform &p_offset) { body_offset = p_offset; body_offset_inverse = body_offset.affine_inverse(); - _fix_joint_offset(); - - set_ignore_transform_notification(true); - reset_to_rest_position(); - set_ignore_transform_notification(false); - -#ifdef TOOLS_ENABLED - if (get_gizmo().is_valid()) - get_gizmo()->redraw(); -#endif -} - -const Transform &PhysicalBone3D::get_joint_offset() const { - return joint_offset; + _update_joint_offset(); } void PhysicalBone3D::set_simulate_physics(bool p_simulate) { @@ -2424,7 +2437,6 @@ bool PhysicalBone3D::is_simulating_physics() { } void PhysicalBone3D::set_bone_name(const String &p_name) { - bone_name = p_name; bone_id = -1; @@ -2433,34 +2445,28 @@ void PhysicalBone3D::set_bone_name(const String &p_name) { } const String &PhysicalBone3D::get_bone_name() const { - return bone_name; } void PhysicalBone3D::set_mass(real_t p_mass) { - ERR_FAIL_COND(p_mass <= 0); mass = p_mass; PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_MASS, mass); } real_t PhysicalBone3D::get_mass() const { - return mass; } void PhysicalBone3D::set_weight(real_t p_weight) { - set_mass(p_weight / real_t(GLOBAL_DEF("physics/3d/default_gravity", 9.8))); } real_t PhysicalBone3D::get_weight() const { - return mass * real_t(GLOBAL_DEF("physics/3d/default_gravity", 9.8)); } void PhysicalBone3D::set_friction(real_t p_friction) { - ERR_FAIL_COND(p_friction < 0 || p_friction > 1); friction = p_friction; @@ -2468,12 +2474,10 @@ void PhysicalBone3D::set_friction(real_t p_friction) { } real_t PhysicalBone3D::get_friction() const { - return friction; } void PhysicalBone3D::set_bounce(real_t p_bounce) { - ERR_FAIL_COND(p_bounce < 0 || p_bounce > 1); bounce = p_bounce; @@ -2481,43 +2485,64 @@ void PhysicalBone3D::set_bounce(real_t p_bounce) { } real_t PhysicalBone3D::get_bounce() const { - return bounce; } void PhysicalBone3D::set_gravity_scale(real_t p_gravity_scale) { - gravity_scale = p_gravity_scale; PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_GRAVITY_SCALE, gravity_scale); } real_t PhysicalBone3D::get_gravity_scale() const { - return gravity_scale; } -PhysicalBone3D::PhysicalBone3D() : - PhysicsBody3D(PhysicsServer3D::BODY_MODE_STATIC), -#ifdef TOOLS_ENABLED - gizmo_move_joint(false), -#endif - joint_data(NULL), - parent_skeleton(NULL), - simulate_physics(false), - _internal_simulate_physics(false), - bone_id(-1), - bone_name(""), - bounce(0), - mass(1), - friction(1), - gravity_scale(1) { +void PhysicalBone3D::set_linear_damp(real_t p_linear_damp) { + ERR_FAIL_COND(p_linear_damp < -1); + linear_damp = p_linear_damp; + PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_LINEAR_DAMP, linear_damp); +} + +real_t PhysicalBone3D::get_linear_damp() const { + return linear_damp; +} + +void PhysicalBone3D::set_angular_damp(real_t p_angular_damp) { + ERR_FAIL_COND(p_angular_damp < -1); + angular_damp = p_angular_damp; + PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP, angular_damp); +} + +real_t PhysicalBone3D::get_angular_damp() const { + return angular_damp; +} +void PhysicalBone3D::set_can_sleep(bool p_active) { + can_sleep = p_active; + PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_CAN_SLEEP, p_active); +} + +bool PhysicalBone3D::is_able_to_sleep() const { + return can_sleep; +} + +void PhysicalBone3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) { + PhysicsServer3D::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock); +} + +bool PhysicalBone3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const { + return PhysicsServer3D::get_singleton()->body_is_axis_locked(get_rid(), p_axis); +} + +PhysicalBone3D::PhysicalBone3D() : + PhysicsBody3D(PhysicsServer3D::BODY_MODE_STATIC) { reset_physics_simulation_state(); } PhysicalBone3D::~PhysicalBone3D() { - if (joint_data) + if (joint_data) { memdelete(joint_data); + } } void PhysicalBone3D::update_bone_id() { @@ -2546,10 +2571,10 @@ void PhysicalBone3D::update_bone_id() { void PhysicalBone3D::update_offset() { #ifdef TOOLS_ENABLED if (parent_skeleton) { - Transform bone_transform(parent_skeleton->get_global_transform()); - if (-1 != bone_id) + if (-1 != bone_id) { bone_transform *= parent_skeleton->get_bone_global_pose(bone_id); + } if (gizmo_move_joint) { bone_transform *= body_offset; @@ -2588,7 +2613,7 @@ void PhysicalBone3D::_stop_physics_simulation() { PhysicsServer3D::get_singleton()->body_set_collision_mask(get_rid(), 0); } if (_internal_simulate_physics) { - PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), NULL, ""); + PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), nullptr, ""); parent_skeleton->set_bone_global_pose_override(bone_id, Transform(), 0.0, false); set_as_toplevel(false); _internal_simulate_physics = false; |