Bugfix for [#17879] Speed vectors/velocity data not working on ALL fluids.
authorDaniel Genrich <daniel.genrich@gmx.net>
Thu, 30 Oct 2008 11:51:15 +0000 (11:51 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Thu, 30 Oct 2008 11:51:15 +0000 (11:51 +0000)
source/blender/blenkernel/BKE_fluidsim.h
source/blender/blenkernel/intern/fluidsim.c
source/blender/render/intern/source/convertblender.c

index 33c706da82b6120593247d95ed60960c91ca5c73..4aac5eafa0036f16268e5258f457ff4e7c84de0d 100644 (file)
@@ -45,6 +45,7 @@ void fluidsim_init(FluidsimModifierData *fluidmd);
 void fluidsim_free(FluidsimModifierData *fluidmd);
 
 DerivedMesh *fluidsim_read_cache(Object *ob, DerivedMesh *orgdm, FluidsimModifierData *fluidmd, int framenr, int useRenderParams);
+void fluidsim_read_vel_cache(FluidsimModifierData *fluidmd, DerivedMesh *dm, char *filename);
 DerivedMesh *fluidsimModifier_do(FluidsimModifierData *fluidmd, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc);
 
 // get bounding box of mesh
index 4580c6cbf8ba649ad9b32a553836022cc9cfb610..29c4e0f2fb543470cc2e9ab6d14b72edf532c8da 100644 (file)
@@ -139,6 +139,9 @@ void fluidsim_init(FluidsimModifierData *fluidmd)
                fluid_get_bb(mesh->mvert, mesh->totvert, ob->obmat, fss->bbStart, fss->bbSize); 
                */
                
+               // (ab)used to store velocities
+               fss->meshSurfNormals = NULL;
+               
                fss->lastgoodframe = -1;
                
                fss->flag = 0;
@@ -153,6 +156,11 @@ void fluidsim_free(FluidsimModifierData *fluidmd)
 #ifndef DISABLE_ELBEEM
        if(fluidmd)
        {
+               if(fluidmd->fss->meshSurfNormals)
+               {
+                       MEM_freeN(fluidmd->fss->meshSurfNormals);
+                       fluidmd->fss->meshSurfNormals = NULL;
+               }
                MEM_freeN(fluidmd->fss);
        }
 #endif
@@ -462,21 +470,86 @@ DerivedMesh *fluidsim_read_cache(Object *ob, DerivedMesh *orgdm, FluidsimModifie
        // load vertex velocities, if they exist...
        // TODO? use generate flag as loading flag as well?
        // warning, needs original .bobj.gz mesh loading filename
-       /*
        if(displaymode==3) 
        {
-               readVelgz(targetFile, srcob);
+               fluidsim_read_vel_cache(fluidmd, dm, targetFile);
        } 
        else 
        {
-               // no data for preview, only clear...
-               int i,j;
-               for(i=0; i<mesh->totvert;i++) { for(j=0; j<3; j++) { srcob->fluidsimSettings->meshSurfNormals[i].co[j] = 0.; }} 
-       }*/
+               if(fss->meshSurfNormals)
+                       MEM_freeN(fss->meshSurfNormals); 
+                       
+               fss->meshSurfNormals = NULL;
+       }
        
        return dm;
 }
 
+
+/* read zipped fluidsim velocities into the co's of the fluidsimsettings normals struct */
+void fluidsim_read_vel_cache(FluidsimModifierData *fluidmd, DerivedMesh *dm, char *filename)
+{
+       int wri, i, j;
+       float wrf;
+       gzFile gzf;
+       FluidsimSettings *fss = fluidmd->fss;
+       int len = strlen(filename);
+       int totvert = dm->getNumVerts(dm);
+       float *velarray = NULL;
+       
+       // mesh and vverts have to be valid from loading...
+       
+       if(fss->meshSurfNormals)
+               MEM_freeN(fss->meshSurfNormals);
+               
+       if(len<7) 
+       { 
+               return; 
+       }
+       
+       if(fss->domainNovecgen>0) return;
+       
+       // abusing pointer to hold an array of 3d-velocities
+       fss->meshSurfNormals = MEM_callocN(sizeof(float)*3*dm->getNumVerts(dm), "Fluidsim_velocities");
+       // abusing pointer to hold an INT
+       fss->meshSurface = SET_INT_IN_POINTER(totvert);
+       
+       velarray = (float *)fss->meshSurfNormals;
+       
+       // .bobj.gz , correct filename
+       // 87654321
+       filename[len-6] = 'v';
+       filename[len-5] = 'e';
+       filename[len-4] = 'l';
+
+       gzf = gzopen(filename, "rb");
+       if (!gzf)
+       {
+               MEM_freeN(fss->meshSurfNormals);
+               fss->meshSurfNormals = NULL;    
+               return;
+       }
+
+       gzread(gzf, &wri, sizeof( wri ));
+       if(wri != totvert) 
+       {
+               MEM_freeN(fss->meshSurfNormals);
+               fss->meshSurfNormals = NULL;
+               return; 
+       }
+
+       for(i=0; i<totvert;i++) 
+       {
+               for(j=0; j<3; j++) 
+               {
+                       gzread(gzf, &wrf, sizeof( wrf )); 
+                       velarray[3*i + j] = wrf;
+               }
+       }
+
+       gzclose(gzf);
+}
+
 void fluid_get_bb(MVert *mvert, int totvert, float obmat[][4],
                 /*RET*/ float start[3], /*RET*/ float size[3] )
 {
@@ -583,60 +656,5 @@ void initElbeemMesh(struct Object *ob,
        dm->release(dm);
 }
 
-/* read zipped fluidsim velocities into the co's of the fluidsimsettings normals struct */
-void readVelgz(char *filename, Object *srcob)
-{
-       int wri, i, j;
-       float wrf;
-       gzFile gzf;
-       MVert *vverts = srcob->fluidsimSettings->meshSurfNormals;
-       int len = strlen(filename);
-       Mesh *mesh = srcob->data;
-       // mesh and vverts have to be valid from loading...
-
-       // clean up in any case
-       for(i=0; i<mesh->totvert;i++) 
-       { 
-               for(j=0; j<3; j++) 
-               {
-                       vverts[i].co[j] = 0.; 
-               } 
-       } 
-       if(srcob->fluidsimSettings->domainNovecgen>0) return;
-
-       if(len<7) 
-       { 
-               return; 
-       }
-
-       // .bobj.gz , correct filename
-       // 87654321
-       filename[len-6] = 'v';
-       filename[len-5] = 'e';
-       filename[len-4] = 'l';
-
-       gzf = gzopen(filename, "rb");
-       if (!gzf)
-               return;
-
-       gzread(gzf, &wri, sizeof( wri ));
-       if(wri != mesh->totvert) 
-       {
-               return; 
-       }
-
-       for(i=0; i<mesh->totvert;i++) 
-       {
-               for(j=0; j<3; j++) 
-               {
-                       gzread(gzf, &wrf, sizeof( wrf )); 
-                       vverts[i].co[j] = wrf;
-               }
-       }
-
-       gzclose(gzf);
-}
-
-
 #endif // DISABLE_ELBEEM
 
index ae955a63f98443463b58d321e9053bbfdbd1bfe4..1a387ad74667bde1e8f9096fb6b5a854ac0c868c 100644 (file)
@@ -5141,23 +5141,30 @@ static int load_fluidsimspeedvectors(Render *re, ObjectInstanceRen *obi, float *
        float hoco[4], ho[4], fsvec[4], camco[4];
        float mat[4][4], winmat[4][4];
        float imat[4][4];
-       MVert *vverts;
-
+       FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(fsob, eModifierType_Fluidsim);
+       FluidsimSettings *fss = fluidmd->fss;
+       float *velarray = NULL;
+       
        /* only one step needed */
        if(step) return 1;
        
+       if(fluidmd)
+               fss = fluidmd->fss;
+       else
+               return 0;
+       
        Mat4CpyMat4(mat, re->viewmat);
        MTC_Mat4Invert(imat, mat);
 
        /* set first vertex OK */
-       if( (!fsob->fluidsimSettings) || (!fsob->fluidsimSettings->meshSurfNormals) ) return 0;
-       vverts = fsob->fluidsimSettings->meshSurfNormals;
-       //fprintf(stderr, "GZ_VEL obj '%s', calc load_fluidsimspeedvectors\n",fsob->id.name); // NT DEBUG
-
-       if( obr->totvert != fsob->fluidsimSettings->meshSurface->totvert ) {
+       if(!fss->meshSurfNormals) return 0;
+       
+       if( obr->totvert != GET_INT_FROM_POINTER(fss->meshSurface) ) {
                //fprintf(stderr, "load_fluidsimspeedvectors - modified fluidsim mesh, not using speed vectors (%d,%d)...\n", obr->totvert, fsob->fluidsimSettings->meshSurface->totvert); // DEBUG
                return 0;
        }
+       
+       velarray = (float *)fss->meshSurfNormals;
 
        if(obi->flag & R_TRANSFORMED)
                Mat4MulMat4(winmat, obi->mat, re->winmat);
@@ -5169,7 +5176,8 @@ static int load_fluidsimspeedvectors(Render *re, ObjectInstanceRen *obi, float *
        so that also small drops/little water volumes return a velocity != 0. 
        But I had no luck in fixing that function - DG */
        for(a=0; a<obr->totvert; a++) {
-               for(j=0;j<3;j++) avgvel[j] += vverts[a].co[j];
+               for(j=0;j<3;j++) avgvel[j] += velarray[3*a + j];
+               
        }
        for(j=0;j<3;j++) avgvel[j] /= (float)(obr->totvert);
        
@@ -5183,7 +5191,7 @@ static int load_fluidsimspeedvectors(Render *re, ObjectInstanceRen *obi, float *
                // get fluid velocity
                fsvec[3] = 0.; 
                //fsvec[0] = fsvec[1] = fsvec[2] = fsvec[3] = 0.; fsvec[2] = 2.; // NT fixed test
-               for(j=0;j<3;j++) fsvec[j] = vverts[a].co[j];
+               for(j=0;j<3;j++) fsvec[j] = velarray[3*a + j];
                
                /* (bad) HACK insert average velocity if none is there (see previous comment) */
                if((fsvec[0] == 0.0) && (fsvec[1] == 0.0) && (fsvec[2] == 0.0))