diff options
Diffstat (limited to 'servers/physics_3d/godot_body_pair_3d.cpp')
-rw-r--r-- | servers/physics_3d/godot_body_pair_3d.cpp | 68 |
1 files changed, 38 insertions, 30 deletions
diff --git a/servers/physics_3d/godot_body_pair_3d.cpp b/servers/physics_3d/godot_body_pair_3d.cpp index 78e3bed007..ce3da390cb 100644 --- a/servers/physics_3d/godot_body_pair_3d.cpp +++ b/servers/physics_3d/godot_body_pair_3d.cpp @@ -364,16 +364,30 @@ bool GodotBodyPair3D::pre_solve(real_t p_step) { c.rA = global_A - A->get_center_of_mass(); c.rB = global_B - B->get_center_of_mass() - offset_B; + // Precompute normal mass, tangent mass, and bias. + Vector3 inertia_A = inv_inertia_tensor_A.xform(c.rA.cross(c.normal)); + Vector3 inertia_B = inv_inertia_tensor_B.xform(c.rB.cross(c.normal)); + real_t kNormal = inv_mass_A + inv_mass_B; + kNormal += c.normal.dot(inertia_A.cross(c.rA)) + c.normal.dot(inertia_B.cross(c.rB)); + c.mass_normal = 1.0f / kNormal; + + c.bias = -bias * inv_dt * MIN(0.0f, -depth + max_penetration); + c.depth = depth; + + Vector3 j_vec = c.normal * c.acc_normal_impulse + c.acc_tangent_impulse; + + c.acc_impulse -= j_vec; + // contact query reporting... if (A->can_report_contacts()) { Vector3 crA = A->get_angular_velocity().cross(c.rA) + A->get_linear_velocity(); - A->add_contact(global_A, -c.normal, depth, shape_A, global_B, shape_B, B->get_instance_id(), B->get_self(), crA); + A->add_contact(global_A, -c.normal, depth, shape_A, global_B, shape_B, B->get_instance_id(), B->get_self(), crA, c.acc_impulse); } if (B->can_report_contacts()) { Vector3 crB = B->get_angular_velocity().cross(c.rB) + B->get_linear_velocity(); - B->add_contact(global_B, c.normal, depth, shape_B, global_A, shape_A, A->get_instance_id(), A->get_self(), crB); + B->add_contact(global_B, c.normal, depth, shape_B, global_A, shape_A, A->get_instance_id(), A->get_self(), crB, -c.acc_impulse); } if (report_contacts_only) { @@ -384,17 +398,6 @@ bool GodotBodyPair3D::pre_solve(real_t p_step) { c.active = true; do_process = true; - // Precompute normal mass, tangent mass, and bias. - Vector3 inertia_A = inv_inertia_tensor_A.xform(c.rA.cross(c.normal)); - Vector3 inertia_B = inv_inertia_tensor_B.xform(c.rB.cross(c.normal)); - real_t kNormal = inv_mass_A + inv_mass_B; - kNormal += c.normal.dot(inertia_A.cross(c.rA)) + c.normal.dot(inertia_B.cross(c.rB)); - c.mass_normal = 1.0f / kNormal; - - c.bias = -bias * inv_dt * MIN(0.0f, -depth + max_penetration); - c.depth = depth; - - Vector3 j_vec = c.normal * c.acc_normal_impulse + c.acc_tangent_impulse; if (collide_A) { A->apply_impulse(-j_vec, c.rA + A->get_center_of_mass()); } @@ -504,6 +507,7 @@ void GodotBodyPair3D::solve(real_t p_step) { if (collide_B) { B->apply_impulse(j, c.rB + B->get_center_of_mass()); } + c.acc_impulse -= j; c.active = true; } @@ -550,6 +554,7 @@ void GodotBodyPair3D::solve(real_t p_step) { if (collide_B) { B->apply_impulse(jt, c.rB + B->get_center_of_mass()); } + c.acc_impulse -= jt; c.active = true; } @@ -745,23 +750,6 @@ bool GodotBodySoftBodyPair3D::pre_solve(real_t p_step) { c.rA = global_A - transform_A.origin - body->get_center_of_mass(); c.rB = global_B; - if (body->can_report_contacts()) { - Vector3 crA = body->get_angular_velocity().cross(c.rA) + body->get_linear_velocity(); - body->add_contact(global_A, -c.normal, depth, body_shape, global_B, 0, soft_body->get_instance_id(), soft_body->get_self(), crA); - } - - if (report_contacts_only) { - collided = false; - continue; - } - - c.active = true; - do_process = true; - - if (body_collides) { - body->set_active(true); - } - // Precompute normal mass, tangent mass, and bias. Vector3 inertia_A = body_inv_inertia_tensor.xform(c.rA.cross(c.normal)); real_t kNormal = body_inv_mass + node_inv_mass; @@ -778,6 +766,24 @@ bool GodotBodySoftBodyPair3D::pre_solve(real_t p_step) { if (soft_body_collides) { soft_body->apply_node_impulse(c.index_B, j_vec); } + c.acc_impulse -= j_vec; + + if (body->can_report_contacts()) { + Vector3 crA = body->get_angular_velocity().cross(c.rA) + body->get_linear_velocity(); + body->add_contact(global_A, -c.normal, depth, body_shape, global_B, 0, soft_body->get_instance_id(), soft_body->get_self(), crA, c.acc_impulse); + } + + if (report_contacts_only) { + collided = false; + continue; + } + + c.active = true; + do_process = true; + + if (body_collides) { + body->set_active(true); + } c.bounce = body->get_bounce(); @@ -880,6 +886,7 @@ void GodotBodySoftBodyPair3D::solve(real_t p_step) { if (soft_body_collides) { soft_body->apply_node_impulse(c.index_B, j); } + c.acc_impulse -= j; c.active = true; } @@ -924,6 +931,7 @@ void GodotBodySoftBodyPair3D::solve(real_t p_step) { if (soft_body_collides) { soft_body->apply_node_impulse(c.index_B, jt); } + c.acc_impulse -= jt; c.active = true; } |