[Bf-blender-cvs] [68275a4] hair_immediate_fixes: Added back spring force definitions outside the implicit solver.

Lukas Tönne noreply at git.blender.org
Mon Sep 15 14:23:23 CEST 2014


Commit: 68275a412d2afa78e9c22cbf809f3563c5586422
Author: Lukas Tönne
Date:   Mon Sep 15 12:10:49 2014 +0200
Branches: hair_immediate_fixes
https://developer.blender.org/rB68275a412d2afa78e9c22cbf809f3563c5586422

Added back spring force definitions outside the implicit solver.

There are currently 3 types of springs: basic linear springs, goal
springs toward a fixed global target (not recommended, but works) and
bending springs.

These are agnostic to the specific spring definition in the cloth system
so hair systems can use the same API without converting everything to
cloth first.

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

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 abff8f9..974fe67 100644
--- a/source/blender/physics/intern/BPH_mass_spring.cpp
+++ b/source/blender/physics/intern/BPH_mass_spring.cpp
@@ -320,6 +320,72 @@ static int UNUSED_FUNCTION(cloth_calc_helper_forces)(Object *UNUSED(ob), ClothMo
 	return 1;
 }
 
+BLI_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, float time)
+{
+	Cloth *cloth = clmd->clothObject;
+	ClothSimSettings *parms = clmd->sim_parms;
+	Implicit_Data *data = cloth->implicit;
+	ClothVertex *verts = cloth->verts;
+	
+	bool no_compress = parms->flags & CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS;
+	
+	zero_v3(s->f);
+	zero_m3(s->dfdx);
+	zero_m3(s->dfdv);
+	
+	s->flags &= ~CLOTH_SPRING_FLAG_NEEDED;
+	
+	// calculate force of structural + shear springs
+	if ((s->type & CLOTH_SPRING_TYPE_STRUCTURAL) || (s->type & CLOTH_SPRING_TYPE_SHEAR) || (s->type & CLOTH_SPRING_TYPE_SEWING) ) {
+#ifdef CLOTH_FORCE_SPRING_STRUCTURAL
+		float k, scaling;
+		
+		s->flags |= CLOTH_SPRING_FLAG_NEEDED;
+		
+		scaling = parms->structural + s->stiffness * fabsf(parms->max_struct - parms->structural);
+		k = scaling / (parms->avg_spring_len + FLT_EPSILON);
+		
+		if (s->type & CLOTH_SPRING_TYPE_SEWING) {
+			// TODO: verify, half verified (couldn't see error)
+			// sewing springs usually have a large distance at first so clamp the force so we don't get tunnelling through colission objects
+			BPH_mass_spring_force_spring_linear(data, s->ij, s->kl, s->matrix_index, s->restlen, k, parms->Cdis, no_compress, parms->max_sewing, s->f, s->dfdx, s->dfdv);
+		}
+		else {
+			BPH_mass_spring_force_spring_linear(data, s->ij, s->kl, s->matrix_index, s->restlen, k, parms->Cdis, no_compress, 0.0f, s->f, s->dfdx, s->dfdv);
+		}
+#endif
+	}
+	else if (s->type & CLOTH_SPRING_TYPE_GOAL) {
+#ifdef CLOTH_FORCE_SPRING_GOAL
+		float goal_x[3], goal_v[3];
+		float k, scaling;
+		
+		s->flags |= CLOTH_SPRING_FLAG_NEEDED;
+		
+		// current_position = xold + t * (newposition - xold)
+		interp_v3_v3v3(goal_x, verts[s->ij].xold, verts[s->ij].xconst, time);
+		sub_v3_v3v3(goal_v, verts[s->ij].xconst, verts[s->ij].xold); // distance covered over dt==1
+		
+		scaling = parms->goalspring + s->stiffness * fabsf(parms->max_struct - parms->goalspring);
+		k = verts[s->ij].goal * scaling / (parms->avg_spring_len + FLT_EPSILON);
+		
+		BPH_mass_spring_force_spring_goal(data, s->ij, s->matrix_index, goal_x, goal_v, k, parms->goalfrict * 0.01f, s->f, s->dfdx, s->dfdv);
+#endif
+	}
+	else {  /* calculate force of bending springs */
+#ifdef CLOTH_FORCE_SPRING_BEND
+		float kb, cb, scaling;
+		
+		s->flags |= CLOTH_SPRING_FLAG_NEEDED;
+		
+		scaling = parms->bending + s->stiffness * fabsf(parms->max_bend - parms->bending);
+		cb = kb = scaling / (20.0f * (parms->avg_spring_len + FLT_EPSILON));
+		
+		BPH_mass_spring_force_spring_bending(data, s->ij, s->kl, s->matrix_index, s->restlen, kb, cb, s->f, s->dfdx, s->dfdv);
+#endif
+	}
+}
+
 static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListBase *effectors, float time)
 {
 	/* Collect forces and derivatives:  F, dFdX, dFdV */
@@ -382,29 +448,13 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListB
 		MEM_freeN(winvec);
 	}
 	
-#if 0
 	// calculate spring forces
-	link = cloth->springs;
-	while (link) {
-		// only handle active springs
-		ClothSpring *spring = link->link;
-		if (!(spring->flags & CLOTH_SPRING_FLAG_DEACTIVATE))
-			cloth_calc_spring_force(clmd, link->link, lF, lX, lV, dFdV, dFdX, time);
-
-		link = link->next;
-	}
-	
-	// apply spring forces
-	link = cloth->springs;
-	while (link) {
+	for (LinkNode *link = cloth->springs; link; link = link->next) {
+		ClothSpring *spring = (ClothSpring *)link->link;
 		// only handle active springs
-		ClothSpring *spring = link->link;
 		if (!(spring->flags & CLOTH_SPRING_FLAG_DEACTIVATE))
-			cloth_apply_spring_force(clmd, link->link, lF, lX, lV, dFdV, dFdX);
-		link = link->next;
+			cloth_calc_spring_force(clmd, spring, time);
 	}
-	// printf("\n");
-#endif
 }
 
 int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors)
diff --git a/source/blender/physics/intern/implicit.h b/source/blender/physics/intern/implicit.h
index c9e8fb2..c7becfd 100644
--- a/source/blender/physics/intern/implicit.h
+++ b/source/blender/physics/intern/implicit.h
@@ -123,6 +123,15 @@ void BPH_mass_spring_force_gravity(struct Implicit_Data *data, const float g[3])
 void BPH_mass_spring_force_drag(struct Implicit_Data *data, float drag);
 void BPH_mass_spring_force_face_wind(struct Implicit_Data *data, int v1, int v2, int v3, int v4, const float (*winvec)[3]);
 void BPH_mass_spring_force_edge_wind(struct Implicit_Data *data, int v1, int v2, const float (*winvec)[3]);
+bool BPH_mass_spring_force_spring_linear(struct Implicit_Data *data, int i, int j, int spring_index, float restlen,
+                                         float stiffness, float damping, bool no_compress, float clamp_force,
+                                         float r_f[3], float r_dfdx[3][3], float r_dfdv[3][3]);
+bool BPH_mass_spring_force_spring_bending(struct Implicit_Data *data, int i, int j, int spring_index, float restlen,
+                                          float kb, float cb,
+                                          float r_f[3], float r_dfdx[3][3], float r_dfdv[3][3]);
+bool BPH_mass_spring_force_spring_goal(struct Implicit_Data *data, int i, int spring_index, const float goal_x[3], const float goal_v[3],
+                                       float stiffness, float damping,
+                                       float r_f[3], float r_dfdx[3][3], float r_dfdv[3][3]);
 
 #ifdef __cplusplus
 }
diff --git a/source/blender/physics/intern/implicit_blender.c b/source/blender/physics/intern/implicit_blender.c
index 5b81844..49c617e 100644
--- a/source/blender/physics/intern/implicit_blender.c
+++ b/source/blender/physics/intern/implicit_blender.c
@@ -573,6 +573,13 @@ DO_INLINE void mulsub_fmatrix_fvector(float to[3], float matrix[3][3], float fro
 	to[1] -= dot_v3v3(matrix[1], from);
 	to[2] -= dot_v3v3(matrix[2], from);
 }
+
+BLI_INLINE void outerproduct(float r[3][3], const float a[3], const float b[3])
+{
+	mul_v3_v3fl(r[0], a, b[0]);
+	mul_v3_v3fl(r[1], a, b[1]);
+	mul_v3_v3fl(r[2], a, b[2]);
+}
 /////////////////////////////////////////////////////////////////
 
 ///////////////////////////
@@ -1112,6 +1119,7 @@ BLI_INLINE void dfdv_root_to_world(float m[3][3], float dfdv[3][3], float mass,
 
 /* ================================ */
 
+#if 0
 DO_INLINE float fb(float length, float L)
 {
 	float x = length / L;
@@ -1149,6 +1157,7 @@ DO_INLINE float fbstar_jacobi(float length, float L, float kb, float cb)
 		return kb * fbderiv(length, L);
 	}
 }
+#endif
 
 DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
 {
@@ -1497,231 +1506,6 @@ static int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector
 }
 #endif
 
-// outer product is NOT cross product!!!
-DO_INLINE void dfdx_spring_type1(float to[3][3], float extent[3], float length, float L, float dot, float k)
-{
-	// dir is unit length direction, rest is spring's restlength, k is spring constant.
-	// return  (outerprod(dir, dir)*k + (I - outerprod(dir, dir))*(k - ((k*L)/length)));
-	float temp[3][3];
-	float temp1 = k * (1.0f - (L / length));
-	
-	mul_fvectorT_fvectorS(temp, extent, extent, 1.0f / dot);
-	sub_fmatrix_fmatrix(to, I, temp);
-	mul_fmatrix_S(to, temp1);
-	
-	mul_fvectorT_fvectorS(temp, extent, extent, k/ dot);
-	add_fmatrix_fmatrix(to, to, temp);
-	
-	/*
-	mul_fvectorT_fvector(temp, dir, dir);
-	sub_fmatrix_fmatrix(to, I, temp);
-	mul_fmatrix_S(to, k* (1.0f-(L/length)));
-	mul_fmatrix_S(temp, k);
-	add_fmatrix_fmatrix(to, temp, to);
-	*/
-}
-
-DO_INLINE void dfdx_spring_type2(float to[3][3], float dir[3], float length, float L, float k, float cb)
-{
-	// return  outerprod(dir, dir)*fbstar_jacobi(length, L, k, cb);
-	mul_fvectorT_fvectorS(to, dir, dir, fbstar_jacobi(length, L, k, cb));
-}
-
-DO_INLINE void dfdv_damp(float to[3][3], float dir[3], float damping)
-{
-	// derivative of force wrt velocity.  
-	mul_fvectorT_fvectorS(to, dir, dir, damping);
-	
-}
-
-DO_INLINE void dfdx_spring(float to[3][3],  float dir[3], float length, float L, float k)
-{
-	// dir is unit length direction, rest is spring's restlength, k is spring constant.
-	//return  ( (I-outerprod(dir, dir))*Min(1.0f, rest/length) - I) * -k;
-	mul_fvectorT_fvector(to, dir, dir);
-	sub_fmatrix_fmatrix(to, I, to);
-
-	mul_fmatrix_S(to, (L/length)); 
-	sub_fmatrix_fmatrix(to, to, I);
-	mul_fmatrix_S(to, -k);
-}
-
-// unused atm
-DO_INLINE void dfdx_damp(float to[3][3],  float dir[3], float length, const float vel[3], float rest, float damping)
-{
-	// inner spring damping   vel is the relative velocity  of the endpoints.  
-	// 	return (I-outerprod(dir, dir)) * (-damping * -(dot(dir, vel)/Max(length, rest)));
-	mul_fvectorT_fvector(to, dir, dir);
-	sub_fmatrix_fmatrix(to, I, to);
-	mul_fmatrix_S(to,  (-damping * -(dot_v3v3(dir, vel)/MAX2(length, rest))));
-
-}
-
-DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *UNUSED(lF), lfVector *X, lfVector *V, fmatrix3x3 *UNUSED(dFdV), fmatrix3x3 *UNUSED(dFdX), float time)
-{
-	Cloth *cloth = clmd->clothObject;
-	ClothVertex *verts = cloth->verts;
-	float extent[3];
-	float length = 0, dot = 0;
-	float dir[3] = {0, 0, 0};
-	float vel[3];
-	float k = 0.0f;
-	float L = s->restlen;
-	float cb; /* = clmd->sim_parms->structural; */ /*UNUSED*/
-
-	float nullf[3] = {0, 0, 0};
-	float stretch_force[3] = {0, 0, 0};
-	float bending_force[3] = {0, 0, 0};
-	float damping_force[3] = {0, 0, 0};
-	float nulldfdx[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
-	
-	float scaling = 0.0;
-
-	int no_compress = clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS;
-	
-	copy_v3_v3(s->f, nullf);
-	cp_fmatrix(s->dfdx, nulldfdx);
-	cp_fmatrix(s->dfdv, nulldfdx);
-
-	// calculate elonglation
-	sub_v3_v3v3(extent, X[s->kl], X[s->ij]);
-	sub_v3_v3v3(vel, V[s->kl], V[s->ij]);
-	dot = dot_v3v3(extent, extent);
-	length = sqrt(dot);
-	
-	s->flags &= ~CLOTH_SPRING

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list