Undo revision 23130 which was a merge with 2.5, a messy one because I did something...
[blender.git] / source / blender / blenkernel / intern / smoke.c
index fe55412..22ea412 100644 (file)
 #include "BKE_DerivedMesh.h"
 #include "BKE_modifier.h"
 #include "BKE_particle.h"
-#include "BKE_pointcache.h"
-#include "BKE_smoke.h"
 #include "BKE_utildefines.h"
 
 #include "DNA_customdata_types.h"
 #include "DNA_group_types.h"
-#include "DNA_lamp_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_modifier_types.h"
@@ -123,7 +120,8 @@ struct DerivedMesh;
 struct SmokeModifierData;
 
 // forward declerations
-static void get_cell(float *p0, int res[3], float dx, float *pos, int *cell, int correct);
+static void get_cell(struct SmokeModifierData *smd, float *pos, int *cell, int correct);
+static void get_bigcell(struct SmokeModifierData *smd, float *pos, int *cell, int correct);
 void calcTriangleDivs(Object *ob, MVert *verts, int numverts, MFace *tris, int numfaces, int numtris, int **tridivs, float cell_len);
 
 #define TRI_UVOFFSET (1./4.)
@@ -165,11 +163,6 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
 
                // calc other res with max_res provided
                VECSUB(size, max, min);
-
-               // prevent crash when initializing a plane as domain
-               if((size[0] < FLT_EPSILON) || (size[1] < FLT_EPSILON) || (size[2] < FLT_EPSILON))
-                       return 0;
-
                if(size[0] > size[1])
                {
                        if(size[0] > size[1])
@@ -212,31 +205,18 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
                // TODO: put in failsafe if res<=0 - dg
 
                // printf("res[0]: %d, res[1]: %d, res[2]: %d\n", smd->domain->res[0], smd->domain->res[1], smd->domain->res[2]);
+
                // dt max is 0.1
                smd->domain->fluid = smoke_init(smd->domain->res, smd->domain->p0, 0.1);
+               smd->domain->wt = smoke_turbulence_init(smd->domain->res,  (smd->domain->flags & MOD_SMOKE_HIGHRES) ? (smd->domain->amplify + 1) : 0, smd->domain->noise);
                smd->time = scene->r.cfra;
-
-               if(smd->domain->flags & MOD_SMOKE_HIGHRES)
-               {
-                       smd->domain->wt = smoke_turbulence_init(smd->domain->res, smd->domain->amplify + 1, smd->domain->noise);
-                       smd->domain->res_wt[0] = smd->domain->res[0] * (smd->domain->amplify + 1);
-                       smd->domain->res_wt[1] = smd->domain->res[1] * (smd->domain->amplify + 1);                      
-                       smd->domain->res_wt[2] = smd->domain->res[2] * (smd->domain->amplify + 1);                      
-                       smd->domain->dx_wt = smd->domain->dx / (smd->domain->amplify + 1);              
-                       printf("smd->domain->amplify: %d\n",  smd->domain->amplify);
-                       printf("(smd->domain->flags & MOD_SMOKE_HIGHRES)\n");
-               }
-
-               if(!smd->domain->shadow)
-                       smd->domain->shadow = MEM_callocN(sizeof(float) * smd->domain->res[0] * smd->domain->res[1] * smd->domain->res[2], "SmokeDomainShadow");
-
+               smd->domain->firstframe = smd->time;
+               
                smoke_initBlenderRNA(smd->domain->fluid, &(smd->domain->alpha), &(smd->domain->beta));
 
-               if(smd->domain->wt)     
-               {
+               if(smd->domain->wt)
                        smoke_initWaveletBlenderRNA(smd->domain->wt, &(smd->domain->strength));
-                       printf("smoke_initWaveletBlenderRNA\n");
-               }
+
                return 1;
        }
        else if((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow)
@@ -276,11 +256,12 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
                        SmokeCollSettings *scs = smd->coll;
                        MVert *mvert = dm->getVertArray(dm);
                        MFace *mface = dm->getFaceArray(dm);
-                       int i = 0, divs = 0;
+                       size_t i = 0, divs = 0;
                        int *tridivs = NULL;
                        float cell_len = 1.0 / 50.0; // for res = 50
-                       int newdivs = 0;
-                       int quads = 0, facecounter = 0;
+                       size_t newdivs = 0;
+                       //size_t max_points = 0;
+                       size_t quads = 0, facecounter = 0;
 
                        // copy obmat
                        Mat4CpyMat4(scs->mat, ob->obmat);
@@ -318,7 +299,7 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
                                int again = 0;
                                do
                                {
-                                       int j, k;
+                                       size_t j, k;
                                        int divs1 = tridivs[3 * facecounter + 0];
                                        int divs2 = tridivs[3 * facecounter + 1];
                                        //int divs3 = tridivs[3 * facecounter + 2];
@@ -415,10 +396,10 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
                {
                        smd->coll->bvhtree = NULL; // bvhtree_build_from_smoke ( ob->obmat, dm->getFaceArray(dm), dm->getNumFaces(dm), dm->getVertArray(dm), dm->getNumVerts(dm), 0.0 );
                }
-               return 1;
+
        }
 
-       return 1;
+       return 0;
 }
 
 /*! init triangle divisions */
@@ -525,9 +506,22 @@ void smokeModifier_freeDomain(SmokeModifierData *smd)
 {
        if(smd->domain)
        {
-               if(smd->domain->shadow)
-                               MEM_freeN(smd->domain->shadow);
-                       smd->domain->shadow = NULL;
+               // free visualisation buffers
+               if(smd->domain->bind)
+               {
+                       glDeleteTextures(smd->domain->max_textures, (GLuint *)smd->domain->bind);
+                       MEM_freeN(smd->domain->bind);
+               }
+               smd->domain->max_textures = 0; // unnecessary but let's be sure
+
+               if(smd->domain->tray)
+                       MEM_freeN(smd->domain->tray);
+               if(smd->domain->tvox)
+                       MEM_freeN(smd->domain->tvox);
+               if(smd->domain->traybig)
+                       MEM_freeN(smd->domain->traybig);
+               if(smd->domain->tvoxbig)
+                       MEM_freeN(smd->domain->tvoxbig);
 
                if(smd->domain->fluid)
                        smoke_free(smd->domain->fluid);
@@ -535,11 +529,6 @@ void smokeModifier_freeDomain(SmokeModifierData *smd)
                if(smd->domain->wt)
                        smoke_turbulence_free(smd->domain->wt);
 
-               BKE_ptcache_free_list(&(smd->domain->ptcaches[0]));
-               smd->domain->point_cache[0] = NULL;
-               BKE_ptcache_free_list(&(smd->domain->ptcaches[1]));
-               smd->domain->point_cache[1] = NULL;
-
                MEM_freeN(smd->domain);
                smd->domain = NULL;
        }
@@ -587,46 +576,50 @@ void smokeModifier_freeCollision(SmokeModifierData *smd)
        }
 }
 
-void smokeModifier_reset_turbulence(struct SmokeModifierData *smd)
-{
-       if(smd && smd->domain && smd->domain->wt)
-       {
-               smoke_turbulence_free(smd->domain->wt);
-               smd->domain->wt = NULL;
-       }
-
-       smd->domain->point_cache[1]->flag &= ~PTCACHE_SIMULATION_VALID;
-       smd->domain->point_cache[1]->flag |= PTCACHE_OUTDATED;
-       smd->domain->point_cache[1]->simframe= 0;
-       smd->domain->point_cache[1]->last_exact= 0;
-}
-
 void smokeModifier_reset(struct SmokeModifierData *smd)
 {
        if(smd)
        {
                if(smd->domain)
                {
-                       if(smd->domain->shadow)
-                               MEM_freeN(smd->domain->shadow);
-                       smd->domain->shadow = NULL;
+                       // free visualisation buffers
+                       if(smd->domain->bind)
+                       {
+                               glDeleteTextures(smd->domain->max_textures, (GLuint *)smd->domain->bind);
+                               MEM_freeN(smd->domain->bind);
+                               smd->domain->bind = NULL;
+                       }
+                       smd->domain->max_textures = 0;
+                       if(smd->domain->viewsettings < MOD_SMOKE_VIEW_USEBIG)
+                               smd->domain->viewsettings = 0;
+                       else
+                               smd->domain->viewsettings = MOD_SMOKE_VIEW_USEBIG;
+
+                       if(smd->domain->tray)
+                               MEM_freeN(smd->domain->tray);
+                       if(smd->domain->tvox)
+                               MEM_freeN(smd->domain->tvox);
+                       if(smd->domain->traybig)
+                               MEM_freeN(smd->domain->traybig);
+                       if(smd->domain->tvoxbig)
+                               MEM_freeN(smd->domain->tvoxbig);
+
+                       smd->domain->tvox = NULL;
+                       smd->domain->tray = NULL;
+                       smd->domain->tvoxbig = NULL;
+                       smd->domain->traybig = NULL;
 
                        if(smd->domain->fluid)
                        {
                                smoke_free(smd->domain->fluid);
                                smd->domain->fluid = NULL;
                        }
-                                       
-                       smd->domain->point_cache[0]->flag &= ~PTCACHE_SIMULATION_VALID;
-                       smd->domain->point_cache[0]->flag |= PTCACHE_OUTDATED;
-                       smd->domain->point_cache[0]->simframe= 0;
-                       smd->domain->point_cache[0]->last_exact= 0;
-
-                       smokeModifier_reset_turbulence(smd);
-
-                       smd->time = -1;
-
-                       // printf("reset domain end\n");
+                       
+                       if(smd->domain->wt)
+                       {
+                               smoke_turbulence_free(smd->domain->wt);
+                               smd->domain->wt = NULL;
+                       }
                }
                else if(smd->flow)
                {
@@ -684,31 +677,31 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
 
                        smd->domain->smd = smd;
 
-                       smd->domain->point_cache[0] = BKE_ptcache_add(&(smd->domain->ptcaches[0]));
-                       smd->domain->point_cache[0]->flag |= PTCACHE_DISK_CACHE;
-                       smd->domain->point_cache[0]->step = 1;
-
-                       smd->domain->point_cache[1] = BKE_ptcache_add(&(smd->domain->ptcaches[1]));
-                       smd->domain->point_cache[1]->flag |= PTCACHE_DISK_CACHE;
-                       smd->domain->point_cache[1]->step = 1;
-
                        /* set some standard values */
                        smd->domain->fluid = NULL;
-                       smd->domain->wt = NULL;                 
+                       smd->domain->wt = NULL;
                        smd->domain->eff_group = NULL;
                        smd->domain->fluid_group = NULL;
                        smd->domain->coll_group = NULL;
                        smd->domain->maxres = 32;
-                       smd->domain->amplify = 1;                       
-                       smd->domain->omega = 1.0;                       
+                       smd->domain->amplify = 1;
+                       smd->domain->omega = 1.0;
                        smd->domain->alpha = -0.001;
                        smd->domain->beta = 0.1;
                        smd->domain->flags = MOD_SMOKE_DISSOLVE_LOG;
                        smd->domain->strength = 2.0;
                        smd->domain->noise = MOD_SMOKE_NOISEWAVE;
+                       smd->domain->visibility = 1;
                        smd->domain->diss_speed = 5;
+
                        // init 3dview buffer
+                       smd->domain->tvox = NULL;
+                       smd->domain->tray = NULL;
+                       smd->domain->tvoxbig = NULL;
+                       smd->domain->traybig = NULL;
                        smd->domain->viewsettings = 0;
+                       smd->domain->bind = NULL;
+                       smd->domain->max_textures = 0;
                }
                else if(smd->type & MOD_SMOKE_TYPE_FLOW)
                {
@@ -742,321 +735,16 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
        }
 }
 
-// forward decleration
-void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct);
-static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct);
-static int get_lamp(Scene *scene, float *light)
-{      
-       Base *base_tmp = NULL;  
-       for(base_tmp = scene->base.first; base_tmp; base_tmp= base_tmp->next)   
-       {               
-               if(base_tmp->object->type == OB_LAMP)           
-               {                       
-                       Lamp *la = (Lamp *)base_tmp->object->data;      
-
-                       if(la->type == LA_LOCAL)                        
-                       {                               
-                               VECCOPY(light, base_tmp->object->obmat[3]);                             
-                               return 1;                       
-                       }               
-               }       
-       }       
-       return 0;
-}
-
-static void smoke_calc_domain(Scene *scene, Object *ob, SmokeModifierData *smd)
-{
-       SmokeDomainSettings *sds = smd->domain;
-       GroupObject *go = NULL;                 
-       Base *base = NULL;      
-
-       // do flows and fluids
-       if(1)                   
-       {                               
-               Object *otherobj = NULL;                                
-               ModifierData *md = NULL;
-               if(sds->fluid_group) // we use groups since we have 2 domains
-                       go = sds->fluid_group->gobject.first;                           
-               else                                    
-                       base = scene->base.first;
-               while(base || go)
-               {                                       
-                       otherobj = NULL;
-                       if(sds->fluid_group) 
-                       {
-                               if(go->ob)                                                      
-                                       otherobj = go->ob;                                      
-                       }                                       
-                       else                                            
-                               otherobj = base->object;
-                       if(!otherobj)
-                       {
-                               if(sds->fluid_group)
-                                       go = go->next;
-                               else
-                                       base= base->next;
-
-                               continue;
-                       }
-
-                       md = modifiers_findByType(otherobj, eModifierType_Smoke);
-                       
-                       // check for active smoke modifier
-                       if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render))
-                       {
-                               SmokeModifierData *smd2 = (SmokeModifierData *)md;
-                               
-                               // check for initialized smoke object
-                               if((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow)                                            
-                               {
-                                       // we got nice flow object
-                                       SmokeFlowSettings *sfs = smd2->flow;
-                                       
-                                       if(sfs->psys && sfs->psys->part && sfs->psys->part->type==PART_EMITTER) // is particle system selected
-                                       {
-                                               ParticleSystem *psys = sfs->psys;
-                                               ParticleSettings *part=psys->part;
-                                               ParticleData *pa = NULL;                                                                
-                                               int p = 0;                                                              
-                                               float *density = smoke_get_density(sds->fluid);                                                         
-                                               float *bigdensity = smoke_turbulence_get_density(sds->wt);                                                              
-                                               float *heat = smoke_get_heat(sds->fluid);                                                               
-                                               float *velocity_x = smoke_get_velocity_x(sds->fluid);                                                           
-                                               float *velocity_y = smoke_get_velocity_y(sds->fluid);                                                           
-                                               float *velocity_z = smoke_get_velocity_z(sds->fluid);                                                           
-                                               unsigned char *obstacle = smoke_get_obstacle(sds->fluid);                                                               
-                                               int bigres[3];  
-                                                                                                               
-                                               // mostly copied from particle code                                                             
-                                               for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++)                                                                
-                                               {                                                                       
-                                                       int cell[3];                                                                    
-                                                       size_t i = 0;                                                                   
-                                                       size_t index = 0;                                                                       
-                                                       int badcell = 0;                                                                                                                                                
-                                                       if(pa->alive == PARS_KILLED) continue;                                                                  
-                                                       else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue;                                                                    
-                                                       else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0) continue;                                                                        
-                                                       else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue;                                                                                                                                               
-                                                       // VECCOPY(pos, pa->state.co);                                                                  
-                                                       // Mat4MulVecfl (ob->imat, pos);                                                                                                                                                
-                                                       // 1. get corresponding cell                                                                    
-                                                       get_cell(smd->domain->p0, smd->domain->res, smd->domain->dx, pa->state.co, cell, 0);                                                                                                                                    
-                                                       // check if cell is valid (in the domain boundary)                                                                      
-                                                       for(i = 0; i < 3; i++)                                                                  
-                                                       {                                                                               
-                                                               if((cell[i] > sds->res[i] - 1) || (cell[i] < 0))                                                                                
-                                                               {                                                                                       
-                                                                       badcell = 1;                                                                                    
-                                                                       break;                                                                          
-                                                               }                                                                       
-                                                       }                                                                                                                                                       
-                                                       if(badcell)                                                                             
-                                                               continue;                                                                                                                                               
-                                                       // 2. set cell values (heat, density and velocity)                                                                      
-                                                       index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]);                                                                                                                                           
-                                                       if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) && !(obstacle[index] & 2)) // this is inflow                                                                      
-                                                       {                                                                               
-                                                               // heat[index] += sfs->temp * 0.1;                                                                              
-                                                               // density[index] += sfs->density * 0.1;
-                                                               heat[index] = sfs->temp;
-                                                               density[index] = sfs->density;
-
-                                                               /*
-                                                               velocity_x[index] = pa->state.vel[0];
-                                                               velocity_y[index] = pa->state.vel[1];
-                                                               velocity_z[index] = pa->state.vel[2];                                                                           
-                                                               */                                                                              
-                                                               
-                                                               // obstacle[index] |= 2;
-                                                               // we need different handling for the high-res feature
-                                                               if(bigdensity)
-                                                               {
-                                                                       // init all surrounding cells according to amplification, too
-                                                                       int i, j, k;
-
-                                                                       smoke_turbulence_get_res(smd->domain->wt, bigres);
-
-                                                                       for(i = 0; i < smd->domain->amplify + 1; i++)
-                                                                               for(j = 0; j < smd->domain->amplify + 1; j++)
-                                                                                       for(k = 0; k < smd->domain->amplify + 1; k++)                                                                                                   
-                                                                                       {                                                                                                               
-                                                                                               index = smoke_get_index((smd->domain->amplify + 1)* cell[0] + i, bigres[0], (smd->domain->amplify + 1)* cell[1] + j, bigres[1], (smd->domain->amplify + 1)* cell[2] + k);                                                                                                               
-                                                                                               bigdensity[index] = sfs->density;                                                                                                       
-                                                                                       }                                                                               
-                                                               }                                                                       
-                                                       }                                                                       
-                                                       else if(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) // outflow                                                                     
-                                                       {                                                                               
-                                                               heat[index] = 0.f;                                                                              
-                                                               density[index] = 0.f;                                                                           
-                                                               velocity_x[index] = 0.f;                                                                                
-                                                               velocity_y[index] = 0.f;                                                                                
-                                                               velocity_z[index] = 0.f;
-                                                               // we need different handling for the high-res feature
-                                                               if(bigdensity)
-                                                               {
-                                                                       // init all surrounding cells according to amplification, too                                                                                   
-                                                                       int i, j, k;
-                                                                       smoke_turbulence_get_res(smd->domain->wt, bigres);
-
-                                                                       for(i = 0; i < smd->domain->amplify + 1; i++)
-                                                                               for(j = 0; j < smd->domain->amplify + 1; j++)
-                                                                                       for(k = 0; k < smd->domain->amplify + 1; k++)
-                                                                                       {                                                                                                               
-                                                                                               index = smoke_get_index((smd->domain->amplify + 1)* cell[0] + i, bigres[0], (smd->domain->amplify + 1)* cell[1] + j, bigres[1], (smd->domain->amplify + 1)* cell[2] + k);                                                                                                               
-                                                                                               bigdensity[index] = 0.f;                                                                                                        
-                                                                                       }                                                                               
-                                                               }                                                                       
-                                                       }       // particles loop                                                       
-                                       }                                                       
-                               }                                                       
-                               else                                                    
-                               {                                                               
-                                       /*                                                              
-                                       for()                                                           
-                                       {                                                                       
-                                               // no psys                                                                      
-                                               BVHTreeNearest nearest;
-                                               nearest.index = -1;
-                                               nearest.dist = FLT_MAX;
-
-                                               BLI_bvhtree_find_nearest(sfs->bvh->tree, pco, &nearest, sfs->bvh->nearest_callback, sfs->bvh);
-                                       }*/                                                     
-                               }                                               
-                       }                                               
-               }
-                       if(sds->fluid_group)
-                               go = go->next;
-                       else
-                               base= base->next;
-               }
-       }
+// forward declaration
+void smoke_calc_transparency(struct SmokeModifierData *smd, float *light, int big);
 
-       // do effectors
-       /*
-       if(sds->eff_group)
-       {
-               for(go = sds->eff_group->gobject.first; go; go = go->next) 
-               {
-                       if(go->ob)
-                       {
-                               if(ob->pd)
-                               {
-                                       
-                               }                                       
-                       }
-               }
-       }
-       */
-
-       // do collisions        
-       if(1)
-       {
-               Object *otherobj = NULL;
-               ModifierData *md = NULL;
-
-               if(sds->coll_group) // we use groups since we have 2 domains
-                       go = sds->coll_group->gobject.first;
-               else
-                       base = scene->base.first;
-
-               while(base || go)
-               {
-                       otherobj = NULL;
-                       if(sds->coll_group) 
-                       {                                               
-                               if(go->ob)                                                      
-                                       otherobj = go->ob;                                      
-                       }                                       
-                       else                                            
-                               otherobj = base->object;                                        
-                       if(!otherobj)                                   
-                       {                                               
-                               if(sds->coll_group)                                                     
-                                       go = go->next;                                          
-                               else                                                    
-                                       base= base->next;                                               
-                               continue;                                       
-                       }                       
-                       md = modifiers_findByType(otherobj, eModifierType_Smoke);
-                       
-                       // check for active smoke modifier
-                       if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render))                                    
-                       {
-                               SmokeModifierData *smd2 = (SmokeModifierData *)md;
-
-                               if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll)
-                               {
-                                       // we got nice collision object
-                                       SmokeCollSettings *scs = smd2->coll;
-                                       size_t i, j;
-                                       unsigned char *obstacles = smoke_get_obstacle(smd->domain->fluid);
-
-                                       for(i = 0; i < scs->numpoints; i++)
-                                       {
-                                               int badcell = 0;
-                                               size_t index = 0;
-                                               int cell[3];
-
-                                               // 1. get corresponding cell
-                                               get_cell(smd->domain->p0, smd->domain->res, smd->domain->dx, &scs->points[3 * i], cell, 0);
-                                       
-                                               // check if cell is valid (in the domain boundary)
-                                               for(j = 0; j < 3; j++)
-                                                       if((cell[j] > sds->res[j] - 1) || (cell[j] < 0))
-                                                       {
-                                                               badcell = 1;
-                                                               break;
-                                                       }
-                                                                                                                               
-                                                       if(badcell)                                                                     
-                                                               continue;
-                                               // 2. set cell values (heat, density and velocity)
-                                               index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]);
-                                                                                                               
-                                               // printf("cell[0]: %d, cell[1]: %d, cell[2]: %d\n", cell[0], cell[1], cell[2]);                                                                
-                                               // printf("res[0]: %d, res[1]: %d, res[2]: %d, index: %d\n\n", sds->res[0], sds->res[1], sds->res[2], index);                                                                                                                                   
-                                               obstacles[index] = 1;
-                                               // for moving gobstacles                                                                
-                                               /*
-                                               const LbmFloat maxVelVal = 0.1666;
-                                               const LbmFloat maxusqr = maxVelVal*maxVelVal*3. *1.5;
-
-                                               LbmVec objvel = vec2L((mMOIVertices[n]-mMOIVerticesOld[n]) /dvec); 
-                                               {                                                               
-                                               const LbmFloat usqr = (objvel[0]*objvel[0]+objvel[1]*objvel[1]+objvel[2]*objvel[2])*1.5;                                                                
-                                               USQRMAXCHECK(usqr, objvel[0],objvel[1],objvel[2], mMaxVlen, mMxvx,mMxvy,mMxvz);                                                                 
-                                               if(usqr>maxusqr) {                                                                      
-                                               // cutoff at maxVelVal                                                                  
-                                               for(int jj=0; jj<3; jj++) {                                                                             
-                                               if(objvel[jj]>0.) objvel[jj] =  maxVelVal;                                                                              
-                                               if(objvel[jj]<0.) objvel[jj] = -maxVelVal;                                                                      
-                                               }                                                               
-                                               } 
-                                               }                                                               
-                                               const LbmFloat dp=dot(objvel, vec2L((*pNormals)[n]) );                                                          
-                                               const LbmVec oldov=objvel; // debug                                                             
-                                               objvel = vec2L((*pNormals)[n]) *dp;                                                             
-                                               */
-                                       }
-                               }
-                       }
-
-                       if(sds->coll_group)
-                               go = go->next;
-                       else
-                               base= base->next;
-               }
-       }
-}
 void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
 {      
+       if(scene->r.cfra >= smd->time)
+               smokeModifier_init(smd, ob, scene, dm);
+
        if((smd->type & MOD_SMOKE_TYPE_FLOW))
        {
-               if(scene->r.cfra >= smd->time)
-                       smokeModifier_init(smd, ob, scene, dm);
-
                if(scene->r.cfra > smd->time)
                {
                        // XXX TODO
@@ -1076,9 +764,6 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
        }
        else if(smd->type & MOD_SMOKE_TYPE_COLL)
        {
-               if(scene->r.cfra >= smd->time)
-                       smokeModifier_init(smd, ob, scene, dm);
-
                if(scene->r.cfra > smd->time)
                {
                        // XXX TODO
@@ -1101,231 +786,459 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
        }
        else if(smd->type & MOD_SMOKE_TYPE_DOMAIN)
        {
-               PointCache *cache = NULL;
-               PTCacheID pid;
-               PointCache *cache_wt = NULL;
-               PTCacheID pid_wt;
-               float timescale;
-               int cache_result = 0, cache_result_wt = 0;
-               int startframe, endframe, framenr, badloading = 0;
                SmokeDomainSettings *sds = smd->domain;
-               float light[3]; 
-
-               framenr = scene->r.cfra;
-
-               cache = sds->point_cache[0];
-
-               BKE_ptcache_id_from_smoke(&pid, ob, smd);
-               BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, &timescale);
-
-               cache_wt = sds->point_cache[1];
-               BKE_ptcache_id_from_smoke_turbulence(&pid_wt, ob, smd);
-
-               /* handle continuous simulation with the play button */
-               if(BKE_ptcache_get_continue_physics()) 
-               {
-                       // TODO
-                       return;
-               }
-
-               if(framenr < startframe)
+               
+               if(scene->r.cfra > smd->time)
                {
-                       cache->flag &= ~PTCACHE_SIMULATION_VALID;
-                       cache->simframe= 0;
-                       cache->last_exact= 0;
-
-                       cache_wt->flag &= ~PTCACHE_SIMULATION_VALID;
-                       cache_wt->simframe= 0;
-                       cache_wt->last_exact= 0;
+                       GroupObject *go = NULL;
+                       Base *base = NULL;
+                       
+                       tstart();
+                       
+                       if(sds->flags & MOD_SMOKE_DISSOLVE)
+                       {
+                               smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
+                               
+                               if(sds->wt)
+                                       smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
+                       }
 
-                       // we got back in time, reset smoke in this case (TODO: use cache later)
-                       // smd->time = scene->r.cfra;
-                       // smokeModifier_reset(smd);
+                       /* reset view for new frame */
+                       if(sds->viewsettings < MOD_SMOKE_VIEW_USEBIG)
+                               sds->viewsettings = 0;
+                       else
+                               sds->viewsettings = MOD_SMOKE_VIEW_USEBIG;
 
-                       return;
-               }
-               else if(framenr > endframe) 
-               {
-                       framenr = endframe;
+                       // do flows and fluids
+                       if(1)
+                       {
+                               Object *otherobj = NULL;
+                               ModifierData *md = NULL;
 
-                       // we load last valid frame here 
-                       // and don't update the smd->time variable later
-                       badloading = 1;
-               }
+                               if(sds->fluid_group) // we use groups since we have 2 domains
+                                       go = sds->fluid_group->gobject.first;
+                               else
+                                       base = scene->base.first;
 
-               if(!(cache->flag & PTCACHE_SIMULATION_VALID))
-               {
-                       BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
-               }
-               if(sds->wt && !(cache_wt->flag & PTCACHE_SIMULATION_VALID))
-               {
-                       BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_OUTDATED);
-               }
+                               while(base || go)
+                               {
+                                       otherobj = NULL;
 
-               if(smd->time == -1 && framenr!= startframe)
-                       return;
+                                       if(sds->fluid_group) 
+                                       {
+                                               if(go->ob)
+                                                       otherobj = go->ob;
+                                       }
+                                       else
+                                               otherobj = base->object;
 
-               if(!smokeModifier_init(smd, ob, scene, dm))
-                       return;
+                                       if(!otherobj)
+                                       {
+                                               if(sds->fluid_group)
+                                                       go = go->next;
+                                               else
+                                                       base= base->next;
 
-               if(!smd->domain->fluid)
-                               return;
+                                               continue;
+                                       }
 
-               /* try to read from cache */
-               cache_result =  BKE_ptcache_read_cache(&pid, (float)framenr, scene->r.frs_sec);
-               // printf("cache_result: %d\n", cache_result);
+                                       md = modifiers_findByType(otherobj, eModifierType_Smoke);
+                                       
+                                       // check for active smoke modifier
+                                       if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render))
+                                       {
+                                               SmokeModifierData *smd2 = (SmokeModifierData *)md;
+                                               
+                                               // check for initialized smoke object
+                                               if((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow)
+                                               {
+                                                       // we got nice flow object
+                                                       SmokeFlowSettings *sfs = smd2->flow;
+                                                       
+                                                       if(sfs->psys && sfs->psys->part && sfs->psys->part->type==PART_EMITTER) // is particle system selected
+                                                       {
+                                                               ParticleSystem *psys = sfs->psys;
+                                                               ParticleSettings *part=psys->part;
+                                                               ParticleData *pa = NULL;
+                                                               int p = 0;
+                                                               float *density = smoke_get_density(sds->fluid);
+                                                               float *bigdensity = smoke_turbulence_get_density(sds->wt);
+                                                               float *heat = smoke_get_heat(sds->fluid);
+                                                               float *velocity_x = smoke_get_velocity_x(sds->fluid);
+                                                               float *velocity_y = smoke_get_velocity_y(sds->fluid);
+                                                               float *velocity_z = smoke_get_velocity_z(sds->fluid);
+                                                               unsigned char *obstacle = smoke_get_obstacle(sds->fluid);
+                                                               int bigres[3];  
+
+                                                               printf("found flow psys\n");
+                                                               
+                                                               // mostly copied from particle code
+                                                               for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++)
+                                                               {
+                                                                       int cell[3];
+                                                                       size_t i = 0;
+                                                                       size_t index = 0;
+                                                                       int badcell = 0;
+                                                                       
+                                                                       if(pa->alive == PARS_KILLED) continue;
+                                                                       else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue;
+                                                                       else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0) continue;
+                                                                       else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue;
+                                                                       
+                                                                       // VECCOPY(pos, pa->state.co);
+                                                                       // Mat4MulVecfl (ob->imat, pos);
+                                                                       
+                                                                       // 1. get corresponding cell
+                                                                       get_cell(smd, pa->state.co, cell, 0);
+                                                               
+                                                                       // check if cell is valid (in the domain boundary)
+                                                                       for(i = 0; i < 3; i++)
+                                                                       {
+                                                                               if((cell[i] > sds->res[i] - 1) || (cell[i] < 0))
+                                                                               {
+                                                                                       badcell = 1;
+                                                                                       break;
+                                                                               }
+                                                                       }
+                                                                               
+                                                                       if(badcell)
+                                                                               continue;
+                                                                       
+                                                                       // 2. set cell values (heat, density and velocity)
+                                                                       index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]);
+                                                                       
+                                                                       if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) && !(obstacle[index] & 2)) // this is inflow
+                                                                       {
+                                                                               // heat[index] += sfs->temp * 0.1;
+                                                                               // density[index] += sfs->density * 0.1;
+
+                                                                               heat[index] = sfs->temp;
+                                                                               density[index] = sfs->density;
+
+                                                                               /*
+                                                                               velocity_x[index] = pa->state.vel[0];
+                                                                               velocity_y[index] = pa->state.vel[1];
+                                                                               velocity_z[index] = pa->state.vel[2];
+                                                                               */
+                                                                               obstacle[index] |= 2;
+
+                                                                               // we need different handling for the high-res feature
+                                                                               if(bigdensity)
+                                                                               {
+                                                                                       // init all surrounding cells according to amplification, too
+                                                                                       int i, j, k;
+
+                                                                                       smoke_turbulence_get_res(smd->domain->wt, bigres);
+
+                                                                                       for(i = 0; i < smd->domain->amplify + 1; i++)
+                                                                                               for(j = 0; j < smd->domain->amplify + 1; j++)
+                                                                                                       for(k = 0; k < smd->domain->amplify + 1; k++)
+                                                                                                       {
+                                                                                                               index = smoke_get_index((smd->domain->amplify + 1)* cell[0] + i, bigres[0], (smd->domain->amplify + 1)* cell[1] + j, bigres[1], (smd->domain->amplify + 1)* cell[2] + k);
+                                                                                                               bigdensity[index] = sfs->density;
+                                                                                                       }
+                                                                               }
+                                                                       }
+                                                                       else if(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) // outflow
+                                                                       {
+                                                                               heat[index] = 0.f;
+                                                                               density[index] = 0.f;
+                                                                               velocity_x[index] = 0.f;
+                                                                               velocity_y[index] = 0.f;
+                                                                               velocity_z[index] = 0.f;
+
+                                                                               // we need different handling for the high-res feature
+                                                                               if(bigdensity)
+                                                                               {
+                                                                                       // init all surrounding cells according to amplification, too
+                                                                                       int i, j, k;
+
+                                                                                       smoke_turbulence_get_res(smd->domain->wt, bigres);
+
+                                                                                       for(i = 0; i < smd->domain->amplify + 1; i++)
+                                                                                               for(j = 0; j < smd->domain->amplify + 1; j++)
+                                                                                                       for(k = 0; k < smd->domain->amplify + 1; k++)
+                                                                                                       {
+                                                                                                               index = smoke_get_index((smd->domain->amplify + 1)* cell[0] + i, bigres[0], (smd->domain->amplify + 1)* cell[1] + j, bigres[1], (smd->domain->amplify + 1)* cell[2] + k);
+                                                                                                               bigdensity[index] = 0.f;
+                                                                                                       }
+                                                                               }
+                                                                       }
+                                                               }
+                                                       }
+                                                       else
+                                                       {
+                                                               /*
+                                                               for()
+                                                               {
+                                                                       // no psys
+                                                                       BVHTreeNearest nearest;
 
-               if(cache_result == PTCACHE_READ_EXACT) 
-               {
-                       SmokeDomainSettings *sds = smd->domain;
+                                                                       nearest.index = -1;
+                                                                       nearest.dist = FLT_MAX;
 
-                       cache->flag |= PTCACHE_SIMULATION_VALID;
-                       cache->simframe= framenr;
-                       sds->v3dnum = framenr;
+                                                                       BLI_bvhtree_find_nearest(sfs->bvh->tree, pco, &nearest, sfs->bvh->nearest_callback, sfs->bvh);
+                                                               }*/
+                                                       }
+                                               }       
+                                       }
 
-                       if(!badloading)
-                               smd->time = scene->r.cfra;
+                                       if(sds->fluid_group)
+                                               go = go->next;
+                                       else
+                                               base= base->next;
+                               }
+                       }
 
-                       // check for wt cache
-                       if(sds->wt)
+                       // do effectors
+                       /*
+                       if(sds->eff_group)
                        {
-                               cache_result_wt = BKE_ptcache_read_cache(&pid_wt, (float)framenr, scene->r.frs_sec);
-                               // printf("cache_result_wt: %d\n", cache_result_wt);
-
-                               // error handling
-                               if(cache_result_wt == PTCACHE_READ_EXACT) 
-                               {
-                                       cache_wt->flag |= PTCACHE_SIMULATION_VALID;
-                                       cache_wt->simframe= framenr;
-                               }
-                               else if(cache_result_wt==PTCACHE_READ_OLD) 
+                               for(go = sds->eff_group->gobject.first; go; go = go->next) 
                                {
-                                       BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_FREE);
-                                       cache_wt->flag |= PTCACHE_SIMULATION_VALID;
-                               }
-                               else if(ob->id.lib || (cache_wt->flag & PTCACHE_BAKED)) 
-                               {
-                                       // if baked and nothing in cache, do nothing 
-                                       cache_wt->flag &= ~PTCACHE_SIMULATION_VALID;
-                                       cache_wt->simframe= 0;
-                                       cache_wt->last_exact= 0;
+                                       if(go->ob)
+                                       {
+                                               if(ob->pd)
+                                               {
+                                                       
+                                               }
+                                       }
                                }
                        }
+                       */
 
-                       // printf("PTCACHE_READ_EXACT\n");
-                       return;
-               }
-               else if(cache_result==PTCACHE_READ_OLD) 
-               {
-                       BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_FREE);
-                       cache->flag |= PTCACHE_SIMULATION_VALID;
+                       // do collisions        
+                       if(1)
+                       {
+                               Object *otherobj = NULL;
+                               ModifierData *md = NULL;
 
-                       BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_FREE);
-                       cache_wt->flag |= PTCACHE_SIMULATION_VALID;
-               }
-               else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) 
-               {
-                       // if baked and nothing in cache, do nothing 
-                       cache->flag &= ~PTCACHE_SIMULATION_VALID;
-                       cache->simframe= 0;
-                       cache->last_exact= 0;
-
-                       cache_wt->flag &= ~PTCACHE_SIMULATION_VALID;
-                       cache_wt->simframe= 0;
-                       cache_wt->last_exact= 0;
-               
-                       // printf("PTCACHE_BAKED\n");
-                       return;
-               }
-               /*
-               else if((cache_result==0) && ((startframe!=framenr) && !(cache->flag & PTCACHE_SIMULATION_VALID || (framenr == smd->time))))
-               {
-                       cache->flag &= ~PTCACHE_SIMULATION_VALID;
-                       cache->simframe= 0;
-                       cache->last_exact= 0;
+                               if(sds->coll_group) // we use groups since we have 2 domains
+                                       go = sds->coll_group->gobject.first;
+                               else
+                                       base = scene->base.first;
 
-                       return;
-               }*/
+                               while(base || go)
+                               {
+                                       otherobj = NULL;
 
-               // printf("framenr: %d, time: %f\n", framenr, smd->time);
+                                       if(sds->coll_group) 
+                                       {
+                                               if(go->ob)
+                                                       otherobj = go->ob;
+                                       }
+                                       else
+                                               otherobj = base->object;
 
-               /* do simulation */
+                                       if(!otherobj)
+                                       {
+                                               if(sds->coll_group)
+                                                       go = go->next;
+                                               else
+                                                       base= base->next;
 
-               // low res
-               cache->flag |= PTCACHE_SIMULATION_VALID;
-               cache->simframe= framenr;
+                                               continue;
+                                       }
+                       
+                                       md = modifiers_findByType(otherobj, eModifierType_Smoke);
+                                       
+                                       // check for active smoke modifier
+                                       if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render))
+                                       {
+                                               SmokeModifierData *smd2 = (SmokeModifierData *)md;
 
-               if(sds->wt)
-               {
-                       cache_wt->flag |= PTCACHE_SIMULATION_VALID;
-                       cache_wt->simframe= framenr;
-               }
-                               
-               tstart();       
+                                               if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll)
+                                               {
+                                                       // we got nice collision object
+                                                       SmokeCollSettings *scs = smd2->coll;
+                                                       size_t i, j;
+                                                       unsigned char *obstacles = smoke_get_obstacle(smd->domain->fluid);
 
-               if(sds->flags & MOD_SMOKE_DISSOLVE)                     
-               {                               
-                       smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);                                                               
-               }
+                                                       for(i = 0; i < scs->numpoints; i++)
+                                                       {
+                                                               int badcell = 0;
+                                                               size_t index = 0;
+                                                               int cell[3];
 
-               smoke_calc_domain(scene, ob, smd);
-               
-               // set new time
-               smd->time = scene->r.cfra;
+                                                               // 1. get corresponding cell
+                                                               get_cell(smd, &scs->points[3 * i], cell, 0);
+                                                       
+                                                               // check if cell is valid (in the domain boundary)
+                                                               for(j = 0; j < 3; j++)
+                                                                       if((cell[j] > sds->res[j] - 1) || (cell[j] < 0))
+                                                                       {
+                                                                               badcell = 1;
+                                                                               break;
+                                                                       }
+                                                                               
+                                                               if(badcell)
+                                                                       continue;
+
+                                                               // 2. set cell values (heat, density and velocity)
+                                                               index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]);
+                                                               
+                                                               // printf("cell[0]: %d, cell[1]: %d, cell[2]: %d\n", cell[0], cell[1], cell[2]);
+                                                               // printf("res[0]: %d, res[1]: %d, res[2]: %d, index: %d\n\n", sds->res[0], sds->res[1], sds->res[2], index);
+                                                                       
+                                                               obstacles[index] = 1;
 
-               // frame 1 is start, don't simulate anything
-               if(smd->time == 1)
-               {
+                                                               // for moving gobstacles
+                                                               /*
+                                                               const LbmFloat maxVelVal = 0.1666;
+                                                               const LbmFloat maxusqr = maxVelVal*maxVelVal*3. *1.5;
+
+                                                               LbmVec objvel = vec2L((mMOIVertices[n]-mMOIVerticesOld[n]) /dvec); { 
+                                                               const LbmFloat usqr = (objvel[0]*objvel[0]+objvel[1]*objvel[1]+objvel[2]*objvel[2])*1.5; 
+                                                               USQRMAXCHECK(usqr, objvel[0],objvel[1],objvel[2], mMaxVlen, mMxvx,mMxvy,mMxvz); 
+                                                               if(usqr>maxusqr) { 
+                                                                       // cutoff at maxVelVal 
+                                                                       for(int jj=0; jj<3; jj++) { 
+                                                                               if(objvel[jj]>0.) objvel[jj] =  maxVelVal;  
+                                                                               if(objvel[jj]<0.) objvel[jj] = -maxVelVal; 
+                                                                       } 
+                                                               } } 
+
+                                                               const LbmFloat dp=dot(objvel, vec2L((*pNormals)[n]) ); 
+                                                               const LbmVec oldov=objvel; // debug
+                                                               objvel = vec2L((*pNormals)[n]) *dp;
+                                                               */
+                                                       }
+                                               }
+                                       }
+
+                                       if(sds->coll_group)
+                                               go = go->next;
+                                       else
+                                               base= base->next;
+                               }
+                       }
+                       
                        // set new time
                        smd->time = scene->r.cfra;
 
-                       BKE_ptcache_write_cache(&pid, framenr);
+                       // simulate the actual smoke (c++ code in intern/smoke)
+                       smoke_step(sds->fluid, smd->time);
                        if(sds->wt)
-                               BKE_ptcache_write_cache(&pid_wt, framenr);
-
-                       if(get_lamp(scene, light))
-                               smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx);
+                               smoke_turbulence_step(sds->wt, sds->fluid);
 
-                       // printf("smd->time: %f\n", smd->time);
-                       return;
+                       tend();
+                       printf ( "Frame: %d, Time: %f\n", (int)smd->time, ( float ) tval() );
                }
+               else if(scene->r.cfra < smd->time)
+               {
+                       // we got back in time, reset smoke in this case (TODO: use cache later)
+                       smd->time = scene->r.cfra;
+                       smokeModifier_reset(smd);
+               }
+       }
+}
 
-               // simulate the actual smoke (c++ code in intern/smoke)
-               smoke_step(sds->fluid, smd->time);
-               BKE_ptcache_write_cache(&pid, framenr);
+// update necessary information for 3dview
+void smoke_prepare_View(SmokeModifierData *smd, float *light)
+{
+       float *density = NULL;
+       int x, y, z;
 
-               if(sds->wt)
-               {
+       if(!smd->domain->tray)
+       {
+               // TRay is for self shadowing
+               smd->domain->tray = MEM_callocN(sizeof(float)*smd->domain->res[0]*smd->domain->res[1]*smd->domain->res[2], "Smoke_tRay");
+       }
+       if(!smd->domain->tvox)
+       {
+               // TVox is for tranaparency
+               smd->domain->tvox = MEM_callocN(sizeof(float)*smd->domain->res[0]*smd->domain->res[1]*smd->domain->res[2], "Smoke_tVox");
+       }
 
-                       if(sds->flags & MOD_SMOKE_DISSOLVE)                                                     
-                               smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
+       // update 3dview
+       density = smoke_get_density(smd->domain->fluid);
+       for(x = 0; x < smd->domain->res[0]; x++)
+                       for(y = 0; y < smd->domain->res[1]; y++)
+                               for(z = 0; z < smd->domain->res[2]; z++)
+                               {
+                                       size_t index;
+
+                                       index = smoke_get_index(x, smd->domain->res[0], y, smd->domain->res[1], z);
+                                       // Transparency computation
+                                       // formula taken from "Visual Simulation of Smoke" / Fedkiw et al. pg. 4
+                                       // T_vox = exp(-C_ext * h)
+                                       // C_ext/sigma_t = density * C_ext
+                                       smoke_set_tvox(smd, index, exp(-density[index] * 7.0 * smd->domain->dx));
+       }
+       smoke_calc_transparency(smd, light, 0);
+}
 
-                       smoke_turbulence_step(sds->wt, sds->fluid);
-                       BKE_ptcache_write_cache(&pid_wt, framenr);
-               }
+// update necessary information for 3dview ("high res" option)
+void smoke_prepare_bigView(SmokeModifierData *smd, float *light)
+{
+       float *density = NULL;
+       size_t i = 0;
+       int bigres[3];
+
+       smoke_turbulence_get_res(smd->domain->wt, bigres);
 
-               if(get_lamp(scene, light))
-                       smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx);
+       if(!smd->domain->traybig)
+       {
+               // TRay is for self shadowing
+               smd->domain->traybig = MEM_callocN(sizeof(float)*bigres[0]*bigres[1]*bigres[2], "Smoke_tRayBig");
+       }
+       if(!smd->domain->tvoxbig)
+       {
+               // TVox is for tranaparency
+               smd->domain->tvoxbig = MEM_callocN(sizeof(float)*bigres[0]*bigres[1]*bigres[2], "Smoke_tVoxBig");
+       }
 
-               tend();
-               // printf ( "Frame: %d, Time: %f\n", (int)smd->time, ( float ) tval() );
+       density = smoke_turbulence_get_density(smd->domain->wt);
+       for (i = 0; i < bigres[0] * bigres[1] * bigres[2]; i++)
+       {
+               // Transparency computation
+               // formula taken from "Visual Simulation of Smoke" / Fedkiw et al. pg. 4
+               // T_vox = exp(-C_ext * h)
+               // C_ext/sigma_t = density * C_ext
+               smoke_set_bigtvox(smd, i, exp(-density[i] * 7.0 * smd->domain->dx / (smd->domain->amplify + 1)) );
        }
+       smoke_calc_transparency(smd, light, 1);
 }
 
-static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct)
+
+float smoke_get_tvox(SmokeModifierData *smd, size_t index)
 {
-       const size_t index = smoke_get_index(pixel[0], res[0], pixel[1], res[1], pixel[2]);
+       return smd->domain->tvox[index];
+}
 
-       // T_ray *= T_vox
-       *tRay *= exp(input[index]*correct);
-       
-       if(result[index] < 0.0f)        
-       {
-#pragma omp critical           
-               result[index] = *tRay;  
-       }       
+void smoke_set_tvox(SmokeModifierData *smd, size_t index, float tvox)
+{
+       smd->domain->tvox[index] = tvox;
+}
+
+float smoke_get_tray(SmokeModifierData *smd, size_t index)
+{
+       return smd->domain->tray[index];
+}
+
+void smoke_set_tray(SmokeModifierData *smd, size_t index, float transparency)
+{
+       smd->domain->tray[index] = transparency;
+}
 
-       return *tRay;
+float smoke_get_bigtvox(SmokeModifierData *smd, size_t index)
+{
+       return smd->domain->tvoxbig[index];
+}
+
+void smoke_set_bigtvox(SmokeModifierData *smd, size_t index, float tvox)
+{
+       smd->domain->tvoxbig[index] = tvox;
+}
+
+float smoke_get_bigtray(SmokeModifierData *smd, size_t index)
+{
+       return smd->domain->traybig[index];
+}
+
+void smoke_set_bigtray(SmokeModifierData *smd, size_t index, float transparency)
+{
+       smd->domain->traybig[index] = transparency;
 }
 
 long long smoke_get_mem_req(int xres, int yres, int zres, int amplify)
@@ -1346,7 +1259,34 @@ long long smoke_get_mem_req(int xres, int yres, int zres, int amplify)
          return totalMB;
 }
 
-static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, float *tRay, bresenham_callback cb, float *result, float *input, int res[3], float correct)
+
+static void calc_voxel_transp(SmokeModifierData *smd, int *pixel, float *tRay)
+{
+       // printf("Pixel(%d, %d, %d)\n", pixel[0], pixel[1], pixel[2]);
+       const size_t index = smoke_get_index(pixel[0], smd->domain->res[0], pixel[1], smd->domain->res[1], pixel[2]);
+
+       // T_ray *= T_vox
+       *tRay *= smoke_get_tvox(smd, index);
+}
+
+static void calc_voxel_transp_big(SmokeModifierData *smd, int *pixel, float *tRay)
+{
+       int bigres[3];
+       size_t index;
+
+       smoke_turbulence_get_res(smd->domain->wt, bigres);
+       index = smoke_get_index(pixel[0], bigres[0], pixel[1], bigres[1], pixel[2]);
+
+       /*
+       if(index > bigres[0]*bigres[1]*bigres[2])
+               printf("pixel[0]: %d, [1]: %d, [2]: %d\n", pixel[0], pixel[1], pixel[2]);
+       */
+
+       // T_ray *= T_vox
+       *tRay *= smoke_get_bigtvox(smd, index);
+}
+
+static void bresenham_linie_3D(SmokeModifierData *smd, int x1, int y1, int z1, int x2, int y2, int z2, float *tRay, int big)
 {
     int dx, dy, dz, i, l, m, n, x_inc, y_inc, z_inc, err_1, err_2, dx2, dy2, dz2;
     int pixel[3];
@@ -1373,8 +1313,12 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f
         err_1 = dy2 - l;
         err_2 = dz2 - l;
         for (i = 0; i < l; i++) {
-               if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON)
-                       break;
+               if(!big)
+                               calc_voxel_transp(smd, pixel, tRay);
+                       else
+                               calc_voxel_transp_big(smd, pixel, tRay);
+               if(*tRay < 0.0f)
+                       return;
             if (err_1 > 0) {
                 pixel[1] += y_inc;
                 err_1 -= dx2;
@@ -1391,8 +1335,12 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f
         err_1 = dx2 - m;
         err_2 = dz2 - m;
         for (i = 0; i < m; i++) {
-               if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON)
-                       break;
+               if(!big)
+                               calc_voxel_transp(smd, pixel, tRay);
+                       else
+                               calc_voxel_transp_big(smd, pixel, tRay);
+               if(*tRay < 0.0f)
+                       return;
             if (err_1 > 0) {
                 pixel[0] += x_inc;
                 err_1 -= dy2;
@@ -1409,8 +1357,12 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f
         err_1 = dy2 - n;
         err_2 = dx2 - n;
         for (i = 0; i < n; i++) {
-               if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON)
-                       break;
+               if(!big)
+                               calc_voxel_transp(smd, pixel, tRay);
+                       else
+                               calc_voxel_transp_big(smd, pixel, tRay);
+               if(*tRay < 0.0f)
+                       return;
             if (err_1 > 0) {
                 pixel[1] += y_inc;
                 err_1 -= dz2;
@@ -1424,15 +1376,41 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f
             pixel[2] += z_inc;
         }
     }
-    cb(result, input, res, pixel, tRay, correct);
+    if(!big)
+       calc_voxel_transp(smd, pixel, tRay);
+    else
+       calc_voxel_transp_big(smd, pixel, tRay);
 }
 
-static void get_cell(float *p0, int res[3], float dx, float *pos, int *cell, int correct)
+static void get_cell(struct SmokeModifierData *smd, float *pos, int *cell, int correct)
 {
        float tmp[3];
 
-       VECSUB(tmp, pos, p0);
-       VecMulf(tmp, 1.0 / dx);
+       VECSUB(tmp, pos, smd->domain->p0);
+       VecMulf(tmp, 1.0 / smd->domain->dx);
+
+       if(correct)
+       {
+               cell[0] = MIN2(smd->domain->res[0] - 1, MAX2(0, (int)floor(tmp[0])));
+               cell[1] = MIN2(smd->domain->res[1] - 1, MAX2(0, (int)floor(tmp[1])));
+               cell[2] = MIN2(smd->domain->res[2] - 1, MAX2(0, (int)floor(tmp[2])));
+       }
+       else
+       {
+               cell[0] = (int)floor(tmp[0]);
+               cell[1] = (int)floor(tmp[1]);
+               cell[2] = (int)floor(tmp[2]);
+       }
+}
+static void get_bigcell(struct SmokeModifierData *smd, float *pos, int *cell, int correct)
+{
+       float tmp[3];
+       int res[3];
+       smoke_turbulence_get_res(smd->domain->wt, res);
+
+       VECSUB(tmp, pos, smd->domain->p0);
+
+       VecMulf(tmp, (smd->domain->amplify + 1)/ smd->domain->dx );
 
        if(correct)
        {
@@ -1448,22 +1426,43 @@ static void get_cell(float *p0, int res[3], float dx, float *pos, int *cell, int
        }
 }
 
-void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct)
+
+void smoke_calc_transparency(struct SmokeModifierData *smd, float *light, int big)
 {
        int x, y, z;
        float bv[6];
+       int res[3];
+       float bigfactor = 1.0;
 
-       memset(result, -1, sizeof(float)*res[0]*res[1]*res[2]); // x
-       bv[0] = p0[0];
-       bv[1] = p1[0];
+       // x
+       bv[0] = smd->domain->p0[0];
+       bv[1] = smd->domain->p1[0];
        // y
-       bv[2] = p0[1];
-       bv[3] = p1[1];
+       bv[2] = smd->domain->p0[1];
+       bv[3] = smd->domain->p1[1];
        // z
-       bv[4] = p0[2];
-       bv[5] = p1[2];
+       bv[4] = smd->domain->p0[2];
+       bv[5] = smd->domain->p1[2];
+/*
+       printf("bv[0]: %f, [1]: %f, [2]: %f, [3]: %f, [4]: %f, [5]: %f\n", bv[0], bv[1], bv[2], bv[3], bv[4], bv[5]);
+
+       printf("p0[0]: %f, p0[1]: %f, p0[2]: %f\n", smd->domain->p0[0], smd->domain->p0[1], smd->domain->p0[2]);
+       printf("p1[0]: %f, p1[1]: %f, p1[2]: %f\n", smd->domain->p1[0], smd->domain->p1[1], smd->domain->p1[2]);
+       printf("dx: %f, amp: %d\n", smd->domain->dx, smd->domain->amplify);
+*/
+       if(!big)
+       {
+               res[0] = smd->domain->res[0];
+               res[1] = smd->domain->res[1];
+               res[2] = smd->domain->res[2];
+       }
+       else
+       {
+               smoke_turbulence_get_res(smd->domain->wt, res);
+               bigfactor = 1.0 / (smd->domain->amplify + 1);
+       }
 
-#pragma omp parallel for schedule(static) private(y, z)
+#pragma omp parallel for schedule(static) private(y, z) shared(big, smd, light, res, bigfactor)
        for(x = 0; x < res[0]; x++)
                for(y = 0; y < res[1]; y++)
                        for(z = 0; z < res[2]; z++)
@@ -1476,29 +1475,41 @@ void smoke_calc_transparency(float *result, float *input, float *p0, float *p1,
 
                                index = smoke_get_index(x, res[0], y, res[1], z);
 
-                               if(result[index] >= 0.0f)                                       
-                                       continue;                                                               
-                               voxelCenter[0] = p0[0] + dx *  x + dx * 0.5;
-                               voxelCenter[1] = p0[1] + dx *  y + dx * 0.5;
-                               voxelCenter[2] = p0[2] + dx *  z + dx * 0.5;
+                               // voxelCenter = m_voxelarray[i].GetCenter();
+                               voxelCenter[0] = smd->domain->p0[0] + smd->domain->dx * bigfactor * x + smd->domain->dx * bigfactor * 0.5;
+                               voxelCenter[1] = smd->domain->p0[1] + smd->domain->dx * bigfactor * y + smd->domain->dx * bigfactor * 0.5;
+                               voxelCenter[2] = smd->domain->p0[2] + smd->domain->dx * bigfactor * z + smd->domain->dx * bigfactor * 0.5;
+
+                               // printf("vc[0]: %f, vc[1]: %f, vc[2]: %f\n", voxelCenter[0], voxelCenter[1], voxelCenter[2]);
+                               // printf("light[0]: %f, light[1]: %f, light[2]: %f\n", light[0], light[1], light[2]);
 
                                // get starting position (in voxel coords)
                                if(BLI_bvhtree_bb_raycast(bv, light, voxelCenter, pos) > FLT_EPSILON)
                                {
                                        // we're ouside
-                                       get_cell(p0, res, dx, pos, cell, 1);
+                                       // printf("out: pos[0]: %f, pos[1]: %f, pos[2]: %f\n", pos[0], pos[1], pos[2]);
+                                       if(!big)
+                                               get_cell(smd, pos, cell, 1);
+                                       else
+                                               get_bigcell(smd, pos, cell, 1);
                                }
                                else
                                {
+                                       // printf("in: pos[0]: %f, pos[1]: %f, pos[2]: %f\n", light[0], light[1], light[2]);
                                        // we're inside
-                                       get_cell(p0, res, dx, light, cell, 1);
+                                       if(!big)
+                                               get_cell(smd, light, cell, 1);
+                                       else
+                                               get_bigcell(smd, light, cell, 1);
                                }
 
-                               bresenham_linie_3D(cell[0], cell[1], cell[2], x, y, z, &tRay, cb, result, input, res, correct);
+                               // printf("cell - [0]: %d, [1]: %d, [2]: %d\n", cell[0], cell[1], cell[2]);
+                               bresenham_linie_3D(smd, cell[0], cell[1], cell[2], x, y, z, &tRay, big);
 
-                               // convention -> from a RGBA float array, use G value for tRay
-// #pragma omp critical
-                               result[index] = tRay;                   
+                               if(!big)
+                                       smoke_set_tray(smd, index, tRay);
+                               else
+                                       smoke_set_bigtray(smd, index, tRay);
                        }
 }