diff options
Diffstat (limited to 'source/blender/physics/intern/hair_volume.cpp')
-rw-r--r-- | source/blender/physics/intern/hair_volume.cpp | 278 |
1 files changed, 139 insertions, 139 deletions
diff --git a/source/blender/physics/intern/hair_volume.cpp b/source/blender/physics/intern/hair_volume.cpp index ad6fbed32e0..cd869046cc1 100644 --- a/source/blender/physics/intern/hair_volume.cpp +++ b/source/blender/physics/intern/hair_volume.cpp @@ -82,7 +82,7 @@ typedef struct HairGridVert { int samples; float velocity[3]; float density; - + float velocity_smooth[3]; } HairGridVert; @@ -107,20 +107,20 @@ BLI_INLINE int hair_grid_offset(const float vec[3], const int res[3], const floa BLI_INLINE int hair_grid_interp_weights(const int res[3], const float gmin[3], float scale, const float vec[3], float uvw[3]) { int i, j, k, offset; - + i = HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, 0); j = HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, 1); k = HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, 2); offset = i + (j + k*res[1])*res[0]; - + uvw[0] = (vec[0] - gmin[0]) * scale - (float)i; uvw[1] = (vec[1] - gmin[1]) * scale - (float)j; uvw[2] = (vec[2] - gmin[2]) * scale - (float)k; - + // BLI_assert(0.0f <= uvw[0] && uvw[0] <= 1.0001f); // BLI_assert(0.0f <= uvw[1] && uvw[1] <= 1.0001f); // BLI_assert(0.0f <= uvw[2] && uvw[2] <= 1.0001f); - + return offset; } @@ -131,12 +131,12 @@ BLI_INLINE void hair_grid_interpolate(const HairGridVert *grid, const int res[3] float uvw[3], muvw[3]; int res2 = res[1] * res[0]; int offset; - + offset = hair_grid_interp_weights(res, gmin, scale, vec, uvw); muvw[0] = 1.0f - uvw[0]; muvw[1] = 1.0f - uvw[1]; muvw[2] = 1.0f - uvw[2]; - + data[0] = grid[offset ]; data[1] = grid[offset +1]; data[2] = grid[offset +res[0] ]; @@ -145,14 +145,14 @@ BLI_INLINE void hair_grid_interpolate(const HairGridVert *grid, const int res[3] data[5] = grid[offset+res2 +1]; data[6] = grid[offset+res2+res[0] ]; data[7] = grid[offset+res2+res[0]+1]; - + if (density) { *density = muvw[2]*( muvw[1]*( muvw[0]*data[0].density + uvw[0]*data[1].density ) + uvw[1]*( muvw[0]*data[2].density + uvw[0]*data[3].density ) ) + uvw[2]*( muvw[1]*( muvw[0]*data[4].density + uvw[0]*data[5].density ) + uvw[1]*( muvw[0]*data[6].density + uvw[0]*data[7].density ) ); } - + if (velocity) { int k; for (k = 0; k < 3; ++k) { @@ -162,7 +162,7 @@ BLI_INLINE void hair_grid_interpolate(const HairGridVert *grid, const int res[3] uvw[1]*( muvw[0]*data[6].velocity[k] + uvw[0]*data[7].velocity[k] ) ); } } - + if (vel_smooth) { int k; for (k = 0; k < 3; ++k) { @@ -172,24 +172,24 @@ BLI_INLINE void hair_grid_interpolate(const HairGridVert *grid, const int res[3] uvw[1]*( muvw[0]*data[6].velocity_smooth[k] + uvw[0]*data[7].velocity_smooth[k] ) ); } } - + if (density_gradient) { density_gradient[0] = muvw[1] * muvw[2] * ( data[0].density - data[1].density ) + uvw[1] * muvw[2] * ( data[2].density - data[3].density ) + muvw[1] * uvw[2] * ( data[4].density - data[5].density ) + uvw[1] * uvw[2] * ( data[6].density - data[7].density ); - + density_gradient[1] = muvw[2] * muvw[0] * ( data[0].density - data[2].density ) + uvw[2] * muvw[0] * ( data[4].density - data[6].density ) + muvw[2] * uvw[0] * ( data[1].density - data[3].density ) + uvw[2] * uvw[0] * ( data[5].density - data[7].density ); - + density_gradient[2] = muvw[2] * muvw[0] * ( data[0].density - data[4].density ) + uvw[2] * muvw[0] * ( data[1].density - data[5].density ) + muvw[2] * uvw[0] * ( data[2].density - data[6].density ) + uvw[2] * uvw[0] * ( data[3].density - data[7].density ); } - + if (velocity_gradient) { /* XXX TODO */ zero_m3(velocity_gradient); @@ -201,21 +201,21 @@ void BPH_hair_volume_vertex_grid_forces(HairGrid *grid, const float x[3], const float f[3], float dfdx[3][3], float dfdv[3][3]) { float gdensity, gvelocity[3], ggrad[3], gvelgrad[3][3], gradlen; - + hair_grid_interpolate(grid->verts, grid->res, grid->gmin, grid->inv_cellsize, x, &gdensity, gvelocity, NULL, ggrad, gvelgrad); - + zero_v3(f); sub_v3_v3(gvelocity, v); mul_v3_v3fl(f, gvelocity, smoothfac); - + gradlen = normalize_v3(ggrad) - minpressure; if (gradlen > 0.0f) { mul_v3_fl(ggrad, gradlen); madd_v3_v3fl(f, ggrad, pressurefac); } - + zero_m3(dfdx); - + sub_m3_m3m3(dfdv, gvelgrad, I); mul_m3_fl(dfdv, smoothfac); } @@ -232,16 +232,16 @@ void BPH_hair_volume_grid_velocity(HairGrid *grid, const float x[3], const float { float gdensity, gvelocity[3], gvel_smooth[3], ggrad[3], gvelgrad[3][3]; float v_pic[3], v_flip[3]; - + hair_grid_interpolate(grid->verts, grid->res, grid->gmin, grid->inv_cellsize, x, &gdensity, gvelocity, gvel_smooth, ggrad, gvelgrad); - + /* velocity according to PIC method (Particle-in-Cell) */ copy_v3_v3(v_pic, gvel_smooth); - + /* velocity according to FLIP method (Fluid-Implicit-Particle) */ sub_v3_v3v3(v_flip, gvel_smooth, gvelocity); add_v3_v3(v_flip, v); - + interp_v3_v3v3(r_v, v_pic, v_flip, fluid_factor); } @@ -283,16 +283,16 @@ BLI_INLINE int hair_grid_weights(const int res[3], const float gmin[3], float sc { int i, j, k, offset; float uvw[3]; - + i = HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, 0); j = HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, 1); k = HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, 2); offset = i + (j + k*res[1])*res[0]; - + uvw[0] = (vec[0] - gmin[0]) * scale; uvw[1] = (vec[1] - gmin[1]) * scale; uvw[2] = (vec[2] - gmin[2]) * scale; - + weights[0] = dist_tent_v3f3(uvw, (float)i , (float)j , (float)k ); weights[1] = dist_tent_v3f3(uvw, (float)(i+1), (float)j , (float)k ); weights[2] = dist_tent_v3f3(uvw, (float)i , (float)(j+1), (float)k ); @@ -301,9 +301,9 @@ BLI_INLINE int hair_grid_weights(const int res[3], const float gmin[3], float sc weights[5] = dist_tent_v3f3(uvw, (float)(i+1), (float)j , (float)(k+1)); weights[6] = dist_tent_v3f3(uvw, (float)i , (float)(j+1), (float)(k+1)); weights[7] = dist_tent_v3f3(uvw, (float)(i+1), (float)(j+1), (float)(k+1)); - + // BLI_assert(fabsf(weights_sum(weights) - 1.0f) < 0.0001f); - + return offset; } @@ -320,18 +320,18 @@ void BPH_hair_volume_add_vertex(HairGrid *grid, const float x[3], const float v[ float weights[8]; int di, dj, dk; int offset; - + if (!hair_grid_point_valid(x, grid->gmin, grid->gmax)) return; - + offset = hair_grid_weights(res, grid->gmin, grid->inv_cellsize, x, weights); - + for (di = 0; di < 2; ++di) { for (dj = 0; dj < 2; ++dj) { for (dk = 0; dk < 2; ++dk) { int voffset = offset + di + (dj + dk*res[1])*res[0]; int iw = di + dj*2 + dk*4; - + grid->verts[voffset].density += weights[iw]; madd_v3_v3fl(grid->verts[voffset].velocity, v, weights[iw]); } @@ -344,15 +344,15 @@ BLI_INLINE void hair_volume_eval_grid_vertex(HairGridVert *vert, const float loc const float x2[3], const float v2[3], const float x3[3], const float v3[3]) { float closest[3], lambda, dist, weight; - + lambda = closest_to_line_v3(closest, loc, x2, x3); dist = len_v3v3(closest, loc); - + weight = (radius - dist) * dist_scale; - + if (weight > 0.0f) { float vel[3]; - + interp_v3_v3v3(vel, v2, v3, lambda); madd_v3_v3fl(vert->velocity, vel, weight); vert->density += weight; @@ -378,37 +378,37 @@ BLI_INLINE void hair_volume_add_segment_2D(HairGrid *grid, { const float radius = 1.5f; const float dist_scale = grid->inv_cellsize; - + int j, k; - + /* boundary checks to be safe */ CLAMP_MIN(jmin, 0); CLAMP_MAX(jmax, resj-1); CLAMP_MIN(kmin, 0); CLAMP_MAX(kmax, resk-1); - + HairGridVert *vert_j = vert + jmin * stride_j; float loc_j[3] = { loc[0], loc[1], loc[2] }; loc_j[axis_j] += (float)jmin; for (j = jmin; j <= jmax; ++j, vert_j += stride_j, loc_j[axis_j] += 1.0f) { - + HairGridVert *vert_k = vert_j + kmin * stride_k; float loc_k[3] = { loc_j[0], loc_j[1], loc_j[2] }; loc_k[axis_k] += (float)kmin; for (k = kmin; k <= kmax; ++k, vert_k += stride_k, loc_k[axis_k] += 1.0f) { - + hair_volume_eval_grid_vertex(vert_k, loc_k, radius, dist_scale, x2, v2, x3, v3); - + #if 0 { float wloc[3], x2w[3], x3w[3]; grid_to_world(grid, wloc, loc_k); grid_to_world(grid, x2w, x2); grid_to_world(grid, x3w, x3); - + if (vert_k->samples > 0) BKE_sim_debug_data_add_circle(wloc, 0.01f, 1.0, 1.0, 0.3, "grid", 2525, debug_i, j, k); - + if (grid->debug_value) { BKE_sim_debug_data_add_dot(wloc, 1, 0, 0, "grid", 93, debug_i, j, k); BKE_sim_debug_data_add_dot(x2w, 0.1, 0.1, 0.7, "grid", 649, debug_i, j, k); @@ -435,55 +435,55 @@ void BPH_hair_volume_add_segment(HairGrid *grid, const float dir1[3], const float dir2[3], const float dir3[3]) { const int res[3] = { grid->res[0], grid->res[1], grid->res[2] }; - + /* find the primary direction from the major axis of the direction vector */ const int axis0 = major_axis_v3(dir2); const int axis1 = (axis0 + 1) % 3; const int axis2 = (axis0 + 2) % 3; - + /* vertex buffer offset factors along cardinal axes */ const int strides[3] = { 1, res[0], res[0] * res[1] }; const int stride0 = strides[axis0]; const int stride1 = strides[axis1]; const int stride2 = strides[axis2]; - + /* increment of secondary directions per step in the primary direction * note: we always go in the positive direction along axis0, so the sign can be inverted */ const float inc1 = dir2[axis1] / dir2[axis0]; const float inc2 = dir2[axis2] / dir2[axis0]; - + /* start/end points, so increment along axis0 is always positive */ const float *start = x2[axis0] < x3[axis0] ? x2 : x3; const float *end = x2[axis0] < x3[axis0] ? x3 : x2; const float start0 = start[axis0], start1 = start[axis1], start2 = start[axis2]; const float end0 = end[axis0]; - + /* range along primary direction */ const int imin = max_ii(floor_int(start[axis0]) - 1, 0); const int imax = min_ii(floor_int(end[axis0]) + 2, res[axis0]-1); - + float h = 0.0f; HairGridVert *vert0; float loc0[3]; int j0, k0, j0_prev, k0_prev; int i; - + for (i = imin; i <= imax; ++i) { float shift1, shift2; /* fraction of a full cell shift [0.0, 1.0) */ int jmin, jmax, kmin, kmax; - + h = CLAMPIS((float)i, start0, end0); - + shift1 = start1 + (h - start0) * inc1; shift2 = start2 + (h - start0) * inc2; - + j0_prev = j0; j0 = floor_int(shift1); - + k0_prev = k0; k0 = floor_int(shift2); - + if (i > imin) { jmin = min_ii(j0, j0_prev); jmax = max_ii(j0, j0_prev); @@ -494,12 +494,12 @@ void BPH_hair_volume_add_segment(HairGrid *grid, jmin = jmax = j0; kmin = kmax = k0; } - + vert0 = grid->verts + i * stride0; loc0[axis0] = (float)i; loc0[axis1] = 0.0f; loc0[axis2] = 0.0f; - + hair_volume_add_segment_2D(grid, x1, v1, x2, v2, x3, v3, x4, v4, dir1, dir2, dir3, res[axis1], res[axis2], jmin-1, jmax+2, kmin-1, kmax+2, vert0, stride1, stride2, loc0, axis1, axis2, @@ -511,11 +511,11 @@ BLI_INLINE void hair_volume_eval_grid_vertex_sample(HairGridVert *vert, const fl const float x[3], const float v[3]) { float dist, weight; - + dist = len_v3v3(x, loc); - + weight = (radius - dist) * dist_scale; - + if (weight > 0.0f) { madd_v3_v3fl(vert->velocity, v, weight); vert->density += weight; @@ -533,34 +533,34 @@ void BPH_hair_volume_add_segment(HairGrid *grid, { const float radius = 1.5f; const float dist_scale = grid->inv_cellsize; - + const int res[3] = { grid->res[0], grid->res[1], grid->res[2] }; const int stride[3] = { 1, res[0], res[0] * res[1] }; const int num_samples = 10; - + int s; - + for (s = 0; s < num_samples; ++s) { float x[3], v[3]; int i, j, k; - + float f = (float)s / (float)(num_samples-1); interp_v3_v3v3(x, x2, x3, f); interp_v3_v3v3(v, v2, v3, f); - + int imin = max_ii(floor_int(x[0]) - 2, 0); int imax = min_ii(floor_int(x[0]) + 2, res[0]-1); int jmin = max_ii(floor_int(x[1]) - 2, 0); int jmax = min_ii(floor_int(x[1]) + 2, res[1]-1); int kmin = max_ii(floor_int(x[2]) - 2, 0); int kmax = min_ii(floor_int(x[2]) + 2, res[2]-1); - + for (k = kmin; k <= kmax; ++k) { for (j = jmin; j <= jmax; ++j) { for (i = imin; i <= imax; ++i) { float loc[3] = { (float)i, (float)j, (float)k }; HairGridVert *vert = grid->verts + i * stride[0] + j * stride[1] + k * stride[2]; - + hair_volume_eval_grid_vertex_sample(vert, loc, radius, dist_scale, x, v); } } @@ -598,25 +598,25 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target { const float flowfac = grid->cellsize; const float inv_flowfac = 1.0f / grid->cellsize; - + /*const int num_cells = hair_grid_size(grid->res);*/ const int res[3] = { grid->res[0], grid->res[1], grid->res[2] }; const int resA[3] = { grid->res[0] + 2, grid->res[1] + 2, grid->res[2] + 2 }; - + const int stride0 = 1; const int stride1 = grid->res[0]; const int stride2 = grid->res[1] * grid->res[0]; const int strideA0 = 1; const int strideA1 = grid->res[0] + 2; const int strideA2 = (grid->res[1] + 2) * (grid->res[0] + 2); - + const int num_cells = res[0] * res[1] * res[2]; const int num_cellsA = (res[0] + 2) * (res[1] + 2) * (res[2] + 2); - + HairGridVert *vert_start = grid->verts - (stride0 + stride1 + stride2); HairGridVert *vert; int i, j, k; - + #define MARGIN_i0 (i < 1) #define MARGIN_j0 (j < 1) #define MARGIN_k0 (k < 1) @@ -630,9 +630,9 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target #define NEIGHBOR_MARGIN_i1 (i >= resA[0]-2) #define NEIGHBOR_MARGIN_j1 (j >= resA[1]-2) #define NEIGHBOR_MARGIN_k1 (k >= resA[2]-2) - + BLI_assert(num_cells >= 1); - + /* Calculate divergence */ lVector B(num_cellsA); for (k = 0; k < resA[2]; ++k) { @@ -640,14 +640,14 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target for (i = 0; i < resA[0]; ++i) { int u = i * strideA0 + j * strideA1 + k * strideA2; bool is_margin = MARGIN_i0 || MARGIN_i1 || MARGIN_j0 || MARGIN_j1 || MARGIN_k0 || MARGIN_k1; - + if (is_margin) { B[u] = 0.0f; continue; } - + vert = vert_start + i * stride0 + j * stride1 + k * stride2; - + const float *v0 = vert->velocity; float dx = 0.0f, dy = 0.0f, dz = 0.0f; if (!NEIGHBOR_MARGIN_i0) @@ -662,19 +662,19 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target dz += v0[2] - (vert - stride2)->velocity[2]; if (!NEIGHBOR_MARGIN_k1) dz += (vert + stride2)->velocity[2] - v0[2]; - + float divergence = -0.5f * flowfac * (dx + dy + dz); - + /* adjustment term for target density */ float target = hair_volume_density_divergence(vert->density, target_density, target_strength); - + /* B vector contains the finite difference approximation of the velocity divergence. * Note: according to the discretized Navier-Stokes equation the rhs vector * and resulting pressure gradient should be multiplied by the (inverse) density; * however, this is already included in the weighting of hair velocities on the grid! */ B[u] = divergence - target; - + #if 0 { float wloc[3], loc[3]; @@ -683,12 +683,12 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target float coln[3] = {1.0, 0.0, 1.0}; float col[3]; float fac; - + loc[0] = (float)(i - 1); loc[1] = (float)(j - 1); loc[2] = (float)(k - 1); grid_to_world(grid, wloc, loc); - + if (divergence > 0.0f) { fac = CLAMPIS(divergence * target_strength, 0.0, 1.0); interp_v3_v3v3(col, col0, colp, fac); @@ -704,11 +704,11 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target } } } - + /* Main Poisson equation system: * This is derived from the discretezation of the Poisson equation * div(grad(p)) = div(v) - * + * * The finite difference approximation yields the linear equation system described here: * https://en.wikipedia.org/wiki/Discrete_Poisson_equation */ @@ -718,13 +718,13 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target * and up to 6 factors -1 on other places. */ A.reserve(Eigen::VectorXi::Constant(num_cellsA, 7)); - + for (k = 0; k < resA[2]; ++k) { for (j = 0; j < resA[1]; ++j) { for (i = 0; i < resA[0]; ++i) { int u = i * strideA0 + j * strideA1 + k * strideA2; bool is_margin = MARGIN_i0 || MARGIN_i1 || MARGIN_j0 || MARGIN_j1 || MARGIN_k0 || MARGIN_k1; - + vert = vert_start + i * stride0 + j * stride1 + k * stride2; if (!is_margin && vert->density > density_threshold) { int neighbors_lo = 0; @@ -733,7 +733,7 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target int neighbor_lo_index[3]; int neighbor_hi_index[3]; int n; - + /* check for upper bounds in advance * to get the correct number of neighbors, * needed for the diagonal element @@ -750,10 +750,10 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target neighbor_hi_index[neighbors_hi++] = u + strideA1; if (!NEIGHBOR_MARGIN_k1 && (vert + stride2)->density > density_threshold) neighbor_hi_index[neighbors_hi++] = u + strideA2; - + /*int liquid_neighbors = neighbors_lo + neighbors_hi;*/ non_solid_neighbors = 6; - + for (n = 0; n < neighbors_lo; ++n) A.insert(neighbor_lo_index[n], u) = -1.0f; A.insert(u, u) = (float)non_solid_neighbors; @@ -766,15 +766,15 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target } } } - + ConjugateGradient cg; cg.setMaxIterations(100); cg.setTolerance(0.01f); - + cg.compute(A); - + lVector p = cg.solve(B); - + if (cg.info() == Eigen::Success) { /* Calculate velocity = grad(p) */ for (k = 0; k < resA[2]; ++k) { @@ -784,7 +784,7 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target bool is_margin = MARGIN_i0 || MARGIN_i1 || MARGIN_j0 || MARGIN_j1 || MARGIN_k0 || MARGIN_k1; if (is_margin) continue; - + vert = vert_start + i * stride0 + j * stride1 + k * stride2; if (vert->density > density_threshold) { float p_left = p[u - strideA0]; @@ -793,14 +793,14 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target float p_up = p[u + strideA1]; float p_bottom = p[u - strideA2]; float p_top = p[u + strideA2]; - + /* finite difference estimate of pressure gradient */ float dvel[3]; dvel[0] = p_right - p_left; dvel[1] = p_up - p_down; dvel[2] = p_top - p_bottom; mul_v3_fl(dvel, -0.5f * inv_flowfac); - + /* pressure gradient describes velocity delta */ add_v3_v3v3(vert->velocity_smooth, vert->velocity, dvel); } @@ -810,14 +810,14 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target } } } - + #if 0 { int axis = 0; float offset = 0.0f; - + int slice = (offset - grid->gmin[axis]) / grid->cellsize; - + for (k = 0; k < resA[2]; ++k) { for (j = 0; j < resA[1]; ++j) { for (i = 0; i < resA[0]; ++i) { @@ -825,21 +825,21 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target bool is_margin = MARGIN_i0 || MARGIN_i1 || MARGIN_j0 || MARGIN_j1 || MARGIN_k0 || MARGIN_k1; if (i != slice) continue; - + vert = vert_start + i * stride0 + j * stride1 + k * stride2; - + float wloc[3], loc[3]; float col0[3] = {0.0, 0.0, 0.0}; float colp[3] = {0.0, 1.0, 1.0}; float coln[3] = {1.0, 0.0, 1.0}; float col[3]; float fac; - + loc[0] = (float)(i - 1); loc[1] = (float)(j - 1); loc[2] = (float)(k - 1); grid_to_world(grid, wloc, loc); - + float pressure = p[u]; if (pressure > 0.0f) { fac = CLAMPIS(pressure * grid->debug1, 0.0, 1.0); @@ -851,19 +851,19 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target } if (fac > 0.05f) BKE_sim_debug_data_add_circle(grid->debug_data, wloc, 0.01f, col[0], col[1], col[2], "grid", 5533, i, j, k); - + if (!is_margin) { float dvel[3]; sub_v3_v3v3(dvel, vert->velocity_smooth, vert->velocity); // BKE_sim_debug_data_add_vector(grid->debug_data, wloc, dvel, 1, 1, 1, "grid", 5566, i, j, k); } - + if (!is_margin) { float d = CLAMPIS(vert->density * grid->debug2, 0.0f, 1.0f); float col0[3] = {0.3, 0.3, 0.3}; float colp[3] = {0.0, 0.0, 1.0}; float col[3]; - + interp_v3_v3v3(col, col0, colp, d); // if (d > 0.05f) // BKE_sim_debug_data_add_dot(grid->debug_data, wloc, col[0], col[1], col[2], "grid", 5544, i, j, k); @@ -873,7 +873,7 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target } } #endif - + return true; } else { @@ -881,7 +881,7 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target for (i = 0, vert = grid->verts; i < num_cells; ++i, ++vert) { zero_v3(vert->velocity_smooth); } - + return false; } } @@ -901,20 +901,20 @@ BLI_INLINE void hair_volume_filter_box_convolute(HairVertexGrid *grid, float inv 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; @@ -930,18 +930,18 @@ void BPH_hair_volume_vertex_grid_filter_box(HairVertexGrid *grid, int kernel_siz 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) { @@ -949,7 +949,7 @@ void BPH_hair_volume_vertex_grid_filter_box(HairVertexGrid *grid, int kernel_siz } } } - + /* apply as new velocity */ for (i = 0; i < size; ++i) { copy_v3_v3(grid->verts[i].velocity, grid->verts[i].velocity_smooth); @@ -966,21 +966,21 @@ HairGrid *BPH_hair_volume_create_vertex_grid(float cellsize, const float gmin[3] int size; HairGrid *grid; int i; - + /* sanity check */ if (cellsize <= 0.0f) cellsize = 1.0f; scale = 1.0f / cellsize; - + sub_v3_v3v3(extent, gmax, gmin); for (i = 0; i < 3; ++i) { resmin[i] = floor_int(gmin[i] * scale); resmax[i] = floor_int(gmax[i] * scale) + 1; - + /* add margin of 1 cell */ resmin[i] -= 1; resmax[i] += 1; - + res[i] = resmax[i] - resmin[i] + 1; /* sanity check: avoid null-sized grid */ if (res[i] < 4) { @@ -992,12 +992,12 @@ HairGrid *BPH_hair_volume_create_vertex_grid(float cellsize, const float gmin[3] res[i] = MAX_HAIR_GRID_RES; resmax[i] = resmin[i] + MAX_HAIR_GRID_RES; } - + gmin_margin[i] = (float)resmin[i] * cellsize; gmax_margin[i] = (float)resmax[i] * cellsize; } size = hair_grid_size(res); - + grid = (HairGrid *)MEM_callocN(sizeof(HairGrid), "hair grid"); grid->res[0] = res[0]; grid->res[1] = res[1]; @@ -1062,23 +1062,23 @@ static HairGridVert *hair_volume_create_collision_grid(ClothModifierData *clmd, float vel[3]; float weights[8]; int di, dj, dk; - + for (v=0; v < col->collmd->numverts; v++, loc0++, loc1++) { int offset; - + if (!hair_grid_point_valid(loc1->co, gmin, gmax)) continue; - + offset = hair_grid_weights(res, gmin, scale, lX[v], weights); - + sub_v3_v3v3(vel, loc1->co, loc0->co); - + for (di = 0; di < 2; ++di) { for (dj = 0; dj < 2; ++dj) { for (dk = 0; dk < 2; ++dk) { int voffset = offset + di + (dj + dk*res)*res; int iw = di + dj*2 + dk*4; - + collgrid[voffset].density += weights[iw]; madd_v3_v3fl(collgrid[voffset].velocity, vel, weights[iw]); } @@ -1095,7 +1095,7 @@ static HairGridVert *hair_volume_create_collision_grid(ClothModifierData *clmd, if (density > 0.0f) mul_v3_fl(collgrid[i].velocity, 1.0f/density); } - + return collgrid; } #endif @@ -1108,9 +1108,9 @@ bool BPH_hair_volume_get_texture_data(HairGrid *grid, VoxelData *vd) vd->resol[0] = grid->res[0]; vd->resol[1] = grid->res[1]; vd->resol[2] = grid->res[2]; - + totres = hair_grid_size(grid->res); - + if (vd->hair_type == TEX_VD_HAIRVELOCITY) { depth = 4; vd->data_type = TEX_VD_RGBA_PREMUL; @@ -1119,20 +1119,20 @@ bool BPH_hair_volume_get_texture_data(HairGrid *grid, VoxelData *vd) depth = 1; vd->data_type = TEX_VD_INTENSITY; } - + if (totres > 0) { vd->dataset = (float *)MEM_mapallocN(sizeof(float) * depth * (totres), "hair volume texture data"); - + for (i = 0; i < totres; ++i) { switch (vd->hair_type) { case TEX_VD_HAIRDENSITY: vd->dataset[i] = grid->verts[i].density; break; - + case TEX_VD_HAIRRESTDENSITY: vd->dataset[i] = 0.0f; // TODO break; - + case TEX_VD_HAIRVELOCITY: { vd->dataset[i + 0*totres] = grid->verts[i].velocity[0]; vd->dataset[i + 1*totres] = grid->verts[i].velocity[1]; @@ -1149,6 +1149,6 @@ bool BPH_hair_volume_get_texture_data(HairGrid *grid, VoxelData *vd) else { vd->dataset = NULL; } - + return true; } |