[Bf-blender-cvs] [4599169] temp_merge_gooseberry_hair: First stage of implementing moving frames of reference for hair/cloth.

Lukas Tönne noreply at git.blender.org
Mon Jan 19 20:48:41 CET 2015


Commit: 4599169a4c7b17e6aad07226ff815389b1069b5e
Author: Lukas Tönne
Date:   Thu Sep 11 17:53:25 2014 +0200
Branches: temp_merge_gooseberry_hair
https://developer.blender.org/rB4599169a4c7b17e6aad07226ff815389b1069b5e

First stage of implementing moving frames of reference for hair/cloth.

This adds transformations for each hair from world to "root space".
Currently positions and velocities are simply transformed for the solver
data and inverse-transformed when copying the results back to the cloth
data. This way the hair movement becomes independent from the movement
of the emitter object. Eventually the "fictitious" forces originating
from emitter movement can be added back in a controlled way.

http://en.wikipedia.org/wiki/Fictitious_force

Ignoring these fictitious forces or scaling their effect is physically
correct, because in the absence of external forces the hair will always
return to rest position in this root frame.

External forces currently are not yet transformed into the root space.

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

M	source/blender/blenkernel/intern/implicit_eigen.cpp
M	source/blender/blenkernel/intern/particle_system.c

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

diff --git a/source/blender/blenkernel/intern/implicit_eigen.cpp b/source/blender/blenkernel/intern/implicit_eigen.cpp
index 92bf127..924f576 100644
--- a/source/blender/blenkernel/intern/implicit_eigen.cpp
+++ b/source/blender/blenkernel/intern/implicit_eigen.cpp
@@ -260,7 +260,17 @@ BLI_INLINE void outerproduct(float r[3][3], const float a[3], const float b[3])
 	mul_v3_v3fl(r[2], a, b[2]);
 }
 
+struct RootTransform {
+	float loc[3];
+	float rot[3][3];
+	
+	float vel[3];
+	float omega[3];
+};
+
 struct Implicit_Data {
+	typedef std::vector<RootTransform> RootTransforms;
+	
 	Implicit_Data(int numverts)
 	{
 		resize(numverts);
@@ -275,6 +285,8 @@ struct Implicit_Data {
 		dFdV.resize(tot, tot);
 		dFdX.resize(tot, tot);
 		
+		root.resize(numverts);
+		
 		X.resize(tot);
 		Xnew.resize(tot);
 		V.resize(tot);
@@ -296,6 +308,8 @@ struct Implicit_Data {
 	lVector F;					/* forces */
 	lMatrix dFdV, dFdX;			/* force jacobians */
 	
+	RootTransforms root;		/* root transforms */
+	
 	/* motion state data */
 	lVector X, Xnew;			/* positions */
 	lVector V, Vnew;			/* velocities */
@@ -309,6 +323,44 @@ struct Implicit_Data {
 	lMatrix S;					/* filtering matrix for constraints */
 };
 
+BLI_INLINE void loc_world_to_root(float r[3], const float v[3], Implicit_Data *id, int i)
+{
+	RootTransform &root = id->root[i];
+	sub_v3_v3v3(r, v, root.loc);
+	mul_transposed_m3_v3(root.rot, r);
+}
+
+BLI_INLINE void loc_root_to_world(float r[3], const float v[3], Implicit_Data *id, int i)
+{
+	RootTransform &root = id->root[i];
+	float t[3];
+	copy_v3_v3(r, v);
+	mul_m3_v3(root.rot, r);
+	add_v3_v3(r, root.loc);
+}
+
+BLI_INLINE void vel_world_to_root(float r[3], const float x_root[3], const float v[3], Implicit_Data *id, int i)
+{
+	RootTransform &root = id->root[i];
+	float angvel[3];
+	cross_v3_v3v3(angvel, root.omega, x_root);
+	
+	sub_v3_v3v3(r, v, root.vel);
+	mul_transposed_m3_v3(root.rot, r);
+	add_v3_v3(r, angvel);
+}
+
+BLI_INLINE void vel_root_to_world(float r[3], const float x_root[3], const float v[3], Implicit_Data *id, int i)
+{
+	RootTransform &root = id->root[i];
+	float angvel[3];
+	cross_v3_v3v3(angvel, root.omega, x_root);
+	
+	sub_v3_v3v3(r, v, angvel);
+	mul_m3_v3(root.rot, r);
+	add_v3_v3(r, root.vel);
+}
+
 static bool simulate_implicit_euler(Implicit_Data *id, float dt)
 {
 #ifdef USE_EIGEN_CORE
@@ -819,8 +871,11 @@ int implicit_solver(Object *ob, float frame, ClothModifierData *clmd, ListBase *
 		for (int i = 0; i < numverts; i++) {
 			// update velocities with constrained velocities from pinned verts
 			if (verts[i].flags & CLOTH_VERT_FLAG_PINNED) {
-				sub_v3_v3v3(lVector_v3(id->V, i), verts[i].xconst, verts[i].xold);
+				float v[3];
+				sub_v3_v3v3(v, verts[i].xconst, verts[i].xold);
 				// mul_v3_fl(id->V[i], clmd->sim_parms->stepsPerFrame);
+				/* note: should be zero for root vertices, but other verts could be pinned as well */
+				vel_world_to_root(lVector_v3(id->V, i), lVector_v3(id->X, i), v, id, i);
 			}
 		}
 	}
@@ -835,7 +890,7 @@ int implicit_solver(Object *ob, float frame, ClothModifierData *clmd, ListBase *
 		
 		/* copy velocities for collision */
 		for (int i = 0; i < numverts; i++) {
-			copy_v3_v3(verts[i].tv, lVector_v3(id->V, i));
+			vel_root_to_world(verts[i].tv, lVector_v3(id->X, i), lVector_v3(id->V, i), id, i);
 			copy_v3_v3(verts[i].v, verts[i].tv);
 		}
 		
@@ -864,11 +919,14 @@ int implicit_solver(Object *ob, float frame, ClothModifierData *clmd, ListBase *
 		for (int i = 0; i < numverts; i++) {
 			/* move pinned verts to correct position */
 			if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) {
-				if (verts[i].flags & CLOTH_VERT_FLAG_PINNED)
-					interp_v3_v3v3(lVector_v3(id->Xnew, i), verts[i].xold, verts[i].xconst, step + dt);
+				if (verts[i].flags & CLOTH_VERT_FLAG_PINNED) {
+					float x[3];
+					interp_v3_v3v3(x, verts[i].xold, verts[i].xconst, step + dt);
+					loc_world_to_root(lVector_v3(id->Xnew, i), x, id, i);
+				}
 			}
 			
-			copy_v3_v3(verts[i].txold, lVector_v3(id->X, i));
+			loc_root_to_world(verts[i].txold, lVector_v3(id->X, i), id, i);
 			
 			if (!(verts[i].flags & CLOTH_VERT_FLAG_PINNED) && i > 0) {
 				BKE_sim_debug_data_add_line(clmd->debug_data, lVector_v3(id->X, i), lVector_v3(id->X, i-1), 0.6, 0.3, 0.3, "hair", hash_vertex(4892, i));
@@ -894,13 +952,13 @@ int implicit_solver(Object *ob, float frame, ClothModifierData *clmd, ListBase *
 			copy_v3_v3(verts[i].x, verts[i].xconst);
 			copy_v3_v3(verts[i].txold, verts[i].x);
 			
-			copy_v3_v3(verts[i].v, lVector_v3(id->V, i));
+			vel_root_to_world(verts[i].v, lVector_v3(id->X, i), lVector_v3(id->V, i), id, i);
 		}
 		else {
-			copy_v3_v3(verts[i].x, lVector_v3(id->X, i));
+			loc_root_to_world(verts[i].x, lVector_v3(id->X, i), id, i);
 			copy_v3_v3(verts[i].txold, verts[i].x);
 			
-			copy_v3_v3(verts[i].v, lVector_v3(id->V, i));
+			vel_root_to_world(verts[i].v, lVector_v3(id->X, i), lVector_v3(id->V, i), id, i);
 		}
 	}
 	
@@ -910,15 +968,21 @@ int implicit_solver(Object *ob, float frame, ClothModifierData *clmd, ListBase *
 void implicit_set_positions(ClothModifierData *clmd)
 {
 	Cloth *cloth = clmd->clothObject;
+	Implicit_Data *id = cloth->implicit;
 	ClothVertex *verts = cloth->verts;
+	ClothHairRoot *cloth_roots = clmd->roots;
 	unsigned int numverts = cloth->numverts, i;
 	
+	Implicit_Data::RootTransforms &root = cloth->implicit->root;
 	lVector &X = cloth->implicit->X;
 	lVector &V = cloth->implicit->V;
 	
 	for (i = 0; i < numverts; i++) {
-		copy_v3_v3(lVector_v3(X, i), verts[i].x);
-		copy_v3_v3(lVector_v3(V, i), verts[i].v);
+		copy_v3_v3(root[i].loc, cloth_roots[i].loc);
+		copy_m3_m3(root[i].rot, cloth_roots[i].rot);
+		
+		loc_world_to_root(lVector_v3(X, i), verts[i].x, id, i);
+		vel_world_to_root(lVector_v3(V, i), lVector_v3(X, i), verts[i].v, id, i);
 	}
 }
 
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index c0d6a18..50e1a27 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -4033,17 +4033,25 @@ static void do_hair_dynamics(ParticleSimulationData *sim)
 	/* make vgroup for pin roots etc.. */
 	psys->particles->hair_index = 1;
 	LOOP_PARTICLES {
+		float root_mat[4][4];
+
 		if (p)
 			pa->hair_index = (pa-1)->hair_index + (pa-1)->totkey + 1;
 
 		psys_mat_hair_to_object(sim->ob, sim->psmd->dm, psys->part->from, pa, hairmat);
+		mul_m4_m4m4(root_mat, sim->ob->obmat, hairmat);
 
 		for (k=0, key=pa->hair; k<pa->totkey; k++,key++) {
-			ClothHairRoot *root = &psys->clmd->roots[pa->hair_index + k - 1];
+			ClothHairRoot *root;
 			
 			/* create fake root before actual root to resist bending */
 			if (k==0) {
 				float temp[3];
+				
+				root = &psys->clmd->roots[pa->hair_index - 1];
+				copy_v3_v3(root->loc, root_mat[3]);
+				copy_m3_m4(root->rot, root_mat);
+				
 				sub_v3_v3v3(temp, key->co, (key+1)->co);
 				copy_v3_v3(mvert->co, key->co);
 				add_v3_v3v3(mvert->co, mvert->co, temp);
@@ -4066,8 +4074,9 @@ static void do_hair_dynamics(ParticleSimulationData *sim)
 			}
 
 			/* store root transform in cloth data */
-			copy_v3_v3(root->loc, hairmat[3]);
-			copy_m3_m4(root->rot, hairmat);
+			root = &psys->clmd->roots[pa->hair_index + k];
+			copy_v3_v3(root->loc, root_mat[3]);
+			copy_m3_m4(root->rot, root_mat);
 
 			copy_v3_v3(mvert->co, key->co);
 			mul_m4_v3(hairmat, mvert->co);




More information about the Bf-blender-cvs mailing list