[Bf-blender-cvs] [ade28fe8a2] cloth-improvements: Optimization: Use inertial solve for pre-collision

Luca Rood noreply at git.blender.org
Mon Jan 30 06:55:13 CET 2017


Commit: ade28fe8a2abce1a3237c385ba7bdeb4338e0bdb
Author: Luca Rood
Date:   Mon Jan 30 03:47:11 2017 -0200
Branches: cloth-improvements
https://developer.blender.org/rBade28fe8a2abce1a3237c385ba7bdeb4338e0bdb

Optimization: Use inertial solve for pre-collision

Instead of doing a full implicit pre-collision solve, do a simple
inertial solve (avance using velocities from previous step), this saves
time by doing one less solve per step, and also improves resting
stability by eliminating the influence of external forces disturbing the
mesh in contacting areas.

This improves general cloth performance by about 30-40% in relation to
the new cloth code, and improves performance by about 3 times in
relation to the original cloth code. This also makes collisions more
reliable by removing the need for positional interpolation, and thus
decreases the number of subframes required for a successful solve.

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

M	source/blender/physics/intern/BPH_mass_spring.cpp
M	source/blender/physics/intern/implicit.h
M	source/blender/physics/intern/implicit_blender.c

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

diff --git a/source/blender/physics/intern/BPH_mass_spring.cpp b/source/blender/physics/intern/BPH_mass_spring.cpp
index eb0b1a4bed..1c5dbbe426 100644
--- a/source/blender/physics/intern/BPH_mass_spring.cpp
+++ b/source/blender/physics/intern/BPH_mass_spring.cpp
@@ -927,25 +927,25 @@ static void cloth_calc_volume_force(ClothModifierData *clmd)
 }
 #endif
 
-/* old collision stuff for cloth, use for continuity
- * until a good replacement is ready
- */
-static void cloth_collision_solve_extra(Object *ob, ClothModifierData *clmd, ListBase *effectors, float frame, float step, float dt)
+static void cloth_solve_collisions(Object *ob, ClothModifierData *clmd, float step, float dt)
 {
 	Cloth *cloth = clmd->clothObject;
 	Implicit_Data *id = cloth->implicit;
 	ClothVertex *verts = cloth->verts;
 	int mvert_num = cloth->mvert_num;
 	const float spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;
-	
-	bool do_extra_solve;
 	int i;
 	
 	if (!(clmd->coll_parms->flags & (CLOTH_COLLSETTINGS_FLAG_ENABLED | CLOTH_COLLSETTINGS_FLAG_SELF)))
 		return;
 	if (!clmd->clothObject->bvhtree)
 		return;
-	
+
+	/* do inertial solve */
+	BPH_mass_spring_solve_velocities_inertial(id);
+
+	BPH_mass_spring_solve_positions(id, dt);
+
 	// update verts to current positions
 	for (i = 0; i < mvert_num; i++) {
 		BPH_mass_spring_get_new_position(id, i, verts[i].tx);
@@ -955,20 +955,10 @@ static void cloth_collision_solve_extra(Object *ob, ClothModifierData *clmd, Lis
 		zero_v3(verts[i].dcvel);
 	}
 	
-#if 0 /* unused */
-	for (i=0, cv=cloth->verts; i<cloth->mvert_num; i++, cv++) {
-		copy_v3_v3(initial_cos[i], cv->tx);
-	}
-#endif
-	
 	// call collision function
 	// TODO: check if "step" or "step+dt" is correct - dg
-	do_extra_solve = cloth_bvh_objcollision(ob, clmd, step / clmd->sim_parms->timescale, dt / clmd->sim_parms->timescale);
 	
-	if (do_extra_solve) {
-		ImplicitSolverResult result;
-//		cloth_calc_helper_forces(ob, clmd, initial_cos, step/clmd->sim_parms->timescale, dt/clmd->sim_parms->timescale);
-		
+	if (cloth_bvh_objcollision(ob, clmd, step / clmd->sim_parms->timescale, dt / clmd->sim_parms->timescale)) {
 		for (i = 0; i < mvert_num; i++) {
 			if ((clmd->sim_parms->vgroup_mass>0) && (verts [i].flags & CLOTH_VERT_FLAG_PINNED))
 				continue;
@@ -982,35 +972,6 @@ static void cloth_collision_solve_extra(Object *ob, ClothModifierData *clmd, Lis
 			madd_v3_v3fl(verts[i].tv, verts[i].dcvel, spf);
 			BPH_mass_spring_set_velocity(id, i, verts[i].tv);
 		}
-
-		/* initialize forces to zero */
-		BPH_mass_spring_clear_forces(id);
-		
-		/* calculate forces */
-		cloth_calc_force(clmd, frame, effectors, step, true);
-		
-		/* solve new velocities */
-		BPH_mass_spring_solve_velocities(id, dt, &result);
-//		cloth_record_result(clmd, &result, clmd->sim_parms->stepsPerFrame);
-
-		for (i = 0; i < mvert_num; i++) {
-			float prex[3];
-
-			/* Get position calculated in pre-collision solve */
-			BPH_mass_spring_get_new_position(id, i, prex);
-
-			/* Solve new possition from old position and velocity solved after collision responce */
-			BPH_mass_spring_get_position(id, i, verts[i].tx);
-			BPH_mass_spring_get_new_velocity(id, i, verts[i].tv);
-			madd_v3_v3fl(verts[i].tx, verts[i].tv, dt);
-
-			/* Apply the average position between pre-collision and post-collision solves,
-			 * this is by no means a physically based operation, but it make resting contacts much more stable
-			 * than if the post-collision positions were fully applied.
-			 * Note that the velocities are nonetheless fully post-collision solved (done above). */
-			mid_v3_v3v3(verts[i].tx, prex, verts[i].tx);
-			BPH_mass_spring_set_new_position(id, i, verts[i].tx);
-		}
 	}
 }
 
@@ -1099,6 +1060,7 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
 		for (i = 0; i < mvert_num; i++) {
 			BPH_mass_spring_get_motion_state(id, i, NULL, verts[i].tv);
 			copy_v3_v3(verts[i].v, verts[i].tv);
+
 		}
 		
 		if (is_hair) {
@@ -1129,6 +1091,11 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
 			}
 		}
 		
+		// calculate collision impulses
+		if (!is_hair) {
+			cloth_solve_collisions(ob, clmd, step, dt);
+		}
+
 		// calculate forces
 		cloth_calc_force(clmd, frame, effectors, step, false);
 		
@@ -1142,10 +1109,6 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
 		
 		BPH_mass_spring_solve_positions(id, dt);
 		
-		if (!is_hair) {
-			cloth_collision_solve_extra(ob, clmd, effectors, frame, step, dt);
-		}
-		
 		BPH_mass_spring_apply_result(id);
 		
 		/* move pinned verts to correct position */
diff --git a/source/blender/physics/intern/implicit.h b/source/blender/physics/intern/implicit.h
index 207316287e..c561a4d171 100644
--- a/source/blender/physics/intern/implicit.h
+++ b/source/blender/physics/intern/implicit.h
@@ -95,6 +95,7 @@ void BPH_mass_spring_add_constraint_ndof1(struct Implicit_Data *data, int index,
 void BPH_mass_spring_add_constraint_ndof2(struct Implicit_Data *data, int index, const float c1[3], const float dV[3]);
 
 bool BPH_mass_spring_solve_velocities(struct Implicit_Data *data, float dt, struct ImplicitSolverResult *result);
+void BPH_mass_spring_solve_velocities_inertial(struct Implicit_Data *data);
 bool BPH_mass_spring_solve_positions(struct Implicit_Data *data, float dt);
 void BPH_mass_spring_apply_result(struct Implicit_Data *data);
 
diff --git a/source/blender/physics/intern/implicit_blender.c b/source/blender/physics/intern/implicit_blender.c
index 801c548840..502df1c8b4 100644
--- a/source/blender/physics/intern/implicit_blender.c
+++ b/source/blender/physics/intern/implicit_blender.c
@@ -1134,6 +1134,11 @@ bool BPH_mass_spring_solve_velocities(Implicit_Data *data, float dt, ImplicitSol
 	return result->status == BPH_SOLVER_SUCCESS;
 }
 
+void BPH_mass_spring_solve_velocities_inertial(Implicit_Data *data)
+{
+	cp_lfvector(data->Vnew, data->V, data->M[0].vcount);
+}
+
 bool BPH_mass_spring_solve_positions(Implicit_Data *data, float dt)
 {
 	int numverts = data->M[0].vcount;




More information about the Bf-blender-cvs mailing list