~ubuntu-branches/ubuntu/trusty/blender/trusty

« back to all changes in this revision

Viewing changes to intern/smoke/intern/smoke_API.cpp

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 * All rights reserved.
20
20
 *
21
21
 * Contributor(s): Daniel Genrich
 
22
 *                 Blender Foundation
22
23
 *
23
24
 * ***** END GPL LICENSE BLOCK *****
24
25
 */
27
28
 *  \ingroup smoke
28
29
 */
29
30
 
30
 
 
31
31
#include "FLUID_3D.h"
32
32
#include "WTURBULENCE.h"
 
33
#include "spectrum.h"
33
34
 
34
35
#include <stdio.h>
35
36
#include <stdlib.h>
36
37
#include <math.h>
37
38
 
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 */
 
40
 
 
41
extern "C" FLUID_3D *smoke_init(int *res, float dx, float dtdef, int use_heat, int use_fire, int use_colors)
40
42
{
41
 
        // smoke lib uses y as top-bottom/vertical axis where blender uses z
42
 
        FLUID_3D *fluid = new FLUID_3D(res, p0);
43
 
 
44
 
        // printf("xres: %d, yres: %d, zres: %d\n", res[0], res[1], res[2]);
45
 
 
 
43
        FLUID_3D *fluid = new FLUID_3D(res, dx, dtdef, use_heat, use_fire, use_colors);
46
44
        return fluid;
47
45
}
48
46
 
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)
50
48
{
51
 
        // initialize wavelet turbulence
52
 
        if(amplify)
53
 
                return new WTURBULENCE(res[0],res[1],res[2], amplify, noisetype);
 
49
        if (amplify)
 
50
                return new WTURBULENCE(res[0],res[1],res[2], amplify, noisetype, use_fire, use_colors);
54
51
        else 
55
52
                return NULL;
56
53
}
69
66
 
70
67
extern "C" size_t smoke_get_index(int x, int max_x, int y, int max_y, int z /*, int max_z */)
71
68
{
72
 
        // // const int index = x + y * smd->res[0] + z * smd->res[0]*smd->res[1];
73
69
        return x + y * max_x + z * max_x*max_y;
74
70
}
75
71
 
78
74
        return x + y * max_x;
79
75
}
80
76
 
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)
82
78
{
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 */
86
 
 
87
 
        float dt = DT_DEFAULT;
88
 
        float maxVelMag = 0.0f;
89
 
        int totalSubsteps;
90
 
        int substep = 0;
91
 
        float dtSubdiv;
92
 
 
93
 
        /* get max velocity and lower the dt value if it is too high */
94
 
        size_t size= fluid->_xRes * fluid->_yRes * fluid->_zRes;
95
 
 
96
 
        for(size_t i = 0; i < size; i++)
97
 
        {
98
 
                float vtemp = (fluid->_xVelocity[i]*fluid->_xVelocity[i]+fluid->_yVelocity[i]*fluid->_yVelocity[i]+fluid->_zVelocity[i]*fluid->_zVelocity[i]);
99
 
                if(vtemp > maxVelMag)
100
 
                        maxVelMag = vtemp;
 
79
        if (fluid->_fuel) {
 
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);
101
82
        }
102
 
 
103
 
        /* adapt timestep for different framerates, dt = 0.1 is at 25fps */
104
 
        dt *= (25.0f / fps);
105
 
 
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;
111
 
 
112
 
        // printf("totalSubsteps: %d, maxVelMag: %f, dt: %f\n", totalSubsteps, maxVelMag, dt);
113
 
 
114
 
        for(substep = 0; substep < totalSubsteps; substep++)
115
 
                fluid->step(dtSubdiv);
 
83
        fluid->step(dtSubdiv, gravity);
116
84
}
117
85
 
118
86
extern "C" void smoke_turbulence_step(WTURBULENCE *wt, FLUID_3D *fluid)
119
87
{
 
88
        if (wt->_fuelBig) {
 
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);
 
91
        }
120
92
        wt->stepTurbulenceFull(fluid->_dt/fluid->_dx, fluid->_xVelocity, fluid->_yVelocity, fluid->_zVelocity, fluid->_obstacles); 
121
93
}
122
94
 
123
 
extern "C" void smoke_initBlenderRNA(FLUID_3D *fluid, float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli)
124
 
{
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)
 
97
{
 
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);
 
99
}
 
100
 
 
101
extern "C" void smoke_initWaveletBlenderRNA(WTURBULENCE *wt, float *strength)
 
102
{
 
103
        wt->initBlenderRNA(strength);
 
104
}
 
105
 
 
106
static void data_dissolve(float *density, float *heat, float *r, float *g, float *b, int total_cells, int speed, int log)
 
107
{
 
108
        if (log) {
 
109
                /* max density/speed = dydx */
 
110
                float fac = 1.0f - (1.0f / (float)speed);
 
111
 
 
112
                for(size_t i = 0; i < total_cells; i++)
 
113
                {
 
114
                        /* density */
 
115
                        density[i] *= fac;
 
116
 
 
117
                        /* heat */
 
118
                        if (heat) {
 
119
                                heat[i] *= fac;
 
120
                        }
 
121
 
 
122
                        /* color */
 
123
                        if (r) {
 
124
                                r[i] *= fac;
 
125
                                g[i] *= fac;
 
126
                                b[i] *= fac;
 
127
                        }
 
128
                }
 
129
        }
 
130
        else // linear falloff
 
131
        {
 
132
                /* max density/speed = dydx */
 
133
                float dydx = 1.0f / (float)speed;
 
134
 
 
135
                for(size_t i = 0; i < total_cells; i++)
 
136
                {
 
137
                        float d = density[i];
 
138
                        /* density */
 
139
                        density[i] -= dydx;
 
140
                        if (density[i] < 0.0f)
 
141
                                density[i] = 0.0f;
 
142
 
 
143
                        /* heat */
 
144
                        if (heat) {
 
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;
 
148
                        }
 
149
 
 
150
                        /* color */
 
151
                        if (r && d) {
 
152
                                r[i] *= (density[i]/d);
 
153
                                g[i] *= (density[i]/d);
 
154
                                b[i] *= (density[i]/d);
 
155
                        }
 
156
                                
 
157
                }
 
158
        }
126
159
}
127
160
 
128
161
extern "C" void smoke_dissolve(FLUID_3D *fluid, int speed, int log)
129
162
{
130
 
        float *density = fluid->_density;
131
 
        //float *densityOld = fluid->_densityOld;
132
 
        float *heat = fluid->_heat;
133
 
 
134
 
        if(log)
135
 
        {
136
 
                /* max density/speed = dydx */
137
 
                float dydx = 1.0 / (float)speed;
138
 
                size_t size= fluid->_xRes * fluid->_yRes * fluid->_zRes;
139
 
 
140
 
                for(size_t i = 0; i < size; i++)
141
 
                {
142
 
                        density[i] *= (1.0 - dydx);
143
 
 
144
 
                        if(density[i] < 0.0f)
145
 
                                density[i] = 0.0f;
146
 
 
147
 
                        heat[i] *= (1.0 - dydx);
148
 
 
149
 
                        /*if(heat[i] < 0.0f)
150
 
                                heat[i] = 0.0f;*/
151
 
                }
152
 
        }
153
 
        else // linear falloff
154
 
        {
155
 
                /* max density/speed = dydx */
156
 
                float dydx = 1.0 / (float)speed;
157
 
                size_t size= fluid->_xRes * fluid->_yRes * fluid->_zRes;
158
 
 
159
 
                for(size_t i = 0; i < size; i++)
160
 
                {
161
 
                        density[i] -= dydx;
162
 
 
163
 
                        if(density[i] < 0.0f)
164
 
                                density[i] = 0.0f;
165
 
 
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;
169
 
                                
170
 
                }
171
 
        }
 
163
        data_dissolve(fluid->_density, fluid->_heat, fluid->_color_r, fluid->_color_g, fluid->_color_b, fluid->_totalCells, speed, log);
172
164
}
173
165
 
174
166
extern "C" void smoke_dissolve_wavelet(WTURBULENCE *wt, int speed, int log)
175
167
{
176
 
        float *density = wt->getDensityBig();
177
 
        Vec3Int r = wt->getResBig();
178
 
 
179
 
        if(log)
180
 
        {
181
 
                /* max density/speed = dydx */
182
 
                float dydx = 1.0 / (float)speed;
183
 
                size_t size= r[0] * r[1] * r[2];
184
 
 
185
 
                for(size_t i = 0; i < size; i++)
186
 
                {
187
 
                        density[i] *= (1.0 - dydx);
188
 
 
189
 
                        if(density[i] < 0.0f)
190
 
                                density[i] = 0.0f;
191
 
                }
192
 
        }
193
 
        else // linear falloff
194
 
        {
195
 
                /* max density/speed = dydx */
196
 
                float dydx = 1.0 / (float)speed;
197
 
                size_t size= r[0] * r[1] * r[2];
198
 
 
199
 
                for(size_t i = 0; i < size; i++)
200
 
                {
201
 
                        density[i] -= dydx;
202
 
 
203
 
                        if(density[i] < 0.0f)
204
 
                                density[i] = 0.0f;                              
205
 
                }
206
 
        }
207
 
}
208
 
 
209
 
extern "C" void smoke_initWaveletBlenderRNA(WTURBULENCE *wt, float *strength)
210
 
{
211
 
        wt->initBlenderRNA(strength);
212
 
}
213
 
 
214
 
template < class T > inline T ABS( T a )
215
 
{
216
 
        return (0 < a) ? a : -a ;
217
 
}
218
 
 
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);
 
169
}
 
170
 
 
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)
220
173
{
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;
232
 
        dt = &(fluid->_dt);
233
 
        dx = &(fluid->_dx);
234
 
 
 
187
        *dt = fluid->_dt;
 
188
        *dx = fluid->_dx;
235
189
}
236
190
 
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)
238
193
{
239
 
        if(!wt)
 
194
        if (!wt)
240
195
                return;
241
196
 
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;
244
204
        *tcu = wt->_tcU;
245
205
        *tcv = wt->_tcV;
246
206
        *tcw = wt->_tcW;
251
211
        return fluid->_density;
252
212
}
253
213
 
 
214
extern "C" float *smoke_get_fuel(FLUID_3D *fluid)
 
215
{
 
216
        return fluid->_fuel;
 
217
}
 
218
 
 
219
extern "C" float *smoke_get_react(FLUID_3D *fluid)
 
220
{
 
221
        return fluid->_react;
 
222
}
 
223
 
254
224
extern "C" float *smoke_get_heat(FLUID_3D *fluid)
255
225
{
256
226
        return fluid->_heat;
286
256
        return fluid->_zForce;
287
257
}
288
258
 
 
259
extern "C" float *smoke_get_flame(FLUID_3D *fluid)
 
260
{
 
261
        return fluid->_flame;
 
262
}
 
263
 
 
264
extern "C" float *smoke_get_color_r(FLUID_3D *fluid)
 
265
{
 
266
        return fluid->_color_r;
 
267
}
 
268
 
 
269
extern "C" float *smoke_get_color_g(FLUID_3D *fluid)
 
270
{
 
271
        return fluid->_color_g;
 
272
}
 
273
 
 
274
extern "C" float *smoke_get_color_b(FLUID_3D *fluid)
 
275
{
 
276
        return fluid->_color_b;
 
277
}
 
278
 
 
279
static void get_rgba(float *r, float *g, float *b, float *a, int total_cells, float *data, int sequential)
 
280
{
 
281
        int i;
 
282
        int m = 4, i_g = 1, i_b = 2, i_a = 3;
 
283
        /* sequential data */
 
284
        if (sequential) {
 
285
                m = 1;
 
286
                i_g *= total_cells;
 
287
                i_b *= total_cells;
 
288
                i_a *= total_cells;
 
289
        }
 
290
 
 
291
        for (i=0; i<total_cells; i++) {
 
292
                float alpha = a[i];
 
293
                if (alpha) {
 
294
                        data[i*m  ] = r[i];
 
295
                        data[i*m+i_g] = g[i];
 
296
                        data[i*m+i_b] = b[i];
 
297
                }
 
298
                else {
 
299
                        data[i*m  ] = data[i*m+i_g] = data[i*m+i_b] = 0.0f;
 
300
                }
 
301
                data[i*m+i_a] = alpha;
 
302
        }
 
303
}
 
304
 
 
305
extern "C" void smoke_get_rgba(FLUID_3D *fluid, float *data, int sequential)
 
306
{
 
307
        get_rgba(fluid->_color_r, fluid->_color_g, fluid->_color_b, fluid->_density, fluid->_totalCells, data, sequential);
 
308
}
 
309
 
 
310
extern "C" void smoke_turbulence_get_rgba(WTURBULENCE *wt, float *data, int sequential)
 
311
{
 
312
        get_rgba(wt->_color_rBig, wt->_color_gBig, wt->_color_bBig, wt->_densityBig, wt->_totalCellsBig, data, sequential);
 
313
}
 
314
 
 
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)
 
317
{
 
318
        int i;
 
319
        int m = 4, i_g = 1, i_b = 2, i_a = 3;
 
320
        /* sequential data */
 
321
        if (sequential) {
 
322
                m = 1;
 
323
                i_g *= total_cells;
 
324
                i_b *= total_cells;
 
325
                i_a *= total_cells;
 
326
        }
 
327
 
 
328
        for (i=0; i<total_cells; i++) {
 
329
                float alpha = a[i];
 
330
                if (alpha) {
 
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;
 
334
                }
 
335
                else {
 
336
                        data[i*m  ] = data[i*m+i_g] = data[i*m+i_b] = 0.0f;
 
337
                }
 
338
                data[i*m+i_a] = alpha;
 
339
        }
 
340
}
 
341
 
 
342
extern "C" void smoke_get_rgba_from_density(FLUID_3D *fluid, float color[3], float *data, int sequential)
 
343
{
 
344
        get_rgba_from_density(color, fluid->_density, fluid->_totalCells, data, sequential);
 
345
}
 
346
 
 
347
extern "C" void smoke_turbulence_get_rgba_from_density(WTURBULENCE *wt, float color[3], float *data, int sequential)
 
348
{
 
349
        get_rgba_from_density(color, wt->_densityBig, wt->_totalCellsBig, data, sequential);
 
350
}
 
351
 
289
352
extern "C" float *smoke_turbulence_get_density(WTURBULENCE *wt)
290
353
{
291
354
        return wt ? wt->getDensityBig() : NULL;
292
355
}
293
356
 
 
357
extern "C" float *smoke_turbulence_get_fuel(WTURBULENCE *wt)
 
358
{
 
359
        return wt ? wt->getFuelBig() : NULL;
 
360
}
 
361
 
 
362
extern "C" float *smoke_turbulence_get_react(WTURBULENCE *wt)
 
363
{
 
364
        return wt ? wt->_reactBig : NULL;
 
365
}
 
366
 
 
367
extern "C" float *smoke_turbulence_get_color_r(WTURBULENCE *wt)
 
368
{
 
369
        return wt ? wt->_color_rBig : NULL;
 
370
}
 
371
 
 
372
extern "C" float *smoke_turbulence_get_color_g(WTURBULENCE *wt)
 
373
{
 
374
        return wt ? wt->_color_gBig : NULL;
 
375
}
 
376
 
 
377
extern "C" float *smoke_turbulence_get_color_b(WTURBULENCE *wt)
 
378
{
 
379
        return wt ? wt->_color_bBig : NULL;
 
380
}
 
381
 
 
382
extern "C" float *smoke_turbulence_get_flame(WTURBULENCE *wt)
 
383
{
 
384
        return wt ? wt->getFlameBig() : NULL;
 
385
}
 
386
 
294
387
extern "C" void smoke_turbulence_get_res(WTURBULENCE *wt, int *res)
295
388
{
296
 
        if(wt)
297
 
        {
 
389
        if (wt) {
298
390
                Vec3Int r = wt->getResBig();
299
391
                res[0] = r[0];
300
392
                res[1] = r[1];
302
394
        }
303
395
}
304
396
 
 
397
extern "C" int smoke_turbulence_get_cells(WTURBULENCE *wt)
 
398
{
 
399
        if (wt) {
 
400
                Vec3Int r = wt->getResBig();
 
401
                return r[0] * r[1] * r[2];
 
402
        }
 
403
        return 0;
 
404
}
 
405
 
305
406
extern "C" unsigned char *smoke_get_obstacle(FLUID_3D *fluid)
306
407
{
307
408
        return fluid->_obstacles;
308
409
}
309
410
 
 
411
extern "C" void smoke_get_ob_velocity(FLUID_3D *fluid, float **x, float **y, float **z)
 
412
{
 
413
        *x = fluid->_xVelocityOb;
 
414
        *y = fluid->_yVelocityOb;
 
415
        *z = fluid->_zVelocityOb;
 
416
}
 
417
 
 
418
#if 0
 
419
extern "C" unsigned char *smoke_get_obstacle_anim(FLUID_3D *fluid)
 
420
{
 
421
        return fluid->_obstaclesAnim;
 
422
}
 
423
#endif
 
424
 
310
425
extern "C" void smoke_turbulence_set_noise(WTURBULENCE *wt, int type)
311
426
{
312
427
        wt->setNoise(type);
313
428
}
 
429
 
 
430
extern "C" void flame_get_spectrum(unsigned char *spec, int width, float t1, float t2)
 
431
{
 
432
        spectrum(t1, t2, width, spec);
 
433
}
 
434
 
 
435
extern "C" int smoke_has_heat(FLUID_3D *fluid)
 
436
{
 
437
        return (fluid->_heat) ? 1 : 0;
 
438
}
 
439
 
 
440
extern "C" int smoke_has_fuel(FLUID_3D *fluid)
 
441
{
 
442
        return (fluid->_fuel) ? 1 : 0;
 
443
}
 
444
 
 
445
extern "C" int smoke_has_colors(FLUID_3D *fluid)
 
446
{
 
447
        return (fluid->_color_r && fluid->_color_g && fluid->_color_b) ? 1 : 0;
 
448
}
 
449
 
 
450
extern "C" int smoke_turbulence_has_fuel(WTURBULENCE *wt)
 
451
{
 
452
        return (wt->_fuelBig) ? 1 : 0;
 
453
}
 
454
 
 
455
extern "C" int smoke_turbulence_has_colors(WTURBULENCE *wt)
 
456
{
 
457
        return (wt->_color_rBig && wt->_color_gBig && wt->_color_bBig) ? 1 : 0;
 
458
}
 
459
 
 
460
/* additional field initialization */
 
461
extern "C" void smoke_ensure_heat(FLUID_3D *fluid)
 
462
{
 
463
        if (fluid) {
 
464
                fluid->initHeat();
 
465
        }
 
466
}
 
467
 
 
468
extern "C" void smoke_ensure_fire(FLUID_3D *fluid, WTURBULENCE *wt)
 
469
{
 
470
        if (fluid) {
 
471
                fluid->initFire();
 
472
        }
 
473
        if (wt) {
 
474
                wt->initFire();
 
475
        }
 
476
}
 
477
 
 
478
extern "C" void smoke_ensure_colors(FLUID_3D *fluid, WTURBULENCE *wt, float init_r, float init_g, float init_b)
 
479
{
 
480
        if (fluid) {
 
481
                fluid->initColors(init_r, init_g, init_b);
 
482
        }
 
483
        if (wt) {
 
484
                wt->initColors(init_r, init_g, init_b);
 
485
        }
 
486
}