Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Tönne <lukas.toenne@gmail.com>2014-09-18 11:06:25 +0400
committerLukas Tönne <lukas.toenne@gmail.com>2015-01-20 11:30:01 +0300
commit226beb986690046adfdf10a3ed72034fa322ccdb (patch)
treea9dfd0f16c58d70566368cb9b0c3e695e06e44d9 /source/blender/physics
parentbbae8f88b8f305a8ed85cab718d2a66b476da3c1 (diff)
Added basic filtering feature for velocity smoothing.
This is part of the original method from "Volumetric Methods for Simulation and Rendering of Hair". The current filter is a simple box filter. Other energy-preserving filters such as gaussian filtering can be implemented later. The filter size is currently given as a cell count. This is not ideal, rather it should use a geometrical length value, but this is too abstract for proper artistical use. Eventually defining the whole grid in terms of spatial size might work better (possibly using an external object).
Diffstat (limited to 'source/blender/physics')
-rw-r--r--source/blender/physics/intern/BPH_mass_spring.cpp3
-rw-r--r--source/blender/physics/intern/hair_volume.c71
-rw-r--r--source/blender/physics/intern/implicit.h1
3 files changed, 75 insertions, 0 deletions
diff --git a/source/blender/physics/intern/BPH_mass_spring.cpp b/source/blender/physics/intern/BPH_mass_spring.cpp
index 0fa14fa4eab..4d8f853a16b 100644
--- a/source/blender/physics/intern/BPH_mass_spring.cpp
+++ b/source/blender/physics/intern/BPH_mass_spring.cpp
@@ -431,6 +431,9 @@ static void cloth_calc_volume_force(ClothModifierData *clmd)
}
BPH_hair_volume_normalize_vertex_grid(vertex_grid);
+ /* apply velocity filter */
+ BPH_hair_volume_vertex_grid_filter_box(vertex_grid, clmd->sim_parms->voxel_filter_size);
+
for (i = 0; i < numverts; i++) {
float x[3], v[3], f[3], dfdx[3][3], dfdv[3][3];
diff --git a/source/blender/physics/intern/hair_volume.c b/source/blender/physics/intern/hair_volume.c
index 2d5efa8260b..7f9704af9f6 100644
--- a/source/blender/physics/intern/hair_volume.c
+++ b/source/blender/physics/intern/hair_volume.c
@@ -71,6 +71,8 @@ BLI_INLINE void hair_grid_get_scale(int res, const float gmin[3], const float gm
typedef struct HairGridVert {
float velocity[3];
float density;
+
+ float velocity_smooth[3];
} HairGridVert;
typedef struct HairVertexGrid {
@@ -293,6 +295,75 @@ void BPH_hair_volume_normalize_vertex_grid(HairVertexGrid *grid)
}
}
+/* Velocity filter kernel
+ * See http://en.wikipedia.org/wiki/Filter_%28large_eddy_simulation%29
+ */
+
+BLI_INLINE void hair_volume_filter_box_convolute(HairVertexGrid *grid, float invD, const int kernel_size[3], int i, int j, int k)
+{
+ int res = grid->res;
+ int p, q, r;
+ int minp = max_ii(i - kernel_size[0], 0), maxp = min_ii(i + kernel_size[0], res-1);
+ int minq = max_ii(j - kernel_size[1], 0), maxq = min_ii(j + kernel_size[1], res-1);
+ int minr = max_ii(k - kernel_size[2], 0), maxr = min_ii(k + kernel_size[2], res-1);
+ int offset, kernel_offset, kernel_dq, kernel_dr;
+ HairGridVert *verts;
+ float *vel_smooth;
+
+ offset = i + (j + k*res)*res;
+ verts = grid->verts;
+ vel_smooth = verts[offset].velocity_smooth;
+
+ kernel_offset = minp + (minq + minr*res)*res;
+ kernel_dq = res;
+ kernel_dr = res * res;
+ for (r = minr; r <= maxr; ++r) {
+ for (q = minq; q <= maxq; ++q) {
+ for (p = minp; p <= maxp; ++p) {
+
+ madd_v3_v3fl(vel_smooth, verts[kernel_offset].velocity, invD);
+
+ kernel_offset += 1;
+ }
+ kernel_offset += kernel_dq;
+ }
+ kernel_offset += kernel_dr;
+ }
+}
+
+void BPH_hair_volume_vertex_grid_filter_box(HairVertexGrid *grid, int kernel_size)
+{
+ int size = hair_grid_size(grid->res);
+ int kernel_sizev[3] = {kernel_size, kernel_size, kernel_size};
+ int tot;
+ float invD;
+ int i, j, k;
+
+ if (kernel_size <= 0)
+ return;
+
+ tot = kernel_size * 2 + 1;
+ invD = 1.0f / (float)(tot*tot*tot);
+
+ /* clear values for convolution */
+ for (i = 0; i < size; ++i) {
+ zero_v3(grid->verts[i].velocity_smooth);
+ }
+
+ for (i = 0; i < grid->res; ++i) {
+ for (j = 0; j < grid->res; ++j) {
+ for (k = 0; k < grid->res; ++k) {
+ hair_volume_filter_box_convolute(grid, invD, kernel_sizev, i, j, k);
+ }
+ }
+ }
+
+ /* apply as new velocity */
+ for (i = 0; i < size; ++i) {
+ copy_v3_v3(grid->verts[i].velocity, grid->verts[i].velocity_smooth);
+ }
+}
+
HairVertexGrid *BPH_hair_volume_create_vertex_grid(int res, const float gmin[3], const float gmax[3])
{
int size = hair_grid_size(res);
diff --git a/source/blender/physics/intern/implicit.h b/source/blender/physics/intern/implicit.h
index 28c4cbcf7ae..2945b0787d4 100644
--- a/source/blender/physics/intern/implicit.h
+++ b/source/blender/physics/intern/implicit.h
@@ -155,6 +155,7 @@ void BPH_hair_volume_free_vertex_grid(struct HairVertexGrid *grid);
void BPH_hair_volume_add_vertex(struct HairVertexGrid *grid, const float x[3], const float v[3]);
void BPH_hair_volume_normalize_vertex_grid(struct HairVertexGrid *grid);
+void BPH_hair_volume_vertex_grid_filter_box(struct HairVertexGrid *grid, int kernel_size);
void BPH_hair_volume_vertex_grid_forces(struct HairVertexGrid *grid, const float x[3], const float v[3],
float smoothfac, float pressurefac, float minpressure,
float f[3], float dfdx[3][3], float dfdv[3][3]);