[Bf-blender-cvs] [59e166c] master: BVH-raycast: Use watertight intersections

Campbell Barton noreply at git.blender.org
Fri Aug 21 09:55:50 CEST 2015


Commit: 59e166c568a57315b78c5ab812837c95923c300e
Author: Campbell Barton
Date:   Fri Aug 21 17:46:23 2015 +1000
Branches: master
https://developer.blender.org/rB59e166c568a57315b78c5ab812837c95923c300e

BVH-raycast: Use watertight intersections

By default watertight intersections are used,
For callbacks where its not needed,
BLI_bvhtree_ray_cast_ex can be called without the BVH_RAYCAST_WATERTIGHT flag.

Fixes T45286

===================================================================

M	source/blender/blenkernel/intern/boids.c
M	source/blender/blenkernel/intern/bvhutils.c
M	source/blender/blenkernel/intern/editmesh_bvh.c
M	source/blender/blenkernel/intern/effect.c
M	source/blender/blenkernel/intern/particle_system.c
M	source/blender/blenlib/BLI_kdopbvh.h
M	source/blender/blenlib/intern/BLI_kdopbvh.c
M	source/blender/editors/armature/meshlaplacian.c

===================================================================

diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index fdc5524..489e26c 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -189,6 +189,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
 
 static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, ParticleData *pa)
 {
+	const int raycast_flag = BVH_RAYCAST_DEFAULT & ~(BVH_RAYCAST_WATERTIGHT);
 	BoidRuleAvoidCollision *acbr = (BoidRuleAvoidCollision*) rule;
 	KDTreeNearest *ptn = NULL;
 	ParticleTarget *pt;
@@ -225,8 +226,11 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
 			col.current = coll->ob;
 			col.md = coll->collmd;
 
-			if (col.md && col.md->bvhtree)
-				BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, BKE_psys_collision_neartest_cb, &col);
+			if (col.md && col.md->bvhtree) {
+				BLI_bvhtree_ray_cast_ex(
+				        col.md->bvhtree, col.co1, ray_dir, radius, &hit,
+				        BKE_psys_collision_neartest_cb, &col, raycast_flag);
+			}
 		}
 		/* then avoid that object */
 		if (hit.index>=0) {
@@ -759,6 +763,7 @@ static void set_boid_values(BoidValues *val, BoidSettings *boids, ParticleData *
 
 static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float ground_co[3], float ground_nor[3])
 {
+	const int raycast_flag = BVH_RAYCAST_DEFAULT & ~(BVH_RAYCAST_WATERTIGHT);
 	BoidParticle *bpa = pa->boid;
 
 	if (bpa->data.mode == eBoidMode_Climbing) {
@@ -802,8 +807,11 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float grou
 			col.md = coll->collmd;
 			col.fac1 = col.fac2 = 0.f;
 
-			if (col.md && col.md->bvhtree)
-				BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, BKE_psys_collision_neartest_cb, &col);
+			if (col.md && col.md->bvhtree) {
+				BLI_bvhtree_ray_cast_ex(
+				        col.md->bvhtree, col.co1, ray_dir, radius, &hit,
+				        BKE_psys_collision_neartest_cb, &col, raycast_flag);
+			}
 		}
 		/* then use that object */
 		if (hit.index>=0) {
@@ -826,8 +834,11 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float grou
 			col.current = coll->ob;
 			col.md = coll->collmd;
 
-			if (col.md && col.md->bvhtree)
-				BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, BKE_psys_collision_neartest_cb, &col);
+			if (col.md && col.md->bvhtree) {
+				BLI_bvhtree_ray_cast_ex(
+				        col.md->bvhtree, col.co1, ray_dir, radius, &hit,
+				        BKE_psys_collision_neartest_cb, &col, raycast_flag);
+			}
 		}
 		/* then use that object */
 		if (hit.index>=0) {
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index 2ecae21..fa2fcd9 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -60,8 +60,14 @@ float bvhtree_ray_tri_intersection(
 {
 	float dist;
 
+#ifdef USE_KDOPBVH_WATERTIGHT
+	if (isect_ray_tri_watertight_v3(ray->origin, ray->isect_precalc, v0, v1, v2, &dist, NULL))
+#else
 	if (isect_ray_tri_epsilon_v3(ray->origin, ray->direction, v0, v1, v2, &dist, NULL, FLT_EPSILON))
+#endif
+	{
 		return dist;
+	}
 
 	return FLT_MAX;
 }
diff --git a/source/blender/blenkernel/intern/editmesh_bvh.c b/source/blender/blenkernel/intern/editmesh_bvh.c
index 0e619f2..07706a3 100644
--- a/source/blender/blenkernel/intern/editmesh_bvh.c
+++ b/source/blender/blenkernel/intern/editmesh_bvh.c
@@ -278,8 +278,13 @@ static void bmbvh_ray_cast_cb(void *userdata, int index, const BVHTreeRay *ray,
 	isect = (ray->radius > 0.0f ?
 	         isect_ray_tri_epsilon_v3(ray->origin, ray->direction,
 	                                  tri_cos[0], tri_cos[1], tri_cos[2], &dist, uv, ray->radius) :
+#ifdef USE_KDOPBVH_WATERTIGHT
+	         isect_ray_tri_watertight_v3(ray->origin, ray->isect_precalc,
+	                                     tri_cos[0], tri_cos[1], tri_cos[2], &dist, uv));
+#else
 	         isect_ray_tri_v3(ray->origin, ray->direction,
 	                          tri_cos[0], tri_cos[1], tri_cos[2], &dist, uv));
+#endif
 
 	if (isect && dist < hit->dist) {
 		hit->dist = dist;
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 6459e2e..bf53acc 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -391,6 +391,7 @@ static void eff_tri_ray_hit(void *UNUSED(userData), int UNUSED(index), const BVH
 // get visibility of a wind ray
 static float eff_calc_visibility(ListBase *colliders, EffectorCache *eff, EffectorData *efd, EffectedPoint *point)
 {
+	const int raycast_flag = BVH_RAYCAST_DEFAULT & ~(BVH_RAYCAST_WATERTIGHT);
 	ListBase *colls = colliders;
 	ColliderCache *col;
 	float norm[3], len = 0.0;
@@ -422,7 +423,10 @@ static float eff_calc_visibility(ListBase *colliders, EffectorCache *eff, Effect
 			hit.dist = len + FLT_EPSILON;
 
 			/* check if the way is blocked */
-			if (BLI_bvhtree_ray_cast(collmd->bvhtree, point->loc, norm, 0.0f, &hit, eff_tri_ray_hit, NULL)>=0) {
+			if (BLI_bvhtree_ray_cast_ex(
+			        collmd->bvhtree, point->loc, norm, 0.0f, &hit,
+			        eff_tri_ray_hit, NULL, raycast_flag) != -1)
+			{
 				absorption= col->ob->pd->absorption;
 
 				/* visibility is only between 0 and 1, calculated from 1-absorption */
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 8b925ff..dd43e63 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -2586,6 +2586,7 @@ void BKE_psys_collision_neartest_cb(void *userdata, int index, const BVHTreeRay
 }
 static int collision_detect(ParticleData *pa, ParticleCollision *col, BVHTreeRayHit *hit, ListBase *colliders)
 {
+	const int raycast_flag = BVH_RAYCAST_DEFAULT & ~(BVH_RAYCAST_WATERTIGHT);
 	ColliderCache *coll;
 	float ray_dir[3];
 
@@ -2616,8 +2617,11 @@ static int collision_detect(ParticleData *pa, ParticleCollision *col, BVHTreeRay
 		col->fac1 = (col->old_cfra - coll->collmd->time_x) / (coll->collmd->time_xnew - coll->collmd->time_x);
 		col->fac2 = (col->cfra - coll->collmd->time_x) / (coll->collmd->time_xnew - coll->collmd->time_x);
 
-		if (col->md && col->md->bvhtree)
-			BLI_bvhtree_ray_cast(col->md->bvhtree, col->co1, ray_dir, col->radius, hit, BKE_psys_collision_neartest_cb, col);
+		if (col->md && col->md->bvhtree) {
+			BLI_bvhtree_ray_cast_ex(
+			        col->md->bvhtree, col->co1, ray_dir, col->radius, hit,
+			        BKE_psys_collision_neartest_cb, col, raycast_flag);
+		}
 	}
 
 	return hit->index >= 0;
diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h
index ce7f3ab..0c359c7 100644
--- a/source/blender/blenlib/BLI_kdopbvh.h
+++ b/source/blender/blenlib/BLI_kdopbvh.h
@@ -41,6 +41,7 @@ extern "C" {
 
 struct BVHTree;
 typedef struct BVHTree BVHTree;
+#define USE_KDOPBVH_WATERTIGHT
 
 typedef struct BVHTreeOverlap {
 	int indexA;
@@ -59,6 +60,9 @@ typedef struct BVHTreeRay {
 	float origin[3];    /* ray origin */
 	float direction[3]; /* ray direction */
 	float radius;       /* radius around ray */
+#ifdef USE_KDOPBVH_WATERTIGHT
+	struct IsectRayPrecalc *isect_precalc;
+#endif
 } BVHTreeRay;
 
 typedef struct BVHTreeRayHit {
@@ -68,6 +72,12 @@ typedef struct BVHTreeRayHit {
 	float dist;         /* distance to the hit point */
 } BVHTreeRayHit;
 
+enum {
+	/* calculate IsectRayPrecalc data */
+	BVH_RAYCAST_WATERTIGHT		= (1 << 0),
+};
+#define BVH_RAYCAST_DEFAULT (BVH_RAYCAST_WATERTIGHT)
+
 /* callback must update nearest in case it finds a nearest result */
 typedef void (*BVHTree_NearestPointCallback)(void *userdata, int index, const float co[3], BVHTreeNearest *nearest);
 
@@ -105,12 +115,21 @@ float BLI_bvhtree_getepsilon(const BVHTree *tree);
 int BLI_bvhtree_find_nearest(BVHTree *tree, const float co[3], BVHTreeNearest *nearest,
                              BVHTree_NearestPointCallback callback, void *userdata);
 
-int BLI_bvhtree_ray_cast(BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit,
-                         BVHTree_RayCastCallback callback, void *userdata);
-
-/* Calls the callback for every ray intersection */
-int BLI_bvhtree_ray_cast_all(BVHTree *tree, const float co[3], const float dir[3], float radius,
-                             BVHTree_RayCastCallback callback, void *userdata);
+int BLI_bvhtree_ray_cast_ex(
+        BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit,
+        BVHTree_RayCastCallback callback, void *userdata,
+        int flag);
+int BLI_bvhtree_ray_cast(
+        BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit,
+        BVHTree_RayCastCallback callback, void *userdata);
+
+int BLI_bvhtree_ray_cast_all_ex(
+        BVHTree *tree, const float co[3], const float dir[3], float radius,
+        BVHTree_RayCastCallback callback, void *userdata,
+        int flag);
+int BLI_bvhtree_ray_cast_all(
+        BVHTree *tree, const float co[3], const float dir[3], float radius,
+        BVHTree_RayCastCallback callback, void *userdata);
 
 float BLI_bvhtree_bb_raycast(const float bv[6], const float light_start[3], const float light_end[3], float pos[3]);
 
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index 1b9b6e3..ddb61e4 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -139,6 +139,10 @@ typedef struct BVHRayCastData {
 
 	BVHTreeRay ray;
 
+#ifdef USE_KDOPBVH_WATERTIGHT
+	struct IsectRayPrecalc isect_precalc;
+#endif
+
 	/* initialized by bvhtree_ray_cast_data_precalc */
 	float ray_dot_axis[13];
 	float idot_axis[13];
@@ -1626,7 +1630,7 @@ static void iterative_raycast(BVHRayCastData *data, BVHNode *node)
 }
 #endif
 
-static void bvhtree_ray_cast_data_precalc(BVHRayCastData *data)
+static void bvhtree_ray_cast_data_precalc(BVHRayCastData *data, int flag)
 {
 	int i;
 
@@ -1642,10 +1646,24 @@ static void bvhtree_ray_cast_data_precalc(BVHRayCastData *da

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list