summaryrefslogtreecommitdiffstats
path: root/servers/physics_3d/godot_body_pair_3d.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'servers/physics_3d/godot_body_pair_3d.cpp')
-rw-r--r--servers/physics_3d/godot_body_pair_3d.cpp68
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;
}