[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