Blender V4.3
draw_fluid.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2005 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10
11#include <cstring>
12
13#include "BLI_listbase.h"
14#include "BLI_utildefines.h"
15
16#include "DNA_fluid_types.h"
17#include "DNA_modifier_types.h"
18
19#include "MEM_guardedalloc.h"
20
21#include "BKE_colorband.hh"
22
24
25#include "GPU_texture.hh"
26
27#include "draw_manager_c.hh"
28
29#include "draw_common_c.hh" /* Own include. */
30
31#ifdef WITH_FLUID
32# include "manta_fluid_API.h"
33#endif
34
35/* -------------------------------------------------------------------- */
38
39#ifdef WITH_FLUID
40
41enum {
42 TFUNC_FLAME_SPECTRUM = 0,
43 TFUNC_COLOR_RAMP = 1,
44};
45
46# define TFUNC_WIDTH 256
47
48static void create_flame_spectrum_texture(float *data)
49{
50# define FIRE_THRESH 7
51# define MAX_FIRE_ALPHA 0.06f
52# define FULL_ON_FIRE 100
53
54 float *spec_pixels = (float *)MEM_mallocN(TFUNC_WIDTH * 4 * 16 * 16 * sizeof(float),
55 "spec_pixels");
56
58
59 for (int i = 0; i < 16; i++) {
60 for (int j = 0; j < 16; j++) {
61 for (int k = 0; k < TFUNC_WIDTH; k++) {
62 int index = (j * TFUNC_WIDTH * 16 + i * TFUNC_WIDTH + k) * 4;
63 if (k >= FIRE_THRESH) {
64 spec_pixels[index] = (data[k * 4]);
65 spec_pixels[index + 1] = (data[k * 4 + 1]);
66 spec_pixels[index + 2] = (data[k * 4 + 2]);
67 spec_pixels[index + 3] = MAX_FIRE_ALPHA *
68 ((k > FULL_ON_FIRE) ?
69 1.0f :
70 (k - FIRE_THRESH) / (float(FULL_ON_FIRE) - FIRE_THRESH));
71 }
72 else {
73 zero_v4(&spec_pixels[index]);
74 }
75 }
76 }
77 }
78
79 memcpy(data, spec_pixels, sizeof(float) * 4 * TFUNC_WIDTH);
80
81 MEM_freeN(spec_pixels);
82
83# undef FIRE_THRESH
84# undef MAX_FIRE_ALPHA
85# undef FULL_ON_FIRE
86}
87
88static void create_color_ramp(const ColorBand *coba, float *data)
89{
90 for (int i = 0; i < TFUNC_WIDTH; i++) {
91 BKE_colorband_evaluate(coba, float(i) / TFUNC_WIDTH, &data[i * 4]);
93 }
94}
95
96static GPUTexture *create_transfer_function(int type, const ColorBand *coba)
97{
98 float *data = (float *)MEM_mallocN(sizeof(float[4]) * TFUNC_WIDTH, __func__);
99
100 switch (type) {
101 case TFUNC_FLAME_SPECTRUM:
102 create_flame_spectrum_texture(data);
103 break;
104 case TFUNC_COLOR_RAMP:
105 create_color_ramp(coba, data);
106 break;
107 }
108
109 GPUTexture *tex = GPU_texture_create_1d(
110 "transf_func", TFUNC_WIDTH, 1, GPU_SRGB8_A8, GPU_TEXTURE_USAGE_SHADER_READ, data);
111
113
114 return tex;
115}
116
117static void swizzle_texture_channel_single(GPUTexture *tex)
118{
119 /* Swizzle texture channels so that we get useful RGBA values when sampling
120 * a texture with fewer channels, e.g. when using density as color. */
121 GPU_texture_swizzle_set(tex, "rrr1");
122}
123
124static float *rescale_3d(const int dim[3],
125 const int final_dim[3],
126 int channels,
127 const float *fpixels)
128{
129 const uint w = dim[0], h = dim[1], d = dim[2];
130 const uint fw = final_dim[0], fh = final_dim[1], fd = final_dim[2];
131 const uint xf = w / fw, yf = h / fh, zf = d / fd;
132 const uint pixel_count = fw * fh * fd;
133 float *nfpixels = (float *)MEM_mallocN(channels * sizeof(float) * pixel_count, __func__);
134
135 if (nfpixels) {
136 printf("Performance: You need to scale a 3D texture, feel the pain!\n");
137
138 for (uint k = 0; k < fd; k++) {
139 for (uint j = 0; j < fh; j++) {
140 for (uint i = 0; i < fw; i++) {
141 /* Obviously doing nearest filtering here,
142 * it's going to be slow in any case, let's not make it worse. */
143 float xb = i * xf;
144 float yb = j * yf;
145 float zb = k * zf;
146 uint offset = k * (fw * fh) + i * fh + j;
147 uint offset_orig = (zb) * (w * h) + (xb)*h + (yb);
148
149 if (channels == 4) {
150 nfpixels[offset * 4] = fpixels[offset_orig * 4];
151 nfpixels[offset * 4 + 1] = fpixels[offset_orig * 4 + 1];
152 nfpixels[offset * 4 + 2] = fpixels[offset_orig * 4 + 2];
153 nfpixels[offset * 4 + 3] = fpixels[offset_orig * 4 + 3];
154 }
155 else if (channels == 1) {
156 nfpixels[offset] = fpixels[offset_orig];
157 }
158 else {
159 BLI_assert(0);
160 }
161 }
162 }
163 }
164 }
165 return nfpixels;
166}
167
168/* Will resize input to fit GL system limits. */
169static GPUTexture *create_volume_texture(const int dim[3],
170 eGPUTextureFormat texture_format,
171 eGPUDataFormat data_format,
172 const void *data)
173{
174 GPUTexture *tex = nullptr;
175 int final_dim[3] = {UNPACK3(dim)};
176
177 if (data == nullptr) {
178 return nullptr;
179 }
180
181 while (true) {
183 "volume", UNPACK3(final_dim), 1, texture_format, GPU_TEXTURE_USAGE_SHADER_READ, nullptr);
184
185 if (tex != nullptr) {
186 break;
187 }
188
189 if (final_dim[0] == 1 && final_dim[1] == 1 && final_dim[2] == 1) {
190 break;
191 }
192
193 for (int i = 0; i < 3; i++) {
194 final_dim[i] = max_ii(1, final_dim[i] / 2);
195 }
196 }
197
198 if (tex == nullptr) {
199 printf("Error: Could not create 3D texture.\n");
200 tex = GPU_texture_create_error(3, false);
201 }
202 else if (equals_v3v3_int(dim, final_dim)) {
203 /* No need to resize, just upload the data. */
204 GPU_texture_update_sub(tex, data_format, data, 0, 0, 0, UNPACK3(final_dim));
205 }
206 else if (data_format != GPU_DATA_FLOAT) {
207 printf("Error: Could not allocate 3D texture and not attempting to rescale non-float data.\n");
208 tex = GPU_texture_create_error(3, false);
209 }
210 else {
211 /* We need to resize the input. */
212 int channels = ELEM(texture_format, GPU_R8, GPU_R16F, GPU_R32F) ? 1 : 4;
213 float *rescaled_data = rescale_3d(dim, final_dim, channels, static_cast<const float *>(data));
214 if (rescaled_data) {
215 GPU_texture_update_sub(tex, GPU_DATA_FLOAT, rescaled_data, 0, 0, 0, UNPACK3(final_dim));
216 MEM_freeN(rescaled_data);
217 }
218 else {
219 printf("Error: Could not allocate rescaled 3d texture!\n");
220 GPU_texture_free(tex);
221 tex = GPU_texture_create_error(3, false);
222 }
223 }
224 return tex;
225}
226
227static GPUTexture *create_field_texture(FluidDomainSettings *fds, bool single_precision)
228{
229 void *field = nullptr;
230 eGPUDataFormat data_format = GPU_DATA_FLOAT;
231 eGPUTextureFormat texture_format = GPU_R8;
232
233 if (single_precision) {
234 texture_format = GPU_R32F;
235 }
236
237 switch (fds->coba_field) {
239 field = manta_smoke_get_density(fds->fluid);
240 break;
242 field = manta_smoke_get_heat(fds->fluid);
243 break;
245 field = manta_smoke_get_fuel(fds->fluid);
246 break;
248 field = manta_smoke_get_react(fds->fluid);
249 break;
251 field = manta_smoke_get_flame(fds->fluid);
252 break;
254 field = manta_get_velocity_x(fds->fluid);
255 break;
257 field = manta_get_velocity_y(fds->fluid);
258 break;
260 field = manta_get_velocity_z(fds->fluid);
261 break;
263 field = manta_smoke_get_color_r(fds->fluid);
264 break;
266 field = manta_smoke_get_color_g(fds->fluid);
267 break;
269 field = manta_smoke_get_color_b(fds->fluid);
270 break;
272 field = manta_get_force_x(fds->fluid);
273 break;
275 field = manta_get_force_y(fds->fluid);
276 break;
278 field = manta_get_force_z(fds->fluid);
279 break;
281 field = manta_get_phi(fds->fluid);
282 texture_format = GPU_R16F;
283 break;
285 field = manta_get_phi_in(fds->fluid);
286 texture_format = GPU_R16F;
287 break;
289 field = manta_get_phiout_in(fds->fluid);
290 texture_format = GPU_R16F;
291 break;
293 field = manta_get_phiobs_in(fds->fluid);
294 texture_format = GPU_R16F;
295 break;
297 field = manta_smoke_get_flags(fds->fluid);
298 data_format = GPU_DATA_INT;
299 texture_format = GPU_R8UI;
300 break;
302 field = manta_get_pressure(fds->fluid);
303 texture_format = GPU_R16F;
304 break;
305 default:
306 return nullptr;
307 }
308
309 if (field == nullptr) {
310 return nullptr;
311 }
312
313 GPUTexture *tex = create_volume_texture(fds->res, texture_format, data_format, field);
314 swizzle_texture_channel_single(tex);
315 return tex;
316}
317
318static GPUTexture *create_density_texture(FluidDomainSettings *fds, int highres)
319{
320 int *dim = (highres) ? fds->res_noise : fds->res;
321
322 float *data;
323 if (highres) {
325 }
326 else {
328 }
329
330 if (data == nullptr) {
331 return nullptr;
332 }
333
334 GPUTexture *tex = create_volume_texture(dim, GPU_R8, GPU_DATA_FLOAT, data);
335 swizzle_texture_channel_single(tex);
336 return tex;
337}
338
339static GPUTexture *create_color_texture(FluidDomainSettings *fds, int highres)
340{
341 const bool has_color = (highres) ? manta_noise_has_colors(fds->fluid) :
343
344 if (!has_color) {
345 return nullptr;
346 }
347
348 int cell_count = (highres) ? manta_noise_get_cells(fds->fluid) : fds->total_cells;
349 int *dim = (highres) ? fds->res_noise : fds->res;
350 float *data = (float *)MEM_callocN(sizeof(float) * cell_count * 4, "smokeColorTexture");
351
352 if (data == nullptr) {
353 return nullptr;
354 }
355
356 if (highres) {
358 }
359 else {
361 }
362
363 GPUTexture *tex = create_volume_texture(dim, GPU_RGBA8, GPU_DATA_FLOAT, data);
364
366
367 return tex;
368}
369
370static GPUTexture *create_flame_texture(FluidDomainSettings *fds, int highres)
371{
372 float *source = nullptr;
373 const bool has_fuel = (highres) ? manta_noise_has_fuel(fds->fluid) :
375 int *dim = (highres) ? fds->res_noise : fds->res;
376
377 if (!has_fuel) {
378 return nullptr;
379 }
380
381 if (highres) {
382 source = manta_noise_get_flame(fds->fluid);
383 }
384 else {
385 source = manta_smoke_get_flame(fds->fluid);
386 }
387
388 GPUTexture *tex = create_volume_texture(dim, GPU_R8, GPU_DATA_FLOAT, source);
389 swizzle_texture_channel_single(tex);
390 return tex;
391}
392
393static bool get_smoke_velocity_field(FluidDomainSettings *fds,
394 float **r_velocity_x,
395 float **r_velocity_y,
396 float **r_velocity_z)
397{
398 const char vector_field = fds->vector_field;
399 switch ((FLUID_DisplayVectorField)vector_field) {
401 *r_velocity_x = manta_get_velocity_x(fds->fluid);
402 *r_velocity_y = manta_get_velocity_y(fds->fluid);
403 *r_velocity_z = manta_get_velocity_z(fds->fluid);
404 break;
406 *r_velocity_x = manta_get_guide_velocity_x(fds->fluid);
407 *r_velocity_y = manta_get_guide_velocity_y(fds->fluid);
408 *r_velocity_z = manta_get_guide_velocity_z(fds->fluid);
409 break;
411 *r_velocity_x = manta_get_force_x(fds->fluid);
412 *r_velocity_y = manta_get_force_y(fds->fluid);
413 *r_velocity_z = manta_get_force_z(fds->fluid);
414 break;
415 }
416
417 return *r_velocity_x && *r_velocity_y && *r_velocity_z;
418}
419
420#endif /* WITH_FLUID */
421
423
424/* -------------------------------------------------------------------- */
427
429{
430#ifndef WITH_FLUID
431 UNUSED_VARS(fmd);
432#else
433 if (fmd->type & MOD_FLUID_TYPE_DOMAIN) {
434 FluidDomainSettings *fds = fmd->domain;
435
436 if (!fds->tex_field) {
437 fds->tex_field = create_field_texture(fds, false);
438 BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_field));
439 }
440 if (!fds->tex_coba && !ELEM(fds->coba_field,
447 {
448 fds->tex_coba = create_transfer_function(TFUNC_COLOR_RAMP, fds->coba);
449 BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_coba));
450 }
451 }
452#endif
453}
454
455void DRW_smoke_ensure(FluidModifierData *fmd, int highres)
456{
457#ifndef WITH_FLUID
458 UNUSED_VARS(fmd, highres);
459#else
460 if (fmd->type & MOD_FLUID_TYPE_DOMAIN) {
461 FluidDomainSettings *fds = fmd->domain;
462
463 if (!fds->tex_density) {
464 fds->tex_density = create_density_texture(fds, highres);
465 BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_density));
466 }
467 if (!fds->tex_color) {
468 fds->tex_color = create_color_texture(fds, highres);
469 BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_color));
470 }
471 if (!fds->tex_flame) {
472 fds->tex_flame = create_flame_texture(fds, highres);
473 BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_flame));
474 }
475 if (!fds->tex_flame_coba && fds->tex_flame) {
476 fds->tex_flame_coba = create_transfer_function(TFUNC_FLAME_SPECTRUM, nullptr);
477 BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_flame_coba));
478 }
479 if (!fds->tex_shadow) {
480 fds->tex_shadow = create_volume_texture(
482 BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_shadow));
483 }
484 }
485#endif /* WITH_FLUID */
486}
487
489{
490#ifndef WITH_FLUID
491 UNUSED_VARS(fmd);
492#else
493 if (fmd->type & MOD_FLUID_TYPE_DOMAIN) {
494 FluidDomainSettings *fds = fmd->domain;
495 float *vel_x = nullptr, *vel_y = nullptr, *vel_z = nullptr;
496
497 if (!get_smoke_velocity_field(fds, &vel_x, &vel_y, &vel_z)) {
499 get_smoke_velocity_field(fds, &vel_x, &vel_y, &vel_z);
500 }
501
502 if (ELEM(nullptr, vel_x, vel_y, vel_z)) {
503 return;
504 }
505
506 if (!fds->tex_velocity_x) {
508 "velx", UNPACK3(fds->res), 1, GPU_R16F, GPU_TEXTURE_USAGE_SHADER_READ, vel_x);
510 "vely", UNPACK3(fds->res), 1, GPU_R16F, GPU_TEXTURE_USAGE_SHADER_READ, vel_y);
512 "velz", UNPACK3(fds->res), 1, GPU_R16F, GPU_TEXTURE_USAGE_SHADER_READ, vel_z);
513 BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_velocity_x));
514 BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_velocity_y));
515 BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_velocity_z));
516 }
517 }
518#endif /* WITH_FLUID */
519}
520
522{
523#ifndef WITH_FLUID
524 UNUSED_VARS(fmd);
525#else
526 if (fmd->type & MOD_FLUID_TYPE_DOMAIN) {
527 FluidDomainSettings *fds = fmd->domain;
528 if (!fds->tex_flags) {
529 fds->tex_flags = create_volume_texture(
531 BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_flags));
532
533 swizzle_texture_channel_single(fds->tex_flags);
534 }
535 }
536#endif /* WITH_FLUID */
537}
538
540{
541#ifndef WITH_FLUID
542 UNUSED_VARS(fmd);
543#else
544 if (fmd->type & MOD_FLUID_TYPE_DOMAIN) {
545 FluidDomainSettings *fds = fmd->domain;
546
547 if (!fds->tex_range_field) {
548 fds->tex_range_field = create_field_texture(fds, true);
549 BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_range_field));
550 }
551 }
552#endif /* WITH_FLUID */
553}
554
555void DRW_smoke_init(DRWData *drw_data)
556{
558}
559
560void DRW_smoke_exit(DRWData *drw_data)
561{
562 /* Free Smoke Textures after rendering */
563 /* XXX This is a waste of processing and GPU bandwidth if nothing
564 * is updated. But the problem is since Textures are stored in the
565 * modifier we don't want them to take precious VRAM if the
566 * modifier is not used for display. We should share them for
567 * all viewport in a redraw at least. */
568 LISTBASE_FOREACH (LinkData *, link, &drw_data->smoke_textures) {
569 GPU_TEXTURE_FREE_SAFE(*(GPUTexture **)link->data);
570 }
571 BLI_freelistN(&drw_data->smoke_textures);
572}
573
bool BKE_colorband_evaluate(const ColorBand *coba, float in, float out[4])
Definition colorband.cc:396
#define BLI_assert(a)
Definition BLI_assert.h:50
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:496
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
struct LinkData * BLI_genericNodeN(void *data)
Definition listbase.cc:909
MINLINE int max_ii(int a, int b)
MINLINE void straight_to_premul_v4(float color[4])
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
#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
GPUTexture * GPU_texture_create_1d(const char *name, int width, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
void GPU_texture_free(GPUTexture *texture)
GPUTexture * GPU_texture_create_error(int dimension, bool array)
eGPUDataFormat
@ GPU_DATA_INT
@ GPU_DATA_FLOAT
@ GPU_TEXTURE_USAGE_SHADER_READ
void GPU_texture_update_sub(GPUTexture *texture, eGPUDataFormat data_format, const void *pixels, int offset_x, int offset_y, int offset_z, int width, int height, int depth)
GPUTexture * GPU_texture_create_3d(const char *name, int width, int height, int depth, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const void *data)
#define GPU_TEXTURE_FREE_SAFE(texture)
eGPUTextureFormat
@ GPU_SRGB8_A8
@ GPU_R8UI
@ GPU_R8
void GPU_texture_swizzle_set(GPUTexture *texture, const char swizzle[4])
void IMB_colormanagement_blackbody_temperature_to_rgb_table(float *r_table, int width, float min, float max)
Read Guarded memory(de)allocation.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a producing a negative Combine Generate a color from its and blue channels(Deprecated)") DefNode(ShaderNode
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
#define printf
void DRW_fluid_ensure_flags(FluidModifierData *fmd)
void DRW_smoke_ensure_coba_field(FluidModifierData *fmd)
void DRW_fluid_ensure_range_field(FluidModifierData *fmd)
void DRW_smoke_ensure(FluidModifierData *fmd, int highres)
void DRW_smoke_ensure_velocity(FluidModifierData *fmd)
void DRW_smoke_exit(DRWData *drw_data)
void DRW_smoke_init(DRWData *drw_data)
DRWManager DST
draw_view in_light_buf[] float
RAYTRACE_GROUP_SIZE additional_info("eevee_shared", "eevee_gbuffer_data", "eevee_global_ubo", "eevee_sampling_data", "eevee_utility_texture", "eevee_hiz_data", "draw_view") .specialization_constant(Type RAYTRACE_GROUP_SIZE in_sh_0_tx in_sh_2_tx screen_normal_tx GPU_RGBA8
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
float * manta_noise_get_density(struct MANTA *smoke)
float * manta_smoke_get_color_r(struct MANTA *smoke)
float * manta_get_force_z(struct MANTA *fluid)
bool manta_noise_has_colors(struct MANTA *smoke)
float * manta_get_force_y(struct MANTA *fluid)
float * manta_get_guide_velocity_y(struct MANTA *fluid)
float * manta_smoke_get_react(struct MANTA *smoke)
float * manta_smoke_get_shadow(struct MANTA *fluid)
float * manta_get_guide_velocity_z(struct MANTA *fluid)
float * manta_get_guide_velocity_x(struct MANTA *fluid)
void manta_noise_get_rgba(struct MANTA *smoke, float *data, int sequential)
float * manta_get_velocity_y(struct MANTA *fluid)
bool manta_noise_has_fuel(struct MANTA *smoke)
float * manta_get_force_x(struct MANTA *fluid)
float * manta_smoke_get_density(struct MANTA *smoke)
float * manta_get_phi(struct MANTA *fluid)
float * manta_get_phi_in(struct MANTA *fluid)
float * manta_get_velocity_z(struct MANTA *fluid)
bool manta_smoke_has_colors(struct MANTA *smoke)
float * manta_get_phiout_in(struct MANTA *fluid)
float * manta_get_phiobs_in(struct MANTA *fluid)
int * manta_smoke_get_flags(struct MANTA *smoke)
float * manta_get_velocity_x(struct MANTA *fluid)
bool manta_smoke_has_fuel(struct MANTA *smoke)
float * manta_get_pressure(struct MANTA *fluid)
float * manta_smoke_get_color_g(struct MANTA *smoke)
int manta_noise_get_cells(struct MANTA *smoke)
float * manta_smoke_get_heat(struct MANTA *smoke)
float * manta_smoke_get_color_b(struct MANTA *smoke)
void manta_smoke_get_rgba(struct MANTA *smoke, float *data, int sequential)
float * manta_smoke_get_fuel(struct MANTA *smoke)
float * manta_smoke_get_flame(struct MANTA *smoke)
float * manta_noise_get_flame(struct MANTA *smoke)
void index(const bNode &, void *r_value)
ListBase smoke_textures
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 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