forked from bartvdbraak/blender
Fluidsim - Restoring simulation speed control (ZanQdo request)
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.
This commit is contained in:
parent
b1667911ef
commit
cfab40b652
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
{
|
||||
}
|
||||
|
@ -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) {
|
||||
@ -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) {
|
||||
@ -958,38 +982,6 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor
|
||||
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);
|
||||
if(!invert_m4_m4(invDomMat, domainMat)) {
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user