[Bf-blender-cvs] [7d11a47] temp_hair_flow: Use the interpolation direction of the hair flow for integrating hair strands.

Lukas Tönne noreply at git.blender.org
Thu Jan 8 11:41:59 CET 2015


Commit: 7d11a478a86c56e1168ae1b196cca10cd1582644
Author: Lukas Tönne
Date:   Thu Jan 8 11:41:19 2015 +0100
Branches: temp_hair_flow
https://developer.blender.org/rB7d11a478a86c56e1168ae1b196cca10cd1582644

Use the interpolation direction of the hair flow for integrating
hair strands.

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

M	source/blender/physics/intern/grid.cpp
M	source/blender/physics/intern/grid.h
M	source/blender/physics/intern/hair_flow.cpp

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

diff --git a/source/blender/physics/intern/grid.cpp b/source/blender/physics/intern/grid.cpp
index 0fc8917..839d215 100644
--- a/source/blender/physics/intern/grid.cpp
+++ b/source/blender/physics/intern/grid.cpp
@@ -213,7 +213,7 @@ void Grid::calc_divergence(GridHash<float> &divergence, const GridHash<bool> &so
 				if (nu)
 					dz += (*nu)[2] - n[2];
 				
-				divergence.add(x, y, z) -= 0.5f * flowfac * (dx + dy + dz);
+				divergence.add(x, y, z) = 0.5f * flowfac * (dx + dy + dz);
 			}
 		}
 	}
diff --git a/source/blender/physics/intern/grid.h b/source/blender/physics/intern/grid.h
index 0b39f02..5f1ccfa 100644
--- a/source/blender/physics/intern/grid.h
+++ b/source/blender/physics/intern/grid.h
@@ -41,6 +41,36 @@
 
 namespace BPH {
 
+/* external function for trilinear interpolation of arbitrary types,
+ * with specialization for non-primitive vectors, etc.
+ */
+template <typename T>
+BLI_INLINE T interp_trilinear(const T data[8], const float uvw[3], const float muvw[3])
+{
+	return muvw[2]*( muvw[1]*( muvw[0]*data[0] + uvw[0]*data[1] )   +
+		              uvw[1]*( muvw[0]*data[2] + uvw[0]*data[3] ) ) +
+		    uvw[2]*( muvw[1]*( muvw[0]*data[4] + uvw[0]*data[5] )   +
+		              uvw[1]*( muvw[0]*data[6] + uvw[0]*data[7] ) );
+}
+
+template <>
+float3 interp_trilinear<float3>(const float3 data[8], const float uvw[3], const float muvw[3])
+{
+	float x = muvw[2]*( muvw[1]*( muvw[0]*data[0].x + uvw[0]*data[1].x )   +
+		                 uvw[1]*( muvw[0]*data[2].x + uvw[0]*data[3].x ) ) +
+		       uvw[2]*( muvw[1]*( muvw[0]*data[4].x + uvw[0]*data[5].x )   +
+		                 uvw[1]*( muvw[0]*data[6].x + uvw[0]*data[7].x ) );
+	float y = muvw[2]*( muvw[1]*( muvw[0]*data[0].y + uvw[0]*data[1].y )   +
+		                 uvw[1]*( muvw[0]*data[2].y + uvw[0]*data[3].y ) ) +
+		       uvw[2]*( muvw[1]*( muvw[0]*data[4].y + uvw[0]*data[5].y )   +
+		                 uvw[1]*( muvw[0]*data[6].y + uvw[0]*data[7].y ) );
+	float z = muvw[2]*( muvw[1]*( muvw[0]*data[0].z + uvw[0]*data[1].z )   +
+		                 uvw[1]*( muvw[0]*data[2].z + uvw[0]*data[3].z ) ) +
+		       uvw[2]*( muvw[1]*( muvw[0]*data[4].z + uvw[0]*data[5].z )   +
+		                 uvw[1]*( muvw[0]*data[6].z + uvw[0]*data[7].z ) );
+	return float3(x, y, z);
+}
+
 template <typename T>
 struct GridHash {
 	GridHash() :
@@ -123,6 +153,59 @@ struct GridHash {
 		}
 	}
 	
+	inline T interpolate(const float vec[3])
+	{
+		T data[8];
+		float uvw[3], muvw[3];
+		int stride[3] = { 1, m_res[0], m_res[0] * m_res[1] };
+		
+		int offset = interp_weights(vec, uvw);
+		muvw[0] = 1.0f - uvw[0];
+		muvw[1] = 1.0f - uvw[1];
+		muvw[2] = 1.0f - uvw[2];
+		
+		data[0] = m_data[offset                                    ];
+		data[1] = m_data[offset                         + stride[0]];
+		data[2] = m_data[offset             + stride[1]            ];
+		data[3] = m_data[offset             + stride[1] + stride[0]];
+		data[4] = m_data[offset + stride[2]                        ];
+		data[5] = m_data[offset + stride[2]             + stride[0]];
+		data[6] = m_data[offset + stride[2] + stride[1]            ];
+		data[7] = m_data[offset + stride[2] + stride[1] + stride[0]];
+		
+		return interp_trilinear(data, uvw, muvw);
+	}
+	
+protected:
+	
+	inline int index_axis(const float vec[3], int axis)
+	{
+		return min_ii( max_ii( (int)vec[axis], 0), m_res[axis]-2 );
+	}
+	
+	inline int offset(const float vec[3], const int res[3], const float gmin[3], float scale)
+	{
+		int i, j, k;
+		i = index_axis(vec, 0);
+		j = index_axis(vec, 1);
+		k = index_axis(vec, 2);
+		return i + (j + k*res[1])*res[0];
+	}
+	
+	inline int interp_weights(const float vec[3], float uvw[3])
+	{
+		int i = index_axis(vec, 0);
+		int j = index_axis(vec, 1);
+		int k = index_axis(vec, 2);
+		int offset = i + (j + k*m_res[1])*m_res[0];
+		
+		uvw[0] = vec[0] - (float)i;
+		uvw[1] = vec[1] - (float)j;
+		uvw[2] = vec[2] - (float)k;
+		
+		return offset;
+	}
+	
 private:
 	T *m_data; /* XXX TODO stub array for now, actually use a hash table here! */
 	int m_res[3];
diff --git a/source/blender/physics/intern/hair_flow.cpp b/source/blender/physics/intern/hair_flow.cpp
index dcf7ca7..91301d6 100644
--- a/source/blender/physics/intern/hair_flow.cpp
+++ b/source/blender/physics/intern/hair_flow.cpp
@@ -75,6 +75,7 @@ struct HairFlowData {
 	}
 	
 	Grid grid;
+	GridHash<float3> direction;
 	
 	MEM_CXX_CLASS_ALLOC_FUNCS("HairFlowData")
 };
@@ -148,10 +149,10 @@ HairFlowData *BPH_strands_solve_hair_flow(Scene *scene, Object *ob, float max_le
 	pressure.resize(data->grid.res);
 	data->grid.solve_pressure(pressure, divergence);
 	
-	GridHash<float3> velocity;
-	velocity.resize(data->grid.res);
-	data->grid.calc_gradient(velocity, pressure);
-	data->grid.normalize(velocity);
+	/* normalized velocity field for defining hair direction */
+	data->direction.resize(data->grid.res);
+	data->grid.calc_gradient(data->direction, pressure);
+	data->grid.normalize(data->direction);
 	
 	{
 		float col0[3] = {0.0, 0.0, 0.0};
@@ -191,7 +192,7 @@ HairFlowData *BPH_strands_solve_hair_flow(Scene *scene, Object *ob, float max_le
 					if (fac > 0.05f)
 						BKE_sim_debug_data_add_circle(debug_data, vec, 0.02f, col[0], col[1], col[2], "hair_flow", 5522, x, y, z);
 					
-					BKE_sim_debug_data_add_vector(debug_data, vec, *velocity.get(x, y, z), 1,1,0, "hair_flow", 957, x, y, z);
+					BKE_sim_debug_data_add_vector(debug_data, vec, *data->direction.get(x, y, z), 1,1,0, "hair_flow", 957, x, y, z);
 				}
 			}
 		}
@@ -228,7 +229,7 @@ static void sample_hair_strand(Object *UNUSED(ob), BMEditStrands *edit, HairFlow
 	DerivedMesh *dm = edit->root_dm;
 	const float inv_dt = 1.0f / dt;
 	
-	float co[3], dir[3];
+	float co[3];
 	BMVert *root, *v;
 	
 	const float seglen = max_length / (float)segments;
@@ -236,8 +237,8 @@ static void sample_hair_strand(Object *UNUSED(ob), BMEditStrands *edit, HairFlow
 	int numseg;
 	
 	{
-		float tang[3];
-		BKE_mesh_sample_eval(dm, sample, co, dir, tang);
+		float nor[3], tang[3];
+		BKE_mesh_sample_eval(dm, sample, co, nor, tang);
 	}
 	
 	root = BM_strands_create(edit->bm, segments + 1, true);
@@ -253,8 +254,13 @@ static void sample_hair_strand(Object *UNUSED(ob), BMEditStrands *edit, HairFlow
 		float nt = t + dt;
 		float prev_co[3];
 		
-		/* TODO evaluate direction */
-		//dir = grid_dir(co);
+		/* evaluate direction */
+		float gridco[3];
+		sub_v3_v3v3(gridco, co, data->grid.offset);
+		mul_v3_fl(gridco, data->grid.inv_cellsize);
+		float3 dir = data->direction.interpolate(gridco);
+		BLI_assert(len_v3(dir) <= 1.0f);
+		normalize_v3(dir);
 		
 		/* forward integrate position */
 		copy_v3_v3(prev_co, co);




More information about the Bf-blender-cvs mailing list