[Bf-blender-cvs] [63f023111d] cloth-improvements: Apply collision responce on state before pre-collision solve (breaks selfcol)

Luca Rood noreply at git.blender.org
Sat Jan 14 06:19:14 CET 2017


Commit: 63f023111db02ec958dcdf562e0f501432c4bb5b
Author: Luca Rood
Date:   Thu Jan 12 19:13:33 2017 -0200
Branches: cloth-improvements
https://developer.blender.org/rB63f023111db02ec958dcdf562e0f501432c4bb5b

Apply collision responce on state before pre-collision solve (breaks selfcol)

This uses the pre-collision solve result only to find the collisions and
calculate the responce impulses, but rolls back to before the
pre-collision solve when it is time to actually apply the responce.

This prevents the cloth from undergoing a double solve per time-step,
which essentially made colliding clothes move much faster than
non-colliding clothes.

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

M	source/blender/blenkernel/BKE_cloth.h
M	source/blender/blenkernel/intern/collision.c
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/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index 52c8e9a472..c505e5fcbd 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -116,6 +116,7 @@ typedef struct ClothVertex {
 	float 	goal;		/* goal, from SB			*/
 	float	impulse[3];	/* used in collision.c */
 	float	xrest[3];   /* rest position of the vertex */
+	float	dcvel[3];	/* delta velocities to be applied by collision responce */
 	unsigned int impulse_count; /* same as above */
 	float 	avg_spring_len; /* average length of connected springs */
 	float 	struct_stiff;
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index a4dfd334d6..445881b394 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -662,6 +662,7 @@ static int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, Collision
 					if (verts[i].impulse_count) {
 						// VECADDMUL ( verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count );
 						VECADD ( verts[i].tv, verts[i].tv, verts[i].impulse);
+						VECADD ( verts[i].dcvel, verts[i].dcvel, verts[i].impulse);
 						zero_v3(verts[i].impulse);
 						verts[i].impulse_count = 0;
 
diff --git a/source/blender/physics/intern/BPH_mass_spring.cpp b/source/blender/physics/intern/BPH_mass_spring.cpp
index 90c5819a43..6077dc9e04 100644
--- a/source/blender/physics/intern/BPH_mass_spring.cpp
+++ b/source/blender/physics/intern/BPH_mass_spring.cpp
@@ -952,6 +952,7 @@ static void cloth_collision_solve_extra(Object *ob, ClothModifierData *clmd, Lis
 		
 		sub_v3_v3v3(verts[i].tv, verts[i].tx, verts[i].txold);
 		copy_v3_v3(verts[i].v, verts[i].tv);
+		zero_v3(verts[i].dcvel);
 	}
 	
 #if 0 /* unused */
@@ -964,47 +965,52 @@ static void cloth_collision_solve_extra(Object *ob, ClothModifierData *clmd, Lis
 	// 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);
 	
-	// copy corrected positions back to simulation
-	for (i = 0; i < mvert_num; i++) {
-		float curx[3];
-		BPH_mass_spring_get_position(id, i, curx);
-		// correct velocity again, just to be sure we had to change it due to adaptive collisions
-		sub_v3_v3v3(verts[i].tv, verts[i].tx, curx);
-	}
-	
 	if (do_extra_solve) {
+		ImplicitSolverResult result;
 //		cloth_calc_helper_forces(ob, clmd, initial_cos, step/clmd->sim_parms->timescale, dt/clmd->sim_parms->timescale);
 		
 		for (i = 0; i < mvert_num; i++) {
-		
-			float newv[3];
-			
 			if ((clmd->sim_parms->vgroup_mass>0) && (verts [i].flags & CLOTH_VERT_FLAG_PINNED))
 				continue;
-			
-			BPH_mass_spring_set_new_position(id, i, verts[i].tx);
-			mul_v3_v3fl(newv, verts[i].tv, spf);
-			BPH_mass_spring_set_new_velocity(id, i, newv);
+
+			/* Update position, based on old position, only applying delta caused by collision responce */
+			add_v3_v3v3(verts[i].tx, verts[i].txold, verts[i].dcvel);
+			BPH_mass_spring_set_position(id, i, verts[i].tx);
+
+			/* Update velocity, based on old velocity, only applying delta caused by collision responce */
+			BPH_mass_spring_get_velocity(id, i, verts[i].tv);
+			madd_v3_v3fl(verts[i].tv, verts[i].dcvel, spf);
+			BPH_mass_spring_set_velocity(id, i, verts[i].tv);
 		}
-	}
-	
-	if (do_extra_solve) {
-		ImplicitSolverResult result;
-		
-		// X = Xnew;
-		BPH_mass_spring_apply_result(id);
 
 		/* initialize forces to zero */
 		BPH_mass_spring_clear_forces(id);
 		
-		// calculate forces
+		/* calculate forces */
 		cloth_calc_force(clmd, frame, effectors, step, true);
 		
-		// calculate new velocity and position
+		/* solve new velocities */
 		BPH_mass_spring_solve_velocities(id, dt, &result);
 //		cloth_record_result(clmd, &result, clmd->sim_parms->stepsPerFrame);
-		
-		/* note: positions are advanced only once in the main solver step! */
+
+		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);
+		}
 	}
 }
 
diff --git a/source/blender/physics/intern/implicit.h b/source/blender/physics/intern/implicit.h
index 64df10aee1..207316287e 100644
--- a/source/blender/physics/intern/implicit.h
+++ b/source/blender/physics/intern/implicit.h
@@ -81,6 +81,7 @@ void BPH_mass_spring_set_position(struct Implicit_Data *data, int index, const f
 void BPH_mass_spring_set_velocity(struct Implicit_Data *data, int index, const float v[3]);
 void BPH_mass_spring_get_motion_state(struct Implicit_Data *data, int index, float x[3], float v[3]);
 void BPH_mass_spring_get_position(struct Implicit_Data *data, int index, float x[3]);
+void BPH_mass_spring_get_velocity(struct Implicit_Data *data, int index, float v[3]);
 
 /* access to modified motion state during solver step */
 void BPH_mass_spring_get_new_position(struct Implicit_Data *data, int index, float x[3]);
diff --git a/source/blender/physics/intern/implicit_blender.c b/source/blender/physics/intern/implicit_blender.c
index 4bfe82d7a4..0f17ed67ee 100644
--- a/source/blender/physics/intern/implicit_blender.c
+++ b/source/blender/physics/intern/implicit_blender.c
@@ -1204,6 +1204,11 @@ void BPH_mass_spring_set_new_position(struct Implicit_Data *data, int index, con
 	world_to_root_v3(data, index, data->Xnew[index], x);
 }
 
+void BPH_mass_spring_get_velocity(struct Implicit_Data *data, int index, float v[3])
+{
+	root_to_world_v3(data, index, v, data->V[index]);
+}
+
 void BPH_mass_spring_get_new_velocity(struct Implicit_Data *data, int index, float v[3])
 {
 	root_to_world_v3(data, index, v, data->Vnew[index]);




More information about the Bf-blender-cvs mailing list