Fluidsim - Restoring simulation speed control (ZanQdo request)
authorJoshua Leung <aligorith@gmail.com>
Sun, 22 Jan 2012 03:42:49 +0000 (03:42 +0000)
committerJoshua Leung <aligorith@gmail.com>
Sun, 22 Jan 2012 03:42:49 +0000 (03:42 +0000)
This commit restores support for freezing or speeding up physics sims. Animate
the "Speed" parameter under Domain->Time, which controls a multiplier factor for
the rate at which the sim proceeds (i.e. the old "Fac-Tim" setting).

Notes:
* Subversion bumped to 4 to patch up defaults for new value so that old sim
files will still run correctly
* Names/descriptions could do with some tweaking
* Porting this across was not that obvious since quite a bit of stuff had
changed (as in, been cleaned up). However, from tests so far, it seems to work
well.

release/scripts/startup/bl_ui/properties_physics_fluid.py
source/blender/blenkernel/BKE_blender.h
source/blender/blenloader/intern/readfile.c
source/blender/editors/physics/physics_fluid.c
source/blender/makesdna/DNA_object_fluidsim.h
source/blender/makesrna/intern/rna_fluidsim.c
source/blender/modifiers/intern/MOD_fluidsim_util.c

index 8717a9b91140d591d5d3a4f757e9e8502af3b078..114d74f1060d5b7ef95a47d15fc043ab1d6bba1e 100644 (file)
@@ -79,6 +79,7 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel, Panel):
             sub = col.column(align=True)
             sub.prop(fluid, "start_time", text="Start")
             sub.prop(fluid, "end_time", text="End")
+            col.prop(fluid, "simulation_rate", text="Speed")
 
             col = split.column()
             col.label()
@@ -230,6 +231,10 @@ class PHYSICS_PT_domain_gravity(PhysicButtonsPanel, Panel):
         if fluid.viscosity_preset == 'MANUAL':
             sub.prop(fluid, "viscosity_base", text="Base")
             sub.prop(fluid, "viscosity_exponent", text="Exponent", slider=True)
+        else:
+            # just for padding to prevent jumping around
+            sub.separator()
+            sub.separator()
 
         col.label(text="Optimization:")
         col.prop(fluid, "grid_levels", slider=True)
index f24687e0fc9bf0ce9a535fba4c59daf5d4ce5830..42d9ae73b9a61d44fd762bd81ca6c772249388a4 100644 (file)
@@ -42,7 +42,7 @@ extern "C" {
  * and keep comment above the defines.
  * Use STRINGIFY() rather than defining with quotes */
 #define BLENDER_VERSION                        261
-#define BLENDER_SUBVERSION             3
+#define BLENDER_SUBVERSION             4
 
 #define BLENDER_MINVERSION             250
 #define BLENDER_MINSUBVERSION  0
index fb49f3974b42b21105838959ceb2c8a5e4dd0695..28f00f355de6258491e18f2a9577ccd5c8113908 100644 (file)
@@ -13019,6 +13019,23 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                }
        }
        
+       if (main->versionfile < 261 || (main->versionfile == 261 && main->subversionfile < 4))
+       {
+               {
+                       /* set fluidsim rate */
+                       Object *ob;
+                       for (ob = main->object.first; ob; ob = ob->id.next) {
+                               ModifierData *md;
+                               for (md = ob->modifiers.first; md; md = md->next) {
+                                       if (md->type == eModifierType_Fluidsim) {
+                                               FluidsimSettings *fss = (FluidsimSettings *)md;
+                                               fss->animRate = 1.0f;
+                                       }
+                               }
+                       }
+               }
+       }
+       
        /* put compatibility code here until next subversion bump */
        {
        }
index d652d2c0e5cc18bfd7ee27135083ecf122a06739..dbc153de108ae55e8fa43673ebc4e45e1cfca85a 100644 (file)
@@ -113,6 +113,18 @@ static float get_fluid_viscosity(FluidsimSettings *settings)
        }
 }
 
+static float get_fluid_rate(FluidsimSettings *settings)
+{
+       float rate = 1.0f; /* default rate if not animated... */
+       
+       rate = settings->animRate;
+       
+       if (rate < 0.0f)
+               rate = 0.0f;
+       
+       return rate;
+}
+
 static void get_fluid_gravity(float *gravity, Scene *scene, FluidsimSettings *fss)
 {
        if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
@@ -243,7 +255,7 @@ static void init_time(FluidsimSettings *domainSettings, FluidAnimChannels *chann
        
        channels->timeAtFrame[0] = channels->timeAtFrame[1] = domainSettings->animStart; // start at index 1
        
-       for(i=2; i<=channels->length; i++) {
+       for (i=2; i <= channels->length; i++) {
                channels->timeAtFrame[i] = channels->timeAtFrame[i-1] + channels->aniFrameTime;
        }
 }
@@ -305,6 +317,8 @@ static void free_domain_channels(FluidAnimChannels *channels)
        channels->DomainGravity = NULL;
        MEM_freeN(channels->DomainViscosity);
        channels->DomainViscosity = NULL;
+       MEM_freeN(channels->DomainTime);
+       channels->DomainTime = NULL;
 }
 
 static void free_all_fluidobject_channels(ListBase *fobjects)
@@ -351,14 +365,13 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid
        int length = channels->length;
        float eval_time;
        
-       /* XXX: first init time channel - temporary for now */
-       /* init time values (should be done after evaluating animated time curve) */
+       /* init time values (assuming that time moves at a constant speed; may be overridden later) */
        init_time(domainSettings, channels);
        
        /* allocate domain animation channels */
        channels->DomainGravity = MEM_callocN( length * (CHANNEL_VEC+1) * sizeof(float), "channel DomainGravity");
        channels->DomainViscosity = MEM_callocN( length * (CHANNEL_FLOAT+1) * sizeof(float), "channel DomainViscosity");
-       //channels->DomainTime = MEM_callocN( length * (CHANNEL_FLOAT+1) * sizeof(float), "channel DomainTime");
+       channels->DomainTime = MEM_callocN( length * (CHANNEL_FLOAT+1) * sizeof(float), "channel DomainTime");
        
        /* allocate fluid objects */
        for (base=scene->base.first; base; base= base->next) {
@@ -406,10 +419,9 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid
        for (i=0; i<channels->length; i++) {
                FluidObject *fobj;
                float viscosity, gravity[3];
-               float timeAtFrame;
+               float timeAtFrame, time;
                
                eval_time = domainSettings->bakeStart + i;
-               timeAtFrame = channels->timeAtFrame[i+1];
                
                /* XXX: This can't be used due to an anim sys optimisation that ignores recalc object animation,
                 * leaving it for the depgraph (this ignores object animation such as modifier properties though... :/ )
@@ -425,12 +437,24 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid
                
                /* now scene data should be current according to animation system, so we fill the channels */
                
-               /* Domain properties - gravity/viscosity/time */
+               /* Domain time */
+               // TODO: have option for not running sim, time mangling, in which case second case comes in handy
+               if (channels->DomainTime) {
+                       time = get_fluid_rate(domainSettings) * channels->aniFrameTime;
+                       timeAtFrame = channels->timeAtFrame[i] + time;
+                       
+                       channels->timeAtFrame[i+1] = timeAtFrame;
+                       set_channel(channels->DomainTime, i, &time, i, CHANNEL_FLOAT);
+               }
+               else {
+                       timeAtFrame = channels->timeAtFrame[i+1];
+               }
+               
+               /* Domain properties - gravity/viscosity */
                get_fluid_gravity(gravity, scene, domainSettings);
                set_channel(channels->DomainGravity, timeAtFrame, gravity, i, CHANNEL_VEC);
                viscosity = get_fluid_viscosity(domainSettings);
                set_channel(channels->DomainViscosity, timeAtFrame, &viscosity, i, CHANNEL_FLOAT);
-               // XXX : set_channel(channels->DomainTime, timeAtFrame, &time, i, CHANNEL_VEC);
                
                /* object movement */
                for (fobj=fobjects->first; fobj; fobj=fobj->next) {
@@ -957,38 +981,6 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor
        /* reset to original current frame */
        scene->r.cfra = origFrame;
        ED_update_for_newframe(CTX_data_main(C), scene, CTX_wm_screen(C), 1);
-       
-       
-       /* ---- XXX: No Time animation curve for now, leaving this code here for reference 
-        
-       { int timeIcu[1] = { FLUIDSIM_TIME };
-               float timeDef[1] = { 1. };
-
-               // time channel is a bit special, init by hand...
-               timeAtIndex = MEM_callocN( (allchannelSize+1)*1*sizeof(float), "fluidsiminit_timeatindex");
-               for(i=0; i<=scene->r.efra; i++) {
-                       timeAtIndex[i] = (float)(i-startFrame);
-               }
-               fluidsimInitChannel(scene, &channelDomainTime, allchannelSize, timeAtIndex, timeIcu,timeDef, domainSettings->ipo, CHANNEL_FLOAT ); // NDEB
-               // time channel is a multiplicator for 
-               if(channelDomainTime) {
-                       for(i=0; i<allchannelSize; i++) { 
-                               channelDomainTime[i*2+0] = aniFrameTime * channelDomainTime[i*2+0]; 
-                               if(channelDomainTime[i*2+0]<0.) channelDomainTime[i*2+0] = 0.;
-                       }
-               }
-               timeAtFrame = MEM_callocN( (allchannelSize+1)*1*sizeof(float), "fluidsiminit_timeatframe");
-               timeAtFrame[0] = timeAtFrame[1] = domainSettings->animStart; // start at index 1
-               if(channelDomainTime) {
-                       for(i=2; i<=allchannelSize; i++) {
-                               timeAtFrame[i] = timeAtFrame[i-1]+channelDomainTime[(i-1)*2+0];
-                       }
-               fsset->} else {
-                       for(i=2; i<=allchannelSize; i++) { timeAtFrame[i] = timeAtFrame[i-1]+aniFrameTime; }
-               }
-
-       } // domain channel init
-       */
                
        /* ******** init domain object's matrix ******** */
        copy_m4_m4(domainMat, fsDomain->obmat);
index 3f87f8a3e9ca72798dc92c2922baf69020c42c6f..90e6e97bc159ff88ec37fc2740229595582a3cb6 100644 (file)
@@ -140,8 +140,8 @@ typedef struct FluidsimSettings {
 
        int lastgoodframe;
        
-       int pad;
-
+       /* Simulation/flow rate control (i.e. old "Fac-Time") */
+       float animRate;
 } FluidsimSettings;
 
 /* ob->fluidsimSettings defines */
index f853e7b8dd98619e67b231e53e933c8a04b04e78..99a84fc8b39ac80b547b0765516c7ab29da3fd70 100644 (file)
@@ -340,6 +340,11 @@ static void rna_def_fluidsim_domain(BlenderRNA *brna)
        RNA_def_property_range(prop, 0.001, 10);
        RNA_def_property_ui_text(prop, "Real World Size", "Size of the simulation domain in metres");
        
+       prop= RNA_def_property(srna, "simulation_rate", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "animRate");
+       RNA_def_property_range(prop, 0.0, 100.0);
+       RNA_def_property_ui_text(prop, "Simulation Speed", "Fluid motion rate (0 = stationary, 1 = normal speed)");
+       
        prop= RNA_def_property(srna, "viscosity_preset", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "viscosityMode");
        RNA_def_property_enum_items(prop, viscosity_items);
index 0452c6a4e7360ecf5096d33b14ab4bfd4856c5bb..b62a497a10c1b43c7bb179f8382499f996d76339 100644 (file)
@@ -95,6 +95,7 @@ void fluidsim_init(FluidsimModifierData *fluidmd)
 
                fss->animStart = 0.0; 
                fss->animEnd = 4.0;
+               fss->animRate = 1.0;
                fss->gstar = 0.005; // used as normgstar
                fss->maxRefine = -1;
                // maxRefine is set according to resolutionxyz during bake