[Bf-blender-cvs] [cbf3e401216] fluid-mantaflow: improved levelset calculation function
Sebastián Barschkis
noreply at git.blender.org
Sun Mar 26 20:41:31 CEST 2017
Commit: cbf3e401216e29fd114949918c0b602c27a47f65
Author: Sebastián Barschkis
Date: Wed Mar 22 14:27:42 2017 +0100
Branches: fluid-mantaflow
https://developer.blender.org/rBcbf3e401216e29fd114949918c0b602c27a47f65
improved levelset calculation function
now using better estimates for min distance and also 14 instead of just 6 raydirs for raycasts (added 8 quadrant diagonals)
===================================================================
M source/blender/blenkernel/intern/smoke.c
===================================================================
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 37fdfbfb917..34e9663b68f 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -1002,7 +1002,7 @@ static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds,
for (z = 0; z < sds->res[0] * sds->res[1] * sds->res[2]; z++)
{
if (phiObs)
- phiObs[z] = 0.5f;
+ phiObs[z] = 9999.f;
if (num_obstacles)
num_obstacles[z] = 0;
@@ -1610,60 +1610,55 @@ static void emit_from_particles(
}
static void update_mesh_distances(int index, float *inflow_map, BVHTreeFromMesh *treeData, const float ray_start[3]) {
- /*****************************************************
- * Liquid inflow based on raycasts in all 6 directions.
- * Uses distances to mesh surface from within and outside flow mesh for inflow map.
- *****************************************************/
-
- /* Calculate map which indicates whether point is inside a mesh or not */
- float min_dist_pos, min_dist_neg, min_dist_combined; // for xyz axis in pos and neg direction and when combining 6 axis
+
+ /* Calculate map of (minimum) distances to flow/obstacle surface. Distances outside mesh are positive, inside negative */
+ float min_dist = 9999;
float inv_ray[3] = {0.0f};
- float hit_dists[6] = {0.0f};
- float ray_dirs[6][3] = {{1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f},
- {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}};
+ /* Raycasts in 14 directions (6 axis + 8 quadrant diagonals) are at least necessary */
+ float ray_dirs[14][3] = {{1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f},
+ {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f},
+ {1.0f, 1.0f, 1.0f}, {1.0f, -1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f},
+ {1.0f, 1.0f, -1.0f}, {1.0f, -1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}};
size_t ray_cnt = sizeof ray_dirs / sizeof ray_dirs[0];
-
- /* Initialize inflow map. Any following initialization leaves points inside mesh ( < 0.0f) unaffected - important when multiple flow / obstacle objects in scene */
- if (inflow_map[index] >= 0.0f) {
- inflow_map[index] = 0.5f;
- }
for (int i = 0; i < ray_cnt; i++) {
BVHTreeRayHit hit_tree = {0};
hit_tree.index = -1;
- hit_tree.dist = BVH_RAYCAST_DIST_MAX;
+ hit_tree.dist = 9999;
BLI_bvhtree_ray_cast(treeData->tree, ray_start, ray_dirs[i], 0.0f, &hit_tree, treeData->raycast_callback, treeData);
- hit_dists[i] = normalize_v3(&hit_tree.dist); // Make sure manta gets normalized distances
+
+ /* Save hit dist first time */
+ min_dist = normalize_v3(&hit_tree.dist);
if (hit_tree.index != -1) {
+ /* Is dot > 0 aka are we inside the mesh? */
if (dot_v3v3(ray_dirs[i], hit_tree.no)) {
+
/* Also cast a ray in opposite direction to make sure
* point is at least surrounded by two faces */
hit_tree.index = -1;
- hit_tree.dist = BVH_RAYCAST_DIST_MAX;
+ hit_tree.dist = 9999;
negate_v3_v3(inv_ray, ray_dirs[i]);
BLI_bvhtree_ray_cast(treeData->tree, ray_start, inv_ray, 0.0f, &hit_tree, treeData->raycast_callback, treeData);
+ /* Save hit dist second time */
+ min_dist = MIN2(min_dist, normalize_v3(&hit_tree.dist));
+
if (hit_tree.index != -1) {
if (dot_v3v3(inv_ray, hit_tree.no)) {
- inflow_map[index] = -1.0f; // place mark in map: current point is inside flow mesh. we need this info later
+ /* Current index is inside mesh, place negative mesh distance */
+ inflow_map[index] = -1.0f * MIN2(fabsf(inflow_map[index]), min_dist);
}
+ /* No second hit, so just write outside mesh distances */
+ } else if (inflow_map[index] >= 0) {
+ /* Current index is outside mesh, place positive mesh distance */
+ inflow_map[index] = MIN2(fabsf(inflow_map[index]), min_dist);
}
}
}
}
-
- /* Get the minimum distance of pos and neg coord systems. Then compare both and again get min */
- min_dist_pos = MIN3(hit_dists[0], hit_dists[1], hit_dists[2]);
- min_dist_neg = MIN3(hit_dists[3], hit_dists[4], hit_dists[5]);
- min_dist_combined = MIN2(min_dist_pos, min_dist_neg);
-
- /* Multiply actual distances to those points inside mesh (those points in inflow map with value -1)*/
- if (inflow_map[index] == -1.0f) {
- inflow_map[index] *= min_dist_combined;
- }
}
static void sample_derivedmesh(
More information about the Bf-blender-cvs
mailing list