diff options
-rw-r--r-- | source/blender/editors/space_view3d/drawobject.c | 14 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawvolume.c | 260 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_intern.h | 5 |
3 files changed, 108 insertions, 171 deletions
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 4ffbf61fb23..a2386c5dffb 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -8093,7 +8093,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short } /* don't show smoke before simulation starts, this could be made an option in the future */ - if (smd->domain->fluid && CFRA >= smd->domain->point_cache[0]->startframe) { + if (sds->fluid && CFRA >= sds->point_cache[0]->startframe) { float p0[3], p1[3]; /* get view vector */ @@ -8112,21 +8112,15 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short p1[2] = (sds->p0[2] + sds->cell_size[2] * sds->res_max[2] + sds->obj_shift_f[2]) * fabsf(ob->size[2]); if (!sds->wt || !(sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { - smd->domain->tex = NULL; + sds->tex = NULL; GPU_create_smoke(smd, 0); - draw_smoke_volume(sds, ob, sds->tex, - p0, p1, - sds->res, sds->dx, sds->scale * sds->maxres, - viewnormal, sds->tex_shadow, sds->tex_flame); + draw_smoke_volume(sds, ob, p0, p1, sds->res, viewnormal); GPU_free_smoke(smd); } else if (sds->wt && (sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { sds->tex = NULL; GPU_create_smoke(smd, 1); - draw_smoke_volume(sds, ob, sds->tex, - p0, p1, - sds->res_wt, sds->dx, sds->scale * sds->maxres, - viewnormal, sds->tex_shadow, sds->tex_flame); + draw_smoke_volume(sds, ob, p0, p1, sds->res_wt, viewnormal); GPU_free_smoke(smd); } diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index d6691f431dd..a27037534f9 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -59,7 +59,7 @@ struct GPUTexture; # include "PIL_time_utildefines.h" #endif -static int intersect_edges(float (*points)[3], float a, float b, float c, float d, float edges[12][2][3]) +static int intersect_edges(float (*points)[3], float a, float b, float c, float d, const float edges[12][2][3]) { int i; float t; @@ -88,74 +88,20 @@ static bool convex(const float p0[3], const float up[3], const float a[3], const return dot_v3v3(up, tmp) >= 0; } -void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, - GPUTexture *tex, const float min[3], const float max[3], - const int res[3], float dx, float UNUSED(base_scale), const float viewnormal[3], - GPUTexture *tex_shadow, GPUTexture *tex_flame) +static GPUTexture *create_flame_spectrum_texture(void) { - const float ob_sizei[3] = { - 1.0f / fabsf(ob->size[0]), - 1.0f / fabsf(ob->size[1]), - 1.0f / fabsf(ob->size[2])}; - - int i, j, k, n, good_index; - float d /*, d0 */ /* UNUSED */, dd, ds; - float (*points)[3] = NULL; - int numpoints = 0; - float cor[3] = {1.0f, 1.0f, 1.0f}; - int gl_depth = 0, gl_blend = 0; - - const bool use_fire = (sds->active_fields & SM_ACTIVE_FIRE) != 0; - - /* draw slices of smoke is adapted from c++ code authored - * by: Johannes Schmid and Ingemar Rask, 2006, johnny@grob.org */ - float cv[][3] = { - {1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f}, {1.0f, -1.0f, 1.0f}, - {1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}, {1.0f, -1.0f, -1.0f} - }; - - /* edges have the form edges[n][0][xyz] + t*edges[n][1][xyz] */ - float edges[12][2][3] = { - {{1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, - {{-1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, - {{-1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, - {{1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, - - {{1.0f, -1.0f, 1.0f}, {0.0f, 2.0f, 0.0f}}, - {{-1.0f, -1.0f, 1.0f}, {0.0f, 2.0f, 0.0f}}, - {{-1.0f, -1.0f, -1.0f}, {0.0f, 2.0f, 0.0f}}, - {{1.0f, -1.0f, -1.0f}, {0.0f, 2.0f, 0.0f}}, - - {{-1.0f, 1.0f, 1.0f}, {2.0f, 0.0f, 0.0f}}, - {{-1.0f, -1.0f, 1.0f}, {2.0f, 0.0f, 0.0f}}, - {{-1.0f, -1.0f, -1.0f}, {2.0f, 0.0f, 0.0f}}, - {{-1.0f, 1.0f, -1.0f}, {2.0f, 0.0f, 0.0f}} - }; - - unsigned char *spec_data; - float *spec_pixels; - GPUTexture *tex_spec; - GPUProgram *smoke_program; - int progtype = (sds->active_fields & SM_ACTIVE_COLORS) ? GPU_PROGRAM_SMOKE_COLORED : GPU_PROGRAM_SMOKE; - float size[3]; - - if (!tex) { - printf("Could not allocate 3D texture for 3D View smoke drawing.\n"); - return; - } - -#ifdef DEBUG_DRAW_TIME - TIMEIT_START(draw); -#endif - - /* generate flame spectrum texture */ #define SPEC_WIDTH 256 #define FIRE_THRESH 7 #define MAX_FIRE_ALPHA 0.06f #define FULL_ON_FIRE 100 - spec_data = malloc(SPEC_WIDTH * 4 * sizeof(unsigned char)); + + GPUTexture *tex; + int i, j, k; + unsigned char *spec_data = malloc(SPEC_WIDTH * 4 * sizeof(unsigned char)); + float *spec_pixels = malloc(SPEC_WIDTH * 4 * 16 * 16 * sizeof(float)); + flame_get_spectrum(spec_data, SPEC_WIDTH, 1500, 3000); - spec_pixels = malloc(SPEC_WIDTH * 4 * 16 * 16 * sizeof(float)); + for (i = 0; i < 16; i++) { for (j = 0; j < 16; j++) { for (k = 0; k < SPEC_WIDTH; k++) { @@ -168,87 +114,93 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, (k > FULL_ON_FIRE) ? 1.0f : (k - FIRE_THRESH) / ((float)FULL_ON_FIRE - FIRE_THRESH)); } else { - spec_pixels[index] = spec_pixels[index + 1] = spec_pixels[index + 2] = spec_pixels[index + 3] = 0.0f; + zero_v4(&spec_pixels[index]); } } } } - tex_spec = GPU_texture_create_1D(SPEC_WIDTH, spec_pixels, NULL); + tex = GPU_texture_create_1D(SPEC_WIDTH, spec_pixels, NULL); + + free(spec_data); + free(spec_pixels); #undef SPEC_WIDTH #undef FIRE_THRESH #undef MAX_FIRE_ALPHA #undef FULL_ON_FIRE - sub_v3_v3v3(size, max, min); - - /* maxx, maxy, maxz */ - cv[0][0] = max[0]; - cv[0][1] = max[1]; - cv[0][2] = max[2]; - /* minx, maxy, maxz */ - cv[1][0] = min[0]; - cv[1][1] = max[1]; - cv[1][2] = max[2]; - /* minx, miny, maxz */ - cv[2][0] = min[0]; - cv[2][1] = min[1]; - cv[2][2] = max[2]; - /* maxx, miny, maxz */ - cv[3][0] = max[0]; - cv[3][1] = min[1]; - cv[3][2] = max[2]; - - /* maxx, maxy, minz */ - cv[4][0] = max[0]; - cv[4][1] = max[1]; - cv[4][2] = min[2]; - /* minx, maxy, minz */ - cv[5][0] = min[0]; - cv[5][1] = max[1]; - cv[5][2] = min[2]; - /* minx, miny, minz */ - cv[6][0] = min[0]; - cv[6][1] = min[1]; - cv[6][2] = min[2]; - /* maxx, miny, minz */ - cv[7][0] = max[0]; - cv[7][1] = min[1]; - cv[7][2] = min[2]; - - copy_v3_v3(edges[0][0], cv[4]); /* maxx, maxy, minz */ - copy_v3_v3(edges[1][0], cv[5]); /* minx, maxy, minz */ - copy_v3_v3(edges[2][0], cv[6]); /* minx, miny, minz */ - copy_v3_v3(edges[3][0], cv[7]); /* maxx, miny, minz */ - - copy_v3_v3(edges[4][0], cv[3]); /* maxx, miny, maxz */ - copy_v3_v3(edges[5][0], cv[2]); /* minx, miny, maxz */ - copy_v3_v3(edges[6][0], cv[6]); /* minx, miny, minz */ - copy_v3_v3(edges[7][0], cv[7]); /* maxx, miny, minz */ - - copy_v3_v3(edges[8][0], cv[1]); /* minx, maxy, maxz */ - copy_v3_v3(edges[9][0], cv[2]); /* minx, miny, maxz */ - copy_v3_v3(edges[10][0], cv[6]); /* minx, miny, minz */ - copy_v3_v3(edges[11][0], cv[5]); /* minx, maxy, minz */ + return tex; +} - // printf("size x: %f, y: %f, z: %f\n", size[0], size[1], size[2]); - // printf("min[2]: %f, max[2]: %f\n", min[2], max[2]); +void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, + const float min[3], const float max[3], + const int res[3], const float viewnormal[3]) +{ + GPUTexture *tex_spec; + GPUProgram *smoke_program; + const int progtype = (sds->active_fields & SM_ACTIVE_COLORS) ? GPU_PROGRAM_SMOKE_COLORED + : GPU_PROGRAM_SMOKE; + + const float ob_sizei[3] = { + 1.0f / fabsf(ob->size[0]), + 1.0f / fabsf(ob->size[1]), + 1.0f / fabsf(ob->size[2]) + }; + + int i, j, n, good_index; + float d /*, d0 */ /* UNUSED */, dd, ds; + float (*points)[3] = NULL; + int numpoints = 0; + float cor[3] = {1.0f, 1.0f, 1.0f}; + int gl_depth = 0, gl_blend = 0; + + const bool use_fire = (sds->active_fields & SM_ACTIVE_FIRE) != 0; + + /* draw slices of smoke is adapted from c++ code authored + * by: Johannes Schmid and Ingemar Rask, 2006, johnny@grob.org */ + const float verts[8][3] = { + { max[0], max[1], max[2] }, + { min[0], max[1], max[2] }, + { min[0], min[1], max[2] }, + { max[0], min[1], max[2] }, + { max[0], max[1], min[2] }, + { min[0], max[1], min[2] }, + { min[0], min[1], min[2] }, + { max[0], min[1], min[2] } + }; + + const float size[3] = { max[0] - min[0], max[1] - min[1], max[2] - min[2] }; + + /* edges have the form edges[n][0][xyz] + t*edges[n][1][xyz] */ + const float edges[12][2][3] = { + {{verts[4][0], verts[4][1], verts[4][2]}, {0.0f, 0.0f, size[2]}}, + {{verts[5][0], verts[5][1], verts[5][2]}, {0.0f, 0.0f, size[2]}}, + {{verts[6][0], verts[6][1], verts[6][2]}, {0.0f, 0.0f, size[2]}}, + {{verts[7][0], verts[7][1], verts[7][2]}, {0.0f, 0.0f, size[2]}}, + + {{verts[3][0], verts[3][1], verts[3][2]}, {0.0f, size[1], 0.0f}}, + {{verts[2][0], verts[2][1], verts[2][2]}, {0.0f, size[1], 0.0f}}, + {{verts[6][0], verts[6][1], verts[6][2]}, {0.0f, size[1], 0.0f}}, + {{verts[7][0], verts[7][1], verts[7][2]}, {0.0f, size[1], 0.0f}}, + + {{verts[1][0], verts[1][1], verts[1][2]}, {size[0], 0.0f, 0.0f}}, + {{verts[2][0], verts[2][1], verts[2][2]}, {size[0], 0.0f, 0.0f}}, + {{verts[6][0], verts[6][1], verts[6][2]}, {size[0], 0.0f, 0.0f}}, + {{verts[5][0], verts[5][1], verts[5][2]}, {size[0], 0.0f, 0.0f}} + }; - edges[0][1][2] = size[2]; - edges[1][1][2] = size[2]; - edges[2][1][2] = size[2]; - edges[3][1][2] = size[2]; + if (!sds->tex) { + printf("Could not allocate 3D texture for 3D View smoke drawing.\n"); + return; + } - edges[4][1][1] = size[1]; - edges[5][1][1] = size[1]; - edges[6][1][1] = size[1]; - edges[7][1][1] = size[1]; +#ifdef DEBUG_DRAW_TIME + TIMEIT_START(draw); +#endif - edges[8][1][0] = size[0]; - edges[9][1][0] = size[0]; - edges[10][1][0] = size[0]; - edges[11][1][0] = size[0]; + // printf("size x: %f, y: %f, z: %f\n", size[0], size[1], size[2]); + // printf("min[2]: %f, max[2]: %f\n", min[2], max[2]); glGetBooleanv(GL_BLEND, (GLboolean *)&gl_blend); glGetBooleanv(GL_DEPTH_TEST, (GLboolean *)&gl_depth); @@ -258,11 +210,9 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, /* find cube vertex that is closest to the viewer */ for (i = 0; i < 8; i++) { - float x, y, z; - - x = cv[i][0] - viewnormal[0] * size[0] * 0.5f; - y = cv[i][1] - viewnormal[1] * size[1] * 0.5f; - z = cv[i][2] - viewnormal[2] * size[2] * 0.5f; + float x = verts[i][0] - viewnormal[0] * size[0] * 0.5f; + float y = verts[i][1] - viewnormal[1] * size[1] * 0.5f; + float z = verts[i][2] - viewnormal[2] * size[2] * 0.5f; if ((x >= min[0]) && (x <= max[0]) && (y >= min[1]) && (y <= max[1]) && @@ -285,7 +235,7 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, GPU_program_bind(smoke_program); /* cell spacing */ - GPU_program_parameter_4f(smoke_program, 0, dx, dx, dx, 1.0); + GPU_program_parameter_4f(smoke_program, 0, sds->dx, sds->dx, sds->dx, 1.0); /* custom parameter for smoke style (higher = thicker) */ if (sds->active_fields & SM_ACTIVE_COLORS) GPU_program_parameter_4f(smoke_program, 1, 1.0, 1.0, 1.0, 10.0); @@ -295,14 +245,15 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, else printf("Your gfx card does not support 3D View smoke drawing.\n"); - GPU_texture_bind(tex, 0); - if (tex_shadow) - GPU_texture_bind(tex_shadow, 1); + GPU_texture_bind(sds->tex, 0); + if (sds->tex_shadow) + GPU_texture_bind(sds->tex_shadow, 1); else printf("No volume shadow\n"); - if (tex_flame) { - GPU_texture_bind(tex_flame, 2); + if (sds->tex_flame) { + GPU_texture_bind(sds->tex_flame, 2); + tex_spec = create_flame_spectrum_texture(); GPU_texture_bind(tex_spec, 3); } @@ -332,16 +283,13 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, points = MEM_callocN(sizeof(*points) * 12, "smoke_points_preview"); while (1) { - float p0[3]; - float tmp_point[3], tmp_point2[3]; + float p0[3], tmp_point[3]; if (dd * (float)n > ds) break; - copy_v3_v3(tmp_point, viewnormal); - mul_v3_fl(tmp_point, -dd * ((ds / dd) - (float)n)); - add_v3_v3v3(tmp_point2, cv[good_index], tmp_point); - d = dot_v3v3(tmp_point2, viewnormal); + madd_v3_v3v3fl(tmp_point, verts[good_index], viewnormal, -dd * ((ds / dd) - (float)n)); + d = dot_v3v3(tmp_point, viewnormal); // printf("my d: %f\n", d); @@ -372,7 +320,6 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, GPU_program_parameter_4f(smoke_program, 2, 1.0, 0.0, 0.0, 0.0); glBegin(GL_POLYGON); - glColor3f(1.0, 1.0, 1.0); for (i = 0; i < numpoints; i++) { glTexCoord3d((points[i][0] - min[0]) * cor[0], (points[i][1] - min[1]) * cor[1], @@ -392,7 +339,6 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, GPU_program_parameter_4f(smoke_program, 2, -1.0, 0.0, 0.0, 0.0); glBegin(GL_POLYGON); - glColor3f(1.0, 1.0, 1.0); for (i = 0; i < numpoints; i++) { glTexCoord3d((points[i][0] - min[0]) * cor[0], (points[i][1] - min[1]) * cor[1], @@ -411,22 +357,20 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, TIMEIT_END(draw); #endif - if (tex_shadow) - GPU_texture_unbind(tex_shadow); - GPU_texture_unbind(tex); - if (tex_flame) { - GPU_texture_unbind(tex_flame); + GPU_texture_unbind(sds->tex); + + if (sds->tex_shadow) + GPU_texture_unbind(sds->tex_shadow); + + if (sds->tex_flame) { + GPU_texture_unbind(sds->tex_flame); GPU_texture_unbind(tex_spec); + GPU_texture_free(tex_spec); } - GPU_texture_free(tex_spec); - - free(spec_data); - free(spec_pixels); if (smoke_program) GPU_program_unbind(smoke_program); - MEM_freeN(points); if (!gl_blend) { diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 95c0ef92680..94c1db8aa5d 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -273,9 +273,8 @@ extern const char *view3d_context_dir[]; /* doc access */ /* draw_volume.c */ void draw_smoke_volume(struct SmokeDomainSettings *sds, struct Object *ob, - struct GPUTexture *tex, const float min[3], const float max[3], - const int res[3], float dx, float base_scale, const float viewnormal[3], - struct GPUTexture *tex_shadow, struct GPUTexture *tex_flame); + const float min[3], const float max[3], + const int res[3], const float viewnormal[3]); //#define SMOKE_DEBUG_VELOCITY //#define SMOKE_DEBUG_HEAT |