[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