31
31
#include "FLUID_3D.h"
32
32
#include "WTURBULENCE.h"
35
36
#include <stdlib.h>
38
// y in smoke is z in blender
39
extern "C" FLUID_3D *smoke_init(int *res, float *p0)
39
#include "../extern/smoke_API.h" /* to ensure valid prototypes */
41
extern "C" FLUID_3D *smoke_init(int *res, float dx, float dtdef, int use_heat, int use_fire, int use_colors)
41
// smoke lib uses y as top-bottom/vertical axis where blender uses z
42
FLUID_3D *fluid = new FLUID_3D(res, p0);
44
// printf("xres: %d, yres: %d, zres: %d\n", res[0], res[1], res[2]);
43
FLUID_3D *fluid = new FLUID_3D(res, dx, dtdef, use_heat, use_fire, use_colors);
49
extern "C" WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype)
47
extern "C" WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype, int use_fire, int use_colors)
51
// initialize wavelet turbulence
53
return new WTURBULENCE(res[0],res[1],res[2], amplify, noisetype);
50
return new WTURBULENCE(res[0],res[1],res[2], amplify, noisetype, use_fire, use_colors);
78
74
return x + y * max_x;
81
extern "C" void smoke_step(FLUID_3D *fluid, size_t framenr, float fps)
77
extern "C" void smoke_step(FLUID_3D *fluid, float gravity[3], float dtSubdiv)
83
/* stability values copied from wturbulence.cpp */
84
const int maxSubSteps = 25;
85
const float maxVel = 0.5f; /* TODO: maybe 0.5 is still too high, please confirm! -dg */
87
float dt = DT_DEFAULT;
88
float maxVelMag = 0.0f;
93
/* get max velocity and lower the dt value if it is too high */
94
size_t size= fluid->_xRes * fluid->_yRes * fluid->_zRes;
96
for(size_t i = 0; i < size; i++)
98
float vtemp = (fluid->_xVelocity[i]*fluid->_xVelocity[i]+fluid->_yVelocity[i]*fluid->_yVelocity[i]+fluid->_zVelocity[i]*fluid->_zVelocity[i]);
80
fluid->processBurn(fluid->_fuel, fluid->_density, fluid->_react, fluid->_flame, fluid->_heat,
81
fluid->_color_r, fluid->_color_g, fluid->_color_b, fluid->_totalCells, (*fluid->_dtFactor)*dtSubdiv);
103
/* adapt timestep for different framerates, dt = 0.1 is at 25fps */
106
maxVelMag = sqrt(maxVelMag) * dt * (*(fluid->_dtFactor));
107
totalSubsteps = (int)((maxVelMag / maxVel) + 1.0f); /* always round up */
108
totalSubsteps = (totalSubsteps < 1) ? 1 : totalSubsteps;
109
totalSubsteps = (totalSubsteps > maxSubSteps) ? maxSubSteps : totalSubsteps;
110
dtSubdiv = (float)dt / (float)totalSubsteps;
112
// printf("totalSubsteps: %d, maxVelMag: %f, dt: %f\n", totalSubsteps, maxVelMag, dt);
114
for(substep = 0; substep < totalSubsteps; substep++)
115
fluid->step(dtSubdiv);
83
fluid->step(dtSubdiv, gravity);
118
86
extern "C" void smoke_turbulence_step(WTURBULENCE *wt, FLUID_3D *fluid)
89
fluid->processBurn(wt->_fuelBig, wt->_densityBig, wt->_reactBig, wt->_flameBig, 0,
90
wt->_color_rBig, wt->_color_gBig, wt->_color_bBig, wt->_totalCellsBig, fluid->_dt);
120
92
wt->stepTurbulenceFull(fluid->_dt/fluid->_dx, fluid->_xVelocity, fluid->_yVelocity, fluid->_zVelocity, fluid->_obstacles);
123
extern "C" void smoke_initBlenderRNA(FLUID_3D *fluid, float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli)
125
fluid->initBlenderRNA(alpha, beta, dt_factor, vorticity, border_colli);
95
extern "C" void smoke_initBlenderRNA(FLUID_3D *fluid, float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli, float *burning_rate,
96
float *flame_smoke, float *flame_smoke_color, float *flame_vorticity, float *flame_ignition_temp, float *flame_max_temp)
98
fluid->initBlenderRNA(alpha, beta, dt_factor, vorticity, border_colli, burning_rate, flame_smoke, flame_smoke_color, flame_vorticity, flame_ignition_temp, flame_max_temp);
101
extern "C" void smoke_initWaveletBlenderRNA(WTURBULENCE *wt, float *strength)
103
wt->initBlenderRNA(strength);
106
static void data_dissolve(float *density, float *heat, float *r, float *g, float *b, int total_cells, int speed, int log)
109
/* max density/speed = dydx */
110
float fac = 1.0f - (1.0f / (float)speed);
112
for(size_t i = 0; i < total_cells; i++)
130
else // linear falloff
132
/* max density/speed = dydx */
133
float dydx = 1.0f / (float)speed;
135
for(size_t i = 0; i < total_cells; i++)
137
float d = density[i];
140
if (density[i] < 0.0f)
145
if (abs(heat[i]) < dydx) heat[i] = 0.0f;
146
else if (heat[i] > 0.0f) heat[i] -= dydx;
147
else if (heat[i] < 0.0f) heat[i] += dydx;
152
r[i] *= (density[i]/d);
153
g[i] *= (density[i]/d);
154
b[i] *= (density[i]/d);
128
161
extern "C" void smoke_dissolve(FLUID_3D *fluid, int speed, int log)
130
float *density = fluid->_density;
131
//float *densityOld = fluid->_densityOld;
132
float *heat = fluid->_heat;
136
/* max density/speed = dydx */
137
float dydx = 1.0 / (float)speed;
138
size_t size= fluid->_xRes * fluid->_yRes * fluid->_zRes;
140
for(size_t i = 0; i < size; i++)
142
density[i] *= (1.0 - dydx);
144
if(density[i] < 0.0f)
147
heat[i] *= (1.0 - dydx);
153
else // linear falloff
155
/* max density/speed = dydx */
156
float dydx = 1.0 / (float)speed;
157
size_t size= fluid->_xRes * fluid->_yRes * fluid->_zRes;
159
for(size_t i = 0; i < size; i++)
163
if(density[i] < 0.0f)
166
if(abs(heat[i]) < dydx) heat[i] = 0.0f;
167
else if (heat[i]>0.0f) heat[i] -= dydx;
168
else if (heat[i]<0.0f) heat[i] += dydx;
163
data_dissolve(fluid->_density, fluid->_heat, fluid->_color_r, fluid->_color_g, fluid->_color_b, fluid->_totalCells, speed, log);
174
166
extern "C" void smoke_dissolve_wavelet(WTURBULENCE *wt, int speed, int log)
176
float *density = wt->getDensityBig();
177
Vec3Int r = wt->getResBig();
181
/* max density/speed = dydx */
182
float dydx = 1.0 / (float)speed;
183
size_t size= r[0] * r[1] * r[2];
185
for(size_t i = 0; i < size; i++)
187
density[i] *= (1.0 - dydx);
189
if(density[i] < 0.0f)
193
else // linear falloff
195
/* max density/speed = dydx */
196
float dydx = 1.0 / (float)speed;
197
size_t size= r[0] * r[1] * r[2];
199
for(size_t i = 0; i < size; i++)
203
if(density[i] < 0.0f)
209
extern "C" void smoke_initWaveletBlenderRNA(WTURBULENCE *wt, float *strength)
211
wt->initBlenderRNA(strength);
214
template < class T > inline T ABS( T a )
216
return (0 < a) ? a : -a ;
219
extern "C" void smoke_export(FLUID_3D *fluid, float *dt, float *dx, float **dens, float **densold, float **heat, float **heatold, float **vx, float **vy, float **vz, float **vxold, float **vyold, float **vzold, unsigned char **obstacles)
168
data_dissolve(wt->_densityBig, 0, wt->_color_rBig, wt->_color_gBig, wt->_color_bBig, wt->_totalCellsBig, speed, log);
171
extern "C" void smoke_export(FLUID_3D *fluid, float *dt, float *dx, float **dens, float **react, float **flame, float **fuel, float **heat,
172
float **heatold, float **vx, float **vy, float **vz, float **r, float **g, float **b, unsigned char **obstacles)
221
174
*dens = fluid->_density;
222
*densold = fluid->_densityOld;
175
*fuel = fluid->_fuel;
176
*react = fluid->_react;
177
*flame = fluid->_flame;
223
178
*heat = fluid->_heat;
224
179
*heatold = fluid->_heatOld;
225
180
*vx = fluid->_xVelocity;
226
181
*vy = fluid->_yVelocity;
227
182
*vz = fluid->_zVelocity;
228
*vxold = fluid->_xVelocityOld;
229
*vyold = fluid->_yVelocityOld;
230
*vzold = fluid->_zVelocityOld;
183
*r = fluid->_color_r;
184
*g = fluid->_color_g;
185
*b = fluid->_color_b;
231
186
*obstacles = fluid->_obstacles;
237
extern "C" void smoke_turbulence_export(WTURBULENCE *wt, float **dens, float **densold, float **tcu, float **tcv, float **tcw)
191
extern "C" void smoke_turbulence_export(WTURBULENCE *wt, float **dens, float **react, float **flame, float **fuel,
192
float **r, float **g, float **b , float **tcu, float **tcv, float **tcw)
242
197
*dens = wt->_densityBig;
243
*densold = wt->_densityBigOld;
198
*fuel = wt->_fuelBig;
199
*react = wt->_reactBig;
200
*flame = wt->_flameBig;
201
*r = wt->_color_rBig;
202
*g = wt->_color_gBig;
203
*b = wt->_color_bBig;
286
256
return fluid->_zForce;
259
extern "C" float *smoke_get_flame(FLUID_3D *fluid)
261
return fluid->_flame;
264
extern "C" float *smoke_get_color_r(FLUID_3D *fluid)
266
return fluid->_color_r;
269
extern "C" float *smoke_get_color_g(FLUID_3D *fluid)
271
return fluid->_color_g;
274
extern "C" float *smoke_get_color_b(FLUID_3D *fluid)
276
return fluid->_color_b;
279
static void get_rgba(float *r, float *g, float *b, float *a, int total_cells, float *data, int sequential)
282
int m = 4, i_g = 1, i_b = 2, i_a = 3;
283
/* sequential data */
291
for (i=0; i<total_cells; i++) {
295
data[i*m+i_g] = g[i];
296
data[i*m+i_b] = b[i];
299
data[i*m ] = data[i*m+i_g] = data[i*m+i_b] = 0.0f;
301
data[i*m+i_a] = alpha;
305
extern "C" void smoke_get_rgba(FLUID_3D *fluid, float *data, int sequential)
307
get_rgba(fluid->_color_r, fluid->_color_g, fluid->_color_b, fluid->_density, fluid->_totalCells, data, sequential);
310
extern "C" void smoke_turbulence_get_rgba(WTURBULENCE *wt, float *data, int sequential)
312
get_rgba(wt->_color_rBig, wt->_color_gBig, wt->_color_bBig, wt->_densityBig, wt->_totalCellsBig, data, sequential);
315
/* get a single color premultiplied voxel grid */
316
static void get_rgba_from_density(float color[3], float *a, int total_cells, float *data, int sequential)
319
int m = 4, i_g = 1, i_b = 2, i_a = 3;
320
/* sequential data */
328
for (i=0; i<total_cells; i++) {
331
data[i*m ] = color[0] * alpha;
332
data[i*m+i_g] = color[1] * alpha;
333
data[i*m+i_b] = color[2] * alpha;
336
data[i*m ] = data[i*m+i_g] = data[i*m+i_b] = 0.0f;
338
data[i*m+i_a] = alpha;
342
extern "C" void smoke_get_rgba_from_density(FLUID_3D *fluid, float color[3], float *data, int sequential)
344
get_rgba_from_density(color, fluid->_density, fluid->_totalCells, data, sequential);
347
extern "C" void smoke_turbulence_get_rgba_from_density(WTURBULENCE *wt, float color[3], float *data, int sequential)
349
get_rgba_from_density(color, wt->_densityBig, wt->_totalCellsBig, data, sequential);
289
352
extern "C" float *smoke_turbulence_get_density(WTURBULENCE *wt)
291
354
return wt ? wt->getDensityBig() : NULL;
357
extern "C" float *smoke_turbulence_get_fuel(WTURBULENCE *wt)
359
return wt ? wt->getFuelBig() : NULL;
362
extern "C" float *smoke_turbulence_get_react(WTURBULENCE *wt)
364
return wt ? wt->_reactBig : NULL;
367
extern "C" float *smoke_turbulence_get_color_r(WTURBULENCE *wt)
369
return wt ? wt->_color_rBig : NULL;
372
extern "C" float *smoke_turbulence_get_color_g(WTURBULENCE *wt)
374
return wt ? wt->_color_gBig : NULL;
377
extern "C" float *smoke_turbulence_get_color_b(WTURBULENCE *wt)
379
return wt ? wt->_color_bBig : NULL;
382
extern "C" float *smoke_turbulence_get_flame(WTURBULENCE *wt)
384
return wt ? wt->getFlameBig() : NULL;
294
387
extern "C" void smoke_turbulence_get_res(WTURBULENCE *wt, int *res)
298
390
Vec3Int r = wt->getResBig();
397
extern "C" int smoke_turbulence_get_cells(WTURBULENCE *wt)
400
Vec3Int r = wt->getResBig();
401
return r[0] * r[1] * r[2];
305
406
extern "C" unsigned char *smoke_get_obstacle(FLUID_3D *fluid)
307
408
return fluid->_obstacles;
411
extern "C" void smoke_get_ob_velocity(FLUID_3D *fluid, float **x, float **y, float **z)
413
*x = fluid->_xVelocityOb;
414
*y = fluid->_yVelocityOb;
415
*z = fluid->_zVelocityOb;
419
extern "C" unsigned char *smoke_get_obstacle_anim(FLUID_3D *fluid)
421
return fluid->_obstaclesAnim;
310
425
extern "C" void smoke_turbulence_set_noise(WTURBULENCE *wt, int type)
312
427
wt->setNoise(type);
430
extern "C" void flame_get_spectrum(unsigned char *spec, int width, float t1, float t2)
432
spectrum(t1, t2, width, spec);
435
extern "C" int smoke_has_heat(FLUID_3D *fluid)
437
return (fluid->_heat) ? 1 : 0;
440
extern "C" int smoke_has_fuel(FLUID_3D *fluid)
442
return (fluid->_fuel) ? 1 : 0;
445
extern "C" int smoke_has_colors(FLUID_3D *fluid)
447
return (fluid->_color_r && fluid->_color_g && fluid->_color_b) ? 1 : 0;
450
extern "C" int smoke_turbulence_has_fuel(WTURBULENCE *wt)
452
return (wt->_fuelBig) ? 1 : 0;
455
extern "C" int smoke_turbulence_has_colors(WTURBULENCE *wt)
457
return (wt->_color_rBig && wt->_color_gBig && wt->_color_bBig) ? 1 : 0;
460
/* additional field initialization */
461
extern "C" void smoke_ensure_heat(FLUID_3D *fluid)
468
extern "C" void smoke_ensure_fire(FLUID_3D *fluid, WTURBULENCE *wt)
478
extern "C" void smoke_ensure_colors(FLUID_3D *fluid, WTURBULENCE *wt, float init_r, float init_g, float init_b)
481
fluid->initColors(init_r, init_g, init_b);
484
wt->initColors(init_r, init_g, init_b);