diff options
author | Miika Hamalainen <blender@miikah.org> | 2012-08-10 20:44:39 +0400 |
---|---|---|
committer | Miika Hamalainen <blender@miikah.org> | 2012-08-10 20:44:39 +0400 |
commit | d9a60226b67de2fdf17b20b65cd619613a0a3607 (patch) | |
tree | c51e2eceea5597c6baca112584336764a3e7daf6 /intern | |
parent | 35de87d10be269a76c1bfce2e685bc43544a6a04 (diff) |
* Some improvements to fire simulation code.
* It's now possible to set "flame rate" higher than 1.0. Higher rate basically means taller flame.
* More tweaking to "Quick Smoke" operator settings. Fire material is now also added by default even for smoke preset. -> You can now use quick smoke to easily setup a basic render settings that cover colored smoke and fire.
* Added settings to use a texture to define smoke flow "strength" for mesh emission. You can use automatically generated coordinates or UV layer.
* Fix: Adaptive domain bounds weren't drawn at all if smoke was uninitialized.
* Code cleanup.
Diffstat (limited to 'intern')
-rw-r--r-- | intern/smoke/extern/smoke_API.h | 6 | ||||
-rw-r--r-- | intern/smoke/intern/FLUID_3D.cpp | 51 | ||||
-rw-r--r-- | intern/smoke/intern/FLUID_3D.h | 5 | ||||
-rw-r--r-- | intern/smoke/intern/WTURBULENCE.cpp | 19 | ||||
-rw-r--r-- | intern/smoke/intern/WTURBULENCE.h | 2 | ||||
-rw-r--r-- | intern/smoke/intern/smoke_API.cpp | 22 |
6 files changed, 83 insertions, 22 deletions
diff --git a/intern/smoke/extern/smoke_API.h b/intern/smoke/extern/smoke_API.h index 6dac980a353..98c63f08fbd 100644 --- a/intern/smoke/extern/smoke_API.h +++ b/intern/smoke/extern/smoke_API.h @@ -48,6 +48,7 @@ void smoke_step(struct FLUID_3D *fluid, float gravity[3], float dtSubdiv); float *smoke_get_density(struct FLUID_3D *fluid); float *smoke_get_flame(struct FLUID_3D *fluid); float *smoke_get_fuel(struct FLUID_3D *fluid); +float *smoke_get_react(struct FLUID_3D *fluid); float *smoke_get_color_r(struct FLUID_3D *fluid); float *smoke_get_color_g(struct FLUID_3D *fluid); float *smoke_get_color_b(struct FLUID_3D *fluid); @@ -85,6 +86,7 @@ void smoke_turbulence_get_rgba(struct WTURBULENCE *wt, float *data, int sequenti void smoke_turbulence_get_rgba_from_density(struct WTURBULENCE *wt, float color[3], float *data, int sequential); float *smoke_turbulence_get_flame(struct WTURBULENCE *wt); float *smoke_turbulence_get_fuel(struct WTURBULENCE *wt); +float *smoke_turbulence_get_react(struct WTURBULENCE *wt); void smoke_turbulence_get_res(struct WTURBULENCE *wt, int *res); int smoke_turbulence_get_cells(struct WTURBULENCE *wt); void smoke_turbulence_set_noise(struct WTURBULENCE *wt, int type); @@ -92,9 +94,9 @@ void smoke_initWaveletBlenderRNA(struct WTURBULENCE *wt, float *strength); void smoke_dissolve_wavelet(struct WTURBULENCE *wt, int speed, int log); /* export */ -void smoke_export(struct FLUID_3D *fluid, float *dt, float *dx, float **dens, float **flame, float **fuel, float **heat, float **heatold, +void smoke_export(struct FLUID_3D *fluid, float *dt, float *dx, float **dens, float **react, float **flame, float **fuel, float **heat, float **heatold, float **vx, float **vy, float **vz, float **r, float **g, float **b, unsigned char **obstacles); -void smoke_turbulence_export(struct WTURBULENCE *wt, float **dens, float **flame, float **fuel, +void smoke_turbulence_export(struct WTURBULENCE *wt, float **dens, float **react, float **flame, float **fuel, float **r, float **g, float **b, float **tcu, float **tcv, float **tcw); /* flame spectrum */ diff --git a/intern/smoke/intern/FLUID_3D.cpp b/intern/smoke/intern/FLUID_3D.cpp index 3b775e84e96..b7b353352e2 100644 --- a/intern/smoke/intern/FLUID_3D.cpp +++ b/intern/smoke/intern/FLUID_3D.cpp @@ -128,6 +128,7 @@ FLUID_3D::FLUID_3D(int *res, float dx, float dtdef, int init_heat, int init_fire } // Fire simulation _flame = _fuel = _fuelTemp = _fuelOld = NULL; + _react = _reactTemp = _reactOld = NULL; if (init_fire) { initFire(); } @@ -173,6 +174,9 @@ void FLUID_3D::initFire() _fuel = new float[_totalCells]; _fuelTemp = new float[_totalCells]; _fuelOld = new float[_totalCells]; + _react = new float[_totalCells]; + _reactTemp = new float[_totalCells]; + _reactOld = new float[_totalCells]; for (int x = 0; x < _totalCells; x++) { @@ -180,6 +184,9 @@ void FLUID_3D::initFire() _fuel[x] = 0.0f; _fuelTemp[x] = 0.0f; _fuelOld[x] = 0.0f; + _react[x] = 0.0f; + _reactTemp[x] = 0.0f; + _reactOld[x] = 0.0f; } } } @@ -281,6 +288,9 @@ FLUID_3D::~FLUID_3D() if (_fuel) delete[] _fuel; if (_fuelTemp) delete[] _fuelTemp; if (_fuelOld) delete[] _fuelOld; + if (_react) delete[] _react; + if (_reactTemp) delete[] _reactTemp; + if (_reactOld) delete[] _reactOld; if (_color_r) delete[] _color_r; if (_color_rOld) delete[] _color_rOld; @@ -428,6 +438,7 @@ void FLUID_3D::step(float dt, float gravity[3]) SWAP_POINTERS(_heat, _heatOld); SWAP_POINTERS(_fuel, _fuelOld); + SWAP_POINTERS(_react, _reactOld); SWAP_POINTERS(_color_r, _color_rOld); SWAP_POINTERS(_color_g, _color_gOld); @@ -737,6 +748,7 @@ void FLUID_3D::wipeBoundaries(int zBegin, int zEnd) setZeroBorder(_density, _res, zBegin, zEnd); if (_fuel) { setZeroBorder(_fuel, _res, zBegin, zEnd); + setZeroBorder(_react, _res, zBegin, zEnd); } if (_color_r) { setZeroBorder(_color_r, _res, zBegin, zEnd); @@ -770,6 +782,7 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd) _density[index] = 0.0f; if (_fuel) { _fuel[index] = 0.0f; + _react[index] = 0.0f; } if (_color_r) { _color_r[index] = 0.0f; @@ -785,6 +798,7 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd) _density[index] = 0.0f; if (_fuel) { _fuel[index] = 0.0f; + _react[index] = 0.0f; } if (_color_r) { _color_r[index] = 0.0f; @@ -808,6 +822,7 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd) _density[index] = 0.0f; if (_fuel) { _fuel[index] = 0.0f; + _react[index] = 0.0f; } if (_color_r) { _color_r[index] = 0.0f; @@ -823,6 +838,7 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd) _density[index] = 0.0f; if (_fuel) { _fuel[index] = 0.0f; + _react[index] = 0.0f; } if (_color_r) { _color_r[index] = 0.0f; @@ -851,6 +867,7 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd) _density[index] = 0.0f; if (_fuel) { _fuel[index] = 0.0f; + _react[index] = 0.0f; } if (_color_r) { _color_r[index] = 0.0f; @@ -877,6 +894,7 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd) _density[indexx] = 0.0f; if (_fuel) { _fuel[index] = 0.0f; + _react[index] = 0.0f; } if (_color_r) { _color_r[index] = 0.0f; @@ -1479,6 +1497,7 @@ void FLUID_3D::advectMacCormackEnd1(int zBegin, int zEnd) } if (_fuel) { advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _fuelOld, _fuelTemp, res, zBegin, zEnd); + advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _reactOld, _reactTemp, res, zBegin, zEnd); } if (_color_r) { advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_rOld, _color_rTemp, res, zBegin, zEnd); @@ -1512,6 +1531,7 @@ void FLUID_3D::advectMacCormackEnd2(int zBegin, int zEnd) } if (_fuel) { advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _fuelOld, _fuel, _fuelTemp, t1, res, _obstacles, zBegin, zEnd); + advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _reactOld, _react, _reactTemp, t1, res, _obstacles, zBegin, zEnd); } if (_color_r) { advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_rOld, _color_r, _color_rTemp, t1, res, _obstacles, zBegin, zEnd); @@ -1536,6 +1556,7 @@ void FLUID_3D::advectMacCormackEnd2(int zBegin, int zEnd) setZeroBorder(_density, res, zBegin, zEnd); if (_fuel) { setZeroBorder(_fuel, res, zBegin, zEnd); + setZeroBorder(_react, res, zBegin, zEnd); } if (_color_r) { setZeroBorder(_color_r, res, zBegin, zEnd); @@ -1545,7 +1566,7 @@ void FLUID_3D::advectMacCormackEnd2(int zBegin, int zEnd) } -void FLUID_3D::processBurn(float *fuel, float *smoke, float *flame, float *heat, +void FLUID_3D::processBurn(float *fuel, float *smoke, float *react, float *flame, float *heat, float *r, float *g, float *b, int total_cells, float dt) { float burning_rate = *_burning_rate; @@ -1558,31 +1579,35 @@ void FLUID_3D::processBurn(float *fuel, float *smoke, float *flame, float *heat, float orig_fuel = fuel[index]; float orig_smoke = smoke[index]; float smoke_emit = 0.0f; + float react_coord = 0.0f; - /* process reaction coordinate */ + /* process fuel */ fuel[index] -= burning_rate * dt; if (fuel[index] < 0.0f) fuel[index] = 0.0f; + /* process reaction coordinate */ + if (orig_fuel) { + react[index] *= fuel[index]/orig_fuel; + react_coord = react[index]; + } + else { + react[index] = 0.0f; + } - /* emit smoke based on reaction time and "flame_smoke" factor */ - smoke_emit = (1.0f-orig_fuel) * (orig_fuel-fuel[index]) * 0.1f * flame_smoke; + /* emit smoke based on fuel burn rate and "flame_smoke" factor */ + smoke_emit = (orig_fuel < 1.0f) ? (1.0f - orig_fuel)*0.5f : 0.0f; + smoke_emit = (smoke_emit + 0.5f) * (orig_fuel-fuel[index]) * 0.1f * flame_smoke; smoke[index] += smoke_emit; CLAMP(smoke[index], 0.0f, 1.0f); /* model flame temperature curve from the reaction coordinate (fuel) */ - /* DISABLED FOR NOW: temp rise region doesnt work well - * when fuel amount isnt 1.0 to start with - if (fuel[index]>=0.9f) { - // linearly interpolate from ignition to max for temp rise region - flame[index] = (1.0f - fuel[index])/0.1f; - } - else */if (fuel[index]>0.0f) { + if (react_coord>0.0f) { /* do a smooth falloff for rest of the values */ - flame[index] = pow(fuel[index]/1.0f, 0.5f); + flame[index] = pow(react_coord, 0.5f); } else flame[index] = 0.0f; - /* for flame set fluid temperature from the flame temperature profile */ + /* set fluid temperature from the flame temperature profile */ if (heat && flame[index]) heat[index] = (1.0f-flame[index])*ignition_point + flame[index]*temp_max; diff --git a/intern/smoke/intern/FLUID_3D.h b/intern/smoke/intern/FLUID_3D.h index 134cec078cb..8cadf3bc989 100644 --- a/intern/smoke/intern/FLUID_3D.h +++ b/intern/smoke/intern/FLUID_3D.h @@ -125,6 +125,9 @@ class FLUID_3D float *_fuel; float *_fuelTemp; float *_fuelOld; + float *_react; + float *_reactTemp; + float *_reactOld; // smoke color float *_color_r; @@ -206,7 +209,7 @@ class FLUID_3D float *_flame_vorticity; // RNA pointer float *_ignition_temp; // RNA pointer float *_max_temp; // RNA pointer - void processBurn(float *fuel, float *smoke, float *flame, float *heat, + void processBurn(float *fuel, float *smoke, float *react, float *flame, float *heat, float *r, float *g, float *b, int total_cells, float dt); // boundary setting functions diff --git a/intern/smoke/intern/WTURBULENCE.cpp b/intern/smoke/intern/WTURBULENCE.cpp index 995ba663c5b..1c89f5d681b 100644 --- a/intern/smoke/intern/WTURBULENCE.cpp +++ b/intern/smoke/intern/WTURBULENCE.cpp @@ -96,6 +96,7 @@ WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int no /* fire */ _flameBig = _fuelBig = _fuelBigOld = NULL; + _reactBig = _reactBigOld = NULL; if (init_fire) { initFire(); } @@ -147,11 +148,15 @@ void WTURBULENCE::initFire() _flameBig = new float[_totalCellsBig]; _fuelBig = new float[_totalCellsBig]; _fuelBigOld = new float[_totalCellsBig]; + _reactBig = new float[_totalCellsBig]; + _reactBigOld = new float[_totalCellsBig]; for(int i = 0; i < _totalCellsBig; i++) { _flameBig[i] = _fuelBig[i] = _fuelBigOld[i] = 0.; + _reactBig[i] = + _reactBigOld[i] = 0.; } } } @@ -186,6 +191,8 @@ WTURBULENCE::~WTURBULENCE() { if (_flameBig) delete[] _flameBig; if (_fuelBig) delete[] _fuelBig; if (_fuelBigOld) delete[] _fuelBigOld; + if (_reactBig) delete[] _reactBig; + if (_reactBigOld) delete[] _reactBigOld; if (_color_rBig) delete[] _color_rBig; if (_color_rBigOld) delete[] _color_rBigOld; @@ -816,7 +823,8 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa // enlarge timestep to match grid const float dt = dtOrg * _amplify; const float invAmp = 1.0f / _amplify; - float *tempFuelBig = NULL, *tempColor_rBig = NULL, *tempColor_gBig = NULL, *tempColor_bBig = NULL; + float *tempFuelBig = NULL, *tempReactBig = NULL; + float *tempColor_rBig = NULL, *tempColor_gBig = NULL, *tempColor_bBig = NULL; float *tempDensityBig = (float *)calloc(_totalCellsBig, sizeof(float)); float *tempBig = (float *)calloc(_totalCellsBig, sizeof(float)); float *bigUx = (float *)calloc(_totalCellsBig, sizeof(float)); @@ -829,6 +837,7 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa if (_fuelBig) { tempFuelBig = (float *)calloc(_totalCellsBig, sizeof(float)); + tempReactBig = (float *)calloc(_totalCellsBig, sizeof(float)); } if (_color_rBig) { tempColor_rBig = (float *)calloc(_totalCellsBig, sizeof(float)); @@ -1042,6 +1051,7 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa // prepare density for an advection SWAP_POINTERS(_densityBig, _densityBigOld); SWAP_POINTERS(_fuelBig, _fuelBigOld); + SWAP_POINTERS(_reactBig, _reactBigOld); SWAP_POINTERS(_color_rBig, _color_rBigOld); SWAP_POINTERS(_color_gBig, _color_gBigOld); SWAP_POINTERS(_color_bBig, _color_bBigOld); @@ -1094,6 +1104,8 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa if (_fuelBig) { FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz, _fuelBigOld, tempFuelBig, _resBig, zBegin, zEnd); + FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz, + _reactBigOld, tempReactBig, _resBig, zBegin, zEnd); } if (_color_rBig) { FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz, @@ -1119,6 +1131,8 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa if (_fuelBig) { FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz, _fuelBigOld, _fuelBig, tempFuelBig, tempBig, _resBig, NULL, zBegin, zEnd); + FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz, + _reactBigOld, _reactBig, tempReactBig, tempBig, _resBig, NULL, zBegin, zEnd); } if (_color_rBig) { FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz, @@ -1136,6 +1150,7 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa if (substep < totalSubsteps - 1) { SWAP_POINTERS(_densityBig, _densityBigOld); SWAP_POINTERS(_fuelBig, _fuelBigOld); + SWAP_POINTERS(_reactBig, _reactBigOld); SWAP_POINTERS(_color_rBig, _color_rBigOld); SWAP_POINTERS(_color_gBig, _color_gBigOld); SWAP_POINTERS(_color_bBig, _color_bBigOld); @@ -1144,6 +1159,7 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa free(tempDensityBig); if (tempFuelBig) free(tempFuelBig); + if (tempReactBig) free(tempReactBig); if (tempColor_rBig) free(tempColor_rBig); if (tempColor_gBig) free(tempColor_gBig); if (tempColor_bBig) free(tempColor_bBig); @@ -1158,6 +1174,7 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa FLUID_3D::setZeroBorder(_densityBig, _resBig, 0 , _resBig[2]); if (_fuelBig) { FLUID_3D::setZeroBorder(_fuelBig, _resBig, 0 , _resBig[2]); + FLUID_3D::setZeroBorder(_reactBig, _resBig, 0 , _resBig[2]); } if (_color_rBig) { FLUID_3D::setZeroBorder(_color_rBig, _resBig, 0 , _resBig[2]); diff --git a/intern/smoke/intern/WTURBULENCE.h b/intern/smoke/intern/WTURBULENCE.h index cb7b67d6f57..1655bd95d32 100644 --- a/intern/smoke/intern/WTURBULENCE.h +++ b/intern/smoke/intern/WTURBULENCE.h @@ -119,6 +119,8 @@ class WTURBULENCE float* _flameBig; float* _fuelBig; float* _fuelBigOld; + float* _reactBig; + float* _reactBigOld; float* _color_rBig; float* _color_rBigOld; diff --git a/intern/smoke/intern/smoke_API.cpp b/intern/smoke/intern/smoke_API.cpp index dffd59f88c2..ad87a23169a 100644 --- a/intern/smoke/intern/smoke_API.cpp +++ b/intern/smoke/intern/smoke_API.cpp @@ -76,7 +76,7 @@ extern "C" size_t smoke_get_index2d(int x, int max_x, int y /*, int max_y, int z extern "C" void smoke_step(FLUID_3D *fluid, float gravity[3], float dtSubdiv) { if (fluid->_fuel) { - fluid->processBurn(fluid->_fuel, fluid->_density, fluid->_flame, fluid->_heat, + fluid->processBurn(fluid->_fuel, fluid->_density, fluid->_react, fluid->_flame, fluid->_heat, fluid->_color_r, fluid->_color_g, fluid->_color_b, fluid->_totalCells, (*fluid->_dtFactor)*dtSubdiv); } fluid->step(dtSubdiv, gravity); @@ -85,7 +85,7 @@ extern "C" void smoke_step(FLUID_3D *fluid, float gravity[3], float dtSubdiv) extern "C" void smoke_turbulence_step(WTURBULENCE *wt, FLUID_3D *fluid) { if (wt->_fuelBig) { - fluid->processBurn(wt->_fuelBig, wt->_densityBig, wt->_flameBig, 0, + fluid->processBurn(wt->_fuelBig, wt->_densityBig, wt->_reactBig, wt->_flameBig, 0, wt->_color_rBig, wt->_color_gBig, wt->_color_bBig, wt->_totalCellsBig, fluid->_dt); } wt->stepTurbulenceFull(fluid->_dt/fluid->_dx, fluid->_xVelocity, fluid->_yVelocity, fluid->_zVelocity, fluid->_obstacles); @@ -168,12 +168,13 @@ extern "C" void smoke_dissolve_wavelet(WTURBULENCE *wt, int speed, int log) data_dissolve(wt->_densityBig, 0, wt->_color_rBig, wt->_color_gBig, wt->_color_bBig, wt->_totalCellsBig, speed, log); } -extern "C" void smoke_export(FLUID_3D *fluid, float *dt, float *dx, float **dens, float **flame, float **fuel, float **heat, +extern "C" void smoke_export(FLUID_3D *fluid, float *dt, float *dx, float **dens, float **react, float **flame, float **fuel, float **heat, float **heatold, float **vx, float **vy, float **vz, float **r, float **g, float **b, unsigned char **obstacles) { *dens = fluid->_density; - *flame = fluid->_flame; *fuel = fluid->_fuel; + *react = fluid->_react; + *flame = fluid->_flame; *heat = fluid->_heat; *heatold = fluid->_heatOld; *vx = fluid->_xVelocity; @@ -187,7 +188,7 @@ extern "C" void smoke_export(FLUID_3D *fluid, float *dt, float *dx, float **dens *dx = fluid->_dx; } -extern "C" void smoke_turbulence_export(WTURBULENCE *wt, float **dens, float **flame, float **fuel, +extern "C" void smoke_turbulence_export(WTURBULENCE *wt, float **dens, float **react, float **flame, float **fuel, float **r, float **g, float **b , float **tcu, float **tcv, float **tcw) { if(!wt) @@ -195,6 +196,7 @@ extern "C" void smoke_turbulence_export(WTURBULENCE *wt, float **dens, float **f *dens = wt->_densityBig; *fuel = wt->_fuelBig; + *react = wt->_reactBig; *flame = wt->_flameBig; *r = wt->_color_rBig; *g = wt->_color_gBig; @@ -214,6 +216,11 @@ extern "C" float *smoke_get_fuel(FLUID_3D *fluid) return fluid->_fuel; } +extern "C" float *smoke_get_react(FLUID_3D *fluid) +{ + return fluid->_react; +} + extern "C" float *smoke_get_heat(FLUID_3D *fluid) { return fluid->_heat; @@ -352,6 +359,11 @@ extern "C" float *smoke_turbulence_get_fuel(WTURBULENCE *wt) return wt ? wt->getFuelBig() : NULL; } +extern "C" float *smoke_turbulence_get_react(WTURBULENCE *wt) +{ + return wt ? wt->_reactBig : NULL; +} + extern "C" float *smoke_turbulence_get_color_r(WTURBULENCE *wt) { return wt ? wt->_color_rBig : NULL; |