forked from bartvdbraak/blender
Smoke:
* Totally new try to get cache running * Didn't try "bake" and such things yet Hint * Very verbose yet * Please do only test new blend files, not old ones! Please give me feedback on my blog about the old crashers.
This commit is contained in:
parent
cf20399993
commit
9f5e42ff76
@ -182,6 +182,9 @@ void FLUID_3D::initBlenderRNA(float *alpha, float *beta)
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void FLUID_3D::step()
|
void FLUID_3D::step()
|
||||||
{
|
{
|
||||||
|
// addSmokeTestCase(_density, _res);
|
||||||
|
// addSmokeTestCase(_heat, _res);
|
||||||
|
|
||||||
// wipe forces
|
// wipe forces
|
||||||
for (int i = 0; i < _totalCells; i++)
|
for (int i = 0; i < _totalCells; i++)
|
||||||
{
|
{
|
||||||
|
@ -47,7 +47,7 @@ class FLUID_3D
|
|||||||
void initVectorNoise(int amplify);
|
void initVectorNoise(int amplify);
|
||||||
|
|
||||||
void addSmokeColumn();
|
void addSmokeColumn();
|
||||||
static void addSmokeTestCase(float* field, Vec3Int res, float value);
|
static void addSmokeTestCase(float* field, Vec3Int res);
|
||||||
|
|
||||||
void step();
|
void step();
|
||||||
void addObstacle(OBSTACLE* obstacle);
|
void addObstacle(OBSTACLE* obstacle);
|
||||||
|
@ -44,8 +44,8 @@ void FLUID_3D::addSmokeColumn() {
|
|||||||
// generic static version, so that it can be applied to the
|
// generic static version, so that it can be applied to the
|
||||||
// WTURBULENCE grid as well
|
// WTURBULENCE grid as well
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
/*
|
|
||||||
void FLUID_3D::addSmokeTestCase(float* field, Vec3Int res, float value)
|
void FLUID_3D::addSmokeTestCase(float* field, Vec3Int res)
|
||||||
{
|
{
|
||||||
const int slabSize = res[0]*res[1]; int maxRes = (int)MAX3V(res);
|
const int slabSize = res[0]*res[1]; int maxRes = (int)MAX3V(res);
|
||||||
float dx = 1.0f / (float)maxRes;
|
float dx = 1.0f / (float)maxRes;
|
||||||
@ -57,22 +57,22 @@ void FLUID_3D::addSmokeTestCase(float* field, Vec3Int res, float value)
|
|||||||
float heighMin = 0.05;
|
float heighMin = 0.05;
|
||||||
float heighMax = 0.10;
|
float heighMax = 0.10;
|
||||||
|
|
||||||
for (int y = 0; y < res[1]; y++)
|
for (int y = 0; y < res[2]; y++)
|
||||||
for (int z = (int)(heighMin*res[2]); z <= (int)(heighMax * res[1]); z++)
|
for (int z = (int)(heighMin*res[2]); z <= (int)(heighMax * res[2]); z++)
|
||||||
for (int x = 0; x < res[0]; x++)
|
for (int x = 0; x < res[0]; x++)
|
||||||
{
|
{
|
||||||
float xLength = x * dx - xTotal * 0.4f;
|
float xLength = x * dx - xTotal * 0.4f;
|
||||||
float yLength = y * dx - zTotal * 0.5f;
|
float yLength = y * dx - yTotal * 0.5f;
|
||||||
float radius = sqrtf(xLength * xLength + yLength * yLength);
|
float radius = sqrtf(xLength * xLength + yLength * yLength);
|
||||||
|
|
||||||
if (radius < 0.075f * xTotal)
|
if (radius < 0.075f * xTotal)
|
||||||
{
|
{
|
||||||
int index = x + y * res[0] + z * slabSize;
|
int index = x + y * res[0] + z * slabSize;
|
||||||
field[index] = value;
|
field[index] = 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// set x direction to Neumann boundary conditions
|
// set x direction to Neumann boundary conditions
|
||||||
@ -295,12 +295,10 @@ void FLUID_3D::advectFieldSemiLagrange(const float dt, const float* velx, const
|
|||||||
const int xres = res[0];
|
const int xres = res[0];
|
||||||
const int yres = res[1];
|
const int yres = res[1];
|
||||||
const int zres = res[2];
|
const int zres = res[2];
|
||||||
static int hits = 0;
|
|
||||||
static int total = 0;
|
|
||||||
const int slabSize = res[0] * res[1];
|
const int slabSize = res[0] * res[1];
|
||||||
|
|
||||||
// scale dt up to grid resolution
|
// scale dt up to grid resolution
|
||||||
#if PARALLEL==1 && !_WIN32
|
#if PARALLEL==1
|
||||||
#pragma omp parallel
|
#pragma omp parallel
|
||||||
#pragma omp for schedule(static)
|
#pragma omp for schedule(static)
|
||||||
#endif
|
#endif
|
||||||
|
@ -81,7 +81,6 @@ extern "C" void smoke_step(FLUID_3D *fluid, size_t framenr)
|
|||||||
|
|
||||||
extern "C" void smoke_turbulence_step(WTURBULENCE *wt, FLUID_3D *fluid)
|
extern "C" void smoke_turbulence_step(WTURBULENCE *wt, FLUID_3D *fluid)
|
||||||
{
|
{
|
||||||
if(wt)
|
|
||||||
wt->stepTurbulenceFull(fluid->_dt/fluid->_dx, fluid->_xVelocity, fluid->_yVelocity, fluid->_zVelocity, fluid->_obstacles);
|
wt->stepTurbulenceFull(fluid->_dt/fluid->_dx, fluid->_xVelocity, fluid->_yVelocity, fluid->_zVelocity, fluid->_obstacles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,6 +167,8 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
|
|||||||
// calc other res with max_res provided
|
// calc other res with max_res provided
|
||||||
VECSUB(size, max, min);
|
VECSUB(size, max, min);
|
||||||
|
|
||||||
|
printf("size: %f, %f, %f\n", size[0], size[1], size[2]);
|
||||||
|
|
||||||
// prevent crash when initializing a plane as domain
|
// prevent crash when initializing a plane as domain
|
||||||
if((size[0] < FLT_EPSILON) || (size[1] < FLT_EPSILON) || (size[2] < FLT_EPSILON))
|
if((size[0] < FLT_EPSILON) || (size[1] < FLT_EPSILON) || (size[2] < FLT_EPSILON))
|
||||||
return 0;
|
return 0;
|
||||||
@ -210,6 +212,8 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("smd->domain->dx: %f\n", smd->domain->dx);
|
||||||
|
|
||||||
// TODO: put in failsafe if res<=0 - dg
|
// 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]);
|
// printf("res[0]: %d, res[1]: %d, res[2]: %d\n", smd->domain->res[0], smd->domain->res[1], smd->domain->res[2]);
|
||||||
@ -595,11 +599,6 @@ void smokeModifier_reset_turbulence(struct SmokeModifierData *smd)
|
|||||||
smoke_turbulence_free(smd->domain->wt);
|
smoke_turbulence_free(smd->domain->wt);
|
||||||
smd->domain->wt = NULL;
|
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)
|
void smokeModifier_reset(struct SmokeModifierData *smd)
|
||||||
@ -618,16 +617,14 @@ void smokeModifier_reset(struct SmokeModifierData *smd)
|
|||||||
smd->domain->fluid = NULL;
|
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]->flag |= PTCACHE_OUTDATED;
|
||||||
smd->domain->point_cache[0]->simframe= 0;
|
smd->domain->point_cache[1]->flag |= PTCACHE_OUTDATED;
|
||||||
smd->domain->point_cache[0]->last_exact= 0;
|
|
||||||
|
|
||||||
smokeModifier_reset_turbulence(smd);
|
smokeModifier_reset_turbulence(smd);
|
||||||
|
|
||||||
smd->time = -1;
|
smd->time = -1;
|
||||||
|
|
||||||
// printf("reset domain end\n");
|
printf("reset domain end\n");
|
||||||
}
|
}
|
||||||
else if(smd->flow)
|
else if(smd->flow)
|
||||||
{
|
{
|
||||||
@ -1102,153 +1099,76 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
|
|||||||
}
|
}
|
||||||
else if(smd->type & MOD_SMOKE_TYPE_DOMAIN)
|
else if(smd->type & MOD_SMOKE_TYPE_DOMAIN)
|
||||||
{
|
{
|
||||||
|
SmokeDomainSettings *sds = smd->domain;
|
||||||
|
float light[3];
|
||||||
PointCache *cache = NULL;
|
PointCache *cache = NULL;
|
||||||
PTCacheID pid;
|
PTCacheID pid;
|
||||||
PointCache *cache_wt = NULL;
|
PointCache *cache_wt = NULL;
|
||||||
PTCacheID pid_wt;
|
PTCacheID pid_wt;
|
||||||
|
int startframe, endframe, framenr;
|
||||||
float timescale;
|
float timescale;
|
||||||
int cache_result = 0, cache_result_wt = 0;
|
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;
|
framenr = scene->r.cfra;
|
||||||
|
|
||||||
cache = sds->point_cache[0];
|
printf("time: %d\n", scene->r.cfra);
|
||||||
|
|
||||||
|
if(framenr == smd->time)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cache = sds->point_cache[0];
|
||||||
BKE_ptcache_id_from_smoke(&pid, ob, smd);
|
BKE_ptcache_id_from_smoke(&pid, ob, smd);
|
||||||
BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, ×cale);
|
BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, ×cale);
|
||||||
|
|
||||||
cache_wt = sds->point_cache[1];
|
cache_wt = sds->point_cache[1];
|
||||||
BKE_ptcache_id_from_smoke_turbulence(&pid_wt, ob, smd);
|
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(framenr < startframe)
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
// we got back in time, reset smoke in this case (TODO: use cache later)
|
|
||||||
// smd->time = scene->r.cfra;
|
|
||||||
// smokeModifier_reset(smd);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if(framenr > endframe)
|
|
||||||
{
|
|
||||||
framenr = endframe;
|
|
||||||
|
|
||||||
// we load last valid frame here
|
|
||||||
// and don't update the smd->time variable later
|
|
||||||
badloading = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(smd->time == -1 && framenr!= startframe)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!smokeModifier_init(smd, ob, scene, dm))
|
if(framenr > endframe)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!smd->domain->fluid)
|
if(!smd->domain->fluid)
|
||||||
|
{
|
||||||
|
BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
|
||||||
|
BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_OUTDATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!smokeModifier_init(smd, ob, scene, dm))
|
||||||
|
{
|
||||||
|
printf("bad smokeModifier_init\n");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* try to read from cache */
|
/* try to read from cache */
|
||||||
cache_result = BKE_ptcache_read_cache(&pid, (float)framenr, scene->r.frs_sec);
|
cache_result = BKE_ptcache_read_cache(&pid, (float)framenr, scene->r.frs_sec);
|
||||||
// printf("cache_result: %d\n", cache_result);
|
printf("cache_result: %d\n", cache_result);
|
||||||
|
|
||||||
if(cache_result == PTCACHE_READ_EXACT)
|
if(cache_result == PTCACHE_READ_EXACT)
|
||||||
{
|
{
|
||||||
SmokeDomainSettings *sds = smd->domain;
|
|
||||||
|
|
||||||
cache->flag |= PTCACHE_SIMULATION_VALID;
|
cache->flag |= PTCACHE_SIMULATION_VALID;
|
||||||
cache->simframe= framenr;
|
cache->simframe= framenr;
|
||||||
sds->v3dnum = framenr;
|
|
||||||
|
|
||||||
if(!badloading)
|
|
||||||
smd->time = scene->r.cfra;
|
|
||||||
|
|
||||||
// check for wt cache
|
|
||||||
if(sds->wt)
|
if(sds->wt)
|
||||||
{
|
{
|
||||||
cache_result_wt = BKE_ptcache_read_cache(&pid_wt, (float)framenr, scene->r.frs_sec);
|
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)
|
if(cache_result_wt == PTCACHE_READ_EXACT)
|
||||||
{
|
{
|
||||||
cache_wt->flag |= PTCACHE_SIMULATION_VALID;
|
cache_wt->flag |= PTCACHE_SIMULATION_VALID;
|
||||||
cache_wt->simframe= framenr;
|
cache_wt->simframe= framenr;
|
||||||
}
|
}
|
||||||
else if(cache_result_wt==PTCACHE_READ_OLD)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// printf("PTCACHE_READ_EXACT\n");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if(cache_result==PTCACHE_READ_OLD)
|
|
||||||
{
|
|
||||||
BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_FREE);
|
|
||||||
cache->flag |= PTCACHE_SIMULATION_VALID;
|
|
||||||
|
|
||||||
BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_FREE);
|
tstart();
|
||||||
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;
|
smoke_calc_domain(scene, ob, smd);
|
||||||
cache_wt->simframe= 0;
|
|
||||||
cache_wt->last_exact= 0;
|
|
||||||
|
|
||||||
// printf("PTCACHE_BAKED\n");
|
// set new time
|
||||||
return;
|
smd->time = scene->r.cfra;
|
||||||
}
|
|
||||||
/*
|
|
||||||
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;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// printf("framenr: %d, time: %f\n", framenr, smd->time);
|
|
||||||
|
|
||||||
/* do simulation */
|
/* do simulation */
|
||||||
|
|
||||||
@ -1256,52 +1176,18 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
|
|||||||
cache->flag |= PTCACHE_SIMULATION_VALID;
|
cache->flag |= PTCACHE_SIMULATION_VALID;
|
||||||
cache->simframe= framenr;
|
cache->simframe= framenr;
|
||||||
|
|
||||||
if(sds->wt)
|
|
||||||
{
|
|
||||||
cache_wt->flag |= PTCACHE_SIMULATION_VALID;
|
|
||||||
cache_wt->simframe= framenr;
|
|
||||||
}
|
|
||||||
|
|
||||||
tstart();
|
|
||||||
|
|
||||||
if(sds->flags & MOD_SMOKE_DISSOLVE)
|
|
||||||
{
|
|
||||||
smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
|
|
||||||
}
|
|
||||||
|
|
||||||
smoke_calc_domain(scene, ob, smd);
|
|
||||||
|
|
||||||
// set new time
|
|
||||||
smd->time = scene->r.cfra;
|
|
||||||
|
|
||||||
// frame 1 is start, don't simulate anything
|
|
||||||
if(smd->time == 1)
|
|
||||||
{
|
|
||||||
// set new time
|
|
||||||
smd->time = scene->r.cfra;
|
|
||||||
|
|
||||||
BKE_ptcache_write_cache(&pid, framenr);
|
|
||||||
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);
|
|
||||||
|
|
||||||
// printf("smd->time: %f\n", smd->time);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// simulate the actual smoke (c++ code in intern/smoke)
|
// simulate the actual smoke (c++ code in intern/smoke)
|
||||||
|
if(framenr!=startframe)
|
||||||
smoke_step(sds->fluid, smd->time);
|
smoke_step(sds->fluid, smd->time);
|
||||||
BKE_ptcache_write_cache(&pid, framenr);
|
BKE_ptcache_write_cache(&pid, framenr);
|
||||||
|
|
||||||
if(sds->wt)
|
if(sds->wt)
|
||||||
{
|
{
|
||||||
|
if(framenr!=startframe)
|
||||||
if(sds->flags & MOD_SMOKE_DISSOLVE)
|
|
||||||
smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
|
|
||||||
|
|
||||||
smoke_turbulence_step(sds->wt, sds->fluid);
|
smoke_turbulence_step(sds->wt, sds->fluid);
|
||||||
|
|
||||||
|
cache_wt->flag |= PTCACHE_SIMULATION_VALID;
|
||||||
|
cache_wt->simframe= framenr;
|
||||||
BKE_ptcache_write_cache(&pid_wt, framenr);
|
BKE_ptcache_write_cache(&pid_wt, framenr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1309,7 +1195,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
|
|||||||
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_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);
|
||||||
|
|
||||||
tend();
|
tend();
|
||||||
// printf ( "Frame: %d, Time: %f\n", (int)smd->time, ( float ) tval() );
|
printf ( "Frame: %d, Time: %f\n", (int)smd->time, ( float ) tval() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user