80#define DT_DEFAULT 0.1f
83#define PHI_MAX 9999.0f
98# define ADD_IF_LOWER_POS(a, b) min_ff((a) + (b), max_ff((a), (b)))
99# define ADD_IF_LOWER_NEG(a, b) max_ff((a) + (b), min_ff((a), (b)))
100# define ADD_IF_LOWER(a, b) (((b) > 0) ? ADD_IF_LOWER_POS((a), (b)) : ADD_IF_LOWER_NEG((a), (b)))
104 if (free_old && fds->
fluid) {
107 if (!
min_iii(res[0], res[1], res[2])) {
108 fds->
fluid =
nullptr;
118 return (fds->
fluid !=
nullptr);
132 int new_shift[3] = {0};
138 int o_total_cells = o_res[0] * o_res[1] * o_res[2];
139 int n_total_cells = n_res[0] * n_res[1] * n_res[2];
142 if (o_total_cells > 1 && n_total_cells > 1) {
199 for (
int z = o_min[2];
z < o_max[2];
z++) {
200 for (
int y = o_min[1];
y < o_max[1];
y++) {
201 for (
int x = o_min[0];
x < o_max[0];
x++) {
203 int xo =
x - o_min[0];
204 int yo =
y - o_min[1];
205 int zo =
z - o_min[2];
208 int xn =
x - n_min[0] - new_shift[0];
209 int yn =
y - n_min[1] - new_shift[1];
210 int zn =
z - n_min[2] - new_shift[2];
214 if (xn < 0 || xn >= n_res[0] || yn < 0 || yn >= n_res[1] || zn < 0 || zn >= n_res[2]) {
228 if (xo < bwidth || yo < bwidth || zo < bwidth || xo >= o_res[0] - bwidth ||
229 yo >= o_res[1] - bwidth || zo >= o_res[2] - bwidth)
234 if (xn < bwidth || yn < bwidth || zn < bwidth || xn >= n_res[0] - bwidth ||
235 yn >= n_res[1] - bwidth || zn >= n_res[2] - bwidth)
245 int xx_o = xo * block_size;
246 int yy_o = yo * block_size;
247 int zz_o = zo * block_size;
249 int xx_n = xn * block_size;
250 int yy_n = yn * block_size;
251 int zz_n = zn * block_size;
254 n_wt_tcu[index_new] = o_wt_tcu[index_old];
255 n_wt_tcv[index_new] = o_wt_tcv[index_old];
256 n_wt_tcw[index_new] = o_wt_tcw[index_old];
258 n_wt_tcu2[index_new] = o_wt_tcu2[index_old];
259 n_wt_tcv2[index_new] = o_wt_tcv2[index_old];
260 n_wt_tcw2[index_new] = o_wt_tcw2[index_old];
262 for (i = 0; i < block_size; i++) {
263 for (j = 0; j < block_size; j++) {
264 for (k = 0; k < block_size; k++) {
266 xx_o + i, wt_res_old[0], yy_o + j, wt_res_old[1], zz_o + k);
270 n_wt_dens[big_index_new] = o_wt_dens[big_index_old];
271 if (n_wt_flame && o_wt_flame) {
272 n_wt_flame[big_index_new] = o_wt_flame[big_index_old];
273 n_wt_fuel[big_index_new] = o_wt_fuel[big_index_old];
274 n_wt_react[big_index_new] = o_wt_react[big_index_old];
276 if (n_wt_r && o_wt_r) {
277 n_wt_r[big_index_new] = o_wt_r[big_index_old];
278 n_wt_g[big_index_new] = o_wt_g[big_index_old];
279 n_wt_b[big_index_new] = o_wt_b[big_index_old];
286 n_dens[index_new] = o_dens[index_old];
288 if (n_heat && o_heat) {
289 n_heat[index_new] = o_heat[index_old];
292 if (n_fuel && o_fuel) {
293 n_flame[index_new] = o_flame[index_old];
294 n_fuel[index_new] = o_fuel[index_old];
295 n_react[index_new] = o_react[index_old];
299 n_r[index_new] = o_r[index_old];
300 n_g[index_new] = o_g[index_old];
301 n_b[index_new] = o_b[index_old];
303 n_vx[index_new] = o_vx[index_old];
304 n_vy[index_new] = o_vy[index_old];
305 n_vz[index_new] = o_vz[index_old];
400 bool init_resolution)
420 fds->
dx = 1.0f / res;
424 if (init_resolution) {
429 for (i = 0; i < 3; i++) {
438 if (!init_resolution || (
size[0] < FLT_EPSILON) || (
size[1] < FLT_EPSILON) ||
439 (
size[2] < FLT_EPSILON))
484static bool fluid_modifier_init(
493 manta_set_domain_from_mesh(fds, ob, mesh,
true);
495 update_final_gravity(fds, scene);
508 res[0] = res[1] = res[2] = 1;
524 fmd->
time = scene_framenr;
533 fmd->
time = scene_framenr;
540 fmd->
time = scene_framenr;
550static float calc_voxel_transp(
551 float *
result,
const float *input,
int res[3],
int *pixel,
float *t_ray,
float correct);
552static void update_distances(
int index,
555 const float ray_start[3],
556 float surface_thickness,
557 bool use_plane_init);
559static int get_light(
Scene *scene,
ViewLayer *view_layer,
float *light)
566 if (base_tmp->object->type ==
OB_LAMP) {
567 Light *la =
static_cast<Light *
>(base_tmp->object->data);
570 copy_v3_v3(light, base_tmp->object->object_to_world().location());
574 copy_v3_v3(light, base_tmp->object->object_to_world().location());
586 const float *min_vel,
587 const float *max_vel,
591 for (
int i = 0; i < 3; i++) {
598 if (min_vel && min_vel[i] < 0.0f) {
601 if (max_vel && max_vel[i] > 0.0f) {
611static bool is_static_object(
Object *ob)
616 for (; md; md = md->
next) {
645struct FluidObjectBB {
650 int min[3],
max[3], res[3];
651 int hmin[3], hmax[3], hres[3];
652 int total_cells, valid;
655static void bb_boundInsert(FluidObjectBB *bb,
const float point[3])
667 if (
point[i] < bb->min[i]) {
670 if (
point[i] > bb->max[i]) {
677static void bb_allocateData(FluidObjectBB *bb,
bool use_velocity,
bool use_influence)
681 for (i = 0; i < 3; i++) {
682 res[i] = bb->max[i] - bb->min[i];
687 bb->total_cells = res[0] * res[1] * res[2];
690 bb->numobjs =
static_cast<float *
>(
693 bb->influence =
static_cast<float *
>(
697 bb->velocity =
static_cast<float *
>(
701 bb->distances =
static_cast<float *
>(
708static void bb_freeData(FluidObjectBB *bb)
724static void bb_combineMaps(FluidObjectBB *
output,
733 memcpy(&bb1,
output,
sizeof(FluidObjectBB));
734 memset(
output, 0,
sizeof(FluidObjectBB));
736 for (i = 0; i < 3; i++) {
738 output->min[i] = std::min(bb1.min[i], bb2->min[i]);
739 output->max[i] = std::max(bb1.max[i], bb2->max[i]);
742 output->min[i] = bb2->min[i];
743 output->max[i] = bb2->max[i];
747 bb_allocateData(
output, (bb1.velocity || bb2->velocity), (bb1.influence || bb2->influence));
760 if (
x >= bb1.min[0] &&
x < bb1.max[0] &&
y >= bb1.min[1] &&
y < bb1.max[1] &&
761 z >= bb1.min[2] &&
z < bb1.max[2])
764 x - bb1.min[0], bb1.res[0],
y - bb1.min[1], bb1.res[1],
z - bb1.min[2]);
767 output->numobjs[index_out] = bb1.numobjs[index_in];
768 if (
output->influence && bb1.influence) {
769 output->influence[index_out] = bb1.influence[index_in];
771 output->distances[index_out] = bb1.distances[index_in];
772 if (
output->velocity && bb1.velocity) {
782 x - bb2->min[0], bb2->res[0],
y - bb2->min[1], bb2->res[1],
z - bb2->min[2]);
785 output->numobjs[index_out] = std::max(bb2->numobjs[index_in],
786 output->numobjs[index_out]);
787 if (
output->influence && bb2->influence) {
789 output->influence[index_out] += bb2->influence[index_in] * sample_size;
792 output->influence[index_out] = std::max(bb2->influence[index_in],
793 output->influence[index_out]);
796 output->distances[index_out] = std::min(bb2->distances[index_in],
797 output->distances[index_out]);
798 if (
output->velocity && bb2->velocity) {
800 output->velocity[index_out * 3] = ADD_IF_LOWER(
output->velocity[index_out * 3],
801 bb2->velocity[index_in * 3]);
802 output->velocity[index_out * 3 + 1] = ADD_IF_LOWER(
output->velocity[index_out * 3 + 1],
803 bb2->velocity[index_in * 3 + 1]);
804 output->velocity[index_out * 3 + 2] = ADD_IF_LOWER(
output->velocity[index_out * 3 + 2],
805 bb2->velocity[index_in * 3 + 2]);
824 float src_distance_value,
826 float src_numobjs_value,
828 float const src_vel_value[3],
835 dest_phi_in[
index] = std::min(src_distance_value, dest_phi_in[index]);
839 if (dest_numobjs && src_numobjs_value > 0) {
840 dest_numobjs[
index] += 1;
844 if (dest_vel_x && src_numobjs_value > 0) {
845 dest_vel_x[
index] += src_vel_value[0];
846 dest_vel_y[
index] += src_vel_value[1];
847 dest_vel_z[
index] += src_vel_value[2];
853 const int *corner_verts,
858 const float ray_start[3],
859 const float *vert_vel,
868 const float surface_distance = 1.732;
870 nearest.
dist_sq = surface_distance * surface_distance;
878 int v1,
v2, v3, tri_i = nearest.
index;
881 v1 = corner_verts[corner_tris[tri_i][0]];
882 v2 = corner_verts[corner_tris[tri_i][1]];
883 v3 = corner_verts[corner_tris[tri_i][2]];
885 weights, vert_positions[v1], vert_positions[
v2], vert_positions[v3], nearest.
co);
889 interp_v3_v3v3v3(hit_vel, &vert_vel[v1 * 3], &vert_vel[
v2 * 3], &vert_vel[v3 * 3], weights);
896 float abs_hit_vel[3];
902 copy_v3_v3(abs_vel, &velocity_map[index * 3]);
907 velocity_map[
index * 3] = (velocity_map[
index * 3] + hit_vel[0]) * 0.5f;
908 velocity_map[
index * 3 + 1] = (velocity_map[
index * 3 + 1] + hit_vel[1]) * 0.5f;
909 velocity_map[
index * 3 + 2] = (velocity_map[
index * 3 + 2] + hit_vel[2]) * 0.5f;
912 velocity_map[
index * 3] = hit_vel[0];
913 velocity_map[
index * 3 + 1] = hit_vel[1];
914 velocity_map[
index * 3 + 2] = hit_vel[2];
917 velocity_map[
index * 3] = std::min(abs_hit_vel[0], abs_vel[0]);
918 velocity_map[
index * 3 + 1] = std::min(abs_hit_vel[1], abs_vel[1]);
919 velocity_map[
index * 3 + 2] = std::min(abs_hit_vel[2], abs_vel[2]);
923 velocity_map[
index * 3] = std::max(abs_hit_vel[0], abs_vel[0]);
924 velocity_map[
index * 3 + 1] = std::max(abs_hit_vel[1], abs_vel[1]);
925 velocity_map[
index * 3 + 2] = std::max(abs_hit_vel[2], abs_vel[2]);
930 velocity_map[
index * 3] = hit_vel[0];
931 velocity_map[
index * 3 + 1] = hit_vel[1];
932 velocity_map[
index * 3 + 2] = hit_vel[2];
935 printf(
"setting effector object vel: [%f, %f, %f]\n", hit_vel[0], hit_vel[1], hit_vel[2]);
949struct ObstaclesFromDMData {
952 blender::Span<blender::float3> vert_positions;
953 blender::Span<int> corner_verts;
954 blender::Span<blender::int3> corner_tris;
956 BVHTreeFromMesh *
tree;
964static void obstacles_from_mesh_task_cb(
void *__restrict userdata,
968 ObstaclesFromDMData *
data =
static_cast<ObstaclesFromDMData *
>(userdata);
969 FluidObjectBB *bb =
data->bb;
974 x - bb->min[0], bb->res[0],
y - bb->min[1], bb->res[1],
z - bb->min[2]);
978 update_distances(index,
982 data->fes->surface_distance,
987 data->vert_positions,
988 data->corner_verts.data(),
989 data->corner_tris.data(),
998 if (bb->distances[index] < 0) {
999 bb->numobjs[
index]++;
1005static void obstacles_from_mesh(
Object *coll_ob,
1015 float *vert_vel =
nullptr;
1016 bool has_velocity =
false;
1021 int min[3],
max[3], res[3];
1029 vert_vel =
static_cast<float *
>(
1030 MEM_callocN(
sizeof(
float[3]) * numverts,
"manta_obs_velocity"));
1038 MEM_callocN(
sizeof(
float[3]) * numverts,
"manta_obs_verts_old"));
1042 has_velocity =
true;
1048 for (i = 0; i < numverts; i++) {
1052 mul_m4_v3(coll_ob->object_to_world().ptr(), positions[i]);
1053 manta_pos_to_cell(fds, positions[i]);
1064 bb_boundInsert(bb, positions[i]);
1069 int bounds_margin =
int(
ceil(5.196));
1070 clamp_bounds_in_domain(fds, bb->min, bb->max,
nullptr,
nullptr, bounds_margin, dt);
1071 bb_allocateData(bb,
true,
false);
1074 for (i = 0; i < 3; i++) {
1075 min[i] = bb->min[i];
1076 max[i] = bb->max[i];
1077 res[i] = bb->res[i];
1084 ObstaclesFromDMData
data{};
1086 data.vert_positions = positions;
1087 data.corner_verts = corner_verts;
1088 data.corner_tris = corner_tris;
1089 data.tree = &tree_data;
1091 data.has_velocity = has_velocity;
1092 data.vert_vel = vert_vel;
1125 int coll_ob_array_len)
1132 active_fields &= ~prev_flags;
1135 for (coll_index = 0; coll_index < coll_ob_array_len; coll_index++) {
1136 Object *coll_ob = coll_ob_array[coll_index];
1165static bool escape_effectorobject(
Object *flowobj,
1170 bool is_static = is_static_object(flowobj);
1182 if (is_static && !is_first_frame && !is_resume) {
1188static void compute_obstaclesemission(
Scene *scene,
1189 FluidObjectBB *bb_maps,
1197 float time_per_frame)
1202 for (
int effec_index = 0; effec_index < numeffecobjs; effec_index++) {
1203 Object *effecobj = effecobjs[effec_index];
1216 FluidObjectBB *bb = &bb_maps[effec_index];
1219 if (escape_effectorobject(effecobj, fds, fes, frame)) {
1225 if (is_first_frame) {
1230 float sample_size = 1.0f /
float(subframes + 1);
1231 float subframe_dt = dt * sample_size;
1234 for (
int subframe = 0; subframe <= subframes; subframe++) {
1237 FluidObjectBB bb_temp = {
nullptr};
1241 if ((subframe < subframes || time_per_frame + dt + FLT_EPSILON < frame_length) &&
1244 scene->
r.
subframe = (time_per_frame + (subframe + 1.0f) * subframe_dt) / frame_length;
1245 scene->
r.
cfra = frame - 1;
1249 scene->
r.
cfra = frame;
1256 "effector: frame (is first: %d): %d // scene current frame: %d // scene current "
1272 obstacles_from_mesh(effecobj, fds, fes, &bb_temp, subframe_dt);
1275 obstacles_from_mesh(effecobj, fds, fes, bb, subframe_dt);
1282 bb_combineMaps(bb, &bb_temp, 0, 0.0f);
1283 bb_freeData(&bb_temp);
1290static void update_obstacles(Depsgraph *
depsgraph,
1294 float time_per_frame,
1299 FluidObjectBB *bb_maps =
nullptr;
1300 Object **effecobjs =
nullptr;
1301 uint numeffecobjs = 0;
1309 update_obstacleflags(fds, effecobjs, numeffecobjs);
1310 ensure_obstaclefields(fds);
1313 bb_maps =
static_cast<FluidObjectBB *
>(
1314 MEM_callocN(
sizeof(FluidObjectBB) * numeffecobjs,
"fluid_effector_bb_maps"));
1317 compute_obstaclesemission(scene,
1344 for (
z = 0;
z < fds->
res[0] * fds->
res[1] * fds->
res[2];
z++) {
1352 if (phi_obsstatic_in && (is_first_frame || use_adaptivedomain)) {
1358 if (num_obstacles) {
1359 num_obstacles[
z] = 0;
1364 if (vel_x && vel_y && vel_z) {
1369 if (vel_x_guide && vel_y_guide && vel_z_guide) {
1370 vel_x_guide[
z] = 0.0f;
1371 vel_y_guide[
z] = 0.0f;
1372 vel_z_guide[
z] = 0.0f;
1377 for (
int effec_index = 0; effec_index < numeffecobjs; effec_index++) {
1378 Object *effecobj = effecobjs[effec_index];
1390 bool is_static = is_static_object(effecobj) && !use_adaptivedomain;
1401 FluidObjectBB *bb = &bb_maps[effec_index];
1402 float *velocity_map = bb->velocity;
1403 float *numobjs_map = bb->numobjs;
1404 float *distance_map = bb->distances;
1406 int gx, gy, gz, ex, ey, ez, dx, dy, dz;
1407 size_t e_index, d_index;
1410 for (gx = bb->min[0]; gx < bb->
max[0]; gx++) {
1411 for (gy = bb->min[1]; gy < bb->
max[1]; gy++) {
1412 for (gz = bb->min[2]; gz < bb->
max[2]; gz++) {
1414 ex = gx - bb->min[0];
1415 ey = gy - bb->min[1];
1416 ez = gz - bb->min[2];
1425 if (dx < 0 || dy < 0 || dz < 0 || dx >= fds->
res[0] || dy >= fds->
res[1] ||
1432 float *levelset = ((is_first_frame || is_resume) && is_static) ? phi_obsstatic_in :
1434 apply_effector_fields(fes,
1436 distance_map[e_index],
1438 numobjs_map[e_index],
1440 &velocity_map[e_index * 3],
1446 apply_effector_fields(fes,
1448 distance_map[e_index],
1450 numobjs_map[e_index],
1452 &velocity_map[e_index * 3],
1476struct EmitFromParticlesData {
1481 float *particle_vel;
1488static void emit_from_particles_task_cb(
void *__restrict userdata,
1492 EmitFromParticlesData *
data =
static_cast<EmitFromParticlesData *
>(userdata);
1494 FluidObjectBB *bb =
data->bb;
1499 x - bb->min[0], bb->res[0],
y - bb->min[1], bb->res[1],
z - bb->min[2]);
1503 KDTreeNearest_3d nearest;
1504 const float range =
data->solid +
data->smooth;
1505 BLI_kdtree_3d_find_nearest(
data->tree, ray_start, &nearest);
1507 if (nearest.dist < range) {
1508 bb->influence[
index] = (nearest.dist <
data->solid) ?
1514 &bb->velocity[index * 3], &data->particle_vel[nearest.index * 3], ffs->vel_multi);
1521static void emit_from_particles(
Object *flow_ob,
1534 float *particle_pos;
1535 float *particle_vel;
1536 int totpart = psys->
totpart, totchild;
1538 int valid_particles = 0;
1539 int bounds_margin = 1;
1543 const float smooth = 0.5f;
1544 KDTree_3d *
tree =
nullptr;
1562 particle_pos =
static_cast<float *
>(
1563 MEM_callocN(
sizeof(
float[3]) * (totpart + totchild),
"manta_flow_particles_pos"));
1564 particle_vel =
static_cast<float *
>(
1565 MEM_callocN(
sizeof(
float[3]) * (totpart + totchild),
"manta_flow_particles_vel"));
1574 for (p = 0; p < totpart + totchild; p++) {
1598 pos = &particle_pos[valid_particles * 3];
1600 manta_pos_to_cell(fds,
pos);
1603 vel = &particle_vel[valid_particles * 3];
1608 BLI_kdtree_3d_insert(
tree, valid_particles,
pos);
1612 bb_boundInsert(bb,
pos);
1617 clamp_bounds_in_domain(fds, bb->min, bb->max,
nullptr,
nullptr, bounds_margin, dt);
1621 for (p = 0; p < valid_particles; p++) {
1628 cell[0] =
floor(particle_pos[p * 3]) - bb->min[0];
1629 cell[1] =
floor(particle_pos[p * 3 + 1]) - bb->min[1];
1630 cell[2] =
floor(particle_pos[p * 3 + 2]) - bb->min[2];
1632 for (i = 0; i < 3; i++) {
1633 if ((cell[i] > bb->res[i] - 1) || (cell[i] < 0)) {
1644 bb->influence[
index] = 1.0f;
1651 else if (valid_particles > 0) {
1652 int min[3],
max[3], res[3];
1655 for (
int i = 0; i < 3; i++) {
1656 min[i] = bb->min[i];
1657 max[i] = bb->max[i];
1658 res[i] = bb->res[i];
1661 BLI_kdtree_3d_balance(
tree);
1663 EmitFromParticlesData
data{};
1667 data.particle_vel = particle_vel;
1681 BLI_kdtree_3d_free(
tree);
1698static void update_distances(
int index,
1699 float *distance_map,
1701 const float ray_start[3],
1702 float surface_thickness,
1703 bool use_plane_init)
1708 if (use_plane_init) {
1714 const float surface_distance = 1.732;
1716 nearest.
dist_sq = surface_distance * surface_distance;
1719 if (surface_thickness) {
1720 nearest.
dist_sq += surface_thickness;
1729 min_dist = (-1.0f) *
fabsf(min_dist);
1736 float ray_dirs[26][3] = {
1737 {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, {-1.0f, 0.0f, 0.0f},
1738 {0.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {1.0f, 1.0f, 0.0f}, {1.0f, -1.0f, 0.0f},
1739 {-1.0f, 1.0f, 0.0f}, {-1.0f, -1.0f, 0.0f}, {1.0f, 0.0f, 1.0f}, {1.0f, 0.0f, -1.0f},
1740 {-1.0f, 0.0f, 1.0f}, {-1.0f, 0.0f, -1.0f}, {0.0f, 1.0f, 1.0f}, {0.0f, 1.0f, -1.0f},
1741 {0.0f, -1.0f, 1.0f}, {0.0f, -1.0f, -1.0f}, {1.0f, 1.0f, 1.0f}, {1.0f, -1.0f, 1.0f},
1742 {-1.0f, 1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f}, {1.0f, 1.0f, -1.0f}, {1.0f, -1.0f, -1.0f},
1743 {-1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}};
1748 int miss_count = 0, dir_count = 0;
1750 for (
int i = 0; i <
ARRAY_SIZE(ray_dirs); i++) {
1752 hit_tree.
index = -1;
1766 if (hit_tree.
index == -1) {
1773 if (
dot_v3v3(ray_dirs[i], hit_tree.
no) <= 0) {
1777 if (hit_tree.
dist < min_dist) {
1778 min_dist = hit_tree.
dist;
1784 if (!(miss_count > 0 || dir_count ==
ARRAY_SIZE(ray_dirs))) {
1785 min_dist = (-1.0f) *
fabsf(min_dist);
1789 if (surface_thickness) {
1790 min_dist -= surface_thickness;
1795 distance_map[
index] = std::min(distance_map[index], min_dist);
1804 const int *corner_verts,
1806 const float (*mloopuv)[2],
1807 float *influence_map,
1808 float *velocity_map,
1810 const int base_res[3],
1811 const float global_size[3],
1812 const float flow_center[3],
1814 const float ray_start[3],
1815 const float *vert_vel,
1823 float ray_dir[3] = {1.0f, 0.0f, 0.0f};
1827 float volume_factor = 0.0f;
1836 const float surface_distance = 1.732;
1838 nearest.
dist_sq = surface_distance * surface_distance;
1840 bool is_gas_flow =
ELEM(
1846 float emission_strength = (is_gas_flow) ? 0.0f : 1.0f;
1858 float dot = ray_dir[0] * hit.
no[0] + ray_dir[1] * hit.
no[1] + ray_dir[2] * hit.
no[2];
1874 if (hit.
index != -1) {
1886 int v1,
v2, v3, tri_i = nearest.
index;
1887 float hit_normal[3];
1890 v1 = corner_verts[corner_tris[tri_i][0]];
1891 v2 = corner_verts[corner_tris[tri_i][1]];
1892 v3 = corner_verts[corner_tris[tri_i][2]];
1894 weights, vert_positions[v1], vert_positions[
v2], vert_positions[v3], nearest.
co);
1901 CLAMP(emission_strength, 0.0f, 1.0f);
1902 emission_strength =
pow(1.0f - emission_strength, 0.5f);
1905 emission_strength = 0.0f;
1909 if (defgrp_index != -1 && dvert) {
1913 emission_strength *= weight_mask;
1918 float tex_co[3] = {0};
1922 tex_co[0] = ((
x - flow_center[0]) / base_res[0]) / ffs->
texture_size;
1923 tex_co[1] = ((
y - flow_center[1]) / base_res[1]) / ffs->
texture_size;
1924 tex_co[2] = ((
z - flow_center[2]) / base_res[2] - ffs->
texture_offset) /
1929 uv[0] = mloopuv[corner_tris[tri_i][0]];
1930 uv[1] = mloopuv[corner_tris[tri_i][1]];
1931 uv[2] = mloopuv[corner_tris[tri_i][2]];
1936 tex_co[0] = tex_co[0] * 2.0f - 1.0f;
1937 tex_co[1] = tex_co[1] * 2.0f - 1.0f;
1941 emission_strength *= texres.tin;
1951 hit_normal, vert_normals[v1], vert_normals[
v2], vert_normals[v3], weights);
1963 hit_vel, &vert_vel[v1 * 3], &vert_vel[
v2 * 3], &vert_vel[v3 * 3], weights);
1969 printf(
"adding flow object vel: [%f, %f, %f]\n", hit_vel[0], hit_vel[1], hit_vel[2]);
1973 float convert_vel[3];
1975 float time_mult = 1.0 / (25.0f *
DT_DEFAULT);
1976 float size_mult = std::max({base_res[0], base_res[1], base_res[2]}) /
1977 std::max({global_size[0], global_size[1], global_size[2]});
1980 velocity_map[
index * 3] += convert_vel[0];
1981 velocity_map[
index * 3 + 1] += convert_vel[1];
1982 velocity_map[
index * 3 + 2] += convert_vel[2];
1984 printf(
"initial vel: [%f, %f, %f]\n",
1985 velocity_map[index * 3],
1986 velocity_map[index * 3 + 1],
1987 velocity_map[index * 3 + 2]);
1993 influence_map[
index] = std::max(volume_factor, emission_strength);
1996struct EmitFromDMData {
2000 blender::Span<blender::float3> vert_positions;
2001 blender::Span<blender::float3> vert_normals;
2002 blender::Span<int> corner_verts;
2003 blender::Span<blender::int3> corner_tris;
2004 const float (*mloopuv)[2];
2008 BVHTreeFromMesh *
tree;
2017static void emit_from_mesh_task_cb(
void *__restrict userdata,
2021 EmitFromDMData *
data =
static_cast<EmitFromDMData *
>(userdata);
2022 FluidObjectBB *bb =
data->bb;
2027 x - bb->min[0], bb->res[0],
y - bb->min[1], bb->res[1],
z - bb->min[2]);
2033 sample_mesh(
data->ffs,
2034 data->vert_positions,
2036 data->corner_verts.data(),
2037 data->corner_tris.data(),
2042 data->fds->base_res,
2043 data->fds->global_size,
2057 update_distances(index,
2061 data->ffs->surface_distance,
2067static void emit_from_mesh(
2074 float *vert_vel =
nullptr;
2075 bool has_velocity =
false;
2078 float flow_center[3] = {0};
2079 int min[3],
max[3], res[3];
2089 const MDeformVert *dvert = mesh->deform_verts().data();
2090 const float(*mloopuv)[2] =
static_cast<const float(*)[2]
>(
2094 vert_vel = static_cast<float *>(
2095 MEM_callocN(sizeof(float[3]) * numverts,
"manta_flow_velocity"));
2097 if (ffs->numverts != numverts || !ffs->verts_old) {
2098 if (ffs->verts_old) {
2099 MEM_freeN(ffs->verts_old);
2101 ffs->verts_old = static_cast<float *>(
2102 MEM_callocN(sizeof(float[3]) * numverts,
"manta_flow_verts_old"));
2103 ffs->numverts = numverts;
2106 has_velocity = true;
2112 for (i = 0; i < numverts; i++) {
2114 mul_m4_v3(flow_ob->object_to_world().ptr(), positions[i]);
2115 manta_pos_to_cell(fds, positions[i]);
2129 bb_boundInsert(bb, positions[i]);
2131 mesh->tag_positions_changed();
2132 mul_m4_v3(flow_ob->object_to_world().ptr(), flow_center);
2133 manta_pos_to_cell(fds, flow_center);
2137 int bounds_margin =
int(
ceil(5.196));
2138 clamp_bounds_in_domain(fds, bb->min, bb->max,
nullptr,
nullptr, bounds_margin, dt);
2142 for (i = 0; i < 3; i++) {
2143 min[i] = bb->min[i];
2144 max[i] = bb->max[i];
2145 res[i] = bb->res[i];
2152 EmitFromDMData
data{};
2155 data.vert_positions = positions;
2156 data.vert_normals = mesh->vert_normals();
2157 data.corner_verts = corner_verts;
2158 data.corner_tris = corner_tris;
2159 data.mloopuv = mloopuv;
2161 data.defgrp_index = defgrp_index;
2162 data.tree = &tree_data;
2164 data.has_velocity = has_velocity;
2165 data.vert_vel = vert_vel;
2166 data.flow_center = flow_center;
2192static void adaptive_domain_adjust(
2196 int new_shift[3] = {0};
2198 float frame_shift_f[3];
2199 float ob_loc[3] = {0};
2201 mul_m4_v3(ob->object_to_world().ptr(), ob_loc);
2207 frame_shift_f[0] = frame_shift_f[0] / fds->
cell_size[0];
2208 frame_shift_f[1] = frame_shift_f[1] / fds->
cell_size[1];
2209 frame_shift_f[2] = frame_shift_f[2] / fds->
cell_size[2];
2231 int min[3] = {32767, 32767, 32767},
max[3] = {-32767, -32767, -32767}, res[3];
2232 int total_cells = 1, res_changed = 0, shift_changed = 0;
2233 float min_vel[3], max_vel[3];
2254 int xn =
x - new_shift[0];
2255 int yn =
y - new_shift[1];
2256 int zn =
z - new_shift[2];
2261 if (xn >=
min[0] && xn <=
max[0] && yn >=
min[1] && yn <=
max[1] && zn >=
min[2] &&
2272 max_den = (fuel) ? std::max(density[index], fuel[index]) : density[
index];
2278 int xx = (
x - fds->
res_min[0]) * block_size;
2279 int yy = (
y - fds->
res_min[1]) * block_size;
2280 int zz = (
z - fds->
res_min[2]) * block_size;
2282 for (i = 0; i < block_size; i++) {
2283 for (j = 0; j < block_size; j++) {
2284 for (k = 0; k < block_size; k++) {
2285 int big_index =
manta_get_index(xx + i, wt_res[0], yy + j, wt_res[1], zz + k);
2286 float den = (bigfuel) ? std::max(bigdensity[big_index], bigfuel[big_index]) :
2287 bigdensity[big_index];
2288 if (den > max_den) {
2319 if (min_vel[0] > vx[index]) {
2320 min_vel[0] = vx[
index];
2322 if (min_vel[1] > vy[index]) {
2323 min_vel[1] = vy[
index];
2325 if (min_vel[2] > vz[index]) {
2326 min_vel[2] = vz[
index];
2328 if (max_vel[0] < vx[index]) {
2329 max_vel[0] = vx[
index];
2331 if (max_vel[1] < vy[index]) {
2332 max_vel[1] = vy[
index];
2334 if (max_vel[2] < vz[index]) {
2335 max_vel[2] = vz[
index];
2342 for (
int i = 0; i < numflowobj; i++) {
2343 FluidObjectBB *bb = &bb_maps[i];
2349 x - bb->min[0], bb->res[0],
y - bb->min[1], bb->res[1],
z - bb->min[2]);
2350 float max_den = bb->influence[
index];
2381 for (
int i = 0; i < 3; i++) {
2383 res[i] =
max[i] -
min[i];
2384 total_cells *= res[i];
2393 for (j = 0; j < 3; j++) {
2407 if (res_changed || shift_changed) {
2422BLI_INLINE void apply_outflow_fields(
int index,
2423 float distance_value,
2436 phiout[
index] = std::min(distance_value, phiout[index]);
2441 density[
index] = 0.0f;
2448 react[
index] = 0.0f;
2451 color_r[
index] = 0.0f;
2452 color_g[
index] = 0.0f;
2453 color_b[
index] = 0.0f;
2458 float emission_value,
2459 float distance_value,
2462 const float *density,
2470 const float *color_r,
2472 const float *color_g,
2474 const float *color_b,
2481 phi_in[
index] = std::min(distance_value, phi_in[index]);
2487 emission_in[
index] = std::max(emission_value, emission_in[index]);
2492 float dens_old = (density) ? density[index] : 0.0;
2495 float fuel_flow = (fuel) ? emission_value * ffs->
fuel_amount : 0.0f;
2497 if (heat && heat_in) {
2498 if (emission_value > 0.0f) {
2504 if (absolute_flow) {
2505 if (density && density_in) {
2508 density_in[
index] = std::max(dens_flow, density_in[index]);
2511 if (fuel && fuel_in) {
2514 fuel_in[
index] = std::max(fuel_flow, fuel_in[index]);
2520 if (density && density_in) {
2522 density_in[
index] += dens_flow;
2523 CLAMP(density_in[index], 0.0f, 1.0f);
2526 if (fuel && fuel_in) {
2528 fuel_in[
index] += fuel_flow;
2529 CLAMP(fuel_in[index], 0.0f, 10.0f);
2535 if (color_r && color_r_in) {
2537 float total_dens = density[
index] / (dens_old + dens_flow);
2538 color_r_in[
index] = (color_r[
index] + ffs->
color[0] * dens_flow) * total_dens;
2539 color_g_in[
index] = (color_g[
index] + ffs->
color[1] * dens_flow) * total_dens;
2540 color_b_in[
index] = (color_b[
index] + ffs->
color[2] * dens_flow) * total_dens;
2545 if (fuel && fuel_in) {
2547 float value = 1.0f -
pow2f(1.0f - emission_value);
2549 if (fuel_in[index] > FLT_EPSILON && value > react[index]) {
2550 float f = fuel_flow / fuel_in[
index];
2551 react_in[
index] = value * f + (1.0f - f) * react[index];
2552 CLAMP(react_in[index], 0.0f, value);
2592 active_fields &= ~prev_flags;
2595 for (flow_index = 0; flow_index < numflowobj; flow_index++) {
2596 Object *flow_ob = flowobjs[flow_index];
2667static bool escape_flowsobject(
Object *flowobj,
2673 bool is_static = is_static_object(flowobj);
2676 bool gas_flow =
ELEM(
2692 if (liquid_flow && is_geometry && !is_first_frame) {
2696 if ((liquid_flow && gas_domain) || (gas_flow && liquid_domain)) {
2701 if (liquid_flow && is_static && !is_first_frame && !is_resume && !use_velocity) {
2707static void compute_flowsemission(
Scene *scene,
2708 FluidObjectBB *bb_maps,
2716 float time_per_frame)
2721 for (
int flow_index = 0; flow_index < numflowobjs; flow_index++) {
2722 Object *flowobj = flowobjs[flow_index];
2735 FluidObjectBB *bb = &bb_maps[flow_index];
2738 if (escape_flowsobject(flowobj, fds, ffs, frame)) {
2744 if (is_first_frame) {
2749 float sample_size = 1.0f /
float(subframes + 1);
2750 float subframe_dt = dt * sample_size;
2753 for (
int subframe = 0; subframe <= subframes; subframe++) {
2755 FluidObjectBB bb_temp = {
nullptr};
2758 if ((subframe < subframes || time_per_frame + dt + FLT_EPSILON < frame_length) &&
2761 scene->
r.
subframe = (time_per_frame + (subframe + 1.0f) * subframe_dt) / frame_length;
2762 scene->
r.
cfra = frame - 1;
2766 scene->
r.
cfra = frame;
2774 "flow: frame (is first: %d): %d // scene current frame: %d // scene current subframe: "
2791 emit_from_particles(flowobj, fds, ffs, &bb_temp,
depsgraph, scene, subframe_dt);
2794 emit_from_particles(flowobj, fds, ffs, bb,
depsgraph, scene, subframe_dt);
2800 emit_from_mesh(flowobj, fds, ffs, &bb_temp, subframe_dt);
2803 emit_from_mesh(flowobj, fds, ffs, bb, subframe_dt);
2807 printf(
"Error: unknown flow emission source\n");
2815 bb_freeData(&bb_temp);
2822 printf(
"flow: frame: %d // time per frame: %f // frame length: %f // dt: %f\n",
2830static void update_flowsfluids(Depsgraph *
depsgraph,
2834 float time_per_frame,
2839 FluidObjectBB *bb_maps =
nullptr;
2840 Object **flowobjs =
nullptr;
2841 uint numflowobjs = 0;
2849 update_flowsflags(fds, flowobjs, numflowobjs);
2850 ensure_flowsfields(fds);
2853 bb_maps =
static_cast<FluidObjectBB *
>(
2854 MEM_callocN(
sizeof(FluidObjectBB) * numflowobjs,
"fluid_flow_bb_maps"));
2857 compute_flowsemission(scene,
2870 adaptive_domain_adjust(fds, ob, bb_maps, numflowobjs, dt);
2906 BLI_assert((color_r && color_g && color_b) || (!color_r && !color_g && !color_b));
2907 BLI_assert((color_r_in && color_g_in && color_b_in) ||
2908 (!color_r_in && !color_g_in && !color_b_in));
2909 BLI_assert((velx_initial && vely_initial && velz_initial) ||
2910 (!velx_initial && !vely_initial && !velz_initial));
2914 for (
z = 0;
z < fds->
res[0] * fds->
res[1] * fds->
res[2];
z++) {
2916 if (phistatic_in && is_first_frame) {
2923 if (phioutstatic_in && is_first_frame) {
2931 density_in[
z] = density[
z];
2934 heat_in[
z] = heat[
z];
2936 if (color_r_in && color_g_in && color_b_in) {
2937 color_r_in[
z] = color_r[
z];
2938 color_g_in[
z] = color_b[
z];
2939 color_b_in[
z] = color_g[
z];
2942 fuel_in[
z] = fuel[
z];
2943 react_in[
z] = react[
z];
2946 emission_in[
z] = 0.0f;
2948 if (velx_initial && vely_initial && velz_initial) {
2949 velx_initial[
z] = 0.0f;
2950 vely_initial[
z] = 0.0f;
2951 velz_initial[
z] = 0.0f;
2960 for (
int flow_index = 0; flow_index < numflowobjs; flow_index++) {
2961 Object *flowobj = flowobjs[flow_index];
2977 bool is_static = is_static_object(flowobj) &&
2980 FluidObjectBB *bb = &bb_maps[flow_index];
2981 float *velocity_map = bb->velocity;
2982 float *emission_map = bb->influence;
2983 float *distance_map = bb->distances;
2985 int gx, gy, gz, ex, ey, ez, dx, dy, dz;
2986 size_t e_index, d_index;
2989 for (gx = bb->min[0]; gx < bb->
max[0]; gx++) {
2990 for (gy = bb->min[1]; gy < bb->
max[1]; gy++) {
2991 for (gz = bb->min[2]; gz < bb->
max[2]; gz++) {
2993 ex = gx - bb->min[0];
2994 ey = gy - bb->min[1];
2995 ez = gz - bb->min[2];
3004 if (dx < 0 || dy < 0 || dz < 0 || dx >= fds->
res[0] || dy >= fds->
res[1] ||
3012 float *levelset = ((is_first_frame || is_resume) && is_static) ? phioutstatic_in :
3014 apply_outflow_fields(d_index,
3015 distance_map[e_index],
3026 else if (is_geometry && !is_first_frame) {
3027 apply_inflow_fields(ffs,
3049 else if (is_geometry || is_inflow) {
3050 float *levelset = ((is_first_frame || is_resume) && is_static && !is_geometry) ?
3053 apply_inflow_fields(ffs,
3054 emission_map[e_index],
3055 distance_map[e_index],
3076 float vel_initial[3];
3077 vel_initial[0] = velx_initial[d_index];
3078 vel_initial[1] = vely_initial[d_index];
3079 vel_initial[2] = velz_initial[d_index];
3081 float vel_map_strength =
len_squared_v3(velocity_map + 3 * e_index);
3082 if (vel_map_strength > vel_initial_strength) {
3083 velx_initial[d_index] = velocity_map[e_index * 3];
3084 vely_initial[d_index] = velocity_map[e_index * 3 + 1];
3085 velz_initial[d_index] = velocity_map[e_index * 3 + 2];
3102struct UpdateEffectorsData {
3119static void update_effectors_task_cb(
void *__restrict userdata,
3123 UpdateEffectorsData *
data =
static_cast<UpdateEffectorsData *
>(userdata);
3126 for (
int y = 0;
y < fds->
res[1];
y++) {
3127 for (
int z = 0;
z < fds->
res[2];
z++) {
3130 float voxel_center[3] = {0, 0, 0}, vel[3] = {0, 0, 0}, retvel[3] = {0, 0, 0};
3133 if ((
data->fuel && std::max(
data->density[index],
data->fuel[index]) < FLT_EPSILON) ||
3134 (
data->density &&
data->density[index] < FLT_EPSILON) ||
3135 (
data->phi_obs_in &&
data->phi_obs_in[index] < 0.0f) ||
3136 data->flags[index] & 2)
3171 CLAMP3(retvel, -1.0f, 1.0f);
3178 printf(
"setting force: [%f, %f, %f]\n",
3179 data->force_x[index],
3180 data->force_y[index],
3181 data->force_z[index]);
3187static void update_effectors(
3197 UpdateEffectorsData
data;
3200 data.effectors = effectors;
3232 float cell_size_scaled[3];
3235 const VArraySpan orig_material_indices = *orig_attributes.
lookup<
int>(
"material_index",
3237 const short mp_mat_nr = orig_material_indices.
is_empty() ? 0 : orig_material_indices[0];
3240 int num_verts, num_faces;
3251 printf(
"num_verts: %d, num_faces: %d\n", num_verts, num_faces);
3254 if (!num_verts || !num_faces) {
3279 float max_size = std::max({
size[0],
size[1],
size[2]});
3282 co_scale[0] = max_size / ob->
scale[0];
3283 co_scale[1] = max_size / ob->
scale[1];
3284 co_scale[2] = max_size / ob->
scale[2];
3287 co_offset[0] = (fds->
p0[0] + fds->
p1[0]) / 2.0f;
3288 co_offset[1] = (fds->
p0[1] + fds->
p1[1]) / 2.0f;
3289 co_offset[2] = (fds->
p0[2] + fds->
p1[2]) / 2.0f;
3298 if (use_speedvectors) {
3304 for (i = 0; i < num_verts; i++) {
3324 printf(
"positions[i][0]: %f, positions[i][1]: %f, positions[i][2]: %f\n",
3332 printf(
"no_s[0]: %d, no_s[1]: %d, no_s[2]: %d\n", no_s[0], no_s[1], no_s[2]);
3335 if (use_speedvectors) {
3341 printf(
"velocities[%d].x: %f, velocities[%d].y: %f, velocities[%d].z: %f\n",
3343 velocities.
span[i].x,
3345 velocities.
span[i].y,
3347 velocities.
span[i].z);
3358 material_indices.
span[i] = mp_mat_nr;
3360 face_offsets[i] = i * 3;
3367 printf(
"mloops[0].v: %d, mloops[1].v: %d, mloops[2].v: %d\n",
3375 material_indices.
finish();
3394 float ob_loc[3] = {0};
3395 float ob_cache_loc[3] = {0};
3448 face_offsets.
fill(4);
3453 corner_vert = &corner_verts[0 * 4];
3459 corner_vert = &corner_verts[1 * 4];
3465 corner_vert = &corner_verts[2 * 4];
3471 corner_vert = &corner_verts[3 * 4];
3477 corner_vert = &corner_verts[4 * 4];
3483 corner_vert = &corner_verts[5 * 4];
3492 mul_m4_v3(ob->object_to_world().ptr(), ob_loc);
3498 for (
int i = 0; i < num_verts; i++) {
3507static int manta_step(
3511 float dt, frame_length, time_total, time_total_old;
3512 float time_per_frame;
3513 bool init_resolution =
true;
3528 manta_set_domain_from_mesh(fds, ob,
mesh, init_resolution);
3541 while (time_per_frame + FLT_EPSILON < frame_length) {
3550 update_flowsfluids(
depsgraph, scene, ob, fds, time_per_frame, frame_length, frame, dt);
3553 if (
G.is_break && !mode_replay) {
3561 update_obstacles(
depsgraph, scene, ob, fds, time_per_frame, frame_length, frame, dt);
3564 if (
G.is_break && !mode_replay) {
3571 update_effectors(
depsgraph, scene, ob, fds, dt);
3576 time_per_frame += dt;
3588 manta_smoke_calc_transparency(
3596static void manta_guiding(
3604 update_obstacles(
depsgraph, scene, ob, fds, dt, dt, frame, dt);
3615 const int scene_framenr)
3617 if (scene_framenr >= fmd->
time) {
3628 if (scene_framenr > fmd->
time) {
3629 fmd->
time = scene_framenr;
3631 else if (scene_framenr < fmd->time) {
3632 fmd->
time = scene_framenr;
3642 const int scene_framenr)
3644 if (scene_framenr >= fmd->
time) {
3655 if (scene_framenr > fmd->
time) {
3656 fmd->
time = scene_framenr;
3658 else if (scene_framenr < fmd->time) {
3659 fmd->
time = scene_framenr;
3669 const int scene_framenr)
3672 Object *guide_parent =
nullptr;
3677 bool is_startframe, has_advanced;
3679 has_advanced = (scene_framenr == fmd->
time + 1);
3683 bool escape =
false;
3688 if (scene_framenr < fds->cache_frame_start ||
3704 if (scene_framenr < fds->cache_frame_start || scene_framenr > fds->
cache_frame_end) {
3710 if (escape && fds->
fluid) {
3738 update_flowsflags(fds, objs, numobj);
3744 update_obstacleflags(fds, objs, numobj);
3751 CLOG_ERROR(&
LOG,
"Fluid initialization failed. Should not happen!");
3760 if (fmd_parent && fmd_parent->
domain) {
3766 int o_res[3], o_min[3], o_max[3], o_shift[3];
3778 update_final_gravity(fds, scene);
3780 int next_frame = scene_framenr + 1;
3781 int prev_frame = scene_framenr - 1;
3785 int data_frame = scene_framenr, noise_frame = scene_framenr;
3786 int mesh_frame = scene_framenr, particles_frame = scene_framenr, guide_frame = scene_framenr;
3788 bool with_smoke, with_liquid;
3792 bool drops, bubble, floater;
3798 bool with_script, with_noise, with_mesh, with_particles, with_guide;
3803 with_particles = drops || bubble || floater;
3805 bool has_data, has_noise, has_mesh, has_particles, has_guide, has_config;
3817 ensure_flowsfields(fds);
3818 ensure_obstaclefields(fds);
3821 bool baking_data, baking_noise, baking_mesh, baking_particles, baking_guide;
3828 bool resume_data, resume_noise, resume_mesh, resume_particles, resume_guide;
3835 bool read_cache, bake_cache;
3837 bake_cache = baking_data || baking_noise || baking_mesh || baking_particles || baking_guide;
3839 bool next_data, next_noise, next_mesh, next_particles, next_guide;
3846 bool prev_data, prev_noise, prev_mesh, prev_particles, prev_guide;
3864 if (!baking_data && !baking_noise && !baking_mesh && !baking_particles && !baking_guide) {
3878 if (baking_data && resume_data) {
3879 data_frame = prev_frame;
3881 if (baking_noise && resume_noise) {
3882 noise_frame = prev_frame;
3884 if (baking_mesh && resume_mesh) {
3885 mesh_frame = prev_frame;
3887 if (baking_particles && resume_particles) {
3888 particles_frame = prev_frame;
3890 if (baking_guide && resume_guide) {
3891 guide_frame = prev_frame;
3905 baking_data = !has_data && (is_startframe || prev_data);
3906 if (with_smoke && with_noise) {
3907 baking_noise = !has_noise && (is_startframe || prev_noise);
3909 if (with_liquid && with_mesh) {
3910 baking_mesh = !has_mesh && (is_startframe || prev_mesh);
3912 if (with_liquid && with_particles) {
3913 baking_particles = !has_particles && (is_startframe || prev_particles);
3922 bool read_partial =
false, read_all =
false;
3929 if (with_liquid && with_mesh) {
3930 if (mesh_frame != scene_framenr) {
3942 if (with_liquid && with_particles) {
3943 if (particles_frame != scene_framenr) {
3947 read_partial = !baking_data && !baking_particles && next_particles;
3948 read_all = !read_partial && with_resumable_cache;
3959 if (with_smoke && with_noise) {
3960 if (noise_frame != scene_framenr) {
3967 fds, o_res, fds->
res, o_min, fds->
res_min, o_max, o_shift, fds->
shift);
3970 read_partial = !baking_data && !baking_noise && next_noise;
3971 read_all = !read_partial && with_resumable_cache;
3974 read_partial = !baking_data && !baking_noise && next_data && next_noise;
3975 read_all = !read_partial && with_resumable_cache;
3980 if (data_frame != scene_framenr) {
3991 read_partial = !baking_data && !baking_particles && !baking_mesh && next_data &&
3993 read_all = !read_partial && with_resumable_cache;
4002 if (!baking_data && !baking_noise && !baking_mesh && !baking_particles && !baking_guide) {
4009 baking_guide = !has_guide && (is_startframe || prev_guide);
4011 baking_data = !has_data && (is_startframe || prev_data);
4012 if (with_smoke && with_noise) {
4013 baking_noise = !has_noise && (is_startframe || prev_noise);
4015 if (with_liquid && with_mesh) {
4016 baking_mesh = !has_mesh && (is_startframe || prev_mesh);
4018 if (with_liquid && with_particles) {
4019 baking_particles = !has_particles && (is_startframe || prev_particles);
4023 if (is_startframe || has_advanced) {
4024 bake_cache = baking_data || baking_noise || baking_mesh || baking_particles;
4035 if (with_script && is_startframe) {
4044 if (baking_guide && with_guide) {
4045 manta_guiding(
depsgraph, scene, ob, fmd, scene_framenr);
4049 if (manta_step(
depsgraph, scene, ob,
mesh, fmd, scene_framenr)) {
4054 if (has_data || baking_data) {
4055 if (baking_noise && with_smoke && with_noise) {
4062 if (baking_mesh && with_liquid && with_mesh) {
4065 if (baking_particles && with_liquid && with_particles) {
4075 fmd->
time = scene_framenr;
4078static void fluid_modifier_process(
4084 fluid_modifier_processFlow(fmd,
depsgraph, scene, ob,
mesh, scene_framenr);
4087 fluid_modifier_processEffector(fmd,
depsgraph, scene, ob,
mesh, scene_framenr);
4090 fluid_modifier_processDomain(fmd,
depsgraph, scene, ob,
mesh, scene_framenr);
4099 bool needs_viewport_update =
false;
4121 needs_viewport_update =
true;
4127 bool baking_data, baking_noise, baking_mesh, baking_particles, baking_guide;
4134 if (with_mesh && !baking_data && !baking_noise && !baking_mesh && !baking_particles &&
4137 needs_viewport_update =
true;
4145 if (needs_viewport_update) {
4180static float calc_voxel_transp(
4181 float *
result,
const float *input,
int res[3],
int *pixel,
float *t_ray,
float correct)
4186 *t_ray *=
expf(input[index] * correct);
4188 if (
result[index] < 0.0f) {
4195static void bresenham_linie_3D(
int x1,
4208 int dx, dy, dz, i,
l, m, n, x_inc, y_inc, z_inc, err_1, err_2, dx2, dy2, dz2;
4219 x_inc = (dx < 0) ? -1 : 1;
4221 y_inc = (dy < 0) ? -1 : 1;
4223 z_inc = (dz < 0) ? -1 : 1;
4229 if ((
l >= m) && (
l >= n)) {
4232 for (i = 0; i <
l; i++) {
4233 if (cb(
result, input, res, pixel, t_ray, correct) <= FLT_EPSILON) {
4249 else if ((m >=
l) && (m >= n)) {
4252 for (i = 0; i < m; i++) {
4253 if (cb(
result, input, res, pixel, t_ray, correct) <= FLT_EPSILON) {
4272 for (i = 0; i < n; i++) {
4273 if (cb(
result, input, res, pixel, t_ray, correct) <= FLT_EPSILON) {
4289 cb(
result, input, res, pixel, t_ray, correct);
4298 int slabsize = fds->
res[0] * fds->
res[1];
4301 float correct = -7.0f * fds->
dx;
4303 if (!get_light(scene, view_layer, light)) {
4309 light[0] = (light[0] - fds->
p0[0]) / fds->
cell_size[0] - 0.5f -
float(fds->
res_min[0]);
4310 light[1] = (light[1] - fds->
p0[1]) / fds->
cell_size[1] - 0.5f -
float(fds->
res_min[1]);
4311 light[2] = (light[2] - fds->
p0[2]) / fds->
cell_size[2] - 0.5f -
float(fds->
res_min[2]);
4319 for (
int z = 0;
z < fds->
res[2];
z++) {
4320 size_t index =
z * slabsize;
4322 for (
int y = 0;
y < fds->
res[1];
y++) {
4324 float voxel_center[3];
4330 shadow[
index] = -1.0f;
4332 voxel_center[0] =
float(
x);
4333 voxel_center[1] =
float(
y);
4334 voxel_center[2] =
float(
z);
4350 CLAMP(cell[0], 0, fds->
res[0] - 1);
4351 CLAMP(cell[1], 0, fds->
res[1] - 1);
4352 CLAMP(cell[2], 0, fds->
res[2] - 1);
4354 bresenham_linie_3D(cell[0],
4368 shadow[
index] = t_ray;
4385 float density = 0.0f, fuel = 0.0f;
4388 manta_pos_to_cell(fds,
pos);
4405 if (
pos[0] < 0.0f ||
pos[1] < 0.0f ||
pos[2] < 0.0f) {
4408 if (
pos[0] > 1.0f ||
pos[1] > 1.0f ||
pos[2] > 1.0f) {
4423 vel_mag =
len_v3(velocity);
4433 return std::max(density, fuel);
4459 const char *pset_name,
4460 const char *parts_name,
4461 const char *psys_name,
4462 const int psys_type)
4470 psys = MEM_cnew<ParticleSystem>(__func__);
4472 part->
type = psys_type;
4497 next_psys = psys->
next;
4498 if (psys->
part->
type == particle_type) {
4613 settings->
type = type;
4633 settings->
type = type;
4638 settings->
type = type;
4645 const char coba_field = settings->
coba_field;
4649 if (
ELEM(coba_field,
4665 if (
ELEM(coba_field,
4730 fmd->
flow =
nullptr;
4778 else if (fmd->
flow) {
4826#ifndef WITH_OPENVDB_BLOSC
4833 char cache_name[64];
5050 else if (tfmd->
flow) {
5107 static int counter = 1;
void free_bvhtree_from_mesh(BVHTreeFromMesh *data)
BVHTree * BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data, const Mesh *mesh, BVHCacheType bvh_cache_type, int tree_type)
@ BVHTREE_FROM_CORNER_TRIS
void BKE_collision_objects_free(struct Object **objects)
struct Object ** BKE_collision_objects_create(struct Depsgraph *depsgraph, struct Object *self, struct Collection *collection, unsigned int *numcollobj, unsigned int modifier_type)
CustomData interface, see also DNA_customdata_types.h.
const void * CustomData_get_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
struct EffectorWeights * BKE_effector_add_weights(struct Collection *collection)
void BKE_effectors_free(struct ListBase *lb)
void BKE_effectors_apply(struct ListBase *effectors, struct ListBase *colliders, struct EffectorWeights *weights, struct EffectedPoint *point, float *force, float *wind_force, float *impulse)
struct ListBase * BKE_effectors_create(struct Depsgraph *depsgraph, struct Object *ob_src, struct ParticleSystem *psys_src, struct EffectorWeights *weights, bool use_rotation)
void pd_point_from_loc(struct Scene *scene, float *loc, float *vel, int index, struct EffectedPoint *point)
void BKE_fluid_cache_free_all(struct FluidDomainSettings *fds, struct Object *ob)
int BKE_fluid_get_data_flags(struct FluidDomainSettings *fds)
bool BKE_fluid_reallocate_fluid(struct FluidDomainSettings *fds, int res[3], int free_old)
void BKE_fluid_particle_system_destroy(struct Object *ob, int particle_type)
struct Mesh * BKE_fluid_modifier_do(struct FluidModifierData *fmd, struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct Mesh *mesh)
void BKE_fluid_particle_system_create(struct Main *bmain, struct Object *ob, const char *pset_name, const char *parts_name, const char *psys_name, int psys_type)
float(* BKE_Fluid_BresenhamFn)(float *result, const float *input, int res[3], int *pixel, float *tRay, float correct)
void BKE_fluid_reallocate_copy_fluid(struct FluidDomainSettings *fds, int o_res[3], int n_res[3], const int o_min[3], const int n_min[3], const int o_max[3], int o_shift[3], int n_shift[3])
float BKE_fluid_get_velocity_at(struct Object *ob, float position[3], float velocity[3])
void BKE_fluid_cache_free(struct FluidDomainSettings *fds, struct Object *ob, int cache_map)
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
ListBase * BKE_view_layer_object_bases_get(ViewLayer *view_layer)
void BKE_id_free(Main *bmain, void *idv)
@ LIB_ID_COPY_SET_COPIED_ON_WRITE
void BKE_mesh_copy_parameters_for_eval(Mesh *me_dst, const Mesh *me_src)
Mesh * BKE_mesh_new_nomain(int verts_num, int edges_num, int faces_num, int corners_num)
Mesh * BKE_mesh_copy_for_eval(const Mesh &source)
void BKE_mesh_texspace_calc(Mesh *mesh)
void BKE_modifier_path_init(char *path, int path_maxncpy, const char *name)
ModifierData * BKE_modifiers_findby_type(const Object *ob, ModifierType type)
void BKE_modifiers_persistent_uid_init(const Object &object, ModifierData &md)
const char * BKE_modifier_path_relbase_from_global(Object *ob)
void BKE_modifier_unique_name(ListBase *modifiers, ModifierData *md)
void BKE_modifier_free(ModifierData *md)
void BKE_modifier_remove_from_list(Object *ob, ModifierData *md)
ModifierData * BKE_modifiers_get_virtual_modifierlist(const Object *ob, VirtualModifierData *data)
ModifierData * BKE_modifier_new(int type)
General operations, lookup, etc. for blender objects.
bool BKE_object_modifier_update_subframe(Depsgraph *depsgraph, Scene *scene, Object *ob, bool update_mesh, int parent_recursion, float frame, int type)
bool BKE_object_moves_in_time(const Object *object, bool recurse_parent)
struct ParticleSystemModifierData * psys_get_modifier(struct Object *ob, struct ParticleSystem *psys)
void psys_sim_data_free(struct ParticleSimulationData *sim)
void psys_free(struct Object *ob, struct ParticleSystem *psys)
struct ParticleSettings * BKE_particlesettings_add(struct Main *bmain, const char *name)
void psys_sim_data_init(struct ParticleSimulationData *sim)
bool psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct ParticleKey *state, bool always)
struct PointCache * BKE_ptcache_copy_list(struct ListBase *ptcaches_new, const struct ListBase *ptcaches_old, int flag)
struct PointCache * BKE_ptcache_add(struct ListBase *ptcaches)
void BKE_ptcache_free_list(struct ListBase *ptcaches)
#define PTCACHE_RESET_OUTDATED
int BKE_ptcache_id_reset(struct Scene *scene, PTCacheID *pid, int mode)
void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct FluidModifierData *fmd)
float BKE_scene_ctime_get(const Scene *scene)
void BKE_texture_get_value(struct Tex *texture, const float *tex_co, struct TexResult *texres, bool use_color_management)
#define BLI_assert_unreachable()
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
int BLI_delete(const char *path, bool dir, bool recursive) ATTR_NONNULL()
BLI_INLINE unsigned int BLI_hash_int(unsigned int k)
float BLI_bvhtree_bb_raycast(const float bv[6], const float light_start[3], const float light_end[3], float pos[3])
int BLI_bvhtree_find_nearest(const BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata)
int BLI_bvhtree_ray_cast(const BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata)
A KD-tree for nearest neighbor search.
#define LISTBASE_FOREACH(type, var, list)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
MINLINE float pow2f(float x)
MINLINE int max_ii(int a, int b)
MINLINE int min_iii(int a, int b, int c)
void interp_weights_tri_v3(float w[3], const float v1[3], const float v2[3], const float v3[3], const float co[3])
void mul_m4_v3(const float M[4][4], float r[3])
void copy_m4_m4(float m1[4][4], const float m2[4][4])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
void mul_mat3_m4_v3(const float mat[4][4], float r[3])
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
MINLINE void add_v3fl_v3fl_v3i(float r[3], const float a[3], const int b[3])
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_fl(float r[3], float f)
MINLINE void madd_v3fl_v3fl_v3fl_v3i(float r[3], const float a[3], const float b[3], const int c[3])
MINLINE void mul_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE bool equals_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT
void interp_v3_v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
void interp_v2_v2v2v2(float r[2], const float a[2], const float b[2], const float c[2], const float t[3])
MINLINE void copy_v3_v3_int(int r[3], const int a[3])
void copy_vn_fl(float *array_tar, int size, float val)
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void zero_v3_int(int r[3])
MINLINE void abs_v3(float r[3])
MINLINE void negate_v3(float r[3])
MINLINE void sub_v3_v3v3_int(int r[3], const int a[3], const int b[3])
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE void zero_v3(float r[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3(float n[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
bool BLI_path_abs(char path[FILE_MAX], const char *basepath) ATTR_NONNULL(1
#define BLI_path_join(...)
#define STRNCPY(dst, src)
size_t BLI_snprintf(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
ThreadRWMutex * BLI_rw_mutex_alloc(void)
pthread_rwlock_t ThreadRWMutex
#define THREAD_LOCK_WRITE
#define BLI_MUTEX_INITIALIZER
void BLI_rw_mutex_lock(ThreadRWMutex *mutex, int mode)
void BLI_mutex_lock(ThreadMutex *mutex)
void BLI_mutex_unlock(ThreadMutex *mutex)
void BLI_rw_mutex_free(ThreadRWMutex *mutex)
void BLI_rw_mutex_unlock(ThreadRWMutex *mutex)
pthread_mutex_t ThreadMutex
#define INIT_MINMAX(min, max)
#define CLAMP3(vec, b, c)
float BLI_voxel_sample_trilinear(const float *data, const int res[3], const float co[3])
#define CLOG_ERROR(clg_ref,...)
float DEG_get_ctime(const Depsgraph *graph)
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
ViewLayer * DEG_get_evaluated_view_layer(const Depsgraph *graph)
#define DNA_struct_default_alloc(struct_name)
#define FLUID_DOMAIN_DIR_DATA
#define FLUID_DOMAIN_DIR_PARTICLES
struct FluidFlowSettings FluidFlowSettings
@ FLUID_DOMAIN_GUIDE_SRC_DOMAIN
@ FLUID_EFFECTOR_GUIDE_MAX
@ FLUID_EFFECTOR_GUIDE_OVERRIDE
@ FLUID_EFFECTOR_GUIDE_AVERAGED
@ FLUID_EFFECTOR_GUIDE_MIN
#define FLUID_DOMAIN_DIR_DEFAULT
@ FLUID_DOMAIN_TYPE_LIQUID
@ FLUID_EFFECTOR_TYPE_GUIDE
@ FLUID_EFFECTOR_TYPE_COLLISION
@ FLUID_DOMAIN_PARTICLE_SPRAY
@ FLUID_DOMAIN_PARTICLE_FOAM
@ FLUID_DOMAIN_PARTICLE_TRACER
@ FLUID_DOMAIN_PARTICLE_BUBBLE
#define FLUID_DOMAIN_DIR_MESH
#define FLUID_DOMAIN_DIR_GUIDE
#define FLUID_DOMAIN_DIR_SCRIPT
@ FLUID_EFFECTOR_NEEDS_UPDATE
@ FLUID_EFFECTOR_USE_EFFEC
@ FLUID_EFFECTOR_USE_PLANE_INIT
@ FLUID_DOMAIN_ACTIVE_COLORS
@ FLUID_DOMAIN_ACTIVE_FIRE
@ FLUID_DOMAIN_ACTIVE_INVEL
@ FLUID_DOMAIN_ACTIVE_GUIDE
@ FLUID_DOMAIN_ACTIVE_OUTFLOW
@ FLUID_DOMAIN_ACTIVE_COLOR_SET
@ FLUID_DOMAIN_ACTIVE_HEAT
@ FLUID_DOMAIN_ACTIVE_OBSTACLE
@ FLUID_DOMAIN_FIELD_COLOR_B
@ FLUID_DOMAIN_FIELD_FLAME
@ FLUID_DOMAIN_FIELD_PHI_OUT
@ FLUID_DOMAIN_FIELD_PHI_OBSTACLE
@ FLUID_DOMAIN_FIELD_DENSITY
@ FLUID_DOMAIN_FIELD_PHI_IN
@ FLUID_DOMAIN_FIELD_HEAT
@ FLUID_DOMAIN_FIELD_COLOR_G
@ FLUID_DOMAIN_FIELD_FUEL
@ FLUID_DOMAIN_FIELD_COLOR_R
@ FLUID_DOMAIN_BAKED_DATA
@ FLUID_DOMAIN_OUTDATED_GUIDE
@ FLUID_DOMAIN_OUTDATED_PARTICLES
@ FLUID_DOMAIN_BAKING_MESH
@ FLUID_DOMAIN_BAKING_NOISE
@ FLUID_DOMAIN_BAKING_GUIDE
@ FLUID_DOMAIN_OUTDATED_NOISE
@ FLUID_DOMAIN_BAKED_NOISE
@ FLUID_DOMAIN_BAKED_MESH
@ FLUID_DOMAIN_OUTDATED_MESH
@ FLUID_DOMAIN_BAKING_DATA
@ FLUID_DOMAIN_BAKED_GUIDE
@ FLUID_DOMAIN_BAKED_PARTICLES
@ FLUID_DOMAIN_OUTDATED_DATA
@ FLUID_DOMAIN_BAKING_PARTICLES
@ FLUID_DOMAIN_BORDER_BOTTOM
@ FLUID_DOMAIN_BORDER_LEFT
@ FLUID_DOMAIN_BORDER_RIGHT
@ FLUID_DOMAIN_BORDER_FRONT
@ FLUID_DOMAIN_BORDER_TOP
@ FLUID_DOMAIN_BORDER_BACK
@ FLUID_FLOW_TEXTURE_MAP_AUTO
@ FLUID_FLOW_TYPE_SMOKEFIRE
struct FluidEffectorSettings FluidEffectorSettings
#define FLUID_DOMAIN_DIR_CONFIG
@ FLUID_FLOW_BEHAVIOR_GEOMETRY
@ FLUID_FLOW_BEHAVIOR_OUTFLOW
@ FLUID_FLOW_BEHAVIOR_INFLOW
struct FluidDomainSettings FluidDomainSettings
@ FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN
@ FLUID_DOMAIN_USE_RESUMABLE_CACHE
@ FLUID_DOMAIN_EXPORT_MANTA_SCRIPT
@ FLUID_DOMAIN_USE_SPEED_VECTORS
#define FLUID_DOMAIN_DIR_NOISE
@ VDB_PRECISION_MINI_FLOAT
@ VDB_PRECISION_HALF_FLOAT
@ FLUID_DOMAIN_CACHE_REPLAY
@ FLUID_DOMAIN_CACHE_MODULAR
@ FLUID_FLOW_SOURCE_PARTICLES
@ FLUID_FLOW_USE_PART_SIZE
@ FLUID_FLOW_NEEDS_UPDATE
@ FLUID_FLOW_USE_PLANE_INIT
@ FLUID_FLOW_INITVELOCITY
struct MDeformVert MDeformVert
@ eModifierFlag_SharedCaches
@ eModifierType_ParticleSystem
@ eModifierType_DynamicPaint
Object is a sort of wrapper for general info.
Types and defines for representing Rigid Body entities.
Read Guarded memory(de)allocation.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
BPy_StructRNA * depsgraph
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
constexpr IndexRange drop_back(int64_t n) const
constexpr void fill(const T &value) const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
GAttributeReader lookup(const StringRef attribute_id) const
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
GSpanAttributeWriter lookup_or_add_for_write_only_span(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type)
pow(value.r - subtrahend, 2.0)") .do_static_compilation(true)
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
smooth(Type::VEC3, "P") .flat(Type out_color storage_buf(0, Qualifier::READ, "Surfel", "surfels_buf[]") .push_constant(Type smooth(Type::VEC4, "interp_color")
void BKE_fluid_cachetype_noise_set(FluidDomainSettings *settings, int cache_noise_format)
void BKE_fluid_flow_behavior_set(Object *, FluidFlowSettings *settings, int behavior)
static void fluid_modifier_reset_ex(FluidModifierData *fmd, bool need_lock)
void BKE_fluid_cachetype_particle_set(FluidDomainSettings *settings, int cache_particle_format)
static void fluid_modifier_freeDomain(FluidModifierData *fmd)
static void fluid_modifier_freeFlow(FluidModifierData *fmd)
void BKE_fluid_domain_type_set(Object *object, FluidDomainSettings *settings, int type)
void BKE_fluid_particles_set(FluidDomainSettings *settings, int value, bool clear)
void BKE_fluid_cachetype_data_set(FluidDomainSettings *settings, int cache_data_format)
static void fluid_modifier_freeEffector(FluidModifierData *fmd)
void BKE_fluid_collisionextents_set(FluidDomainSettings *settings, int value, bool clear)
void BKE_fluid_modifier_copy(const FluidModifierData *fmd, FluidModifierData *tfmd, const int flag)
void BKE_fluid_modifier_create_type_data(FluidModifierData *fmd)
void BKE_fluid_cache_new_name_for_current_session(int maxlen, char *r_name)
void BKE_fluid_cache_endframe_set(FluidDomainSettings *settings, int value)
void BKE_fluid_fields_sanitize(FluidDomainSettings *settings)
void BKE_fluid_cache_startframe_set(FluidDomainSettings *settings, int value)
void BKE_fluid_modifier_reset(FluidModifierData *fmd)
void BKE_fluid_flow_type_set(Object *object, FluidFlowSettings *settings, int type)
void BKE_fluid_cachetype_mesh_set(FluidDomainSettings *settings, int cache_mesh_format)
void BKE_fluid_effector_type_set(Object *, FluidEffectorSettings *settings, int type)
void BKE_fluid_modifier_free(FluidModifierData *fmd)
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_dupallocN)(const void *vmemh)
float * manta_noise_get_density(struct MANTA *smoke)
bool manta_has_particles(struct MANTA *fluid, struct FluidModifierData *fmd, int framenr)
float * manta_smoke_get_color_r(struct MANTA *smoke)
float * manta_noise_get_texture_v(struct MANTA *smoke)
float * manta_smoke_get_heat_in(struct MANTA *smoke)
bool manta_has_mesh(struct MANTA *fluid, struct FluidModifierData *fmd, int framenr)
float manta_liquid_get_vertex_y_at(struct MANTA *liquid, int i)
float * manta_noise_get_react(struct MANTA *smoke)
float * manta_get_force_z(struct MANTA *fluid)
bool manta_ensure_invelocity(struct MANTA *fluid, struct FluidModifierData *fmd)
bool manta_read_guiding(struct MANTA *fluid, struct FluidModifierData *fmd, int framenr, bool sourceDomain)
bool manta_has_data(struct MANTA *fluid, struct FluidModifierData *fmd, int framenr)
bool manta_bake_particles(struct MANTA *fluid, struct FluidModifierData *fmd, int framenr)
bool manta_smoke_ensure_colors(struct MANTA *smoke, struct FluidModifierData *fmd)
float * manta_smoke_get_fuel_in(struct MANTA *smoke)
float * manta_noise_get_texture_u(struct MANTA *smoke)
void manta_free(struct MANTA *fluid)
float * manta_get_num_guide(struct MANTA *fluid)
bool manta_smoke_has_heat(struct MANTA *smoke)
int manta_liquid_get_num_triangles(struct MANTA *liquid)
float * manta_get_force_y(struct MANTA *fluid)
bool manta_bake_mesh(struct MANTA *fluid, struct FluidModifierData *fmd, int framenr)
float manta_get_timestep(struct MANTA *fluid)
float * manta_get_guide_velocity_y(struct MANTA *fluid)
float * manta_smoke_get_react(struct MANTA *smoke)
float * manta_get_in_velocity_y(struct MANTA *fluid)
bool manta_bake_noise(struct MANTA *fluid, struct FluidModifierData *fmd, int framenr)
float * manta_smoke_get_shadow(struct MANTA *fluid)
float * manta_get_ob_velocity_x(struct MANTA *fluid)
float * manta_get_ob_velocity_z(struct MANTA *fluid)
float * manta_noise_get_texture_w(struct MANTA *smoke)
bool manta_read_mesh(struct MANTA *fluid, struct FluidModifierData *fmd, int framenr)
bool manta_liquid_ensure_sndparts(struct MANTA *fluid, struct FluidModifierData *fmd)
float * manta_get_guide_velocity_z(struct MANTA *fluid)
float * manta_get_in_velocity_x(struct MANTA *fluid)
struct MANTA * manta_init(int *res, struct FluidModifierData *fmd)
float * manta_get_guide_velocity_x(struct MANTA *fluid)
float * manta_smoke_get_color_g_in(struct MANTA *smoke)
float * manta_noise_get_fuel(struct MANTA *smoke)
bool manta_write_data(struct MANTA *fluid, struct FluidModifierData *fmd, int framenr)
float * manta_noise_get_texture_v2(struct MANTA *smoke)
float * manta_get_phioutstatic_in(struct MANTA *fluid)
bool manta_smoke_ensure_fire(struct MANTA *smoke, struct FluidModifierData *fmd)
void manta_noise_get_res(struct MANTA *smoke, int *res)
float * manta_get_velocity_y(struct MANTA *fluid)
float manta_liquid_get_vertvel_y_at(struct MANTA *liquid, int i)
float * manta_noise_get_color_b(struct MANTA *smoke)
int manta_liquid_get_num_verts(struct MANTA *liquid)
float * manta_smoke_get_color_b_in(struct MANTA *smoke)
bool manta_ensure_obstacle(struct MANTA *fluid, struct FluidModifierData *fmd)
bool manta_write_config(struct MANTA *fluid, struct FluidModifierData *fmd, int framenr)
bool manta_needs_realloc(struct MANTA *fluid, struct FluidModifierData *fmd)
float * manta_noise_get_texture_w2(struct MANTA *smoke)
float * manta_get_force_x(struct MANTA *fluid)
bool manta_has_noise(struct MANTA *fluid, struct FluidModifierData *fmd, int framenr)
float * manta_get_phiguide_in(struct MANTA *fluid)
float manta_liquid_get_vertvel_z_at(struct MANTA *liquid, int i)
bool manta_read_noise(struct MANTA *fluid, struct FluidModifierData *fmd, int framenr, bool resumable)
size_t manta_get_index(int x, int max_x, int y, int max_y, int z)
float * manta_get_ob_velocity_y(struct MANTA *fluid)
bool manta_read_particles(struct MANTA *fluid, struct FluidModifierData *fmd, int framenr, bool resumable)
bool manta_write_noise(struct MANTA *fluid, struct FluidModifierData *fmd, int framenr)
float * manta_smoke_get_density(struct MANTA *smoke)
float * manta_get_phiobsstatic_in(struct MANTA *fluid)
float manta_liquid_get_vertvel_x_at(struct MANTA *liquid, int i)
float * manta_get_in_velocity_z(struct MANTA *fluid)
float * manta_noise_get_color_g(struct MANTA *smoke)
float * manta_smoke_get_color_r_in(struct MANTA *smoke)
bool manta_smoke_ensure_heat(struct MANTA *smoke, struct FluidModifierData *fmd)
float * manta_get_num_obstacle(struct MANTA *fluid)
void manta_update_pointers(struct MANTA *fluid, struct FluidModifierData *fmd, bool flush)
bool manta_ensure_guiding(struct MANTA *fluid, struct FluidModifierData *fmd)
float * manta_get_phi_in(struct MANTA *fluid)
bool manta_read_data(struct MANTA *fluid, struct FluidModifierData *fmd, int framenr, bool resumable)
float * manta_smoke_get_react_in(struct MANTA *smoke)
float * manta_get_velocity_z(struct MANTA *fluid)
bool manta_has_guiding(struct MANTA *fluid, struct FluidModifierData *fmd, int framenr, bool domain)
bool manta_smoke_has_colors(struct MANTA *smoke)
bool manta_read_config(struct MANTA *fluid, struct FluidModifierData *fmd, int framenr)
float * manta_smoke_get_density_in(struct MANTA *smoke)
float manta_liquid_get_vertex_z_at(struct MANTA *liquid, int i)
float * manta_noise_get_texture_u2(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)
int manta_liquid_get_triangle_z_at(struct MANTA *liquid, int i)
bool manta_smoke_has_fuel(struct MANTA *smoke)
float * manta_smoke_get_emission_in(struct MANTA *smoke)
float manta_liquid_get_vertex_x_at(struct MANTA *liquid, int i)
float * manta_smoke_get_color_g(struct MANTA *smoke)
bool manta_liquid_export_script(struct MANTA *smoke, struct FluidModifierData *fmd)
bool manta_ensure_outflow(struct MANTA *fluid, struct FluidModifierData *fmd)
void manta_update_variables(struct MANTA *fluid, struct FluidModifierData *fmd)
float * manta_smoke_get_heat(struct MANTA *smoke)
int manta_liquid_get_triangle_x_at(struct MANTA *liquid, int i)
float * manta_get_phistatic_in(struct MANTA *fluid)
float * manta_smoke_get_color_b(struct MANTA *smoke)
void manta_adapt_timestep(struct MANTA *fluid)
int manta_liquid_get_triangle_y_at(struct MANTA *liquid, int i)
bool manta_bake_data(struct MANTA *fluid, struct FluidModifierData *fmd, int framenr)
float * manta_smoke_get_fuel(struct MANTA *smoke)
bool manta_smoke_export_script(struct MANTA *smoke, struct FluidModifierData *fmd)
float * manta_smoke_get_flame(struct MANTA *smoke)
float * manta_noise_get_flame(struct MANTA *smoke)
float * manta_noise_get_color_r(struct MANTA *smoke)
bool manta_bake_guiding(struct MANTA *fluid, struct FluidModifierData *fmd, int framenr)
ccl_device_inline float2 floor(const float2 a)
ccl_device_inline float3 ceil(const float3 a)
static void clear(Message &msg)
void mesh_smooth_set(Mesh &mesh, bool use_smooth, bool keep_sharp_edges=false)
void mesh_calc_edges(Mesh &mesh, bool keep_existing_edges, bool select_new_edges)
MatBase< T, NumCol, NumRow > scale(const MatBase< T, NumCol, NumRow > &mat, const VectorT &scale)
OffsetIndices< int > accumulate_counts_to_offsets(MutableSpan< int > counts_to_offsets, int start_offset=0)
bool is_adaptive(const CpuPatchTable *patch_table)
VecBase< int32_t, 3 > int3
static void update_velocities(PTCacheEdit *edit)
BVHTree_RayCastCallback raycast_callback
BVHTree_NearestPointCallback nearest_callback
float gridlines_upper_bound
float gridlines_lower_bound
float sndparticle_tau_min_wc
struct ListBase ptcaches[2]
int sndparticle_update_radius
struct FluidModifierData * fmd
char sndparticle_boundary
float fractions_threshold
char cache_particle_format
float particle_randomness
int sndparticle_potential_radius
int cache_frame_pause_mesh
struct Collection * force_group
float mesh_particle_radius
int cache_frame_pause_data
float flame_smoke_color[3]
float sndparticle_tau_max_wc
float sndparticle_tau_max_ta
struct Collection * effector_group
int cache_frame_pause_particles
int cache_frame_pause_guide
float sndparticle_tau_min_ta
char gridlines_cell_filter
struct PointCache * point_cache[2]
char sndparticle_combined_export
float particle_band_width
float sndparticle_tau_min_k
char cache_directory[1024]
float gridlines_range_color[4]
char vector_scale_with_magnitude
char vector_draw_mac_components
int cache_frame_pause_noise
struct Object * guide_parent
float sndparticle_tau_max_k
struct Collection * fluid_group
struct EffectorWeights * effector_weights
char gridlines_color_field
struct FluidModifierData * fmd
struct FluidModifierData * fmd
struct ParticleSystem * psys
struct Tex * noise_texture
struct FluidDomainSettings * domain
struct FluidEffectorSettings * effector
struct FluidFlowSettings * flow
struct ModifierData * next
ObjectRuntimeHandle * runtime
struct RigidBodyOb * rigidbody_object
struct PointCache * cache
struct Depsgraph * depsgraph
struct ParticleSystem * psys
struct ParticleSystem * psys
struct ParticleSystem * next
struct PointCache * pointcache
struct PhysicsSettings physics_settings
MutableVArraySpan< T > span
ccl_device_inline int abs(int x)