Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/fluid.cc
| Show First 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | |||||
| dest_vel_x[index] += src_vel_value[0]; | dest_vel_x[index] += src_vel_value[0]; | ||||
| dest_vel_y[index] += src_vel_value[1]; | dest_vel_y[index] += src_vel_value[1]; | ||||
| dest_vel_z[index] += src_vel_value[2]; | dest_vel_z[index] += src_vel_value[2]; | ||||
| } | } | ||||
| } | } | ||||
| static void update_velocities(FluidEffectorSettings *fes, | static void update_velocities(FluidEffectorSettings *fes, | ||||
| const float (*vert_positions)[3], | const float (*vert_positions)[3], | ||||
| const MLoop *mloop, | const int *corner_verts, | ||||
| const MLoopTri *mlooptri, | const MLoopTri *mlooptri, | ||||
| float *velocity_map, | float *velocity_map, | ||||
| int index, | int index, | ||||
| BVHTreeFromMesh *tree_data, | BVHTreeFromMesh *tree_data, | ||||
| const float ray_start[3], | const float ray_start[3], | ||||
| const float *vert_vel, | const float *vert_vel, | ||||
| bool has_velocity) | bool has_velocity) | ||||
| { | { | ||||
| Show All 9 Lines | |||||
| /* Find the nearest point on the mesh. */ | /* Find the nearest point on the mesh. */ | ||||
| if (has_velocity && | if (has_velocity && | ||||
| BLI_bvhtree_find_nearest( | BLI_bvhtree_find_nearest( | ||||
| tree_data->tree, ray_start, &nearest, tree_data->nearest_callback, tree_data) != -1) { | tree_data->tree, ray_start, &nearest, tree_data->nearest_callback, tree_data) != -1) { | ||||
| float weights[3]; | float weights[3]; | ||||
| int v1, v2, v3, f_index = nearest.index; | int v1, v2, v3, f_index = nearest.index; | ||||
| /* Calculate barycentric weights for nearest point. */ | /* Calculate barycentric weights for nearest point. */ | ||||
| v1 = mloop[mlooptri[f_index].tri[0]].v; | v1 = corner_verts[mlooptri[f_index].tri[0]]; | ||||
| v2 = mloop[mlooptri[f_index].tri[1]].v; | v2 = corner_verts[mlooptri[f_index].tri[1]]; | ||||
| v3 = mloop[mlooptri[f_index].tri[2]].v; | v3 = corner_verts[mlooptri[f_index].tri[2]]; | ||||
| interp_weights_tri_v3( | interp_weights_tri_v3( | ||||
| weights, vert_positions[v1], vert_positions[v2], vert_positions[v3], nearest.co); | weights, vert_positions[v1], vert_positions[v2], vert_positions[v3], nearest.co); | ||||
| /* Apply object velocity. */ | /* Apply object velocity. */ | ||||
| float hit_vel[3]; | float hit_vel[3]; | ||||
| interp_v3_v3v3v3(hit_vel, &vert_vel[v1 * 3], &vert_vel[v2 * 3], &vert_vel[v3 * 3], weights); | interp_v3_v3v3v3(hit_vel, &vert_vel[v1 * 3], &vert_vel[v2 * 3], &vert_vel[v3 * 3], weights); | ||||
| /* Guiding has additional velocity multiplier */ | /* Guiding has additional velocity multiplier */ | ||||
| ▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | |||||
| copy_v3_fl(velocity_map, 0.0); | copy_v3_fl(velocity_map, 0.0); | ||||
| } | } | ||||
| } | } | ||||
| struct ObstaclesFromDMData { | struct ObstaclesFromDMData { | ||||
| FluidEffectorSettings *fes; | FluidEffectorSettings *fes; | ||||
| const float (*vert_positions)[3]; | const float (*vert_positions)[3]; | ||||
| const MLoop *mloop; | const int *corner_verts; | ||||
| const MLoopTri *mlooptri; | const MLoopTri *mlooptri; | ||||
| BVHTreeFromMesh *tree; | BVHTreeFromMesh *tree; | ||||
| FluidObjectBB *bb; | FluidObjectBB *bb; | ||||
| bool has_velocity; | bool has_velocity; | ||||
| float *vert_vel; | float *vert_vel; | ||||
| int *min, *max, *res; | int *min, *max, *res; | ||||
| Show All 18 Lines | |||||
| data->tree, | data->tree, | ||||
| ray_start, | ray_start, | ||||
| data->fes->surface_distance, | data->fes->surface_distance, | ||||
| data->fes->flags & FLUID_EFFECTOR_USE_PLANE_INIT); | data->fes->flags & FLUID_EFFECTOR_USE_PLANE_INIT); | ||||
| /* Calculate object velocities. Result in bb->velocity. */ | /* Calculate object velocities. Result in bb->velocity. */ | ||||
| update_velocities(data->fes, | update_velocities(data->fes, | ||||
| data->vert_positions, | data->vert_positions, | ||||
| data->mloop, | data->corner_verts, | ||||
| data->mlooptri, | data->mlooptri, | ||||
| bb->velocity, | bb->velocity, | ||||
| index, | index, | ||||
| data->tree, | data->tree, | ||||
| ray_start, | ray_start, | ||||
| data->vert_vel, | data->vert_vel, | ||||
| data->has_velocity); | data->has_velocity); | ||||
| Show All 19 Lines | |||||
| float *vert_vel = nullptr; | float *vert_vel = nullptr; | ||||
| bool has_velocity = false; | bool has_velocity = false; | ||||
| Mesh *me = BKE_mesh_copy_for_eval(fes->mesh, false); | Mesh *me = BKE_mesh_copy_for_eval(fes->mesh, false); | ||||
| float(*positions)[3] = BKE_mesh_vert_positions_for_write(me); | float(*positions)[3] = BKE_mesh_vert_positions_for_write(me); | ||||
| int min[3], max[3], res[3]; | int min[3], max[3], res[3]; | ||||
| const MLoop *mloop = BKE_mesh_loops(me); | const blender::Span<int> corner_verts = me->corner_verts(); | ||||
| looptri = BKE_mesh_runtime_looptri_ensure(me); | looptri = BKE_mesh_runtime_looptri_ensure(me); | ||||
| numverts = me->totvert; | numverts = me->totvert; | ||||
| /* TODO(sebbas): Make initialization of vertex velocities optional? */ | /* TODO(sebbas): Make initialization of vertex velocities optional? */ | ||||
| { | { | ||||
| vert_vel = static_cast<float *>( | vert_vel = static_cast<float *>( | ||||
| MEM_callocN(sizeof(float[3]) * numverts, "manta_obs_velocity")); | MEM_callocN(sizeof(float[3]) * numverts, "manta_obs_velocity")); | ||||
| ▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | |||||
| /* Skip effector sampling loop if object has disabled effector. */ | /* Skip effector sampling loop if object has disabled effector. */ | ||||
| bool use_effector = fes->flags & FLUID_EFFECTOR_USE_EFFEC; | bool use_effector = fes->flags & FLUID_EFFECTOR_USE_EFFEC; | ||||
| if (use_effector && BKE_bvhtree_from_mesh_get(&tree_data, me, BVHTREE_FROM_LOOPTRI, 4)) { | if (use_effector && BKE_bvhtree_from_mesh_get(&tree_data, me, BVHTREE_FROM_LOOPTRI, 4)) { | ||||
| ObstaclesFromDMData data{}; | ObstaclesFromDMData data{}; | ||||
| data.fes = fes; | data.fes = fes; | ||||
| data.vert_positions = positions; | data.vert_positions = positions; | ||||
| data.mloop = mloop; | data.corner_verts = corner_verts.data(); | ||||
| data.mlooptri = looptri; | data.mlooptri = looptri; | ||||
| data.tree = &tree_data; | data.tree = &tree_data; | ||||
| data.bb = bb; | data.bb = bb; | ||||
| data.has_velocity = has_velocity; | data.has_velocity = has_velocity; | ||||
| data.vert_vel = vert_vel; | data.vert_vel = vert_vel; | ||||
| data.min = min; | data.min = min; | ||||
| data.max = max; | data.max = max; | ||||
| data.res = res; | data.res = res; | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| /* Sanity check: Ensure that distances don't explode. */ | /* Sanity check: Ensure that distances don't explode. */ | ||||
| CLAMP(distance_map[index], -PHI_MAX, PHI_MAX); | CLAMP(distance_map[index], -PHI_MAX, PHI_MAX); | ||||
| } | } | ||||
| static void sample_mesh(FluidFlowSettings *ffs, | static void sample_mesh(FluidFlowSettings *ffs, | ||||
| const float (*vert_positions)[3], | const float (*vert_positions)[3], | ||||
| const float (*vert_normals)[3], | const float (*vert_normals)[3], | ||||
| const MLoop *mloop, | const int *corner_verts, | ||||
| const MLoopTri *mlooptri, | const MLoopTri *mlooptri, | ||||
| const float (*mloopuv)[2], | const float (*mloopuv)[2], | ||||
| float *influence_map, | float *influence_map, | ||||
| float *velocity_map, | float *velocity_map, | ||||
| int index, | int index, | ||||
| const int base_res[3], | const int base_res[3], | ||||
| const float global_size[3], | const float global_size[3], | ||||
| const float flow_center[3], | const float flow_center[3], | ||||
| ▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | |||||
| /* Find the nearest point on the mesh. */ | /* Find the nearest point on the mesh. */ | ||||
| if (BLI_bvhtree_find_nearest( | if (BLI_bvhtree_find_nearest( | ||||
| tree_data->tree, ray_start, &nearest, tree_data->nearest_callback, tree_data) != -1) { | tree_data->tree, ray_start, &nearest, tree_data->nearest_callback, tree_data) != -1) { | ||||
| float weights[3]; | float weights[3]; | ||||
| int v1, v2, v3, f_index = nearest.index; | int v1, v2, v3, f_index = nearest.index; | ||||
| float hit_normal[3]; | float hit_normal[3]; | ||||
| /* Calculate barycentric weights for nearest point. */ | /* Calculate barycentric weights for nearest point. */ | ||||
| v1 = mloop[mlooptri[f_index].tri[0]].v; | v1 = corner_verts[mlooptri[f_index].tri[0]]; | ||||
| v2 = mloop[mlooptri[f_index].tri[1]].v; | v2 = corner_verts[mlooptri[f_index].tri[1]]; | ||||
| v3 = mloop[mlooptri[f_index].tri[2]].v; | v3 = corner_verts[mlooptri[f_index].tri[2]]; | ||||
| interp_weights_tri_v3( | interp_weights_tri_v3( | ||||
| weights, vert_positions[v1], vert_positions[v2], vert_positions[v3], nearest.co); | weights, vert_positions[v1], vert_positions[v2], vert_positions[v3], nearest.co); | ||||
| /* Compute emission strength for smoke flow. */ | /* Compute emission strength for smoke flow. */ | ||||
| if (is_gas_flow) { | if (is_gas_flow) { | ||||
| /* Emission from surface is based on UI configurable distance value. */ | /* Emission from surface is based on UI configurable distance value. */ | ||||
| if (ffs->surface_distance) { | if (ffs->surface_distance) { | ||||
| emission_strength = sqrtf(nearest.dist_sq) / ffs->surface_distance; | emission_strength = sqrtf(nearest.dist_sq) / ffs->surface_distance; | ||||
| ▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| struct EmitFromDMData { | struct EmitFromDMData { | ||||
| FluidDomainSettings *fds; | FluidDomainSettings *fds; | ||||
| FluidFlowSettings *ffs; | FluidFlowSettings *ffs; | ||||
| const float (*vert_positions)[3]; | const float (*vert_positions)[3]; | ||||
| const float (*vert_normals)[3]; | const float (*vert_normals)[3]; | ||||
| const MLoop *mloop; | const int *corner_verts; | ||||
| const MLoopTri *mlooptri; | const MLoopTri *mlooptri; | ||||
| const float (*mloopuv)[2]; | const float (*mloopuv)[2]; | ||||
| const MDeformVert *dvert; | const MDeformVert *dvert; | ||||
| int defgrp_index; | int defgrp_index; | ||||
| BVHTreeFromMesh *tree; | BVHTreeFromMesh *tree; | ||||
| FluidObjectBB *bb; | FluidObjectBB *bb; | ||||
| Show All 17 Lines | |||||
| const float ray_start[3] = {(float(x)) + 0.5f, (float(y)) + 0.5f, (float(z)) + 0.5f}; | const float ray_start[3] = {(float(x)) + 0.5f, (float(y)) + 0.5f, (float(z)) + 0.5f}; | ||||
| /* Compute emission only for flow objects that produce fluid (i.e. skip outflow objects). | /* Compute emission only for flow objects that produce fluid (i.e. skip outflow objects). | ||||
| * Result in bb->influence. Also computes initial velocities. Result in bb->velocity. */ | * Result in bb->influence. Also computes initial velocities. Result in bb->velocity. */ | ||||
| if (ELEM(data->ffs->behavior, FLUID_FLOW_BEHAVIOR_GEOMETRY, FLUID_FLOW_BEHAVIOR_INFLOW)) { | if (ELEM(data->ffs->behavior, FLUID_FLOW_BEHAVIOR_GEOMETRY, FLUID_FLOW_BEHAVIOR_INFLOW)) { | ||||
| sample_mesh(data->ffs, | sample_mesh(data->ffs, | ||||
| data->vert_positions, | data->vert_positions, | ||||
| data->vert_normals, | data->vert_normals, | ||||
| data->mloop, | data->corner_verts, | ||||
| data->mlooptri, | data->mlooptri, | ||||
| data->mloopuv, | data->mloopuv, | ||||
| bb->influence, | bb->influence, | ||||
| bb->velocity, | bb->velocity, | ||||
| index, | index, | ||||
| data->fds->base_res, | data->fds->base_res, | ||||
| data->fds->global_size, | data->fds->global_size, | ||||
| data->flow_center, | data->flow_center, | ||||
| Show All 33 Lines | |||||
| float flow_center[3] = {0}; | float flow_center[3] = {0}; | ||||
| int min[3], max[3], res[3]; | int min[3], max[3], res[3]; | ||||
| /* Copy mesh for thread safety as we modify it. | /* Copy mesh for thread safety as we modify it. | ||||
| * Main issue is its VertArray being modified, then replaced and freed. */ | * Main issue is its VertArray being modified, then replaced and freed. */ | ||||
| Mesh *me = BKE_mesh_copy_for_eval(ffs->mesh, false); | Mesh *me = BKE_mesh_copy_for_eval(ffs->mesh, false); | ||||
| float(*positions)[3] = BKE_mesh_vert_positions_for_write(me); | float(*positions)[3] = BKE_mesh_vert_positions_for_write(me); | ||||
| const MLoop *mloop = BKE_mesh_loops(me); | const blender::Span<int> corner_verts = me->corner_verts(); | ||||
| const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me); | const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me); | ||||
| const int numverts = me->totvert; | const int numverts = me->totvert; | ||||
| const MDeformVert *dvert = BKE_mesh_deform_verts(me); | const MDeformVert *dvert = BKE_mesh_deform_verts(me); | ||||
| const float(*mloopuv)[2] = static_cast<const float(*)[2]>( | const float(*mloopuv)[2] = static_cast<const float(*)[2]>( | ||||
| CustomData_get_layer_named(&me->ldata, CD_PROP_FLOAT2, ffs->uvlayer_name)); | CustomData_get_layer_named(&me->ldata, CD_PROP_FLOAT2, ffs->uvlayer_name)); | ||||
| if (ffs->flags & FLUID_FLOW_INITVELOCITY) { | if (ffs->flags & FLUID_FLOW_INITVELOCITY) { | ||||
| vert_vel = static_cast<float *>( | vert_vel = static_cast<float *>( | ||||
| ▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | |||||
| bool use_flow = ffs->flags & FLUID_FLOW_USE_INFLOW; | bool use_flow = ffs->flags & FLUID_FLOW_USE_INFLOW; | ||||
| if (use_flow && BKE_bvhtree_from_mesh_get(&tree_data, me, BVHTREE_FROM_LOOPTRI, 4)) { | if (use_flow && BKE_bvhtree_from_mesh_get(&tree_data, me, BVHTREE_FROM_LOOPTRI, 4)) { | ||||
| EmitFromDMData data{}; | EmitFromDMData data{}; | ||||
| data.fds = fds; | data.fds = fds; | ||||
| data.ffs = ffs; | data.ffs = ffs; | ||||
| data.vert_positions = positions; | data.vert_positions = positions; | ||||
| data.vert_normals = vert_normals; | data.vert_normals = vert_normals; | ||||
| data.mloop = mloop; | data.corner_verts = corner_verts.data(); | ||||
| data.mlooptri = mlooptri; | data.mlooptri = mlooptri; | ||||
| data.mloopuv = mloopuv; | data.mloopuv = mloopuv; | ||||
| data.dvert = dvert; | data.dvert = dvert; | ||||
| data.defgrp_index = defgrp_index; | data.defgrp_index = defgrp_index; | ||||
| data.tree = &tree_data; | data.tree = &tree_data; | ||||
| data.bb = bb; | data.bb = bb; | ||||
| data.has_velocity = has_velocity; | data.has_velocity = has_velocity; | ||||
| data.vert_vel = vert_vel; | data.vert_vel = vert_vel; | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| static Mesh *create_liquid_geometry(FluidDomainSettings *fds, | static Mesh *create_liquid_geometry(FluidDomainSettings *fds, | ||||
| Scene *scene, | Scene *scene, | ||||
| Mesh *orgmesh, | Mesh *orgmesh, | ||||
| Object *ob) | Object *ob) | ||||
| { | { | ||||
| Mesh *me; | Mesh *me; | ||||
| MPoly *mpolys; | MPoly *mpolys; | ||||
| MLoop *mloops; | int *corner_verts; | ||||
| float min[3]; | float min[3]; | ||||
| float max[3]; | float max[3]; | ||||
| float size[3]; | float size[3]; | ||||
| float cell_size_scaled[3]; | float cell_size_scaled[3]; | ||||
| /* Assign material + flags to new mesh. | /* Assign material + flags to new mesh. | ||||
| * If there are no faces in original mesh, keep materials and flags unchanged. */ | * If there are no faces in original mesh, keep materials and flags unchanged. */ | ||||
| MPoly *mpoly; | MPoly *mpoly; | ||||
| Show All 27 Lines | |||||
| } | } | ||||
| me = BKE_mesh_new_nomain(num_verts, 0, 0, num_faces * 3, num_faces); | me = BKE_mesh_new_nomain(num_verts, 0, 0, num_faces * 3, num_faces); | ||||
| if (!me) { | if (!me) { | ||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| float(*positions)[3] = BKE_mesh_vert_positions_for_write(me); | float(*positions)[3] = BKE_mesh_vert_positions_for_write(me); | ||||
| mpolys = BKE_mesh_polys_for_write(me); | mpolys = BKE_mesh_polys_for_write(me); | ||||
| mloops = BKE_mesh_loops_for_write(me); | corner_verts = me->corner_verts_for_write().data(); | ||||
| /* Get size (dimension) but considering scaling. */ | /* Get size (dimension) but considering scaling. */ | ||||
| copy_v3_v3(cell_size_scaled, fds->cell_size); | copy_v3_v3(cell_size_scaled, fds->cell_size); | ||||
| mul_v3_v3(cell_size_scaled, ob->scale); | mul_v3_v3(cell_size_scaled, ob->scale); | ||||
| madd_v3fl_v3fl_v3fl_v3i(min, fds->p0, cell_size_scaled, fds->res_min); | madd_v3fl_v3fl_v3fl_v3i(min, fds->p0, cell_size_scaled, fds->res_min); | ||||
| madd_v3fl_v3fl_v3fl_v3i(max, fds->p0, cell_size_scaled, fds->res_max); | madd_v3fl_v3fl_v3fl_v3i(max, fds->p0, cell_size_scaled, fds->res_max); | ||||
| sub_v3_v3v3(size, max, min); | sub_v3_v3v3(size, max, min); | ||||
| ▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | |||||
| velarray[i][2]); | velarray[i][2]); | ||||
| # endif | # endif | ||||
| } | } | ||||
| } | } | ||||
| int *material_indices = BKE_mesh_material_indices_for_write(me); | int *material_indices = BKE_mesh_material_indices_for_write(me); | ||||
| /* Loop for triangles. */ | /* Loop for triangles. */ | ||||
| for (i = 0; i < num_faces; i++, mpolys++, mloops += 3) { | for (i = 0; i < num_faces; i++, mpolys++, corner_verts += 3) { | ||||
| /* Initialize from existing face. */ | /* Initialize from existing face. */ | ||||
| material_indices[i] = mp_mat_nr; | material_indices[i] = mp_mat_nr; | ||||
| mpolys->flag = mp_flag; | mpolys->flag = mp_flag; | ||||
| mpolys->loopstart = i * 3; | mpolys->loopstart = i * 3; | ||||
| mpolys->totloop = 3; | mpolys->totloop = 3; | ||||
| mloops[0].v = manta_liquid_get_triangle_x_at(fds->fluid, i); | corner_verts[0] = manta_liquid_get_triangle_x_at(fds->fluid, i); | ||||
| mloops[1].v = manta_liquid_get_triangle_y_at(fds->fluid, i); | corner_verts[1] = manta_liquid_get_triangle_y_at(fds->fluid, i); | ||||
| mloops[2].v = manta_liquid_get_triangle_z_at(fds->fluid, i); | corner_verts[2] = manta_liquid_get_triangle_z_at(fds->fluid, i); | ||||
| # ifdef DEBUG_PRINT | # ifdef DEBUG_PRINT | ||||
| /* Debugging: Print mesh faces. */ | /* Debugging: Print mesh faces. */ | ||||
| printf("mloops[0].v: %d, mloops[1].v: %d, mloops[2].v: %d\n", | printf("mloops[0].v: %d, mloops[1].v: %d, mloops[2].v: %d\n", | ||||
| mloops[0].v, | mloops[0].v, | ||||
| mloops[1].v, | mloops[1].v, | ||||
| mloops[2].v); | mloops[2].v); | ||||
| # endif | # endif | ||||
| } | } | ||||
| BKE_mesh_calc_edges(me, false, false); | BKE_mesh_calc_edges(me, false, false); | ||||
| return me; | return me; | ||||
| } | } | ||||
| static Mesh *create_smoke_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Object *ob) | static Mesh *create_smoke_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Object *ob) | ||||
| { | { | ||||
| Mesh *result; | Mesh *result; | ||||
| MPoly *mpolys; | MPoly *mpolys; | ||||
| MLoop *mloops; | int *corner_verts; | ||||
| float min[3]; | float min[3]; | ||||
| float max[3]; | float max[3]; | ||||
| float *co; | float *co; | ||||
| MPoly *mp; | MPoly *mp; | ||||
| MLoop *ml; | int *corner_vert; | ||||
| int num_verts = 8; | int num_verts = 8; | ||||
| int num_faces = 6; | int num_faces = 6; | ||||
| float ob_loc[3] = {0}; | float ob_loc[3] = {0}; | ||||
| float ob_cache_loc[3] = {0}; | float ob_cache_loc[3] = {0}; | ||||
| /* Just copy existing mesh if there is no content or if the adaptive domain is not being used. */ | /* Just copy existing mesh if there is no content or if the adaptive domain is not being used. */ | ||||
| if (fds->total_cells <= 1 || (fds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) == 0) { | if (fds->total_cells <= 1 || (fds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) == 0) { | ||||
| return BKE_mesh_copy_for_eval(orgmesh, false); | return BKE_mesh_copy_for_eval(orgmesh, false); | ||||
| } | } | ||||
| result = BKE_mesh_new_nomain(num_verts, 0, 0, num_faces * 4, num_faces); | result = BKE_mesh_new_nomain(num_verts, 0, 0, num_faces * 4, num_faces); | ||||
| float(*positions)[3] = BKE_mesh_vert_positions_for_write(result); | float(*positions)[3] = BKE_mesh_vert_positions_for_write(result); | ||||
| mpolys = BKE_mesh_polys_for_write(result); | mpolys = BKE_mesh_polys_for_write(result); | ||||
| mloops = BKE_mesh_loops_for_write(result); | corner_verts = result->corner_verts_for_write().data(); | ||||
| if (num_verts) { | if (num_verts) { | ||||
| /* Volume bounds. */ | /* Volume bounds. */ | ||||
| madd_v3fl_v3fl_v3fl_v3i(min, fds->p0, fds->cell_size, fds->res_min); | madd_v3fl_v3fl_v3fl_v3i(min, fds->p0, fds->cell_size, fds->res_min); | ||||
| madd_v3fl_v3fl_v3fl_v3i(max, fds->p0, fds->cell_size, fds->res_max); | madd_v3fl_v3fl_v3fl_v3i(max, fds->p0, fds->cell_size, fds->res_max); | ||||
| /* Set vertices of smoke BB. Especially important, when BB changes (adaptive domain). */ | /* Set vertices of smoke BB. Especially important, when BB changes (adaptive domain). */ | ||||
| /* Top slab */ | /* Top slab */ | ||||
| Show All 29 Lines | |||||
| co = positions[7]; | co = positions[7]; | ||||
| co[0] = min[0]; | co[0] = min[0]; | ||||
| co[1] = max[1]; | co[1] = max[1]; | ||||
| co[2] = min[2]; | co[2] = min[2]; | ||||
| /* Create faces. */ | /* Create faces. */ | ||||
| /* Top side. */ | /* Top side. */ | ||||
| mp = &mpolys[0]; | mp = &mpolys[0]; | ||||
| ml = &mloops[0 * 4]; | corner_vert = &corner_verts[0 * 4]; | ||||
| mp->loopstart = 0 * 4; | mp->loopstart = 0 * 4; | ||||
| mp->totloop = 4; | mp->totloop = 4; | ||||
| ml[0].v = 0; | corner_vert[0] = 0; | ||||
| ml[1].v = 1; | corner_vert[1] = 1; | ||||
| ml[2].v = 2; | corner_vert[2] = 2; | ||||
| ml[3].v = 3; | corner_vert[3] = 3; | ||||
| /* Right side. */ | /* Right side. */ | ||||
| mp = &mpolys[1]; | mp = &mpolys[1]; | ||||
| ml = &mloops[1 * 4]; | corner_vert = &corner_verts[1 * 4]; | ||||
| mp->loopstart = 1 * 4; | mp->loopstart = 1 * 4; | ||||
| mp->totloop = 4; | mp->totloop = 4; | ||||
| ml[0].v = 2; | corner_vert[0] = 2; | ||||
| ml[1].v = 1; | corner_vert[1] = 1; | ||||
| ml[2].v = 5; | corner_vert[2] = 5; | ||||
| ml[3].v = 6; | corner_vert[3] = 6; | ||||
| /* Bottom side. */ | /* Bottom side. */ | ||||
| mp = &mpolys[2]; | mp = &mpolys[2]; | ||||
| ml = &mloops[2 * 4]; | corner_vert = &corner_verts[2 * 4]; | ||||
| mp->loopstart = 2 * 4; | mp->loopstart = 2 * 4; | ||||
| mp->totloop = 4; | mp->totloop = 4; | ||||
| ml[0].v = 7; | corner_vert[0] = 7; | ||||
| ml[1].v = 6; | corner_vert[1] = 6; | ||||
| ml[2].v = 5; | corner_vert[2] = 5; | ||||
| ml[3].v = 4; | corner_vert[3] = 4; | ||||
| /* Left side. */ | /* Left side. */ | ||||
| mp = &mpolys[3]; | mp = &mpolys[3]; | ||||
| ml = &mloops[3 * 4]; | corner_vert = &corner_verts[3 * 4]; | ||||
| mp->loopstart = 3 * 4; | mp->loopstart = 3 * 4; | ||||
| mp->totloop = 4; | mp->totloop = 4; | ||||
| ml[0].v = 0; | corner_vert[0] = 0; | ||||
| ml[1].v = 3; | corner_vert[1] = 3; | ||||
| ml[2].v = 7; | corner_vert[2] = 7; | ||||
| ml[3].v = 4; | corner_vert[3] = 4; | ||||
| /* Front side. */ | /* Front side. */ | ||||
| mp = &mpolys[4]; | mp = &mpolys[4]; | ||||
| ml = &mloops[4 * 4]; | corner_vert = &corner_verts[4 * 4]; | ||||
| mp->loopstart = 4 * 4; | mp->loopstart = 4 * 4; | ||||
| mp->totloop = 4; | mp->totloop = 4; | ||||
| ml[0].v = 3; | corner_vert[0] = 3; | ||||
| ml[1].v = 2; | corner_vert[1] = 2; | ||||
| ml[2].v = 6; | corner_vert[2] = 6; | ||||
| ml[3].v = 7; | corner_vert[3] = 7; | ||||
| /* Back side. */ | /* Back side. */ | ||||
| mp = &mpolys[5]; | mp = &mpolys[5]; | ||||
| ml = &mloops[5 * 4]; | corner_vert = &corner_verts[5 * 4]; | ||||
| mp->loopstart = 5 * 4; | mp->loopstart = 5 * 4; | ||||
| mp->totloop = 4; | mp->totloop = 4; | ||||
| ml[0].v = 1; | corner_vert[0] = 1; | ||||
| ml[1].v = 0; | corner_vert[1] = 0; | ||||
| ml[2].v = 4; | corner_vert[2] = 4; | ||||
| ml[3].v = 5; | corner_vert[3] = 5; | ||||
| /* Calculate required shift to match domain's global position | /* Calculate required shift to match domain's global position | ||||
| * it was originally simulated at (if object moves without manta step). */ | * it was originally simulated at (if object moves without manta step). */ | ||||
| invert_m4_m4(ob->world_to_object, ob->object_to_world); | invert_m4_m4(ob->world_to_object, ob->object_to_world); | ||||
| mul_m4_v3(ob->object_to_world, ob_loc); | mul_m4_v3(ob->object_to_world, ob_loc); | ||||
| mul_m4_v3(fds->obmat, ob_cache_loc); | mul_m4_v3(fds->obmat, ob_cache_loc); | ||||
| sub_v3_v3v3(fds->obj_shift_f, ob_cache_loc, ob_loc); | sub_v3_v3v3(fds->obj_shift_f, ob_cache_loc, ob_loc); | ||||
| /* Convert shift to local space and apply to vertices. */ | /* Convert shift to local space and apply to vertices. */ | ||||
| ▲ Show 20 Lines • Show All 92 Lines • Show Last 20 Lines | |||||