Debug drawing feature to visualize the hair continuum grid.

This commit is contained in:
Lukas Tönne 2014-10-31 14:23:32 +01:00
parent aea309779f
commit c3968861b3
8 changed files with 127 additions and 4 deletions

View File

@ -343,7 +343,9 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel):
col.label(text="Quality:")
col.prop(cloth, "quality", text="Steps", slider=True)
col.prop(cloth_md, "show_debug_data", text="Debug")
row = col.row()
row.prop(psys.settings, "show_hair_grid", text="HairGrid")
row.prop(cloth_md, "show_debug_data", text="Debug")
if result:
box = layout.box()

View File

@ -5186,6 +5186,79 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
if (part->draw_col == PART_DRAW_COL_MAT)
glEnableClientState(GL_COLOR_ARRAY);
}
if (part->draw & PART_DRAW_HAIR_GRID) {
ClothModifierData *clmd = psys->clmd;
if (clmd) {
float *a = clmd->hair_grid_min;
float *b = clmd->hair_grid_max;
int *res = clmd->hair_grid_res;
int i;
glDisable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
if (select)
UI_ThemeColor(TH_ACTIVE);
else
UI_ThemeColor(TH_WIRE);
glBegin(GL_LINES);
glVertex3f(a[0], a[1], a[2]); glVertex3f(b[0], a[1], a[2]);
glVertex3f(b[0], a[1], a[2]); glVertex3f(b[0], b[1], a[2]);
glVertex3f(b[0], b[1], a[2]); glVertex3f(a[0], b[1], a[2]);
glVertex3f(a[0], b[1], a[2]); glVertex3f(a[0], a[1], a[2]);
glVertex3f(a[0], a[1], b[2]); glVertex3f(b[0], a[1], b[2]);
glVertex3f(b[0], a[1], b[2]); glVertex3f(b[0], b[1], b[2]);
glVertex3f(b[0], b[1], b[2]); glVertex3f(a[0], b[1], b[2]);
glVertex3f(a[0], b[1], b[2]); glVertex3f(a[0], a[1], b[2]);
glVertex3f(a[0], a[1], a[2]); glVertex3f(a[0], a[1], b[2]);
glVertex3f(b[0], a[1], a[2]); glVertex3f(b[0], a[1], b[2]);
glVertex3f(a[0], b[1], a[2]); glVertex3f(a[0], b[1], b[2]);
glVertex3f(b[0], b[1], a[2]); glVertex3f(b[0], b[1], b[2]);
glEnd();
if (select)
UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -100);
else
UI_ThemeColorShadeAlpha(TH_WIRE, 0, -100);
glEnable(GL_BLEND);
glBegin(GL_LINES);
for (i = 1; i < res[0]; ++i) {
float f = interpf(b[0], a[0], (float)i / (float)res[0]);
glVertex3f(f, a[1], a[2]); glVertex3f(f, b[1], a[2]);
glVertex3f(f, b[1], a[2]); glVertex3f(f, b[1], b[2]);
glVertex3f(f, b[1], b[2]); glVertex3f(f, a[1], b[2]);
glVertex3f(f, a[1], b[2]); glVertex3f(f, a[1], a[2]);
}
for (i = 1; i < res[1]; ++i) {
float f = interpf(b[1], a[1], (float)i / (float)res[1]);
glVertex3f(a[0], f, a[2]); glVertex3f(b[0], f, a[2]);
glVertex3f(b[0], f, a[2]); glVertex3f(b[0], f, b[2]);
glVertex3f(b[0], f, b[2]); glVertex3f(a[0], f, b[2]);
glVertex3f(a[0], f, b[2]); glVertex3f(a[0], f, a[2]);
}
for (i = 1; i < res[2]; ++i) {
float f = interpf(b[2], a[2], (float)i / (float)res[2]);
glVertex3f(a[0], a[1], f); glVertex3f(b[0], a[1], f);
glVertex3f(b[0], a[1], f); glVertex3f(b[0], b[1], f);
glVertex3f(b[0], b[1], f); glVertex3f(a[0], b[1], f);
glVertex3f(a[0], b[1], f); glVertex3f(a[0], a[1], f);
}
glEnd();
glDisable(GL_BLEND);
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glEnableClientState(GL_NORMAL_ARRAY);
if ((dflag & DRAW_CONSTCOLOR) == 0)
if (part->draw_col == PART_DRAW_COL_MAT)
glEnableClientState(GL_COLOR_ARRAY);
}
}
}
/* draw child particles */

View File

@ -566,6 +566,11 @@ typedef struct ClothModifierData {
struct ListBase ptcaches;
/* XXX nasty hack, remove once hair can be separated from cloth modifier data */
struct ClothHairRoot *roots;
/* grid geometry values of hair continuum */
float hair_grid_min[3];
float hair_grid_max[3];
int hair_grid_res[3];
int pad;
struct ClothSolverResult *solver_result;

View File

@ -334,6 +334,7 @@ typedef enum eParticleDrawFlag {
PART_DRAW_REN_STRAND = (1 << 15),
PART_DRAW_NO_SCALE_OB = (1 << 16), /* used with dupliobjects/groups */
PART_DRAW_GUIDE_HAIRS = (1 << 17),
PART_DRAW_HAIR_GRID = (1 << 18),
} eParticleDrawFlag;
/* part->type */

View File

@ -2182,6 +2182,11 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Guide Hairs", "Show guide hairs");
RNA_def_property_update(prop, 0, "rna_Particle_redo");
prop = RNA_def_property(srna, "show_hair_grid", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_HAIR_GRID);
RNA_def_property_ui_text(prop, "Guide Hairs", "Show guide hairs");
RNA_def_property_update(prop, 0, "rna_Particle_redo");
prop = RNA_def_property(srna, "show_velocity", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_VEL);
RNA_def_property_ui_text(prop, "Velocity", "Show particle velocity");

View File

@ -601,6 +601,11 @@ static void cloth_continuum_step(ClothModifierData *clmd)
float gmin[3], gmax[3];
int i;
/* clear grid info */
zero_v3_int(clmd->hair_grid_res);
zero_v3(clmd->hair_grid_min);
zero_v3(clmd->hair_grid_max);
hair_get_boundbox(clmd, gmin, gmax);
/* gather velocities & density */
@ -637,6 +642,9 @@ static void cloth_continuum_step(ClothModifierData *clmd)
BPH_mass_spring_set_new_velocity(data, i, nv);
}
/* store basic grid info in the modifier data */
BPH_hair_volume_grid_geometry(vertex_grid, NULL, clmd->hair_grid_res, clmd->hair_grid_min, clmd->hair_grid_max);
BPH_hair_volume_free_vertex_grid(vertex_grid);
}
}

View File

@ -38,9 +38,14 @@
/* ================ Volumetric Hair Interaction ================
* adapted from
* Volumetric Methods for Simulation and Rendering of Hair
* by Lena Petrovic, Mark Henne and John Anderson
* Pixar Technical Memo #06-08, Pixar Animation Studios
*
* Volumetric Methods for Simulation and Rendering of Hair
* (Petrovic, Henne, Anderson, Pixar Technical Memo #06-08, Pixar Animation Studios)
*
* as well as
*
* "Detail Preserving Continuum Simulation of Straight Hair"
* (McAdams, Selle 2009)
*/
/* Note about array indexing:
@ -113,6 +118,10 @@ BLI_INLINE int hair_grid_interp_weights(int res, const float gmin[3], const floa
uvw[1] = (vec[1] - gmin[1]) / scale[1] - (float)j;
uvw[2] = (vec[2] - gmin[2]) / scale[2] - (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;
}
@ -244,6 +253,15 @@ BLI_INLINE float dist_tent_v3f3(const float a[3], float x, float y, float z)
return w;
}
BLI_INLINE float weights_sum(const float weights[8])
{
float totweight = 0.0f;
int i;
for (i = 0; i < 8; ++i)
totweight += weights[i];
return totweight;
}
/* 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])
{
@ -268,6 +286,8 @@ static int hair_grid_weights(int res, const float gmin[3], const float scale[3],
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;
}
@ -409,6 +429,14 @@ void BPH_hair_volume_free_vertex_grid(HairVertexGrid *grid)
}
}
void BPH_hair_volume_grid_geometry(HairVertexGrid *grid, float cellsize[3], 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 (gmin) copy_v3_v3(gmin, grid->gmin);
if (gmax) copy_v3_v3(gmax, grid->gmax);
}
#if 0
static HairGridVert *hair_volume_create_collision_grid(ClothModifierData *clmd, lfVector *lX, unsigned int numverts)
{

View File

@ -170,6 +170,7 @@ struct HairColliderGrid;
struct HairVertexGrid *BPH_hair_volume_create_vertex_grid(int res, const float gmin[3], const float gmax[3]);
void BPH_hair_volume_free_vertex_grid(struct HairVertexGrid *grid);
void BPH_hair_volume_grid_geometry(struct HairVertexGrid *grid, float cellsize[3], int res[3], float gmin[3], float gmax[3]);
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);