Blender  V2.93
draw_fluid.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2005 Blender Foundation.
17  * All rights reserved.
18  */
19 
26 #include <string.h>
27 
28 #include "BLI_math.h"
29 #include "BLI_utildefines.h"
30 
31 #include "DNA_fluid_types.h"
32 #include "DNA_modifier_types.h"
33 
34 #include "MEM_guardedalloc.h"
35 
36 #include "BKE_colorband.h"
37 
38 #include "GPU_texture.h"
39 
40 #include "draw_common.h" /* Own include. */
41 
42 #ifdef WITH_FLUID
43 # include "manta_fluid_API.h"
44 #endif
45 
46 /* -------------------------------------------------------------------- */
50 #ifdef WITH_FLUID
51 
52 enum {
53  TFUNC_FLAME_SPECTRUM = 0,
54  TFUNC_COLOR_RAMP = 1,
55 };
56 
57 # define TFUNC_WIDTH 256
58 
59 static void create_flame_spectrum_texture(float *data)
60 {
61 # define FIRE_THRESH 7
62 # define MAX_FIRE_ALPHA 0.06f
63 # define FULL_ON_FIRE 100
64 
65  float *spec_pixels = (float *)MEM_mallocN(TFUNC_WIDTH * 4 * 16 * 16 * sizeof(float),
66  "spec_pixels");
67 
68  blackbody_temperature_to_rgb_table(data, TFUNC_WIDTH, 1500, 3000);
69 
70  for (int i = 0; i < 16; i++) {
71  for (int j = 0; j < 16; j++) {
72  for (int k = 0; k < TFUNC_WIDTH; k++) {
73  int index = (j * TFUNC_WIDTH * 16 + i * TFUNC_WIDTH + k) * 4;
74  if (k >= FIRE_THRESH) {
75  spec_pixels[index] = (data[k * 4]);
76  spec_pixels[index + 1] = (data[k * 4 + 1]);
77  spec_pixels[index + 2] = (data[k * 4 + 2]);
78  spec_pixels[index + 3] = MAX_FIRE_ALPHA *
79  ((k > FULL_ON_FIRE) ?
80  1.0f :
81  (k - FIRE_THRESH) / ((float)FULL_ON_FIRE - FIRE_THRESH));
82  }
83  else {
84  zero_v4(&spec_pixels[index]);
85  }
86  }
87  }
88  }
89 
90  memcpy(data, spec_pixels, sizeof(float) * 4 * TFUNC_WIDTH);
91 
92  MEM_freeN(spec_pixels);
93 
94 # undef FIRE_THRESH
95 # undef MAX_FIRE_ALPHA
96 # undef FULL_ON_FIRE
97 }
98 
99 static void create_color_ramp(const struct ColorBand *coba, float *data)
100 {
101  for (int i = 0; i < TFUNC_WIDTH; i++) {
102  BKE_colorband_evaluate(coba, (float)i / TFUNC_WIDTH, &data[i * 4]);
103  straight_to_premul_v4(&data[i * 4]);
104  }
105 }
106 
107 static GPUTexture *create_transfer_function(int type, const struct ColorBand *coba)
108 {
109  float *data = (float *)MEM_mallocN(sizeof(float[4]) * TFUNC_WIDTH, __func__);
110 
111  switch (type) {
112  case TFUNC_FLAME_SPECTRUM:
113  create_flame_spectrum_texture(data);
114  break;
115  case TFUNC_COLOR_RAMP:
116  create_color_ramp(coba, data);
117  break;
118  }
119 
120  GPUTexture *tex = GPU_texture_create_1d("transf_func", TFUNC_WIDTH, 1, GPU_SRGB8_A8, data);
121 
122  MEM_freeN(data);
123 
124  return tex;
125 }
126 
127 static void swizzle_texture_channel_single(GPUTexture *tex)
128 {
129  /* Swizzle texture channels so that we get useful RGBA values when sampling
130  * a texture with fewer channels, e.g. when using density as color. */
131  GPU_texture_swizzle_set(tex, "rrr1");
132 }
133 
134 static float *rescale_3d(const int dim[3],
135  const int final_dim[3],
136  int channels,
137  const float *fpixels)
138 {
139  const uint w = dim[0], h = dim[1], d = dim[2];
140  const uint fw = final_dim[0], fh = final_dim[1], fd = final_dim[2];
141  const uint xf = w / fw, yf = h / fh, zf = d / fd;
142  const uint pixel_count = fw * fh * fd;
143  float *nfpixels = (float *)MEM_mallocN(channels * sizeof(float) * pixel_count, __func__);
144 
145  if (nfpixels) {
146  printf("Performance: You need to scale a 3D texture, feel the pain!\n");
147 
148  for (uint k = 0; k < fd; k++) {
149  for (uint j = 0; j < fh; j++) {
150  for (uint i = 0; i < fw; i++) {
151  /* Obviously doing nearest filtering here,
152  * it's going to be slow in any case, let's not make it worse. */
153  float xb = i * xf;
154  float yb = j * yf;
155  float zb = k * zf;
156  uint offset = k * (fw * fh) + i * fh + j;
157  uint offset_orig = (zb) * (w * h) + (xb)*h + (yb);
158 
159  if (channels == 4) {
160  nfpixels[offset * 4] = fpixels[offset_orig * 4];
161  nfpixels[offset * 4 + 1] = fpixels[offset_orig * 4 + 1];
162  nfpixels[offset * 4 + 2] = fpixels[offset_orig * 4 + 2];
163  nfpixels[offset * 4 + 3] = fpixels[offset_orig * 4 + 3];
164  }
165  else if (channels == 1) {
166  nfpixels[offset] = fpixels[offset_orig];
167  }
168  else {
169  BLI_assert(0);
170  }
171  }
172  }
173  }
174  }
175  return nfpixels;
176 }
177 
178 /* Will resize input to fit GL system limits. */
179 static GPUTexture *create_volume_texture(const int dim[3],
180  eGPUTextureFormat texture_format,
181  eGPUDataFormat data_format,
182  const void *data)
183 {
184  GPUTexture *tex = NULL;
185  int final_dim[3] = {UNPACK3(dim)};
186 
187  if (data == NULL) {
188  return NULL;
189  }
190 
191  while (1) {
193  "volume", UNPACK3(final_dim), 1, texture_format, data_format, NULL);
194 
195  if (tex != NULL) {
196  break;
197  }
198 
199  if (final_dim[0] == 1 && final_dim[1] == 1 && final_dim[2] == 1) {
200  break;
201  }
202 
203  for (int i = 0; i < 3; i++) {
204  final_dim[i] = max_ii(1, final_dim[i] / 2);
205  }
206  }
207 
208  if (tex == NULL) {
209  printf("Error: Could not create 3D texture.\n");
210  tex = GPU_texture_create_error(3, false);
211  }
212  else if (equals_v3v3_int(dim, final_dim)) {
213  /* No need to resize, just upload the data. */
214  GPU_texture_update_sub(tex, data_format, data, 0, 0, 0, UNPACK3(final_dim));
215  }
216  else if (data_format != GPU_DATA_FLOAT) {
217  printf("Error: Could not allocate 3D texture and not attempting to rescale non-float data.\n");
218  tex = GPU_texture_create_error(3, false);
219  }
220  else {
221  /* We need to resize the input. */
222  int channels = (ELEM(texture_format, GPU_R8, GPU_R16F, GPU_R32F)) ? 1 : 4;
223  float *rescaled_data = rescale_3d(dim, final_dim, channels, data);
224  if (rescaled_data) {
225  GPU_texture_update_sub(tex, GPU_DATA_FLOAT, rescaled_data, 0, 0, 0, UNPACK3(final_dim));
226  MEM_freeN(rescaled_data);
227  }
228  else {
229  printf("Error: Could not allocate rescaled 3d texture!\n");
231  tex = GPU_texture_create_error(3, false);
232  }
233  }
234  return tex;
235 }
236 
237 static GPUTexture *create_field_texture(FluidDomainSettings *fds, bool single_precision)
238 {
239  void *field = NULL;
240  eGPUDataFormat data_format = GPU_DATA_FLOAT;
241  eGPUTextureFormat texture_format = GPU_R8;
242 
243  if (single_precision) {
244  texture_format = GPU_R32F;
245  }
246 
247  switch (fds->coba_field) {
249  field = manta_smoke_get_density(fds->fluid);
250  break;
252  field = manta_smoke_get_heat(fds->fluid);
253  break;
255  field = manta_smoke_get_fuel(fds->fluid);
256  break;
258  field = manta_smoke_get_react(fds->fluid);
259  break;
261  field = manta_smoke_get_flame(fds->fluid);
262  break;
264  field = manta_get_velocity_x(fds->fluid);
265  break;
267  field = manta_get_velocity_y(fds->fluid);
268  break;
270  field = manta_get_velocity_z(fds->fluid);
271  break;
273  field = manta_smoke_get_color_r(fds->fluid);
274  break;
276  field = manta_smoke_get_color_g(fds->fluid);
277  break;
279  field = manta_smoke_get_color_b(fds->fluid);
280  break;
282  field = manta_get_force_x(fds->fluid);
283  break;
285  field = manta_get_force_y(fds->fluid);
286  break;
288  field = manta_get_force_z(fds->fluid);
289  break;
291  field = manta_get_phi(fds->fluid);
292  texture_format = GPU_R16F;
293  break;
295  field = manta_get_phi_in(fds->fluid);
296  texture_format = GPU_R16F;
297  break;
299  field = manta_get_phiout_in(fds->fluid);
300  texture_format = GPU_R16F;
301  break;
303  field = manta_get_phiobs_in(fds->fluid);
304  texture_format = GPU_R16F;
305  break;
307  field = manta_smoke_get_flags(fds->fluid);
308  data_format = GPU_DATA_INT;
309  texture_format = GPU_R8UI;
310  break;
312  field = manta_get_pressure(fds->fluid);
313  texture_format = GPU_R16F;
314  break;
315  default:
316  return NULL;
317  }
318 
319  if (field == NULL) {
320  return NULL;
321  }
322 
323  GPUTexture *tex = create_volume_texture(fds->res, texture_format, data_format, field);
324  swizzle_texture_channel_single(tex);
325  return tex;
326 }
327 
328 static GPUTexture *create_density_texture(FluidDomainSettings *fds, int highres)
329 {
330  int *dim = (highres) ? fds->res_noise : fds->res;
331 
332  float *data;
333  if (highres) {
335  }
336  else {
338  }
339 
340  if (data == NULL) {
341  return NULL;
342  }
343 
344  GPUTexture *tex = create_volume_texture(dim, GPU_R8, GPU_DATA_FLOAT, data);
345  swizzle_texture_channel_single(tex);
346  return tex;
347 }
348 
349 static GPUTexture *create_color_texture(FluidDomainSettings *fds, int highres)
350 {
351  const bool has_color = (highres) ? manta_noise_has_colors(fds->fluid) :
353 
354  if (!has_color) {
355  return NULL;
356  }
357 
358  int cell_count = (highres) ? manta_noise_get_cells(fds->fluid) : fds->total_cells;
359  int *dim = (highres) ? fds->res_noise : fds->res;
360  float *data = (float *)MEM_callocN(sizeof(float) * cell_count * 4, "smokeColorTexture");
361 
362  if (data == NULL) {
363  return NULL;
364  }
365 
366  if (highres) {
367  manta_noise_get_rgba(fds->fluid, data, 0);
368  }
369  else {
370  manta_smoke_get_rgba(fds->fluid, data, 0);
371  }
372 
373  GPUTexture *tex = create_volume_texture(dim, GPU_RGBA8, GPU_DATA_FLOAT, data);
374 
375  MEM_freeN(data);
376 
377  return tex;
378 }
379 
380 static GPUTexture *create_flame_texture(FluidDomainSettings *fds, int highres)
381 {
382  float *source = NULL;
383  const bool has_fuel = (highres) ? manta_noise_has_fuel(fds->fluid) :
385  int *dim = (highres) ? fds->res_noise : fds->res;
386 
387  if (!has_fuel) {
388  return NULL;
389  }
390 
391  if (highres) {
392  source = manta_noise_get_flame(fds->fluid);
393  }
394  else {
395  source = manta_smoke_get_flame(fds->fluid);
396  }
397 
398  GPUTexture *tex = create_volume_texture(dim, GPU_R8, GPU_DATA_FLOAT, source);
399  swizzle_texture_channel_single(tex);
400  return tex;
401 }
402 
403 static bool get_smoke_velocity_field(FluidDomainSettings *fds,
404  float **r_velocity_x,
405  float **r_velocity_y,
406  float **r_velocity_z)
407 {
408  const char vector_field = fds->vector_field;
409  switch ((FLUID_DisplayVectorField)vector_field) {
411  *r_velocity_x = manta_get_velocity_x(fds->fluid);
412  *r_velocity_y = manta_get_velocity_y(fds->fluid);
413  *r_velocity_z = manta_get_velocity_z(fds->fluid);
414  break;
416  *r_velocity_x = manta_get_guide_velocity_x(fds->fluid);
417  *r_velocity_y = manta_get_guide_velocity_y(fds->fluid);
418  *r_velocity_z = manta_get_guide_velocity_z(fds->fluid);
419  break;
421  *r_velocity_x = manta_get_force_x(fds->fluid);
422  *r_velocity_y = manta_get_force_y(fds->fluid);
423  *r_velocity_z = manta_get_force_z(fds->fluid);
424  break;
425  }
426 
427  return *r_velocity_x && *r_velocity_y && *r_velocity_z;
428 }
429 
430 #endif /* WITH_FLUID */
431 
434 /* -------------------------------------------------------------------- */
439 {
440  if (fmd->type & MOD_FLUID_TYPE_DOMAIN && fmd->domain) {
441  if (fmd->domain->tex_density) {
443  fmd->domain->tex_density = NULL;
444  }
445 
446  if (fmd->domain->tex_color) {
448  fmd->domain->tex_color = NULL;
449  }
450 
451  if (fmd->domain->tex_shadow) {
453  fmd->domain->tex_shadow = NULL;
454  }
455 
456  if (fmd->domain->tex_flame) {
458  fmd->domain->tex_flame = NULL;
459  }
460 
461  if (fmd->domain->tex_flame_coba) {
463  fmd->domain->tex_flame_coba = NULL;
464  }
465 
466  if (fmd->domain->tex_coba) {
468  fmd->domain->tex_coba = NULL;
469  }
470 
471  if (fmd->domain->tex_field) {
473  fmd->domain->tex_field = NULL;
474  }
475  }
476 }
477 
479 {
480 #ifndef WITH_FLUID
481  UNUSED_VARS(fmd);
482 #else
483  if (fmd->type & MOD_FLUID_TYPE_DOMAIN) {
484  FluidDomainSettings *fds = fmd->domain;
485 
486  if (!fds->tex_field) {
487  fds->tex_field = create_field_texture(fds, false);
488  }
489  if (!fds->tex_coba && !ELEM(fds->coba_field,
496  fds->tex_coba = create_transfer_function(TFUNC_COLOR_RAMP, fds->coba);
497  }
498  }
499 #endif
500 }
501 
502 void DRW_smoke_ensure(FluidModifierData *fmd, int highres)
503 {
504 #ifndef WITH_FLUID
505  UNUSED_VARS(fmd, highres);
506 #else
507  if (fmd->type & MOD_FLUID_TYPE_DOMAIN) {
508  FluidDomainSettings *fds = fmd->domain;
509 
510  if (!fds->tex_density) {
511  fds->tex_density = create_density_texture(fds, highres);
512  }
513  if (!fds->tex_color) {
514  fds->tex_color = create_color_texture(fds, highres);
515  }
516  if (!fds->tex_flame) {
517  fds->tex_flame = create_flame_texture(fds, highres);
518  }
519  if (!fds->tex_flame_coba && fds->tex_flame) {
520  fds->tex_flame_coba = create_transfer_function(TFUNC_FLAME_SPECTRUM, NULL);
521  }
522  if (!fds->tex_shadow) {
523  fds->tex_shadow = create_volume_texture(
525  }
526  }
527 #endif /* WITH_FLUID */
528 }
529 
531 {
532 #ifndef WITH_FLUID
533  UNUSED_VARS(fmd);
534 #else
535  if (fmd->type & MOD_FLUID_TYPE_DOMAIN) {
536  FluidDomainSettings *fds = fmd->domain;
537  float *vel_x = NULL, *vel_y = NULL, *vel_z = NULL;
538 
539  if (!get_smoke_velocity_field(fds, &vel_x, &vel_y, &vel_z)) {
541  get_smoke_velocity_field(fds, &vel_x, &vel_y, &vel_z);
542  }
543 
544  if (ELEM(NULL, vel_x, vel_y, vel_z)) {
545  return;
546  }
547 
548  if (!fds->tex_velocity_x) {
550  "velx", UNPACK3(fds->res), 1, GPU_R16F, GPU_DATA_FLOAT, vel_x);
552  "vely", UNPACK3(fds->res), 1, GPU_R16F, GPU_DATA_FLOAT, vel_y);
554  "velz", UNPACK3(fds->res), 1, GPU_R16F, GPU_DATA_FLOAT, vel_z);
555  }
556  }
557 #endif /* WITH_FLUID */
558 }
559 
561 {
562 #ifndef WITH_FLUID
563  UNUSED_VARS(fmd);
564 #else
565  if (fmd->type & MOD_FLUID_TYPE_DOMAIN) {
566  FluidDomainSettings *fds = fmd->domain;
567  if (!fds->tex_flags) {
568  fds->tex_flags = create_volume_texture(
570 
571  swizzle_texture_channel_single(fds->tex_flags);
572  }
573  }
574 #endif /* WITH_FLUID */
575 }
576 
578 {
579 #ifndef WITH_FLUID
580  UNUSED_VARS(fmd);
581 #else
582  if (fmd->type & MOD_FLUID_TYPE_DOMAIN) {
583  FluidDomainSettings *fds = fmd->domain;
584 
585  if (!fds->tex_range_field) {
586  fds->tex_range_field = create_field_texture(fds, true);
587  }
588  }
589 #endif /* WITH_FLUID */
590 }
591 
592 /* TODO Unify with the other GPU_free_smoke. */
594 {
595  if (fmd->type & MOD_FLUID_TYPE_DOMAIN && fmd->domain) {
596  if (fmd->domain->tex_velocity_x) {
598  }
599 
600  if (fmd->domain->tex_velocity_y) {
602  }
603 
604  if (fmd->domain->tex_velocity_z) {
606  }
607 
608  if (fmd->domain->tex_flags) {
610  }
611 
612  if (fmd->domain->tex_range_field) {
614  }
615 
616  fmd->domain->tex_velocity_x = NULL;
617  fmd->domain->tex_velocity_y = NULL;
618  fmd->domain->tex_velocity_z = NULL;
619  fmd->domain->tex_flags = NULL;
620  fmd->domain->tex_range_field = NULL;
621  }
622 }
623 
typedef float(TangentPoint)[2]
bool BKE_colorband_evaluate(const struct ColorBand *coba, float in, float out[4])
#define BLI_assert(a)
Definition: BLI_assert.h:58
MINLINE int max_ii(int a, int b)
MINLINE void straight_to_premul_v4(float color[4])
void blackbody_temperature_to_rgb_table(float *r_table, int width, float min, float max)
Definition: math_color.c:704
MINLINE bool equals_v3v3_int(const int v1[3], const int v2[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void zero_v4(float r[4])
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNUSED_VARS(...)
#define UNPACK3(a)
#define ELEM(...)
@ FLUID_DOMAIN_FIELD_COLOR_B
@ FLUID_DOMAIN_FIELD_FLAME
@ FLUID_DOMAIN_FIELD_REACT
@ FLUID_DOMAIN_FIELD_PHI_OUT
@ FLUID_DOMAIN_FIELD_FORCE_Z
@ FLUID_DOMAIN_FIELD_PHI_OBSTACLE
@ FLUID_DOMAIN_FIELD_FLAGS
@ FLUID_DOMAIN_FIELD_VELOCITY_Z
@ FLUID_DOMAIN_FIELD_FORCE_Y
@ FLUID_DOMAIN_FIELD_PHI
@ FLUID_DOMAIN_FIELD_PRESSURE
@ FLUID_DOMAIN_FIELD_VELOCITY_X
@ FLUID_DOMAIN_FIELD_DENSITY
@ FLUID_DOMAIN_FIELD_VELOCITY_Y
@ FLUID_DOMAIN_FIELD_PHI_IN
@ FLUID_DOMAIN_FIELD_HEAT
@ FLUID_DOMAIN_FIELD_COLOR_G
@ FLUID_DOMAIN_FIELD_FORCE_X
@ FLUID_DOMAIN_FIELD_FUEL
@ FLUID_DOMAIN_FIELD_COLOR_R
FLUID_DisplayVectorField
@ FLUID_DOMAIN_VECTOR_FIELD_FORCE
@ FLUID_DOMAIN_VECTOR_FIELD_VELOCITY
@ FLUID_DOMAIN_VECTOR_FIELD_GUIDE_VELOCITY
@ MOD_FLUID_TYPE_DOMAIN
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
void GPU_texture_swizzle_set(GPUTexture *tex, const char swizzle[4])
Definition: gpu_texture.cc:503
void GPU_texture_update_sub(GPUTexture *tex, eGPUDataFormat data_format, const void *pixels, int offset_x, int offset_y, int offset_z, int width, int height, int depth)
Definition: gpu_texture.cc:356
GPUTexture * GPU_texture_create_1d(const char *name, int w, int mip_len, eGPUTextureFormat format, const float *data)
Definition: gpu_texture.cc:237
struct GPUTexture GPUTexture
Definition: GPU_texture.h:33
eGPUDataFormat
Definition: GPU_texture.h:171
@ GPU_DATA_INT
Definition: GPU_texture.h:173
@ GPU_DATA_FLOAT
Definition: GPU_texture.h:172
void GPU_texture_free(GPUTexture *tex)
Definition: gpu_texture.cc:508
eGPUTextureFormat
Definition: GPU_texture.h:84
@ GPU_R32F
Definition: GPU_texture.h:111
@ GPU_SRGB8_A8
Definition: GPU_texture.h:122
@ GPU_R16F
Definition: GPU_texture.h:114
@ GPU_R8UI
Definition: GPU_texture.h:106
@ GPU_R8
Definition: GPU_texture.h:108
@ GPU_RGBA8
Definition: GPU_texture.h:88
GPUTexture * GPU_texture_create_3d(const char *name, int w, int h, int d, int mip_len, eGPUTextureFormat texture_format, eGPUDataFormat data_format, const void *data)
Definition: gpu_texture.cc:263
GPUTexture * GPU_texture_create_error(int dimension, bool array)
Definition: gpu_texture.cc:329
Read Guarded memory(de)allocation.
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
void DRW_fluid_ensure_flags(FluidModifierData *fmd)
Definition: draw_fluid.c:560
void DRW_smoke_ensure_coba_field(FluidModifierData *fmd)
Definition: draw_fluid.c:478
void DRW_fluid_ensure_range_field(FluidModifierData *fmd)
Definition: draw_fluid.c:577
void DRW_smoke_ensure(FluidModifierData *fmd, int highres)
Definition: draw_fluid.c:502
void DRW_smoke_ensure_velocity(FluidModifierData *fmd)
Definition: draw_fluid.c:530
void DRW_smoke_free_velocity(FluidModifierData *fmd)
Definition: draw_fluid.c:593
void DRW_smoke_free(FluidModifierData *fmd)
Definition: draw_fluid.c:438
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
float * manta_smoke_get_shadow(struct MANTA *fluid)
float * manta_smoke_get_color_g(struct MANTA *smoke)
float * manta_get_force_y(struct MANTA *fluid)
float * manta_get_phiobs_in(struct MANTA *fluid)
float * manta_smoke_get_color_b(struct MANTA *smoke)
float * manta_smoke_get_fuel(struct MANTA *smoke)
float * manta_smoke_get_heat(struct MANTA *smoke)
bool manta_noise_has_colors(struct MANTA *smoke)
float * manta_get_guide_velocity_z(struct MANTA *fluid)
float * manta_smoke_get_density(struct MANTA *smoke)
float * manta_smoke_get_color_r(struct MANTA *smoke)
float * manta_get_force_x(struct MANTA *fluid)
float * manta_get_velocity_x(struct MANTA *fluid)
float * manta_smoke_get_flame(struct MANTA *smoke)
int * manta_smoke_get_flags(struct MANTA *smoke)
float * manta_get_phi_in(struct MANTA *fluid)
float * manta_get_velocity_y(struct MANTA *fluid)
void manta_noise_get_rgba(struct MANTA *smoke, float *data, int sequential)
bool manta_noise_has_fuel(struct MANTA *smoke)
float * manta_get_phi(struct MANTA *fluid)
float * manta_get_force_z(struct MANTA *fluid)
float * manta_get_pressure(struct MANTA *fluid)
float * manta_noise_get_density(struct MANTA *smoke)
float * manta_get_guide_velocity_x(struct MANTA *fluid)
float * manta_get_phiout_in(struct MANTA *fluid)
float * manta_noise_get_flame(struct MANTA *smoke)
bool manta_smoke_has_colors(struct MANTA *smoke)
float * manta_get_velocity_z(struct MANTA *fluid)
bool manta_smoke_has_fuel(struct MANTA *smoke)
float * manta_smoke_get_react(struct MANTA *smoke)
int manta_noise_get_cells(struct MANTA *smoke)
float * manta_get_guide_velocity_y(struct MANTA *fluid)
void manta_smoke_get_rgba(struct MANTA *smoke, float *data, int sequential)
struct GPUTexture * tex_density
struct GPUTexture * tex_range_field
struct GPUTexture * tex_velocity_x
struct GPUTexture * tex_color
struct GPUTexture * tex_velocity_y
struct GPUTexture * tex_field
struct MANTA * fluid
struct GPUTexture * tex_velocity_z
struct GPUTexture * tex_shadow
struct ColorBand * coba
struct GPUTexture * tex_flags
struct GPUTexture * tex_coba
struct GPUTexture * tex_flame
struct GPUTexture * tex_flame_coba
struct FluidDomainSettings * domain