Smoke:
[blender.git] / intern / smoke / intern / smoke_API.cpp
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2009 by Daniel Genrich
21  * All rights reserved.
22  *
23  * Contributor(s): Daniel Genrich
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 #include "FLUID_3D.h"
29 #include "WTURBULENCE.h"
30
31 #include <stdio.h>
32 #include <stdlib.h>
33
34 // y in smoke is z in blender
35 extern "C" FLUID_3D *smoke_init(int *res, float *p0, float dt)
36 {
37         // smoke lib uses y as top-bottom/vertical axis where blender uses z
38         FLUID_3D *fluid = new FLUID_3D(res, p0, dt);
39
40         // printf("xres: %d, yres: %d, zres: %d\n", res[0], res[1], res[2]);
41
42         return fluid;
43 }
44
45 extern "C" WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype)
46 {
47         // initialize wavelet turbulence
48         if(amplify)
49                 return new WTURBULENCE(res[0],res[1],res[2], amplify, noisetype);
50         else 
51                 return NULL;
52 }
53
54 extern "C" void smoke_free(FLUID_3D *fluid)
55 {
56         delete fluid;
57         fluid = NULL;
58 }
59
60 extern "C" void smoke_turbulence_free(WTURBULENCE *wt)
61 {
62          delete wt;
63          wt = NULL;
64 }
65
66 extern "C" size_t smoke_get_index(int x, int max_x, int y, int max_y, int z /*, int max_z */)
67 {
68         // // const int index = x + y * smd->res[0] + z * smd->res[0]*smd->res[1];
69         return x + y * max_x + z * max_x*max_y;
70 }
71
72 extern "C" size_t smoke_get_index2d(int x, int max_x, int y /*, int max_y, int z, int max_z */)
73 {
74         return x + y * max_x;
75 }
76
77 extern "C" void smoke_step(FLUID_3D *fluid, size_t framenr)
78 {
79         fluid->step();
80 }
81
82 extern "C" void smoke_turbulence_step(WTURBULENCE *wt, FLUID_3D *fluid)
83 {
84         wt->stepTurbulenceFull(fluid->_dt/fluid->_dx, fluid->_xVelocity, fluid->_yVelocity, fluid->_zVelocity, fluid->_obstacles); 
85 }
86
87 extern "C" void smoke_initBlenderRNA(FLUID_3D *fluid, float *alpha, float *beta)
88 {
89         fluid->initBlenderRNA(alpha, beta);
90 }
91
92 extern "C" void smoke_dissolve(FLUID_3D *fluid, int speed, int log)
93 {
94         float *density = fluid->_density;
95         //float *densityOld = fluid->_densityOld;
96         float *heat = fluid->_heat;
97
98         if(log)
99         {
100                 /* max density/speed = dydx */
101                 float dydx = 1.0 / (float)speed;
102                 size_t size= fluid->_xRes * fluid->_yRes * fluid->_zRes;
103
104                 for(size_t i = 0; i < size; i++)
105                 {
106                         density[i] *= (1.0 - dydx);
107
108                         if(density[i] < 0.0f)
109                                 density[i] = 0.0f;
110
111                         heat[i] *= (1.0 - dydx);
112
113                         if(heat[i] < 0.0f)
114                                 heat[i] = 0.0f;
115                 }
116         }
117         else // linear falloff
118         {
119                 /* max density/speed = dydx */
120                 float dydx = 1.0 / (float)speed;
121                 size_t size= fluid->_xRes * fluid->_yRes * fluid->_zRes;
122
123                 for(size_t i = 0; i < size; i++)
124                 {
125                         density[i] -= dydx;
126
127                         if(density[i] < 0.0f)
128                                 density[i] = 0.0f;
129
130                         heat[i] -= dydx;
131
132                         if(heat[i] < 0.0f)
133                                 heat[i] = 0.0f;
134                                 
135                 }
136         }
137 }
138
139 extern "C" void smoke_dissolve_wavelet(WTURBULENCE *wt, int speed, int log)
140 {
141         float *density = wt->getDensityBig();
142         Vec3Int r = wt->getResBig();
143
144         if(log)
145         {
146                 /* max density/speed = dydx */
147                 float dydx = 1.0 / (float)speed;
148                 size_t size= r[0] * r[1] * r[2];
149
150                 for(size_t i = 0; i < size; i++)
151                 {
152                         density[i] *= (1.0 - dydx);
153
154                         if(density[i] < 0.0f)
155                                 density[i] = 0.0f;
156                 }
157         }
158         else // linear falloff
159         {
160                 /* max density/speed = dydx */
161                 float dydx = 1.0 / (float)speed;
162                 size_t size= r[0] * r[1] * r[2];
163
164                 for(size_t i = 0; i < size; i++)
165                 {
166                         density[i] -= dydx;
167
168                         if(density[i] < 0.0f)
169                                 density[i] = 0.0f;                              
170                 }
171         }
172 }
173
174 extern "C" void smoke_initWaveletBlenderRNA(WTURBULENCE *wt, float *strength)
175 {
176         wt->initBlenderRNA(strength);
177 }
178
179 template < class T > inline T ABS( T a ) {
180         return (0 < a) ? a : -a ;
181 }
182
183 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)
184 {
185         *dens = fluid->_density;
186         *densold = fluid->_densityOld;
187         *heat = fluid->_heat;
188         *heatold = fluid->_heatOld;
189         *vx = fluid->_xVelocity;
190         *vy = fluid->_yVelocity;
191         *vz = fluid->_zVelocity;
192         *vxold = fluid->_xVelocityOld;
193         *vyold = fluid->_yVelocityOld;
194         *vzold = fluid->_zVelocityOld;
195         *obstacles = fluid->_obstacles;
196         dt = &(fluid->_dt);
197         dx = &(fluid->_dx);
198
199 }
200
201 extern "C" void smoke_turbulence_export(WTURBULENCE *wt, float **dens, float **densold, float **tcu, float **tcv, float **tcw)
202 {
203         if(!wt)
204                 return;
205
206         *dens = wt->_densityBig;
207         *densold = wt->_densityBigOld;
208         *tcu = wt->_tcU;
209         *tcv = wt->_tcV;
210         *tcw = wt->_tcW;
211 }
212
213 extern "C" float *smoke_get_density(FLUID_3D *fluid)
214 {
215         return fluid->_density;
216 }
217
218 extern "C" float *smoke_get_heat(FLUID_3D *fluid)
219 {
220         return fluid->_heat;
221 }
222
223 extern "C" float *smoke_get_velocity_x(FLUID_3D *fluid)
224 {
225         return fluid->_xVelocity;
226 }
227
228 extern "C" float *smoke_get_velocity_y(FLUID_3D *fluid)
229 {
230         return fluid->_yVelocity;
231 }
232
233 extern "C" float *smoke_get_velocity_z(FLUID_3D *fluid)
234 {
235         return fluid->_zVelocity;
236 }
237
238 extern "C" float *smoke_turbulence_get_density(WTURBULENCE *wt)
239 {
240         return wt ? wt->getDensityBig() : NULL;
241 }
242
243 extern "C" void smoke_turbulence_get_res(WTURBULENCE *wt, int *res)
244 {
245         if(wt)
246         {
247                 Vec3Int r = wt->getResBig();
248                 res[0] = r[0];
249                 res[1] = r[1];
250                 res[2] = r[2];
251         }
252 }
253
254 extern "C" unsigned char *smoke_get_obstacle(FLUID_3D *fluid)
255 {
256         return fluid->_obstacles;
257 }
258
259 extern "C" void smoke_turbulence_set_noise(WTURBULENCE *wt, int type)
260 {
261         wt->setNoise(type);
262 }