[Bf-blender-cvs] [dfefd36] master: Fix T43406: Bring back cloth collisions.

Lukas Tönne noreply at git.blender.org
Sun Mar 1 12:37:47 CET 2015


Commit: dfefd3683710a4bf70cf90c874b65a9c118d2c06
Author: Lukas Tönne
Date:   Sun Mar 1 12:33:30 2015 +0100
Branches: master
https://developer.blender.org/rBdfefd3683710a4bf70cf90c874b65a9c118d2c06

Fix T43406: Bring back cloth collisions.

This was disabled during the course of hair dynamics work. The cloth
collision solution is based on a secondary velocity-only solver step.

While this approach is usable in general, the collision response
calculation still does not work well for hair meshes. Better contact
point generation is needed here (Bullet) and preferably an improved
solver for unilateral constraints.

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

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 6cddbc6..483dfd0 100644
--- a/source/blender/physics/intern/BPH_mass_spring.cpp
+++ b/source/blender/physics/intern/BPH_mass_spring.cpp
@@ -51,6 +51,11 @@ extern "C" {
 #include "BPH_mass_spring.h"
 #include "implicit.h"
 
+/* old collision stuff for cloth, use for continuity
+ * until a good replacement is ready
+ */
+#define USE_COLLISION_DOUBLE_SOLVE
+
 static float I3[3][3] = {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}};
 
 /* Number of off-diagonal non-zero matrix blocks.
@@ -214,6 +219,8 @@ static void cloth_setup_constraints(ClothModifierData *clmd, ColliderContacts *c
 	
 	const float ZERO[3] = {0.0f, 0.0f, 0.0f};
 	
+	BPH_mass_spring_clear_constraints(data);
+	
 	for (v = 0; v < numverts; v++) {
 		if (verts[v].flags & CLOTH_VERT_FLAG_PINNED) {
 			/* pinned vertex constraints */
@@ -848,6 +855,86 @@ static void cloth_calc_volume_force(ClothModifierData *clmd)
 }
 #endif
 
+static void cloth_collision_solve_extra(Object *ob, ClothModifierData *clmd, ListBase *effectors, float frame, float step, float dt)
+{
+	Cloth *cloth = clmd->clothObject;
+	Implicit_Data *id = cloth->implicit;
+	ClothVertex *verts = cloth->verts;
+	int numverts = cloth->numverts;
+	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))
+		return;
+	if (!clmd->clothObject->bvhtree)
+		return;
+	
+	// update verts to current positions
+	for (i = 0; i < numverts; i++) {
+		BPH_mass_spring_get_new_position(id, i, verts[i].tx);
+		
+		sub_v3_v3v3(verts[i].tv, verts[i].tx, verts[i].txold);
+		copy_v3_v3(verts[i].v, verts[i].tv);
+	}
+	
+#if 0 /* unused */
+	for (i=0, cv=cloth->verts; i<cloth->numverts; 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);
+	
+	// copy corrected positions back to simulation
+	for (i = 0; i < numverts; 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) {
+//		cloth_calc_helper_forces(ob, clmd, initial_cos, step/clmd->sim_parms->timescale, dt/clmd->sim_parms->timescale);
+		
+		for (i = 0; i < numverts; i++) {
+		
+			float newv[3];
+			
+			if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (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);
+		}
+	}
+	
+	// X = Xnew;
+	BPH_mass_spring_apply_result(id);
+	
+	if (do_extra_solve) {
+		ImplicitSolverResult result;
+		
+		/* initialize forces to zero */
+		BPH_mass_spring_clear_forces(id);
+		
+		// calculate forces
+		cloth_calc_force(clmd, frame, effectors, step);
+		
+		// calculate new velocity and position
+		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! */
+		
+		BPH_mass_spring_apply_result(id);
+	}
+}
+
 static void cloth_clear_result(ClothModifierData *clmd)
 {
 	ClothSolverResult *sres = clmd->solver_result;
@@ -897,8 +984,10 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
 	unsigned int numverts = cloth->numverts;
 	float dt = clmd->sim_parms->timescale / clmd->sim_parms->stepsPerFrame;
 	Implicit_Data *id = cloth->implicit;
+#ifndef USE_COLLISION_DOUBLE_SOLVE
 	ColliderContacts *contacts = NULL;
 	int totcolliders = 0;
+#endif
 	
 	BKE_sim_debug_data_clear_category("collision");
 	
@@ -921,16 +1010,13 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
 	while (step < tf) {
 		ImplicitSolverResult result;
 		
-		/* initialize forces to zero */
-		BPH_mass_spring_clear_forces(id);
-		BPH_mass_spring_clear_constraints(id);
-		
 		/* copy velocities for collision */
 		for (i = 0; i < numverts; i++) {
 			BPH_mass_spring_get_motion_state(id, i, NULL, verts[i].tv);
 			copy_v3_v3(verts[i].v, verts[i].tv);
 		}
 		
+#ifndef USE_COLLISION_DOUBLE_SOLVE
 		/* determine contact points */
 		if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED) {
 			if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_POINTS) {
@@ -940,6 +1026,13 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
 		
 		/* setup vertex constraints for pinned vertices and contacts */
 		cloth_setup_constraints(clmd, contacts, totcolliders, dt);
+#else
+		/* setup vertex constraints for pinned vertices */
+		cloth_setup_constraints(clmd, NULL, 0, dt);
+#endif
+		
+		/* initialize forces to zero */
+		BPH_mass_spring_clear_forces(id);
 		
 		// damping velocity for artistic reasons
 		// this is a bad way to do it, should be removed imo - lukas_t
@@ -963,6 +1056,10 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
 		
 		BPH_mass_spring_solve_positions(id, dt);
 		
+#ifdef USE_COLLISION_DOUBLE_SOLVE
+		cloth_collision_solve_extra(ob, clmd, effectors, frame, step, dt);
+#endif
+		
 		BPH_mass_spring_apply_result(id);
 		
 		/* move pinned verts to correct position */
@@ -978,10 +1075,12 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
 			BPH_mass_spring_get_motion_state(id, i, verts[i].txold, NULL);
 		}
 		
+#ifndef USE_COLLISION_DOUBLE_SOLVE
 		/* free contact points */
 		if (contacts) {
 			cloth_free_contacts(contacts, totcolliders);
 		}
+#endif
 		
 		step += dt;
 	}
diff --git a/source/blender/physics/intern/implicit.h b/source/blender/physics/intern/implicit.h
index 7ded479..d286d3d 100644
--- a/source/blender/physics/intern/implicit.h
+++ b/source/blender/physics/intern/implicit.h
@@ -82,7 +82,9 @@ void BPH_mass_spring_set_velocity(struct Implicit_Data *data, int index, const f
 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]);
 
-/* modified velocity during solver step */
+/* access to modified motion state during solver step */
+void BPH_mass_spring_get_new_position(struct Implicit_Data *data, int index, float x[3]);
+void BPH_mass_spring_set_new_position(struct Implicit_Data *data, int index, const float x[3]);
 void BPH_mass_spring_get_new_velocity(struct Implicit_Data *data, int index, float v[3]);
 void BPH_mass_spring_set_new_velocity(struct Implicit_Data *data, int index, const float v[3]);
 
diff --git a/source/blender/physics/intern/implicit_blender.c b/source/blender/physics/intern/implicit_blender.c
index e6ba55a..5b1d83a 100644
--- a/source/blender/physics/intern/implicit_blender.c
+++ b/source/blender/physics/intern/implicit_blender.c
@@ -1225,6 +1225,16 @@ void BPH_mass_spring_get_position(struct Implicit_Data *data, int index, float x
 	root_to_world_v3(data, index, x, data->X[index]);
 }
 
+void BPH_mass_spring_get_new_position(struct Implicit_Data *data, int index, float x[3])
+{
+	root_to_world_v3(data, index, x, data->Xnew[index]);
+}
+
+void BPH_mass_spring_set_new_position(struct Implicit_Data *data, int index, const float x[3])
+{
+	world_to_root_v3(data, index, data->Xnew[index], x);
+}
+
 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