diff options
author | Daniel Genrich <daniel.genrich@gmx.net> | 2009-07-30 19:00:26 +0400 |
---|---|---|
committer | Daniel Genrich <daniel.genrich@gmx.net> | 2009-07-30 19:00:26 +0400 |
commit | 58c88bcf7636abce291168af189284181f2f7033 (patch) | |
tree | f99c18e5601242113b0d3888331578d5b0966c59 /source/blender/editors | |
parent | 1b26fe50c35afe5c83a0bf3a69fce55db00374d3 (diff) |
BF2.5: First commit of smoke code.
Not working:
a) rendering (since volumterics branch is not merged yet)
b) moving collision objects of any kind
c) saving of collision objects (because that's what I am working on)
d) pointcache
e) A bunch of other things I already know of
So please do not report any bugs on this one yet :-)
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/CMakeLists.txt | 2 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/SConscript | 1 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawobject.c | 331 |
3 files changed, 333 insertions, 1 deletions
diff --git a/source/blender/editors/CMakeLists.txt b/source/blender/editors/CMakeLists.txt index b7a868ad537..28cfcb3ff6e 100644 --- a/source/blender/editors/CMakeLists.txt +++ b/source/blender/editors/CMakeLists.txt @@ -35,7 +35,7 @@ SET(INC ../windowmanager ../../../intern/decimation/extern ../blenloader ../python ../../kernel/gen_system ../../../intern/SoundSystem ../readstreamglue ../quicktime ../../../intern/elbeem/extern - ../../../intern/ghost ../../../intern/opennl/extern ../../../extern/glew/include + ../../../intern/ghost ../../../intern/opennl/extern ../../../extern/glew/include ../../../intern/smoke/extern ../nodes ../gpu ../blenfont diff --git a/source/blender/editors/space_view3d/SConscript b/source/blender/editors/space_view3d/SConscript index 7d51d237ef0..4eb9f3f5ecb 100644 --- a/source/blender/editors/space_view3d/SConscript +++ b/source/blender/editors/space_view3d/SConscript @@ -8,6 +8,7 @@ incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' incs += ' ../../render/extern/include #/intern/guardedalloc' incs += ' ../../gpu ../../makesrna ../../blenfont' +incs += ' #/intern/smoke/extern' if env['WITH_BF_GAMEENGINE']: defs.append('GAMEBLENDER=1') diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 53630b2bee0..d0bee9c18f8 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -59,6 +59,7 @@ #include "DNA_space_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" +#include "DNA_smoke_types.h" #include "DNA_userdef_types.h" #include "DNA_view3d_types.h" #include "DNA_world_types.h" @@ -88,7 +89,9 @@ #include "BKE_object.h" #include "BKE_particle.h" #include "BKE_property.h" +#include "BKE_smoke.h" #include "BKE_utildefines.h" +#include "smoke_API.h" #include "BIF_gl.h" #include "BIF_glutil.h" @@ -4898,6 +4901,7 @@ void drawRBpivot(bRigidBodyJointConstraint *data) void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) { static int warning_recursive= 0; + ModifierData *md = NULL; Object *ob; Curve *cu; RegionView3D *rv3d= ar->regiondata; @@ -5293,6 +5297,333 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) if(col) cpack(col); } + /* draw code for smoke */ + if(md = modifiers_findByType(ob, eModifierType_Smoke)) + { + SmokeModifierData *smd = (SmokeModifierData *)md; + + // draw collision objects + if((smd->type & MOD_SMOKE_TYPE_COLL) && smd->coll) + { + SmokeCollSettings *scs = smd->coll; + /* + if(scs->points) + { + size_t i; + + wmLoadMatrix(rv3d->viewmat); + + if(col || (ob->flag & SELECT)) cpack(0xFFFFFF); + glDepthMask(GL_FALSE); + glEnable(GL_BLEND); + + + // glPointSize(3.0); + bglBegin(GL_POINTS); + + for(i = 0; i < scs->numpoints; i++) + { + bglVertex3fv(&scs->points[3*i]); + } + + bglEnd(); + glPointSize(1.0); + + wmMultMatrix(ob->obmat); + glDisable(GL_BLEND); + glDepthMask(GL_TRUE); + if(col) cpack(col); + + } + */ + } + + // only draw domains + if(smd->domain && smd->domain->fluid) + { + int x, y, z, i; + float *density = NULL; + float viewnormal[3]; + int mainaxis[3] = {0,0,0}; + float align = 0; + int max_textures = 0, counter_textures = 0; + int counter=0; + float *buffer = NULL; + int res[3]; + float bigfactor = 1.0; + int big = smd->domain->flags & MOD_SMOKE_HIGHRES; + int new = 0; + + // GUI sent redraw event + if(smd->domain->flags & MOD_SMOKE_VIEW_REDRAWNICE) + { + new = 1; + smd->domain->flags &= ~MOD_SMOKE_VIEW_REDRAWNICE; + } + + if(!big) + { + res[0] = smd->domain->res[0]; + res[1] = smd->domain->res[1]; + res[2] = smd->domain->res[2]; + } + else + { + smoke_get_bigres(smd->domain->fluid, res); + bigfactor = 1.0 / smd->domain->amplify; + } + + wmLoadMatrix(rv3d->viewmat); + + if(col || (ob->flag & SELECT)) cpack(0xFFFFFF); /* for visibility, also while wpaint */ + glDepthMask(GL_FALSE); + glEnable(GL_BLEND); + + // get view vector + VECCOPY(viewnormal, rv3d->viewinv[2]); + Normalize(viewnormal); + for(i = 0; i < 3; i++) + { + if(ABS(viewnormal[i]) > align) + { + mainaxis[0] = i; + align = ABS(viewnormal[i]); + } + } + mainaxis[1] = (mainaxis[0] + 1) % 3; + mainaxis[2] = (mainaxis[0] + 2) % 3; + + if(!smd->domain->bind) + { + smd->domain->bind = MEM_callocN(sizeof(GLuint)*256, "Smoke_bind"); + if(big) + smd->domain->viewsettings |= MOD_SMOKE_VIEW_CHANGETOBIG; + new = 3; + } + + // check if view axis / mode has been changed + if(smd->domain->viewsettings) + { + if(big) + { + if(!(smd->domain->viewsettings & MOD_SMOKE_VIEW_BIG)) + new = 2; + else if(!(smd->domain->viewsettings & MOD_SMOKE_VIEW_CHANGETOBIG)) + new = 1; + + smd->domain->viewsettings |= MOD_SMOKE_VIEW_CHANGETOBIG; + } + else + { + if(!(smd->domain->viewsettings & MOD_SMOKE_VIEW_SMALL)) + new = 2; + else if(smd->domain->viewsettings & MOD_SMOKE_VIEW_CHANGETOBIG) + new = 1; + + smd->domain->viewsettings &= ~MOD_SMOKE_VIEW_CHANGETOBIG; + } + + if(!new) + { + if((mainaxis[0] == 0) && !(smd->domain->viewsettings & MOD_SMOKE_VIEW_X)) + new = 1; + else if((mainaxis[0] == 1) && !(smd->domain->viewsettings & MOD_SMOKE_VIEW_Y)) + new = 1; + else if((mainaxis[0] == 2) && !(smd->domain->viewsettings & MOD_SMOKE_VIEW_Z)) + new = 1; + + // printf("check axis\n"); + } + } + else + new = 3; + + if(new > 1) + { + float light[3] = {0.0,0.0,2.0}; + + if(!big && !(smd->domain->viewsettings & MOD_SMOKE_VIEW_SMALL)) + { + smoke_prepare_View(smd, light); + // printf("prepared View!\n"); + } + else if(big && !(smd->domain->viewsettings & MOD_SMOKE_VIEW_BIG)) + { + smoke_prepare_bigView(smd, light); + // printf("prepared bigView!\n"); + } + } + + // printf("big: %d, new: %d\n", big, new); + + // only create buffer if we need to create new textures + if(new) + buffer = MEM_mallocN(sizeof(float)*res[mainaxis[1]]*res[mainaxis[2]]*4, "SmokeDrawBuffer"); + + if(buffer || smd->domain->viewsettings) + { + int mod_texture = 0; + + // printf("if(buffer || smd->domain->viewsettings)\n"); + + max_textures = (res[mainaxis[0]] > 256) ? 256 : res[mainaxis[0]]; + + if(!smd->domain->viewsettings) // new frame or new start + { + smd->domain->max_textures = max_textures; + glGenTextures(smd->domain->max_textures, smd->domain->bind); + new = 1; + // printf("glGenTextures\n"); + } + else + { + if(new) + { + // printf("glDeleteTextures\n"); + glDeleteTextures(smd->domain->max_textures, smd->domain->bind); + smd->domain->max_textures = max_textures; + glGenTextures(smd->domain->max_textures, smd->domain->bind); + } + } + + mod_texture = MAX3(1, smd->domain->visibility, (int)(res[mainaxis[0]] / smd->domain->max_textures )); + + for (z = res[mainaxis[0]]-1; z >= 0; z--) // 2 + { + float quad[4][3]; + + if(new) + { + for (y = 0; y < res[mainaxis[1]]; y++) // 1 + { + for (x = 0; x < res[mainaxis[2]]; x++) // 0 + { + size_t index; + size_t image_index; + float tray, tvox; + + if(mainaxis[0] == 0) + { + // mainaxis[1] == 1, mainaxis[2] == 2 + image_index = smoke_get_index2d(y, res[mainaxis[1]], x, res[mainaxis[2]], z, res[mainaxis[0]]); + index = smoke_get_index(z, res[mainaxis[0]], y, res[mainaxis[1]], x, res[mainaxis[2]]); + } + else if(mainaxis[0] == 1) + { + // mainaxis[1] == 2, mainaxis[2] == 0 + image_index = smoke_get_index2d(y, res[mainaxis[1]], x, res[mainaxis[2]], z, res[mainaxis[0]]); + index = smoke_get_index(x, res[mainaxis[2]], z, res[mainaxis[0]], y, res[mainaxis[1]]); + } + else // mainaxis[0] == 2 + { + // mainaxis[1] == 0, mainaxis[2] == 1 + image_index = smoke_get_index2d(y, res[mainaxis[1]], x, res[mainaxis[2]], z, res[mainaxis[0]]); + index = smoke_get_index(y, res[mainaxis[1]], x, res[mainaxis[2]], z, res[mainaxis[0]]); + } + + if(!big) + { + tvox = smoke_get_tvox(smd, index); + tray = smoke_get_tray(smd, index); + } + else + { + tvox = smoke_get_bigtvox(smd, index); + tray = smoke_get_bigtray(smd, index); + } + + // fill buffer with luminance and alpha + // 1 - T_vox + buffer[image_index*4 + 3] = 1.0 - tvox; // 0 = transparent => d.h. tvox = 1 + + // L_vox = Omega * L_light * (1 - T_vox) * T_ray + buffer[image_index*4] = buffer[image_index*4 + 1] = buffer[image_index*4 + 2] = smd->domain->omega * 1.0 * tvox * tray; + } + } + } + glBindTexture(GL_TEXTURE_2D, smd->domain->bind[counter_textures]); + glEnable(GL_TEXTURE_2D); + + if(new) + { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, res[mainaxis[1]], res[mainaxis[2]], 0, GL_RGBA, GL_FLOAT, buffer); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // Linear Filtering + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtering + } + + if((z % mod_texture) == 0 ) + { + // botttom left + quad[3][mainaxis[0]] = smd->domain->p0[mainaxis[0]] + z * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5; + quad[3][mainaxis[1]] = smd->domain->p0[mainaxis[1]] + smd->domain->dx * bigfactor * 0.5; + quad[3][mainaxis[2]] = smd->domain->p0[mainaxis[2]] + smd->domain->dx * bigfactor * 0.5; + + // top right + quad[1][mainaxis[0]] = smd->domain->p0[mainaxis[0]] + z * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5; + quad[1][mainaxis[1]] = smd->domain->p0[mainaxis[1]] + (res[mainaxis[1]] - 1) * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5; + quad[1][mainaxis[2]] = smd->domain->p0[mainaxis[2]] + (res[mainaxis[2]] - 1) * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5; + + // top left + quad[2][mainaxis[0]] = smd->domain->p0[mainaxis[0]] + z * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5; + quad[2][mainaxis[1]] = smd->domain->p0[mainaxis[1]] + smd->domain->dx * bigfactor * 0.5; + quad[2][mainaxis[2]] = smd->domain->p0[mainaxis[2]] + (res[mainaxis[2]] - 1) * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5; + + // bottom right + quad[0][mainaxis[0]] = smd->domain->p0[mainaxis[0]] + z * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5; + quad[0][mainaxis[1]] = smd->domain->p0[mainaxis[1]] + (res[mainaxis[1]] - 1) * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5; + quad[0][mainaxis[2]] = smd->domain->p0[mainaxis[2]] + smd->domain->dx * bigfactor * 0.5; + + glBegin(GL_QUADS); // Start Drawing Quads + + glTexCoord2f(1.0f, 0.0f); + glVertex3fv(quad[0]); // Left And Up 1 Unit (Top Left) + glTexCoord2f(1.0f, 1.0f); + glVertex3fv(quad[1]); // Right And Up 1 Unit (Top Right) + glTexCoord2f(0.0f, 1.0f); + glVertex3fv(quad[2]); // Right And Down One Unit (Bottom Right) + glTexCoord2f(0.0f, 0.0f); + glVertex3fv(quad[3]); // Left And Down One Unit (Bottom Left) + + glEnd(); + } + counter_textures++; + } + } + if(buffer) + { + MEM_freeN(buffer); + buffer = NULL; + } + + // set correct flag for viewsettings + if(1) + { + // do not clear BIG/SMALL flag + smd->domain->viewsettings &= ~MOD_SMOKE_VIEW_X; + smd->domain->viewsettings &= ~MOD_SMOKE_VIEW_Y; + smd->domain->viewsettings &= ~MOD_SMOKE_VIEW_Z; + + // set what caches we have + if(big) + smd->domain->viewsettings |= MOD_SMOKE_VIEW_BIG; + else + smd->domain->viewsettings |= MOD_SMOKE_VIEW_SMALL; + + if(mainaxis[0] == 0) + smd->domain->viewsettings |= MOD_SMOKE_VIEW_X; + else if(mainaxis[0] == 1) + smd->domain->viewsettings |= MOD_SMOKE_VIEW_Y; + else if(mainaxis[0] == 2) + smd->domain->viewsettings |= MOD_SMOKE_VIEW_Z; + } + + wmMultMatrix(ob->obmat); + glDisable(GL_BLEND); + glDepthMask(GL_TRUE); + if(col) cpack(col); + } + } + { bConstraint *con; for(con=ob->constraints.first; con; con= con->next) |