|
@@ -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;
|
|
|
}
|