Blender V5.0
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
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 = MEM_malloc_arrayN<float>(TFUNC_WIDTH * 4 * 16 * 16, "spec_pixels");
55
57
58 for (int i = 0; i < 16; i++) {
59 for (int j = 0; j < 16; j++) {
60 for (int k = 0; k < TFUNC_WIDTH; k++) {
61 int index = (j * TFUNC_WIDTH * 16 + i * TFUNC_WIDTH + k) * 4;
62 if (k >= FIRE_THRESH) {
63 spec_pixels[index] = (data[k * 4]);
64 spec_pixels[index + 1] = (data[k * 4 + 1]);
65 spec_pixels[index + 2] = (data[k * 4 + 2]);
66 spec_pixels[index + 3] = MAX_FIRE_ALPHA *
67 ((k > FULL_ON_FIRE) ?
68 1.0f :
69 (k - FIRE_THRESH) / (float(FULL_ON_FIRE) - FIRE_THRESH));
70 }
71 else {
72 zero_v4(&spec_pixels[index]);
73 }
74 }
75 }
76 }
77
78 memcpy(data, spec_pixels, sizeof(float) * 4 * TFUNC_WIDTH);
79
80 MEM_freeN(spec_pixels);
81
82# undef FIRE_THRESH
83# undef MAX_FIRE_ALPHA
84# undef FULL_ON_FIRE
85}
86
87static void create_color_ramp(const ColorBand *coba, float *data)
88{
89 for (int i = 0; i < TFUNC_WIDTH; i++) {
90 BKE_colorband_evaluate(coba, float(i) / TFUNC_WIDTH, &data[i * 4]);
92 }
93}
94
95static blender::gpu::Texture *create_transfer_function(int type, const ColorBand *coba)
96{
97 float *data = (float *)MEM_mallocN(sizeof(float[4]) * TFUNC_WIDTH, __func__);
98
99 switch (type) {
100 case TFUNC_FLAME_SPECTRUM:
101 create_flame_spectrum_texture(data);
102 break;
103 case TFUNC_COLOR_RAMP:
104 create_color_ramp(coba, data);
105 break;
106 }
107
108 blender::gpu::Texture *tex = GPU_texture_create_1d("transf_func",
109 TFUNC_WIDTH,
110 1,
111 blender::gpu::TextureFormat::SRGBA_8_8_8_8,
113 data);
114
116
117 return tex;
118}
119
120static void swizzle_texture_channel_single(blender::gpu::Texture *tex)
121{
122 /* Swizzle texture channels so that we get useful RGBA values when sampling
123 * a texture with fewer channels, e.g. when using density as color. */
124 GPU_texture_swizzle_set(tex, "rrr1");
125}
126
127static float *rescale_3d(const int dim[3],
128 const int final_dim[3],
129 int channels,
130 const float *fpixels)
131{
132 const uint w = dim[0], h = dim[1], d = dim[2];
133 const uint fw = final_dim[0], fh = final_dim[1], fd = final_dim[2];
134 const uint xf = w / fw, yf = h / fh, zf = d / fd;
135 const uint pixel_count = fw * fh * fd;
136 float *nfpixels = (float *)MEM_mallocN(channels * sizeof(float) * pixel_count, __func__);
137
138 if (nfpixels) {
139 printf("Performance: You need to scale a 3D texture, feel the pain!\n");
140
141 for (uint k = 0; k < fd; k++) {
142 for (uint j = 0; j < fh; j++) {
143 for (uint i = 0; i < fw; i++) {
144 /* Obviously doing nearest filtering here,
145 * it's going to be slow in any case, let's not make it worse. */
146 float xb = i * xf;
147 float yb = j * yf;
148 float zb = k * zf;
149 uint offset = k * (fw * fh) + i * fh + j;
150 uint offset_orig = (zb) * (w * h) + (xb)*h + (yb);
151
152 if (channels == 4) {
153 nfpixels[offset * 4] = fpixels[offset_orig * 4];
154 nfpixels[offset * 4 + 1] = fpixels[offset_orig * 4 + 1];
155 nfpixels[offset * 4 + 2] = fpixels[offset_orig * 4 + 2];
156 nfpixels[offset * 4 + 3] = fpixels[offset_orig * 4 + 3];
157 }
158 else if (channels == 1) {
159 nfpixels[offset] = fpixels[offset_orig];
160 }
161 else {
162 BLI_assert(0);
163 }
164 }
165 }
166 }
167 }
168 return nfpixels;
169}
170
171/* Will resize input to fit GL system limits. */
172static blender::gpu::Texture *create_volume_texture(const int dim[3],
173 blender::gpu::TextureFormat texture_format,
174 eGPUDataFormat data_format,
175 const void *data)
176{
177 blender::gpu::Texture *tex = nullptr;
178 blender::int3 final_dim = {UNPACK3(dim)};
179
180 if (data == nullptr) {
181 return nullptr;
182 }
183
184 while (true) {
186 "volume", UNPACK3(final_dim), 1, texture_format, GPU_TEXTURE_USAGE_SHADER_READ, nullptr);
187
188 if (tex != nullptr) {
189 break;
190 }
191
192 if (final_dim[0] == 1 && final_dim[1] == 1 && final_dim[2] == 1) {
193 break;
194 }
195
196 for (int i = 0; i < 3; i++) {
197 final_dim[i] = max_ii(1, final_dim[i] / 2);
198 }
199 }
200
201 if (tex == nullptr) {
202 printf("Error: Could not create 3D texture.\n");
203 tex = GPU_texture_create_error(3, false);
204 }
205 else if (blender::int3(dim) == final_dim) {
206 /* No need to resize, just upload the data. */
207 GPU_texture_update_sub(tex, data_format, data, 0, 0, 0, UNPACK3(final_dim));
208 }
209 else if (data_format != GPU_DATA_FLOAT) {
210 printf("Error: Could not allocate 3D texture and not attempting to rescale non-float data.\n");
211 tex = GPU_texture_create_error(3, false);
212 }
213 else {
214 /* We need to resize the input. */
215 int channels = ELEM(texture_format,
216 blender::gpu::TextureFormat::UNORM_8,
217 blender::gpu::TextureFormat::SFLOAT_16,
218 blender::gpu::TextureFormat::SFLOAT_32) ?
219 1 :
220 4;
221 float *rescaled_data = rescale_3d(dim, final_dim, channels, static_cast<const float *>(data));
222 if (rescaled_data) {
223 GPU_texture_update_sub(tex, GPU_DATA_FLOAT, rescaled_data, 0, 0, 0, UNPACK3(final_dim));
224 MEM_freeN(rescaled_data);
225 }
226 else {
227 printf("Error: Could not allocate rescaled 3d texture!\n");
228 GPU_texture_free(tex);
229 tex = GPU_texture_create_error(3, false);
230 }
231 }
232 return tex;
233}
234
235static blender::gpu::Texture *create_field_texture(FluidDomainSettings *fds, bool single_precision)
236{
237 void *field = nullptr;
238 eGPUDataFormat data_format = GPU_DATA_FLOAT;
239 blender::gpu::TextureFormat texture_format = blender::gpu::TextureFormat::UNORM_8;
240
241 if (single_precision) {
242 texture_format = blender::gpu::TextureFormat::SFLOAT_32;
243 }
244
245 switch (fds->coba_field) {
247 field = manta_smoke_get_density(fds->fluid);
248 break;
250 field = manta_smoke_get_heat(fds->fluid);
251 break;
253 field = manta_smoke_get_fuel(fds->fluid);
254 break;
256 field = manta_smoke_get_react(fds->fluid);
257 break;
259 field = manta_smoke_get_flame(fds->fluid);
260 break;
262 field = manta_get_velocity_x(fds->fluid);
263 break;
265 field = manta_get_velocity_y(fds->fluid);
266 break;
268 field = manta_get_velocity_z(fds->fluid);
269 break;
271 field = manta_smoke_get_color_r(fds->fluid);
272 break;
274 field = manta_smoke_get_color_g(fds->fluid);
275 break;
277 field = manta_smoke_get_color_b(fds->fluid);
278 break;
280 field = manta_get_force_x(fds->fluid);
281 break;
283 field = manta_get_force_y(fds->fluid);
284 break;
286 field = manta_get_force_z(fds->fluid);
287 break;
289 field = manta_get_phi(fds->fluid);
290 texture_format = blender::gpu::TextureFormat::SFLOAT_16;
291 break;
293 field = manta_get_phi_in(fds->fluid);
294 texture_format = blender::gpu::TextureFormat::SFLOAT_16;
295 break;
297 field = manta_get_phiout_in(fds->fluid);
298 texture_format = blender::gpu::TextureFormat::SFLOAT_16;
299 break;
301 field = manta_get_phiobs_in(fds->fluid);
302 texture_format = blender::gpu::TextureFormat::SFLOAT_16;
303 break;
305 field = manta_smoke_get_flags(fds->fluid);
306 data_format = GPU_DATA_INT;
307 texture_format = blender::gpu::TextureFormat::UINT_8;
308 break;
310 field = manta_get_pressure(fds->fluid);
311 texture_format = blender::gpu::TextureFormat::SFLOAT_16;
312 break;
313 default:
314 return nullptr;
315 }
316
317 if (field == nullptr) {
318 return nullptr;
319 }
320
321 blender::gpu::Texture *tex = create_volume_texture(fds->res, texture_format, data_format, field);
322 swizzle_texture_channel_single(tex);
323 return tex;
324}
325
326static blender::gpu::Texture *create_density_texture(FluidDomainSettings *fds, int highres)
327{
328 int *dim = (highres) ? fds->res_noise : fds->res;
329
330 float *data;
331 if (highres) {
333 }
334 else {
336 }
337
338 if (data == nullptr) {
339 return nullptr;
340 }
341
342 blender::gpu::Texture *tex = create_volume_texture(
343 dim, blender::gpu::TextureFormat::UNORM_8, GPU_DATA_FLOAT, data);
344 swizzle_texture_channel_single(tex);
345 return tex;
346}
347
348static blender::gpu::Texture *create_color_texture(FluidDomainSettings *fds, int highres)
349{
350 const bool has_color = (highres) ? manta_noise_has_colors(fds->fluid) :
352
353 if (!has_color) {
354 return nullptr;
355 }
356
357 int cell_count = (highres) ? manta_noise_get_cells(fds->fluid) : fds->total_cells;
358 int *dim = (highres) ? fds->res_noise : fds->res;
359 float *data = MEM_calloc_arrayN<float>(cell_count * 4, "smokeColorTexture");
360
361 if (data == nullptr) {
362 return nullptr;
363 }
364
365 if (highres) {
367 }
368 else {
370 }
371
372 blender::gpu::Texture *tex = create_volume_texture(
373 dim, blender::gpu::TextureFormat::UNORM_8_8_8_8, GPU_DATA_FLOAT, data);
374
376
377 return tex;
378}
379
380static blender::gpu::Texture *create_flame_texture(FluidDomainSettings *fds, int highres)
381{
382 float *source = nullptr;
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 nullptr;
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 blender::gpu::Texture *tex = create_volume_texture(
399 dim, blender::gpu::TextureFormat::UNORM_8, GPU_DATA_FLOAT, source);
400 swizzle_texture_channel_single(tex);
401 return tex;
402}
403
404static bool get_smoke_velocity_field(FluidDomainSettings *fds,
405 float **r_velocity_x,
406 float **r_velocity_y,
407 float **r_velocity_z)
408{
409 const char vector_field = fds->vector_field;
410 switch ((FLUID_DisplayVectorField)vector_field) {
412 *r_velocity_x = manta_get_velocity_x(fds->fluid);
413 *r_velocity_y = manta_get_velocity_y(fds->fluid);
414 *r_velocity_z = manta_get_velocity_z(fds->fluid);
415 break;
417 *r_velocity_x = manta_get_guide_velocity_x(fds->fluid);
418 *r_velocity_y = manta_get_guide_velocity_y(fds->fluid);
419 *r_velocity_z = manta_get_guide_velocity_z(fds->fluid);
420 break;
422 *r_velocity_x = manta_get_force_x(fds->fluid);
423 *r_velocity_y = manta_get_force_y(fds->fluid);
424 *r_velocity_z = manta_get_force_z(fds->fluid);
425 break;
426 }
427
428 return *r_velocity_x && *r_velocity_y && *r_velocity_z;
429}
430
431#endif /* WITH_FLUID */
432
434
435/* -------------------------------------------------------------------- */
438
440{
441#ifndef WITH_FLUID
442 UNUSED_VARS(fmd);
443#else
444 if (fmd->type & MOD_FLUID_TYPE_DOMAIN) {
445 FluidDomainSettings *fds = fmd->domain;
446
447 if (!fds->tex_field) {
448 fds->tex_field = create_field_texture(fds, false);
449 BLI_addtail(&drw_get().data->smoke_textures, BLI_genericNodeN(&fds->tex_field));
450 }
451 if (!fds->tex_coba && !ELEM(fds->coba_field,
458 {
459 fds->tex_coba = create_transfer_function(TFUNC_COLOR_RAMP, fds->coba);
460 BLI_addtail(&drw_get().data->smoke_textures, BLI_genericNodeN(&fds->tex_coba));
461 }
462 }
463#endif
464}
465
466void DRW_smoke_ensure(FluidModifierData *fmd, int highres)
467{
468#ifndef WITH_FLUID
469 UNUSED_VARS(fmd, highres);
470#else
471 if (fmd->type & MOD_FLUID_TYPE_DOMAIN) {
472 FluidDomainSettings *fds = fmd->domain;
473
474 if (!fds->tex_density) {
475 fds->tex_density = create_density_texture(fds, highres);
476 BLI_addtail(&drw_get().data->smoke_textures, BLI_genericNodeN(&fds->tex_density));
477 }
478 if (!fds->tex_color) {
479 fds->tex_color = create_color_texture(fds, highres);
480 BLI_addtail(&drw_get().data->smoke_textures, BLI_genericNodeN(&fds->tex_color));
481 }
482 if (!fds->tex_flame) {
483 fds->tex_flame = create_flame_texture(fds, highres);
484 BLI_addtail(&drw_get().data->smoke_textures, BLI_genericNodeN(&fds->tex_flame));
485 }
486 if (!fds->tex_flame_coba && fds->tex_flame) {
487 fds->tex_flame_coba = create_transfer_function(TFUNC_FLAME_SPECTRUM, nullptr);
488 BLI_addtail(&drw_get().data->smoke_textures, BLI_genericNodeN(&fds->tex_flame_coba));
489 }
490 if (!fds->tex_shadow) {
491 fds->tex_shadow = create_volume_texture(fds->res,
492 blender::gpu::TextureFormat::UNORM_8,
495 BLI_addtail(&drw_get().data->smoke_textures, BLI_genericNodeN(&fds->tex_shadow));
496 }
497 }
498#endif /* WITH_FLUID */
499}
500
502{
503#ifndef WITH_FLUID
504 UNUSED_VARS(fmd);
505#else
506 if (fmd->type & MOD_FLUID_TYPE_DOMAIN) {
507 FluidDomainSettings *fds = fmd->domain;
508 float *vel_x = nullptr, *vel_y = nullptr, *vel_z = nullptr;
509
510 if (!get_smoke_velocity_field(fds, &vel_x, &vel_y, &vel_z)) {
512 get_smoke_velocity_field(fds, &vel_x, &vel_y, &vel_z);
513 }
514
515 if (ELEM(nullptr, vel_x, vel_y, vel_z)) {
516 return;
517 }
518
519 if (!fds->tex_velocity_x) {
521 UNPACK3(fds->res),
522 1,
523 blender::gpu::TextureFormat::SFLOAT_16,
525 vel_x);
527 UNPACK3(fds->res),
528 1,
529 blender::gpu::TextureFormat::SFLOAT_16,
531 vel_y);
533 UNPACK3(fds->res),
534 1,
535 blender::gpu::TextureFormat::SFLOAT_16,
537 vel_z);
538 BLI_addtail(&drw_get().data->smoke_textures, BLI_genericNodeN(&fds->tex_velocity_x));
539 BLI_addtail(&drw_get().data->smoke_textures, BLI_genericNodeN(&fds->tex_velocity_y));
540 BLI_addtail(&drw_get().data->smoke_textures, BLI_genericNodeN(&fds->tex_velocity_z));
541 }
542 }
543#endif /* WITH_FLUID */
544}
545
547{
548#ifndef WITH_FLUID
549 UNUSED_VARS(fmd);
550#else
551 if (fmd->type & MOD_FLUID_TYPE_DOMAIN) {
552 FluidDomainSettings *fds = fmd->domain;
553 if (!fds->tex_flags) {
554 fds->tex_flags = create_volume_texture(fds->res,
555 blender::gpu::TextureFormat::UINT_8,
558 BLI_addtail(&drw_get().data->smoke_textures, BLI_genericNodeN(&fds->tex_flags));
559
560 swizzle_texture_channel_single(fds->tex_flags);
561 }
562 }
563#endif /* WITH_FLUID */
564}
565
567{
568#ifndef WITH_FLUID
569 UNUSED_VARS(fmd);
570#else
571 if (fmd->type & MOD_FLUID_TYPE_DOMAIN) {
572 FluidDomainSettings *fds = fmd->domain;
573
574 if (!fds->tex_range_field) {
575 fds->tex_range_field = create_field_texture(fds, true);
576 BLI_addtail(&drw_get().data->smoke_textures, BLI_genericNodeN(&fds->tex_range_field));
577 }
578 }
579#endif /* WITH_FLUID */
580}
581
583{
585}
586
587void DRW_smoke_exit(DRWData *drw_data)
588{
589 /* Free Smoke Textures after rendering */
590 /* XXX This is a waste of processing and GPU bandwidth if nothing
591 * is updated. But the problem is since Textures are stored in the
592 * modifier we don't want them to take precious VRAM if the
593 * modifier is not used for display. We should share them for
594 * all viewport in a redraw at least. */
595 LISTBASE_FOREACH (LinkData *, link, &drw_data->smoke_textures) {
597 }
598 BLI_freelistN(&drw_data->smoke_textures);
599}
600
bool BKE_colorband_evaluate(const ColorBand *coba, float in, float out[4])
Definition colorband.cc:396
#define BLI_assert(a)
Definition BLI_assert.h:46
LinkData * BLI_genericNodeN(void *data)
Definition listbase.cc:922
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:497
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
MINLINE int max_ii(int a, int b)
MINLINE void straight_to_premul_v4(float color[4])
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
void GPU_texture_swizzle_set(blender::gpu::Texture *texture, const char swizzle[4])
void GPU_texture_update_sub(blender::gpu::Texture *texture, eGPUDataFormat data_format, const void *pixels, int offset_x, int offset_y, int offset_z, int width, int height, int depth)
eGPUDataFormat
@ GPU_DATA_INT
@ GPU_DATA_FLOAT
@ GPU_TEXTURE_USAGE_SHADER_READ
#define GPU_TEXTURE_FREE_SAFE(texture)
blender::gpu::Texture * GPU_texture_create_error(int dimension, bool array)
void GPU_texture_free(blender::gpu::Texture *texture)
blender::gpu::Texture * GPU_texture_create_3d(const char *name, int width, int height, int depth, int mip_len, blender::gpu::TextureFormat format, eGPUTextureUsage usage, const void *data)
blender::gpu::Texture * GPU_texture_create_1d(const char *name, int width, int mip_len, blender::gpu::TextureFormat format, eGPUTextureUsage usage, const float *data)
void IMB_colormanagement_blackbody_temperature_to_rgb_table(float *r_table, int width, float min, float max)
Read Guarded memory(de)allocation.
BMesh const char void * data
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
nullptr float
DRWContext & drw_get()
void DRW_fluid_ensure_flags(FluidModifierData *fmd)
void DRW_smoke_begin_sync(DRWData *drw_data)
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)
#define printf(...)
void * MEM_mallocN(size_t len, const char *str)
Definition mallocn.cc:128
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:133
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
float * manta_noise_get_density(struct MANTA *smoke)
float * manta_smoke_get_color_r(struct MANTA *smoke)
float * manta_smoke_get_shadow(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_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)
VecBase< int32_t, 3 > int3
ListBase smoke_textures
GPUTexture * tex_velocity_z
GPUTexture * tex_velocity_y
GPUTexture * tex_range_field
GPUTexture * tex_flame_coba
struct ColorBand * coba
GPUTexture * tex_velocity_x
struct FluidDomainSettings * domain
i
Definition text_draw.cc:230