diff options
author | Daniel Genrich <daniel.genrich@gmx.net> | 2009-08-12 21:32:02 +0400 |
---|---|---|
committer | Daniel Genrich <daniel.genrich@gmx.net> | 2009-08-12 21:32:02 +0400 |
commit | fb7c9d5a0d049651aab759e09338d774d1ce258b (patch) | |
tree | 6739197111c6c776feb14e863ee98dadc3061be2 /intern/smoke | |
parent | b8fcda9ea57d65b1b956695bb1ff17c4e41f0ab4 (diff) |
Smoke:
* New feature: "Dissolve Smoke" - Idea by nudelZ
Diffstat (limited to 'intern/smoke')
-rw-r--r-- | intern/smoke/extern/smoke_API.h | 6 | ||||
-rw-r--r-- | intern/smoke/intern/FLUID_3D.cpp | 25 | ||||
-rw-r--r-- | intern/smoke/intern/FLUID_3D.h | 5 | ||||
-rw-r--r-- | intern/smoke/intern/FLUID_3D_STATIC.cpp | 4 | ||||
-rw-r--r-- | intern/smoke/intern/smoke_API.cpp | 102 |
5 files changed, 118 insertions, 24 deletions
diff --git a/intern/smoke/extern/smoke_API.h b/intern/smoke/extern/smoke_API.h index 52df3891ca0..f0dba3cc7a4 100644 --- a/intern/smoke/extern/smoke_API.h +++ b/intern/smoke/extern/smoke_API.h @@ -36,7 +36,7 @@ struct FLUID_3D *smoke_init(int *res, float *p0, float dt); void smoke_free(struct FLUID_3D *fluid); void smoke_initBlenderRNA(struct FLUID_3D *fluid, float *alpha, float *beta); -void smoke_step(struct FLUID_3D *fluid); +void smoke_step(struct FLUID_3D *fluid, size_t framenr); float *smoke_get_density(struct FLUID_3D *fluid); float *smoke_get_heat(struct FLUID_3D *fluid); @@ -49,6 +49,8 @@ unsigned char *smoke_get_obstacle(struct FLUID_3D *fluid); size_t smoke_get_index(int x, int max_x, int y, int max_y, int z); size_t smoke_get_index2d(int x, int max_x, int y); +void smoke_dissolve(struct FLUID_3D *fluid, int speed, int log); + // wavelet turbulence functions struct WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype); void smoke_turbulence_free(struct WTURBULENCE *wt); @@ -59,6 +61,8 @@ void smoke_turbulence_get_res(struct WTURBULENCE *wt, int *res); void smoke_turbulence_set_noise(struct WTURBULENCE *wt, int type); void smoke_initWaveletBlenderRNA(struct WTURBULENCE *wt, float *strength); +void smoke_dissolve_wavelet(struct WTURBULENCE *wt, int speed, int log); + #ifdef __cplusplus } #endif diff --git a/intern/smoke/intern/FLUID_3D.cpp b/intern/smoke/intern/FLUID_3D.cpp index 0e1fe637bb8..8f72b1da536 100644 --- a/intern/smoke/intern/FLUID_3D.cpp +++ b/intern/smoke/intern/FLUID_3D.cpp @@ -101,6 +101,11 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dt) : _h = new float[_totalCells]; _Precond = new float[_totalCells]; + _spectrum = new unsigned char[256*4*16*16]; + + + // DG TODO: check if alloc went fine + for (int x = 0; x < _totalCells; x++) { _density[x] = 0.0f; @@ -202,6 +207,8 @@ FLUID_3D::~FLUID_3D() if (_obstacles) delete[] _obstacles; // if (_wTurbulence) delete _wTurbulence; + if(_spectrum) delete[] _spectrum; + printf("deleted fluid\n"); } @@ -219,7 +226,10 @@ void FLUID_3D::step() { // wipe forces for (int i = 0; i < _totalCells; i++) + { _xForce[i] = _yForce[i] = _zForce[i] = 0.0f; + _obstacles[i] &= ~2; + } wipeBoundaries(); @@ -683,16 +693,17 @@ void FLUID_3D::advectMacCormack() const float dt0 = _dt / _dx; // use force arrays as temp arrays - for (int x = 0; x < _totalCells; x++) - _xForce[x] = _yForce[x] = 0.0; + for (int x = 0; x < _totalCells; x++) + _xForce[x] = _yForce[x] = 0.0; + float* t1 = _xForce; float* t2 = _yForce; - advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _densityOld, _density, t1,t2, res, NULL); - advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heat, t1,t2, res, NULL); - advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _xVelocityOld, _xVelocity, t1,t2, res, NULL); - advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _yVelocityOld, _yVelocity, t1,t2, res, NULL); - advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _zVelocityOld, _zVelocity, t1,t2, res, NULL); + advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _densityOld, _density, t1,t2, res, _obstacles); + advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heat, t1,t2, res, _obstacles); + advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _xVelocityOld, _xVelocity, t1,t2, res, _obstacles); + advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _yVelocityOld, _yVelocity, t1,t2, res, _obstacles); + advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _zVelocityOld, _zVelocity, t1,t2, res, _obstacles); if(DOMAIN_BC_LEFT == 0) copyBorderX(_xVelocity, res); else setZeroX(_xVelocity, res); diff --git a/intern/smoke/intern/FLUID_3D.h b/intern/smoke/intern/FLUID_3D.h index 614ea4e46de..f228abc05a9 100644 --- a/intern/smoke/intern/FLUID_3D.h +++ b/intern/smoke/intern/FLUID_3D.h @@ -99,6 +99,7 @@ class FLUID_3D float* _h; float* _Precond; unsigned char* _obstacles; + unsigned char *_spectrum; // CG fields float* _residual; @@ -161,13 +162,13 @@ class FLUID_3D static void advectFieldSemiLagrange(const float dt, const float* velx, const float* vely, const float* velz, float* oldField, float* newField, Vec3Int res); static void advectFieldMacCormack(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity, - float* oldField, float* newField, float* temp1, float* temp2, Vec3Int res, const float* obstacles); + float* oldField, float* newField, float* temp1, float* temp2, Vec3Int res, const unsigned char* obstacles); // maccormack helper functions static void clampExtrema(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity, float* oldField, float* newField, Vec3Int res); static void clampOutsideRays(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity, - float* oldField, float* newField, Vec3Int res, const float* obstacles, const float *oldAdvection); + float* oldField, float* newField, Vec3Int res, const unsigned char* obstacles, const float *oldAdvection); // output helper functions // static void writeImageSliceXY(const float *field, Vec3Int res, int slice, string prefix, int picCnt, float scale=1.); diff --git a/intern/smoke/intern/FLUID_3D_STATIC.cpp b/intern/smoke/intern/FLUID_3D_STATIC.cpp index ebb351dc323..4474129beea 100644 --- a/intern/smoke/intern/FLUID_3D_STATIC.cpp +++ b/intern/smoke/intern/FLUID_3D_STATIC.cpp @@ -338,7 +338,7 @@ void FLUID_3D::advectFieldSemiLagrange(const float dt, const float* velx, const // comments are the pseudocode from selle's paper ////////////////////////////////////////////////////////////////////// void FLUID_3D::advectFieldMacCormack(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity, - float* oldField, float* newField, float* temp1, float* temp2, Vec3Int res, const float* obstacles) + float* oldField, float* newField, float* temp1, float* temp2, Vec3Int res, const unsigned char* obstacles) { float* phiHatN = temp1; float* phiHatN1 = temp2; @@ -459,7 +459,7 @@ void FLUID_3D::clampExtrema(const float dt, const float* velx, const float* vely // incorrect ////////////////////////////////////////////////////////////////////// void FLUID_3D::clampOutsideRays(const float dt, const float* velx, const float* vely, const float* velz, - float* oldField, float* newField, Vec3Int res, const float* obstacles, const float *oldAdvection) + float* oldField, float* newField, Vec3Int res, const unsigned char* obstacles, const float *oldAdvection) { const int sx= res[0]; const int sy= res[1]; diff --git a/intern/smoke/intern/smoke_API.cpp b/intern/smoke/intern/smoke_API.cpp index c4dd23146c2..7f90971f14d 100644 --- a/intern/smoke/intern/smoke_API.cpp +++ b/intern/smoke/intern/smoke_API.cpp @@ -63,7 +63,18 @@ extern "C" void smoke_turbulence_free(WTURBULENCE *wt) wt = NULL; } -extern "C" void smoke_step(FLUID_3D *fluid) +extern "C" size_t smoke_get_index(int x, int max_x, int y, int max_y, int z /*, int max_z */) +{ + // // const int index = x + y * smd->res[0] + z * smd->res[0]*smd->res[1]; + return x + y * max_x + z * max_x*max_y; +} + +extern "C" size_t smoke_get_index2d(int x, int max_x, int y /*, int max_y, int z, int max_z */) +{ + return x + y * max_x; +} + +extern "C" void smoke_step(FLUID_3D *fluid, size_t framenr) { fluid->step(); } @@ -79,6 +90,84 @@ extern "C" void smoke_initBlenderRNA(FLUID_3D *fluid, float *alpha, float *beta) fluid->initBlenderRNA(alpha, beta); } +extern "C" void smoke_dissolve(FLUID_3D *fluid, int speed, int log) +{ + float *density = fluid->_density; + float *densityOld = fluid->_densityOld; + float *heat = fluid->_heat; + + if(log) + { + /* max density/speed = dydx */ + float dydx = 1.0 / (float)speed; + + for(size_t i = 0; i < fluid->_xRes * fluid->_yRes * fluid->_zRes; i++) + { + density[i] *= (1.0 - dydx); + + if(density[i] < 0.0f) + density[i] = 0.0f; + + heat[i] *= (1.0 - dydx); + + if(heat[i] < 0.0f) + heat[i] = 0.0f; + } + } + else // linear falloff + { + /* max density/speed = dydx */ + float dydx = 1.0 / (float)speed; + + for(size_t i = 0; i < fluid->_xRes * fluid->_yRes * fluid->_zRes; i++) + { + density[i] -= dydx; + + if(density[i] < 0.0f) + density[i] = 0.0f; + + heat[i] -= dydx; + + if(heat[i] < 0.0f) + heat[i] = 0.0f; + + } + } +} + +extern "C" void smoke_dissolve_wavelet(WTURBULENCE *wt, int speed, int log) +{ + float *density = wt->getDensityBig(); + Vec3Int r = wt->getResBig(); + + if(log) + { + /* max density/speed = dydx */ + float dydx = 1.0 / (float)speed; + + for(size_t i = 0; i < r[0] * r[1] * r[2]; i++) + { + density[i] *= (1.0 - dydx); + + if(density[i] < 0.0f) + density[i] = 0.0f; + } + } + else // linear falloff + { + /* max density/speed = dydx */ + float dydx = 1.0 / (float)speed; + + for(size_t i = 0; i < r[0] * r[1] * r[2]; i++) + { + density[i] -= dydx; + + if(density[i] < 0.0f) + density[i] = 0.0f; + } + } +} + extern "C" void smoke_initWaveletBlenderRNA(WTURBULENCE *wt, float *strength) { wt->initBlenderRNA(strength); @@ -134,17 +223,6 @@ extern "C" unsigned char *smoke_get_obstacle(FLUID_3D *fluid) return fluid->_obstacles; } -extern "C" size_t smoke_get_index(int x, int max_x, int y, int max_y, int z /*, int max_z */) -{ - // // const int index = x + y * smd->res[0] + z * smd->res[0]*smd->res[1]; - return x + y * max_x + z * max_x*max_y; -} - -extern "C" size_t smoke_get_index2d(int x, int max_x, int y /*, int max_y, int z, int max_z */) -{ - return x + y * max_x; -} - extern "C" void smoke_turbulence_set_noise(WTURBULENCE *wt, int type) { wt->setNoise(type); |