diff options
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/intern/smoke.c | 4 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawobject.c | 7 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawvolume.c | 204 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_intern.h | 6 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_smoke_types.h | 10 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_smoke.c | 24 |
6 files changed, 205 insertions, 50 deletions
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index d0f546e9bef..05540f51588 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -543,6 +543,7 @@ void smokeModifier_createType(struct SmokeModifierData *smd) smd->domain->slice_per_voxel = 5.0f; smd->domain->slice_depth = 0.5f; smd->domain->slice_axis = 0; + smd->domain->vector_scale = 1.0f; } else if (smd->type & MOD_SMOKE_TYPE_FLOW) { @@ -642,6 +643,9 @@ void smokeModifier_copy(struct SmokeModifierData *smd, struct SmokeModifierData tsmd->domain->slice_per_voxel = smd->domain->slice_per_voxel; tsmd->domain->slice_depth = smd->domain->slice_depth; tsmd->domain->slice_axis = smd->domain->slice_axis; + tsmd->domain->draw_velocity = smd->domain->draw_velocity; + tsmd->domain->vector_draw_type = smd->domain->vector_draw_type; + tsmd->domain->vector_scale = smd->domain->vector_scale; } else if (tsmd->flow) { tsmd->flow->psys = smd->flow->psys; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index a74c0f0f467..ea40d4eb5e1 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -7912,9 +7912,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short } /* smoke debug render */ -#ifdef SMOKE_DEBUG_VELOCITY - draw_smoke_velocity(smd->domain, ob); -#endif + if (!render_override && sds->draw_velocity) { + draw_smoke_velocity(sds, viewnormal); + } + #ifdef SMOKE_DEBUG_HEAT draw_smoke_heat(smd->domain, ob); #endif diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index d743e7c09e7..ef4db7ed6b8 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -40,6 +40,7 @@ #include "BLI_utildefines.h" #include "BLI_math.h" +#include "BKE_DerivedMesh.h" #include "BKE_particle.h" #include "smoke_API.h" @@ -571,61 +572,180 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, } } -#ifdef SMOKE_DEBUG_VELOCITY -void draw_smoke_velocity(SmokeDomainSettings *domain, Object *ob) +static void add_tri(float (*verts)[3], float(*colors)[3], int *offset, + float p1[3], float p2[3], float p3[3], float rgb[3]) { - float x, y, z; - float x0, y0, z0; - int *base_res = domain->base_res; - int *res = domain->res; - int *res_min = domain->res_min; - int *res_max = domain->res_max; - float *vel_x = smoke_get_velocity_x(domain->fluid); - float *vel_y = smoke_get_velocity_y(domain->fluid); - float *vel_z = smoke_get_velocity_z(domain->fluid); + copy_v3_v3(verts[*offset + 0], p1); + copy_v3_v3(verts[*offset + 1], p2); + copy_v3_v3(verts[*offset + 2], p3); - float min[3]; - float *cell_size = domain->cell_size; - float step_size = ((float)max_iii(base_res[0], base_res[1], base_res[2])) / 16.f; - float vf = domain->scale / 16.f * 2.f; /* velocity factor */ + copy_v3_v3(colors[*offset + 0], rgb); + copy_v3_v3(colors[*offset + 1], rgb); + copy_v3_v3(colors[*offset + 2], rgb); - glLineWidth(1.0f); + *offset += 3; +} + +static void add_needle(float (*verts)[3], float (*colors)[3], float center[3], + float dir[3], float scale, float voxel_size, int *offset) +{ + float len = len_v3(dir); + + float rgb[3]; + weight_to_rgb(rgb, len); + + if (len != 0.0f) { + mul_v3_fl(dir, 1.0f / len); + len *= scale; + } + + len *= voxel_size; + + float corners[4][3] = { + { 0.0f, 0.2f, -0.5f }, + { -0.2f * 0.866f, -0.2f * 0.5f, -0.5f }, + { 0.2f * 0.866f, -0.2f * 0.5f, -0.5f }, + { 0.0f, 0.0f, 0.5f } + }; + + const float up[3] = { 0.0f, 0.0f, 1.0f }; + float rot[3][3]; + + rotation_between_vecs_to_mat3(rot, up, dir); + transpose_m3(rot); + + for (int i = 0; i < 4; i++) { + mul_m3_v3(rot, corners[i]); + mul_v3_fl(corners[i], len); + add_v3_v3(corners[i], center); + } + + add_tri(verts, colors, offset, corners[0], corners[1], corners[2], rgb); + add_tri(verts, colors, offset, corners[0], corners[1], corners[3], rgb); + add_tri(verts, colors, offset, corners[1], corners[2], corners[3], rgb); + add_tri(verts, colors, offset, corners[2], corners[0], corners[3], rgb); +} + +static void add_streamline(float (*verts)[3], float(*colors)[3], float center[3], + float dir[3], float scale, float voxel_size, int *offset) +{ + const float len = len_v3(dir); + + float rgb[3]; + weight_to_rgb(rgb, len); + + copy_v3_v3(colors[(*offset)], rgb); + copy_v3_v3(verts[(*offset)++], center); + + mul_v3_fl(dir, scale * voxel_size); + add_v3_v3(center, dir); + + copy_v3_v3(colors[(*offset)], rgb); + copy_v3_v3(verts[(*offset)++], center); +} + +typedef void (*vector_draw_func)(float(*)[3], float(*)[3], float*, float*, float, float, int*); + +void draw_smoke_velocity(SmokeDomainSettings *domain, float viewnormal[3]) +{ + const int *base_res = domain->base_res; + const int *res = domain->res; + const int *res_min = domain->res_min; + + int res_max[3]; + copy_v3_v3_int(res_max, domain->res_max); + + const float *vel_x = smoke_get_velocity_x(domain->fluid); + const float *vel_y = smoke_get_velocity_y(domain->fluid); + const float *vel_z = smoke_get_velocity_z(domain->fluid); + + const float *cell_size = domain->cell_size; + const float step_size = ((float)max_iii(base_res[0], base_res[1], base_res[2])) / 16.0f; /* set first position so that it doesn't jump when domain moves */ - x0 = res_min[0] + fmod(-(float)domain->shift[0] + res_min[0], step_size); - y0 = res_min[1] + fmod(-(float)domain->shift[1] + res_min[1], step_size); - z0 = res_min[2] + fmod(-(float)domain->shift[2] + res_min[2], step_size); - if (x0 < res_min[0]) x0 += step_size; - if (y0 < res_min[1]) y0 += step_size; - if (z0 < res_min[2]) z0 += step_size; + float xyz[3] = { + res_min[0] + fmod(-(float)domain->shift[0] + res_min[0], step_size), + res_min[1] + fmod(-(float)domain->shift[1] + res_min[1], step_size), + res_min[2] + fmod(-(float)domain->shift[2] + res_min[2], step_size) + }; + + if (xyz[0] < res_min[0]) xyz[0] += step_size; + if (xyz[1] < res_min[1]) xyz[1] += step_size; + if (xyz[2] < res_min[2]) xyz[2] += step_size; + + float min[3]; add_v3_v3v3(min, domain->p0, domain->obj_shift_f); - for (x = floor(x0); x < res_max[0]; x += step_size) - for (y = floor(y0); y < res_max[1]; y += step_size) - for (z = floor(z0); z < res_max[2]; z += step_size) { + int num_points_v[3] = { + ((float)(res_max[0] - floor(xyz[0])) / step_size) + 0.5f, + ((float)(res_max[1] - floor(xyz[1])) / step_size) + 0.5f, + ((float)(res_max[2] - floor(xyz[2])) / step_size) + 0.5f + }; + + if (domain->slice_method == MOD_SMOKE_SLICE_AXIS_ALIGNED && + domain->axis_slice_method == AXIS_SLICE_SINGLE) + { + const int axis = (domain->slice_axis == SLICE_AXIS_AUTO) ? + axis_dominant_v3_single(viewnormal) : domain->slice_axis - 1; + + xyz[axis] = (float)res[axis] * domain->slice_depth; + num_points_v[axis] = 1; + res_max[axis] = xyz[axis] + 1; + } + + vector_draw_func func; + int max_points; + + if (domain->vector_draw_type == VECTOR_DRAW_NEEDLE) { + func = add_needle; + max_points = (num_points_v[0] * num_points_v[1] * num_points_v[2]) * 4 * 3; + } + else { + func = add_streamline; + max_points = (num_points_v[0] * num_points_v[1] * num_points_v[2]) * 2; + } + + float (*verts)[3] = MEM_mallocN(sizeof(float) * 3 * max_points, ""); + float (*colors)[3] = MEM_mallocN(sizeof(float) * 3 * max_points, ""); + + int num_points = 0; + + for (float x = floor(xyz[0]); x < res_max[0]; x += step_size) { + for (float y = floor(xyz[1]); y < res_max[1]; y += step_size) { + for (float z = floor(xyz[2]); z < res_max[2]; z += step_size) { int index = (floor(x) - res_min[0]) + (floor(y) - res_min[1]) * res[0] + (floor(z) - res_min[2]) * res[0] * res[1]; - float pos[3] = {min[0] + ((float)x + 0.5f) * cell_size[0], min[1] + ((float)y + 0.5f) * cell_size[1], min[2] + ((float)z + 0.5f) * cell_size[2]}; - float vel = sqrtf(vel_x[index] * vel_x[index] + vel_y[index] * vel_y[index] + vel_z[index] * vel_z[index]); + float pos[3] = { + min[0] + ((float)x + 0.5f) * cell_size[0], + min[1] + ((float)y + 0.5f) * cell_size[1], + min[2] + ((float)z + 0.5f) * cell_size[2] + }; - /* draw heat as scaled "arrows" */ - if (vel >= 0.01f) { - float col_g = 1.0f - vel; - CLAMP(col_g, 0.0f, 1.0f); - glColor3f(1.0f, col_g, 0.0f); - glPointSize(10.0f * vel); + float vel[3] = { + vel_x[index], vel_y[index], vel_z[index] + }; - glBegin(GL_LINES); - glVertex3f(pos[0], pos[1], pos[2]); - glVertex3f(pos[0] + vel_x[index] * vf, pos[1] + vel_y[index] * vf, pos[2] + vel_z[index] * vf); - glEnd(); - glBegin(GL_POINTS); - glVertex3f(pos[0] + vel_x[index] * vf, pos[1] + vel_y[index] * vf, pos[2] + vel_z[index] * vf); - glEnd(); - } + func(verts, colors, pos, vel, domain->vector_scale, cell_size[0], &num_points); } + } + } + + glLineWidth(1.0f); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, verts); + + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(3, GL_FLOAT, 0, colors); + + glDrawArrays(GL_LINES, 0, num_points); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + MEM_freeN(verts); + MEM_freeN(colors); } -#endif #ifdef SMOKE_DEBUG_HEAT void draw_smoke_heat(SmokeDomainSettings *domain, Object *ob) diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 314dadbaa52..0e2cb95dd89 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -296,12 +296,10 @@ void draw_smoke_volume(struct SmokeDomainSettings *sds, struct Object *ob, const float min[3], const float max[3], const float viewnormal[3]); -//#define SMOKE_DEBUG_VELOCITY //#define SMOKE_DEBUG_HEAT -#ifdef SMOKE_DEBUG_VELOCITY -void draw_smoke_velocity(struct SmokeDomainSettings *domain, struct Object *ob); -#endif +void draw_smoke_velocity(struct SmokeDomainSettings *domain, float viewnormal[3]); + #ifdef SMOKE_DEBUG_HEAT void draw_smoke_heat(struct SmokeDomainSettings *domain, struct Object *ob); #endif diff --git a/source/blender/makesdna/DNA_smoke_types.h b/source/blender/makesdna/DNA_smoke_types.h index 5526c18f656..ba7f73c2f63 100644 --- a/source/blender/makesdna/DNA_smoke_types.h +++ b/source/blender/makesdna/DNA_smoke_types.h @@ -72,6 +72,11 @@ enum { SLICE_AXIS_Z = 3, }; +enum { + VECTOR_DRAW_NEEDLE = 0, + VECTOR_DRAW_STREAMLINE = 1, +}; + /* cache compression */ #define SM_CACHE_LIGHT 0 #define SM_CACHE_HEAVY 1 @@ -184,10 +189,13 @@ typedef struct SmokeDomainSettings { /* Display settings */ char slice_method, axis_slice_method; - char slice_axis, pad2; + char slice_axis, draw_velocity; float slice_per_voxel; float slice_depth; float display_thickness; + float vector_scale; + char vector_draw_type; + char pad2[3]; } SmokeDomainSettings; diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c index 22c1a115a15..40a45416aca 100644 --- a/source/blender/makesrna/intern/rna_smoke.c +++ b/source/blender/makesrna/intern/rna_smoke.c @@ -463,6 +463,12 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; + static EnumPropertyItem vector_draw_items[] = { + {VECTOR_DRAW_NEEDLE, "NEEDLE", 0, "Needle", "Draw vectors as needles"}, + {VECTOR_DRAW_STREAMLINE, "STREAMLINE", 0, "Streamlines", "Draw vectors as streamlines"}, + {0, NULL, 0, NULL, NULL} + }; + srna = RNA_def_struct(brna, "SmokeDomainSettings", NULL); RNA_def_struct_ui_text(srna, "Domain Settings", "Smoke domain settings"); RNA_def_struct_sdna(srna, "SmokeDomainSettings"); @@ -781,6 +787,24 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0.1, 100.0, 0.1, 3); RNA_def_property_ui_text(prop, "Thickness", "Thickness of smoke drawing in the viewport"); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, NULL); + + prop = RNA_def_property(srna, "draw_velocity", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "draw_velocity", 0); + RNA_def_property_ui_text(prop, "Draw Velocity", "Toggle visualation of the velocity field as needles"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); + + prop = RNA_def_property(srna, "vector_draw_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "vector_draw_type"); + RNA_def_property_enum_items(prop, vector_draw_items); + RNA_def_property_ui_text(prop, "Draw Type", ""); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); + + prop = RNA_def_property(srna, "vector_scale", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "vector_scale"); + RNA_def_property_range(prop, 0.0, 1000.0); + RNA_def_property_ui_range(prop, 0.0, 100.0, 0.1, 3); + RNA_def_property_ui_text(prop, "Scale", "Multiplier for scaling the vectors"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); } static void rna_def_smoke_flow_settings(BlenderRNA *brna) |