[Bf-blender-cvs] [ca154310a6b] soc-2021-simulation-display: Cleanup: Fixed missed forces bug by taking the average of all forces applied in one timestep.

soumya pochiraju noreply at git.blender.org
Thu Jul 15 11:17:56 CEST 2021


Commit: ca154310a6b1cbd03657ce127a40fe2dd2c84c9d
Author: soumya pochiraju
Date:   Thu Jul 15 14:45:08 2021 +0530
Branches: soc-2021-simulation-display
https://developer.blender.org/rBca154310a6b1cbd03657ce127a40fe2dd2c84c9d

Cleanup: Fixed missed forces bug by taking the average of all forces applied in one timestep.

===================================================================

M	intern/rigidbody/RBI_api.h
M	intern/rigidbody/rb_bullet_api.cpp
M	source/blender/blenkernel/intern/rigidbody.c

===================================================================

diff --git a/intern/rigidbody/RBI_api.h b/intern/rigidbody/RBI_api.h
index 59500d1a234..bc92a9afc07 100644
--- a/intern/rigidbody/RBI_api.h
+++ b/intern/rigidbody/RBI_api.h
@@ -88,8 +88,8 @@ void RB_dworld_get_impulse(rbDynamicsWorld *world,
                            float norm_forces[3][3],
                            float fric_forces[3][3],
                            float vec_locations[3][3],
-                           int norm_flag,
-                           int fric_flag);
+                           bool norm_flag,
+                           bool fric_flag);
 
 /* Simulation ----------------------- */
 
diff --git a/intern/rigidbody/rb_bullet_api.cpp b/intern/rigidbody/rb_bullet_api.cpp
index 425f65b346d..c9ac3d9f2d3 100644
--- a/intern/rigidbody/rb_bullet_api.cpp
+++ b/intern/rigidbody/rb_bullet_api.cpp
@@ -213,36 +213,44 @@ void RB_dworld_get_impulse(rbDynamicsWorld *world,
                            float norm_forces[3][3],
                            float fric_forces[3][3],
                            float vec_locations[3][3],
-                           int norm_flag,
-                           int fric_flag)
+                           bool norm_flag,
+                           bool fric_flag)
 {
   int numManifolds = world->dispatcher->getNumManifolds();
   int num_norm_forces = 0;
   int num_fric_forces = 0;
+
+  /*Loop thrhough all persisent contact manifolds. */
   for (int i = 0; i < numManifolds; i++) {
     btPersistentManifold *contactManifold = world->dispatcher->getManifoldByIndexInternal(i);
     const void *obA = contactManifold->getBody0();
     const void *obB = contactManifold->getBody1();
-    if (num_norm_forces > 2)
+
+    /* Break if we cannot store any more forces. */
+    /* Friction cannot exist without a normal force, so counting number of normal forces stored is enough. */
+    if (num_norm_forces > 2) {
       break;
-        if (obA != rbo->body && obB != rbo->body) {
-          continue;
-        }
-        else {
+    }
+    /* Continue to next manifold if this one does not invlove the current rigid body. */
+    if (obA != rbo->body && obB != rbo->body) {
+      continue;
+    }
+    else {
       btVector3 tot_impulse = btVector3(0.0, 0.0, 0.0);
       btVector3 final_loc = btVector3(0.0, 0.0, 0.0);
       btScalar tot_impulse_magnitude = 0.f;
       btVector3 tot_lat_impulse = btVector3(0.0, 0.0, 0.0);
       int numContacts = contactManifold->getNumContacts();
       int num_impulse_points = 0;
+      /* Find points where impulse was appplied. */
       for (int j = 0; j < numContacts; j++) {
-        /* Find points where impulse was appplied. */
         btManifoldPoint &pt = contactManifold->getContactPoint(j);
         if (pt.getAppliedImpulse() > 0.f || -pt.getAppliedImpulse() > 0.f) {
           num_impulse_points++;
         }
       }
 
+      /* Loop throught contact points and add impulses applied at each point. */
       for (int j = 0; j < numContacts; j++) {
         btManifoldPoint &pt = contactManifold->getContactPoint(j);
         if (pt.getAppliedImpulse() > 0.f || -pt.getAppliedImpulse() > 0.f) {
@@ -250,7 +258,7 @@ void RB_dworld_get_impulse(rbDynamicsWorld *world,
           const btVector3 imp = (rbo->body == obB) ?
                                     -pt.m_normalWorldOnB * pt.getAppliedImpulse() / timeSubStep :
                                     pt.m_normalWorldOnB * pt.getAppliedImpulse() / timeSubStep;
-          tot_impulse_magnitude += pt.getAppliedImpulse();
+          tot_impulse_magnitude += pt.getAppliedImpulse() > 0.f? pt.getAppliedImpulse() : -pt.getAppliedImpulse();
           tot_impulse += imp;
           final_loc += num_impulse_points > 1 ? loc * pt.getAppliedImpulse() : loc;
           if (fric_flag) {
@@ -268,9 +276,14 @@ void RB_dworld_get_impulse(rbDynamicsWorld *world,
           }
         }
       }
-
-      if (num_impulse_points > 1)
+      /* If impulse was applied at more than one point, the location of the force is taken as average of points
+       * weighted by magnitude of impulse applied at each point. */
+      if(fabsf(tot_impulse_magnitude)==0.0f){
+          continue;
+      }
+      if (num_impulse_points > 1) {
         final_loc = final_loc / tot_impulse_magnitude;
+      }
       copy_v3_btvec3(vec_locations[num_norm_forces], final_loc);
       if (norm_flag) {
         copy_v3_btvec3(norm_forces[num_norm_forces], tot_impulse);
@@ -937,10 +950,6 @@ rbCollisionShape *RB_shape_new_gimpact_mesh(rbMeshData *mesh)
   return shape;
 }
 
-void RB_mesh_collision_shape_draw_data(rbCollisionShape *shape) {
-
-}
-
 /* Compound Shape ---------------- */
 
 rbCollisionShape *RB_shape_new_compound()
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index a88dd689324..5ef22ae659a 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -461,7 +461,6 @@ static void rigidbody_store_convex_hull_draw_data(Object *ob) {
         int reverse_index = plConvexHullGetReversedLoopIndex(hull, i);
         mloop_src[i].e = edge_index;
         mloop_src[reverse_index].e = edge_index;
-        printf("edge verts:%d %d  loop,rev:%d,%d, edge:%d\n", v_from, v_to, i, reverse_index, (int)edge_index);
         edge_index++;
 
       }
@@ -488,7 +487,6 @@ static void rigidbody_store_convex_hull_draw_data(Object *ob) {
         loop->v = src_loop.v;
         loop->e = src_loop.e;
         loop++;
-        printf("loop: v:%d e:%d\n", (int)src_loop.v, (int)src_loop.e);
       }
       j += len;
       MEM_freeN(loops);
@@ -2409,30 +2407,40 @@ void BKE_rigidbody_do_simulation(Depsgraph *depsgraph, Scene *scene, float ctime
     const float interp_step = 1.0f / rbw->substeps_per_frame;
     float cur_interp_val = interp_step;
 
-    /* Set all Objects normal forces to zero. */
+    /* Set all contact forces and their locations to zero. (for drawing debug info) */
     for (int i = 0; i < rbw->numbodies; i++) {
         Object *ob = rbw->objects[i];
-        zero_v3(ob->rigidbody_object->norm_forces[0].vector);
-        zero_v3(ob->rigidbody_object->norm_forces[1].vector);
-        zero_v3(ob->rigidbody_object->norm_forces[2].vector);
+        for(int j=0; j<3; j++) {
+          zero_v3(ob->rigidbody_object->norm_forces[j].vector);
+          zero_v3(ob->rigidbody_object->vec_locations[j].vector);
+          zero_v3(ob->rigidbody_object->fric_forces[j].vector);
+        }
     }
 
     for (int i = 0; i < rbw->substeps_per_frame; i++) {
       rigidbody_update_kinematic_obj_substep(&substep_targets, cur_interp_val);
       RB_dworld_step_simulation(rbw->shared->physics_world, substep, 0, substep);
       cur_interp_val += interp_step;
+
+      /*Loop through all rigid bodies and get the forces being applied in the substep (for drawing debug info).
+       * Store average force acting on objects during all substeps.
+       * We store the average of the forces and not the forces themselves, because storing forces
+       * would mean that only the force applied in the last substep is displayed on the screen.
+       * Average is a better representation of what happened during the whole timestep.*/
       for (int j = 0; j < rbw->numbodies; j++) {
 
+        float num_substeps = (float)rbw->substeps_per_frame;
+
         float norm_forces[3][3] = {{0.0f}};
         float fric_forces[3][3] = {{0.0f}};
         float vec_locations[3][3] = {{0.0f}};
         Object *ob = rbw->objects[j];
         if (ob->rigidbody_object != NULL) {
           rbRigidBody *rbo = (rbRigidBody *)(ob->rigidbody_object->shared->physics_object);
-          int norm_flag = (ob->rigidbody_object->display_force_types & RB_SIM_NORMAL) ||
+          bool norm_flag = (ob->rigidbody_object->display_force_types & RB_SIM_NORMAL) ||
                           (ob->rigidbody_object->display_force_types & RB_SIM_NET_FORCE) ||
                           (ob->rigidbody_object->sim_display_options & RB_SIM_COLLISIONS);
-          int fric_flag = (ob->rigidbody_object->display_force_types & RB_SIM_FRICTION) ||
+          bool fric_flag = (ob->rigidbody_object->display_force_types & RB_SIM_FRICTION) ||
                           (ob->rigidbody_object->display_force_types & RB_SIM_NET_FORCE);
           if (norm_flag || fric_flag) {
             RB_dworld_get_impulse(rbw->shared->physics_world,
@@ -2444,20 +2452,30 @@ void BKE_rigidbody_do_simulation(Depsgraph *depsgraph, Scene *scene, float ctime
                                   norm_flag,
                                   fric_flag);
             for(int k=0; k<3; k++){
-              if(len_v3(norm_forces[k])>len_v3(ob->rigidbody_object->norm_forces[k].vector)){
-                copy_v3_v3(ob->rigidbody_object->vec_locations[k].vector, vec_locations[k]);
-                if (norm_flag) {
-                  copy_v3_v3(ob->rigidbody_object->norm_forces[k].vector, norm_forces[k]);
+                 if (norm_flag || fric_flag) {
+
+                   //printf("loc0:%f %f %f\n", ob->rigidbody_object->vec_locations[k].vector[0], ob->rigidbody_object->vec_locations[k].vector[1], ob->rigidbody_object->vec_locations[k].vector[2]);
+                   //printf("loc1:%f %f %f\n", ob->rigidbody_object->vec_locations[k].vector[0], ob->rigidbody_object->vec_locations[k].vector[1], ob->rigidbody_object->vec_locations[k].vector[2]);
+
+                  mul_v3_fl(norm_forces[k], 1/num_substeps);
+                  add_v3_v3(ob->rigidbody_object->norm_forces[k].vector, norm_forces[k]);
+                  mul_v3_fl(vec_locations[k], len_v3(norm_forces[k]));
+                  add_v3_v3(ob->rigidbody_object->vec_locations[k].vector, vec_locations[k]);
                 }
                 if (fric_flag) {
-                  copy_v3_v3(ob->rigidbody_object->fric_forces[k].vector, fric_forces[k]);
+                  mul_v3_fl(fric_forces[k], 1/num_substeps);
+                  add_v3_v3(ob->rigidbody_object->fric_forces[k].vector, fric_forces[k]);
+                }
+
+                if(i == (int)num_substeps-1 && fabsf(len_v3(ob->rigidbody_object->norm_forces[k].vector))>0.0f) {
+                    mul_v3_fl(ob->rigidbody_object->vec_locations[k].vector, (1.0f/(float)

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list