forked from bartvdbraak/blender
Use a fixed, uniform cell size for hair continuum grids.
This is a bit more awkward for artists to use, but necessary for a stable solution of the hair continuum calculation. The grid size is defined by the user, the extent of the grid is then calculated based on the hair geometry. A hard upper limit prevents bad memory allocation in case too small values are entered. Conflicts: source/blender/physics/intern/BPH_mass_spring.cpp
This commit is contained in:
parent
8dbb6f0d5d
commit
bf96400558
@ -329,7 +329,7 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel):
|
||||
# XXX disabled due to stability issues
|
||||
#sub.prop(cloth, "pressure", slider=True, text="Pressure")
|
||||
#sub.prop(cloth, "pressure_threshold", slider=True, text="Threshold")
|
||||
col.prop(cloth, "voxel_resolution")
|
||||
col.prop(cloth, "voxel_cell_size")
|
||||
|
||||
split.separator()
|
||||
|
||||
|
@ -153,7 +153,7 @@ void cloth_init(ClothModifierData *clmd )
|
||||
clmd->sim_parms->goalfrict = 0.0f;
|
||||
clmd->sim_parms->velocity_smooth = 0.0f;
|
||||
|
||||
clmd->sim_parms->voxel_res = 32;
|
||||
clmd->sim_parms->voxel_cell_size = 0.1f;
|
||||
|
||||
if (!clmd->sim_parms->effector_weights)
|
||||
clmd->sim_parms->effector_weights = BKE_add_effector_weights(NULL);
|
||||
|
@ -80,7 +80,7 @@ typedef struct ClothSimSettings {
|
||||
* should really be separate, this struct is a horrible mess already
|
||||
*/
|
||||
float bending_damping; /* damping of bending springs */
|
||||
int voxel_res; /* resolution of voxel grid for interaction */
|
||||
float voxel_cell_size; /* size of voxel grid cells for continuum dynamics */
|
||||
int pad;
|
||||
|
||||
int stepsPerFrame; /* Number of time steps per frame. */
|
||||
|
@ -470,11 +470,11 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Shrink Factor Max", "Max amount to shrink cloth by");
|
||||
RNA_def_property_update(prop, 0, "rna_cloth_update");
|
||||
|
||||
prop = RNA_def_property(srna, "voxel_resolution", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_int_sdna(prop, NULL, "voxel_res");
|
||||
RNA_def_property_range(prop, 1, 128);
|
||||
RNA_def_property_int_default(prop, 32);
|
||||
RNA_def_property_ui_text(prop, "Voxel Grid Resolution", "Resolution of the voxel grid for interaction effects");
|
||||
prop = RNA_def_property(srna, "voxel_cell_size", PROP_FLOAT, PROP_UNSIGNED);
|
||||
RNA_def_property_float_sdna(prop, NULL, "voxel_cell_size");
|
||||
RNA_def_property_range(prop, 0.0001f, 10000.0f);
|
||||
RNA_def_property_float_default(prop, 0.1f);
|
||||
RNA_def_property_ui_text(prop, "Voxel Grid Cell Size", "Size of the voxel grid cells for interaction effects");
|
||||
RNA_def_property_update(prop, 0, "rna_cloth_update");
|
||||
|
||||
/* springs */
|
||||
|
@ -584,7 +584,7 @@ static void cloth_calc_volume_force(ClothModifierData *clmd)
|
||||
#endif
|
||||
|
||||
/* returns active vertexes' motion state, or original location the vertex is disabled */
|
||||
BLI_INLINE bool cloth_get_grid_location(Implicit_Data *data, const float cell_scale[3], const float cell_offset[3],
|
||||
BLI_INLINE bool cloth_get_grid_location(Implicit_Data *data, float cell_scale, const float cell_offset[3],
|
||||
ClothVertex *vert, int index, float x[3], float v[3])
|
||||
{
|
||||
bool is_motion_state;
|
||||
@ -592,7 +592,7 @@ BLI_INLINE bool cloth_get_grid_location(Implicit_Data *data, const float cell_sc
|
||||
BPH_mass_spring_get_new_velocity(data, index, v);
|
||||
is_motion_state = true;
|
||||
|
||||
mul_v3_v3(x, cell_scale);
|
||||
mul_v3_fl(x, cell_scale);
|
||||
add_v3_v3(x, cell_offset);
|
||||
|
||||
return is_motion_state;
|
||||
@ -618,7 +618,7 @@ BLI_INLINE LinkNode *hair_spring_next(LinkNode *spring_link)
|
||||
* (3,4), (2,3), (1,2)
|
||||
* This is currently the only way to figure out hair geometry inside this code ...
|
||||
*/
|
||||
static LinkNode *cloth_continuum_add_hair_segments(HairGrid *grid, const float cell_scale[3], const float cell_offset[3], Cloth *cloth, LinkNode *spring_link)
|
||||
static LinkNode *cloth_continuum_add_hair_segments(HairGrid *grid, const float cell_scale, const float cell_offset[3], Cloth *cloth, LinkNode *spring_link)
|
||||
{
|
||||
Implicit_Data *data = cloth->implicit;
|
||||
LinkNode *next_spring_link = NULL; /* return value */
|
||||
@ -723,16 +723,14 @@ static void cloth_continuum_fill_grid(HairGrid *grid, Cloth *cloth)
|
||||
}
|
||||
#else
|
||||
LinkNode *link;
|
||||
float cellsize[3], gmin[3], cell_scale[3], cell_offset[3];
|
||||
float cellsize, gmin[3], cell_scale, cell_offset[3];
|
||||
|
||||
/* scale and offset for transforming vertex locations into grid space
|
||||
* (cell size is 0..1, gmin becomes origin)
|
||||
*/
|
||||
BPH_hair_volume_grid_geometry(grid, cellsize, NULL, gmin, NULL);
|
||||
cell_scale[0] = cellsize[0] > 0.0f ? 1.0f / cellsize[0] : 0.0f;
|
||||
cell_scale[1] = cellsize[1] > 0.0f ? 1.0f / cellsize[1] : 0.0f;
|
||||
cell_scale[2] = cellsize[2] > 0.0f ? 1.0f / cellsize[2] : 0.0f;
|
||||
mul_v3_v3v3(cell_offset, gmin, cell_scale);
|
||||
BPH_hair_volume_grid_geometry(grid, &cellsize, NULL, gmin, NULL);
|
||||
cell_scale = cellsize > 0.0f ? 1.0f / cellsize : 0.0f;
|
||||
mul_v3_v3fl(cell_offset, gmin, cell_scale);
|
||||
negate_v3(cell_offset);
|
||||
|
||||
link = cloth->springs;
|
||||
@ -760,7 +758,6 @@ static void cloth_continuum_step(ClothModifierData *clmd)
|
||||
float pressfac = parms->pressure;
|
||||
float minpress = parms->pressure_threshold;
|
||||
float gmin[3], gmax[3];
|
||||
float cellsize[3];
|
||||
int i;
|
||||
|
||||
/* clear grid info */
|
||||
@ -772,11 +769,9 @@ static void cloth_continuum_step(ClothModifierData *clmd)
|
||||
|
||||
/* gather velocities & density */
|
||||
if (smoothfac > 0.0f || pressfac > 0.0f) {
|
||||
HairGrid *grid = BPH_hair_volume_create_vertex_grid(clmd->sim_parms->voxel_res, gmin, gmax);
|
||||
HairGrid *grid = BPH_hair_volume_create_vertex_grid(clmd->sim_parms->voxel_cell_size, gmin, gmax);
|
||||
BPH_hair_volume_set_debug_data(grid, clmd->debug_data);
|
||||
|
||||
BPH_hair_volume_grid_geometry(grid, cellsize, NULL, NULL, NULL);
|
||||
|
||||
cloth_continuum_fill_grid(grid, cloth);
|
||||
|
||||
for (i = 0, vert = cloth->verts; i < numverts; i++, vert++) {
|
||||
@ -1010,7 +1005,7 @@ bool BPH_cloth_solver_get_texture_data(Object *UNUSED(ob), ClothModifierData *cl
|
||||
|
||||
hair_get_boundbox(clmd, gmin, gmax);
|
||||
|
||||
grid = BPH_hair_volume_create_vertex_grid(clmd->sim_parms->voxel_res, gmin, gmax);
|
||||
grid = BPH_hair_volume_create_vertex_grid(clmd->sim_parms->voxel_cell_size, gmin, gmax);
|
||||
cloth_continuum_fill_grid(grid, cloth);
|
||||
|
||||
BPH_hair_volume_get_texture_data(grid, vd);
|
||||
|
@ -66,15 +66,9 @@
|
||||
|
||||
static float I[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
|
||||
|
||||
static int hair_grid_size(int res)
|
||||
BLI_INLINE int hair_grid_size(const int res[3])
|
||||
{
|
||||
return res * res * res;
|
||||
}
|
||||
|
||||
BLI_INLINE void hair_grid_get_scale(int res, const float gmin[3], const float gmax[3], float scale[3])
|
||||
{
|
||||
sub_v3_v3v3(scale, gmax, gmin);
|
||||
mul_v3_fl(scale, 1.0f / (res-1));
|
||||
return res[0] * res[1] * res[2];
|
||||
}
|
||||
|
||||
typedef struct HairGridVert {
|
||||
@ -86,36 +80,36 @@ typedef struct HairGridVert {
|
||||
|
||||
typedef struct HairGrid {
|
||||
HairGridVert *verts;
|
||||
int res;
|
||||
int res[3];
|
||||
float gmin[3], gmax[3];
|
||||
float scale[3];
|
||||
float cellsize, inv_cellsize;
|
||||
|
||||
struct SimDebugData *debug_data;
|
||||
} HairGrid;
|
||||
|
||||
#define HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, axis) ( min_ii( max_ii( (int)((vec[axis] - gmin[axis]) / scale[axis]), 0), res-2 ) )
|
||||
#define HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, axis) ( min_ii( max_ii( (int)((vec[axis] - gmin[axis]) * scale), 0), res[axis]-2 ) )
|
||||
|
||||
BLI_INLINE int hair_grid_offset(const float vec[3], int res, const float gmin[3], const float scale[3])
|
||||
BLI_INLINE int hair_grid_offset(const float vec[3], const int res[3], const float gmin[3], float scale)
|
||||
{
|
||||
int i, j, k;
|
||||
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);
|
||||
return i + (j + k*res)*res;
|
||||
return i + (j + k*res[1])*res[0];
|
||||
}
|
||||
|
||||
BLI_INLINE int hair_grid_interp_weights(int res, const float gmin[3], const float scale[3], const float vec[3], float uvw[3])
|
||||
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)*res;
|
||||
offset = i + (j + k*res[1])*res[0];
|
||||
|
||||
uvw[0] = (vec[0] - gmin[0]) / scale[0] - (float)i;
|
||||
uvw[1] = (vec[1] - gmin[1]) / scale[1] - (float)j;
|
||||
uvw[2] = (vec[2] - gmin[2]) / scale[2] - (float)k;
|
||||
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);
|
||||
@ -124,12 +118,12 @@ BLI_INLINE int hair_grid_interp_weights(int res, const float gmin[3], const floa
|
||||
return offset;
|
||||
}
|
||||
|
||||
BLI_INLINE void hair_grid_interpolate(const HairGridVert *grid, int res, const float gmin[3], const float scale[3], const float vec[3],
|
||||
BLI_INLINE void hair_grid_interpolate(const HairGridVert *grid, const int res[3], const float gmin[3], float scale, const float vec[3],
|
||||
float *density, float velocity[3], float density_gradient[3], float velocity_gradient[3][3])
|
||||
{
|
||||
HairGridVert data[8];
|
||||
float uvw[3], muvw[3];
|
||||
int res2 = res * res;
|
||||
int res2 = res[1] * res[0];
|
||||
int offset;
|
||||
|
||||
offset = hair_grid_interp_weights(res, gmin, scale, vec, uvw);
|
||||
@ -137,14 +131,14 @@ BLI_INLINE void hair_grid_interpolate(const HairGridVert *grid, int res, const f
|
||||
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 ];
|
||||
data[3] = grid[offset +res+1];
|
||||
data[4] = grid[offset+res2 ];
|
||||
data[5] = grid[offset+res2 +1];
|
||||
data[6] = grid[offset+res2+res ];
|
||||
data[7] = grid[offset+res2+res+1];
|
||||
data[0] = grid[offset ];
|
||||
data[1] = grid[offset +1];
|
||||
data[2] = grid[offset +res[0] ];
|
||||
data[3] = grid[offset +res[0]+1];
|
||||
data[4] = grid[offset+res2 ];
|
||||
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 ) +
|
||||
@ -186,31 +180,13 @@ BLI_INLINE void hair_grid_interpolate(const HairGridVert *grid, int res, const f
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void hair_velocity_collision(const HairGridVert *collgrid, const float gmin[3], const float scale[3], float collfac,
|
||||
lfVector *lF, lfVector *lX, lfVector *lV, unsigned int numverts)
|
||||
{
|
||||
int v;
|
||||
/* calculate forces */
|
||||
for (v = 0; v < numverts; v++) {
|
||||
int offset = hair_grid_offset(lX[v], hair_grid_res, gmin, scale);
|
||||
|
||||
if (collgrid[offset].density > 0.0f) {
|
||||
lF[v][0] += collfac * (collgrid[offset].velocity[0] - lV[v][0]);
|
||||
lF[v][1] += collfac * (collgrid[offset].velocity[1] - lV[v][1]);
|
||||
lF[v][2] += collfac * (collgrid[offset].velocity[2] - lV[v][2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void BPH_hair_volume_vertex_grid_forces(HairGrid *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])
|
||||
{
|
||||
float gdensity, gvelocity[3], ggrad[3], gvelgrad[3][3], gradlen;
|
||||
|
||||
hair_grid_interpolate(grid->verts, grid->res, grid->gmin, grid->scale, x, &gdensity, gvelocity, ggrad, gvelgrad);
|
||||
hair_grid_interpolate(grid->verts, grid->res, grid->gmin, grid->inv_cellsize, x, &gdensity, gvelocity, ggrad, gvelgrad);
|
||||
|
||||
zero_v3(f);
|
||||
sub_v3_v3(gvelocity, v);
|
||||
@ -231,7 +207,7 @@ void BPH_hair_volume_vertex_grid_forces(HairGrid *grid, const float x[3], const
|
||||
void BPH_hair_volume_grid_interpolate(HairGrid *grid, const float x[3],
|
||||
float *density, float velocity[3], float density_gradient[3], float velocity_gradient[3][3])
|
||||
{
|
||||
hair_grid_interpolate(grid->verts, grid->res, grid->gmin, grid->scale, x, density, velocity, density_gradient, velocity_gradient);
|
||||
hair_grid_interpolate(grid->verts, grid->res, grid->gmin, grid->inv_cellsize, x, density, velocity, density_gradient, velocity_gradient);
|
||||
}
|
||||
|
||||
void BPH_hair_volume_grid_velocity(HairGrid *grid, const float x[3], const float v[3],
|
||||
@ -240,7 +216,7 @@ void BPH_hair_volume_grid_velocity(HairGrid *grid, const float x[3], const float
|
||||
{
|
||||
float gdensity, gvelocity[3], ggrad[3], gvelgrad[3][3];
|
||||
|
||||
hair_grid_interpolate(grid->verts, grid->res, grid->gmin, grid->scale, x, &gdensity, gvelocity, ggrad, gvelgrad);
|
||||
hair_grid_interpolate(grid->verts, grid->res, grid->gmin, grid->inv_cellsize, x, &gdensity, gvelocity, ggrad, gvelgrad);
|
||||
|
||||
/* XXX TODO implement FLIP method and use fluid_factor to blend between FLIP and PIC */
|
||||
copy_v3_v3(r_v, gvelocity);
|
||||
@ -268,7 +244,7 @@ BLI_INLINE float weights_sum(const float weights[8])
|
||||
}
|
||||
|
||||
/* returns the grid array offset as well to avoid redundant calculation */
|
||||
static int hair_grid_weights(int res, const float gmin[3], const float scale[3], const float vec[3], float weights[8])
|
||||
BLI_INLINE int hair_grid_weights(const int res[3], const float gmin[3], float scale, const float vec[3], float weights[8])
|
||||
{
|
||||
int i, j, k, offset;
|
||||
float uvw[3];
|
||||
@ -276,11 +252,11 @@ static int hair_grid_weights(int res, const float gmin[3], const float scale[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)*res;
|
||||
offset = i + (j + k*res[1])*res[0];
|
||||
|
||||
uvw[0] = (vec[0] - gmin[0]) / scale[0];
|
||||
uvw[1] = (vec[1] - gmin[1]) / scale[1];
|
||||
uvw[2] = (vec[2] - gmin[2]) / scale[2];
|
||||
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 );
|
||||
@ -298,7 +274,7 @@ static int hair_grid_weights(int res, const float gmin[3], const float scale[3],
|
||||
|
||||
void BPH_hair_volume_add_vertex(HairGrid *grid, const float x[3], const float v[3])
|
||||
{
|
||||
int res = grid->res;
|
||||
const int res[3] = { grid->res[0], grid->res[1], grid->res[2] };
|
||||
float weights[8];
|
||||
int di, dj, dk;
|
||||
int offset;
|
||||
@ -306,12 +282,12 @@ void BPH_hair_volume_add_vertex(HairGrid *grid, const float x[3], const float v[
|
||||
if (!hair_grid_point_valid(x, grid->gmin, grid->gmax))
|
||||
return;
|
||||
|
||||
offset = hair_grid_weights(res, grid->gmin, grid->scale, x, weights);
|
||||
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)*res;
|
||||
int voffset = offset + di + (dj + dk*res[1])*res[0];
|
||||
int iw = di + dj*2 + dk*4;
|
||||
|
||||
grid->verts[voffset].density += weights[iw];
|
||||
@ -348,7 +324,7 @@ BLI_INLINE int major_axis_v3(const float v[3])
|
||||
BLI_INLINE void grid_to_world(HairGrid *grid, float vecw[3], const float vec[3])
|
||||
{
|
||||
copy_v3_v3(vecw, vec);
|
||||
mul_v3_v3(vecw, grid->scale);
|
||||
mul_v3_fl(vecw, grid->cellsize);
|
||||
add_v3_v3(vecw, grid->gmin);
|
||||
}
|
||||
|
||||
@ -366,7 +342,7 @@ void BPH_hair_volume_add_segment(HairGrid *grid,
|
||||
{
|
||||
SimDebugData *debug_data = grid->debug_data;
|
||||
|
||||
const int res[3] = { grid->res, grid->res, grid->res };
|
||||
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);
|
||||
@ -384,7 +360,7 @@ void BPH_hair_volume_add_segment(HairGrid *grid,
|
||||
const int grid_start1 = (int)x2[axis1]; /* offset of cells on minor axes */
|
||||
const int grid_start2 = (int)x2[axis2]; /* offset of cells on minor axes */
|
||||
|
||||
const float cellsize[3] = { grid->scale[axis0], grid->scale[axis1], grid->scale[axis2] };
|
||||
const float cellsize = grid->cellsize;
|
||||
float shift[2] = { x2[axis1] - floorf(x2[axis1]), /* fraction of a full cell shift [0.0, 1.0) */
|
||||
x2[axis2] - floorf(x2[axis2]) };
|
||||
|
||||
@ -397,7 +373,7 @@ void BPH_hair_volume_add_segment(HairGrid *grid,
|
||||
|
||||
const float radius = 1.5f;
|
||||
/* XXX cell size should be fixed and uniform! */
|
||||
const float dist_scale = 1.0f / cellsize[0];
|
||||
const float dist_scale = grid->inv_cellsize;
|
||||
|
||||
HairGridVert *vert0;
|
||||
float loc0[3];
|
||||
@ -414,7 +390,7 @@ void BPH_hair_volume_add_segment(HairGrid *grid,
|
||||
loc0[axis2] = (float)k0;
|
||||
|
||||
/* loop over all planes crossed along the primary direction */
|
||||
for (i = imin; i < imax; ++i, vert0 += stride0, loc0[axis0] += cellsize[0]) {
|
||||
for (i = imin; i < imax; ++i, vert0 += stride0, loc0[axis0] += cellsize) {
|
||||
const int jmin = max_ii(j0, 0);
|
||||
const int jmax = min_ii(j0 + 5, res[axis1]);
|
||||
const int kmin = max_ii(k0, 0);
|
||||
@ -565,27 +541,55 @@ void BPH_hair_volume_vertex_grid_filter_box(HairVertexGrid *grid, int kernel_siz
|
||||
}
|
||||
#endif
|
||||
|
||||
HairGrid *BPH_hair_volume_create_vertex_grid(int res, const float gmin[3], const float gmax[3])
|
||||
HairGrid *BPH_hair_volume_create_vertex_grid(float cellsize, const float gmin[3], const float gmax[3])
|
||||
{
|
||||
float cellsize[3], gmin_margin[3], gmax_margin[3];
|
||||
float scale;
|
||||
float extent[3];
|
||||
int resmin[3], resmax[3], res[3];
|
||||
float gmin_margin[3], gmax_margin[3];
|
||||
int size;
|
||||
HairGrid *grid;
|
||||
int i;
|
||||
|
||||
/* original cell size, before adding margin */
|
||||
hair_grid_get_scale(res, gmin, gmax, cellsize);
|
||||
/* sanity check */
|
||||
if (cellsize <= 0.0f)
|
||||
cellsize = 1.0f;
|
||||
scale = 1.0f / cellsize;
|
||||
|
||||
/* add margin of 1 cell */
|
||||
res += 2;
|
||||
sub_v3_v3v3(extent, gmax, gmin);
|
||||
for (i = 0; i < 3; ++i) {
|
||||
resmin[i] = (int)(gmin[i] * scale);
|
||||
resmax[i] = (int)(gmax[i] * scale) + 1;
|
||||
|
||||
/* add margin of 1 cell */
|
||||
resmin[i] -= 1;
|
||||
resmax[i] += 1;
|
||||
|
||||
res[i] = resmax[i] - resmin[i];
|
||||
/* sanity check: avoid null-sized grid */
|
||||
if (res[i] < 3) {
|
||||
res[i] = 3;
|
||||
resmax[i] = resmin[i] + 3;
|
||||
}
|
||||
/* sanity check: avoid too large grid size */
|
||||
if (res[i] > MAX_HAIR_GRID_RES) {
|
||||
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);
|
||||
sub_v3_v3v3(gmin_margin, gmin, cellsize);
|
||||
add_v3_v3v3(gmax_margin, gmax, cellsize);
|
||||
|
||||
grid = MEM_callocN(sizeof(HairGrid), "hair grid");
|
||||
grid->res = res;
|
||||
grid->res[0] = res[0];
|
||||
grid->res[1] = res[1];
|
||||
grid->res[2] = res[2];
|
||||
copy_v3_v3(grid->gmin, gmin_margin);
|
||||
copy_v3_v3(grid->gmax, gmax_margin);
|
||||
copy_v3_v3(grid->scale, cellsize);
|
||||
grid->cellsize = cellsize;
|
||||
grid->inv_cellsize = scale;
|
||||
grid->verts = MEM_mallocN(sizeof(HairGridVert) * size, "hair voxel data");
|
||||
|
||||
/* initialize grid */
|
||||
@ -611,10 +615,10 @@ void BPH_hair_volume_set_debug_data(HairGrid *grid, SimDebugData *debug_data)
|
||||
grid->debug_data = debug_data;
|
||||
}
|
||||
|
||||
void BPH_hair_volume_grid_geometry(HairGrid *grid, float cellsize[3], int res[3], float gmin[3], float gmax[3])
|
||||
void BPH_hair_volume_grid_geometry(HairGrid *grid, float *cellsize, int res[3], float gmin[3], float gmax[3])
|
||||
{
|
||||
if (cellsize) copy_v3_v3(cellsize, grid->scale);
|
||||
if (res) { res[0] = res[1] = res[2] = grid->res; }
|
||||
if (cellsize) *cellsize = grid->cellsize;
|
||||
if (res) copy_v3_v3_int(res, grid->res);
|
||||
if (gmin) copy_v3_v3(gmin, grid->gmin);
|
||||
if (gmax) copy_v3_v3(gmax, grid->gmax);
|
||||
}
|
||||
@ -696,9 +700,9 @@ bool BPH_hair_volume_get_texture_data(HairGrid *grid, VoxelData *vd)
|
||||
int totres, i;
|
||||
int depth;
|
||||
|
||||
vd->resol[0] = grid->res;
|
||||
vd->resol[1] = grid->res;
|
||||
vd->resol[2] = grid->res;
|
||||
vd->resol[0] = grid->res[0];
|
||||
vd->resol[1] = grid->res[1];
|
||||
vd->resol[2] = grid->res[2];
|
||||
|
||||
totres = hair_grid_size(grid->res);
|
||||
|
||||
|
@ -170,10 +170,12 @@ struct HairGrid;
|
||||
struct Object;
|
||||
struct VoxelData;
|
||||
|
||||
struct HairGrid *BPH_hair_volume_create_vertex_grid(int res, const float gmin[3], const float gmax[3]);
|
||||
#define MAX_HAIR_GRID_RES 256
|
||||
|
||||
struct HairGrid *BPH_hair_volume_create_vertex_grid(float cellsize, const float gmin[3], const float gmax[3]);
|
||||
void BPH_hair_volume_free_vertex_grid(struct HairGrid *grid);
|
||||
void BPH_hair_volume_set_debug_data(struct HairGrid *grid, struct SimDebugData *debug_data);
|
||||
void BPH_hair_volume_grid_geometry(struct HairGrid *grid, float cellsize[3], int res[3], float gmin[3], float gmax[3]);
|
||||
void BPH_hair_volume_grid_geometry(struct HairGrid *grid, float *cellsize, int res[3], float gmin[3], float gmax[3]);
|
||||
|
||||
void BPH_hair_volume_add_vertex(struct HairGrid *grid, const float x[3], const float v[3]);
|
||||
void BPH_hair_volume_add_segment(struct HairGrid *grid,
|
||||
|
Loading…
Reference in New Issue
Block a user