From c727fc59abe2b7e525bdc6594bbd7ec3285936e0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 21 Aug 2015 17:05:48 +1000 Subject: BVH-raycast: ensure input direction is unit-length This was already the case for most users of ray-cast. Doing this avoids 2x normalize calls per ray-cast in many places. --- source/blender/blenkernel/intern/boids.c | 6 +++--- source/blender/blenkernel/intern/constraint.c | 1 + source/blender/blenkernel/intern/dynamicpaint.c | 5 ++--- source/blender/blenkernel/intern/particle_system.c | 2 +- source/blender/blenlib/intern/BLI_kdopbvh.c | 8 ++++---- source/blender/editors/armature/meshlaplacian.c | 8 +++++--- source/blender/editors/mesh/editmesh_knife.c | 5 +++-- 7 files changed, 19 insertions(+), 16 deletions(-) diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index 11879c7973c..fdc5524e84c 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -214,7 +214,7 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues * mul_v3_fl(ray_dir, acbr->look_ahead); col.f = 0.0f; hit.index = -1; - hit.dist = col.original_ray_length = len_v3(ray_dir); + hit.dist = col.original_ray_length = normalize_v3(ray_dir); /* find out closest deflector object */ for (coll = bbd->sim->colliders->first; coll; coll=coll->next) { @@ -794,7 +794,7 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float grou sub_v3_v3v3(ray_dir, col.co2, col.co1); col.f = 0.0f; hit.index = -1; - hit.dist = col.original_ray_length = len_v3(ray_dir); + hit.dist = col.original_ray_length = normalize_v3(ray_dir); col.pce.inside = 0; for (coll = bbd->sim->colliders->first; coll; coll = coll->next) { @@ -820,7 +820,7 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float grou sub_v3_v3v3(ray_dir, col.co2, col.co1); col.f = 0.0f; hit.index = -1; - hit.dist = col.original_ray_length = len_v3(ray_dir); + hit.dist = col.original_ray_length = normalize_v3(ray_dir); for (coll = bbd->sim->colliders->first; coll; coll = coll->next) { col.current = coll->ob; diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index e7f6210fef4..2aba4fcde27 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -4106,6 +4106,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase mul_v3_m4v3(ray_end, imat, cob->matrix[3]); sub_v3_v3v3(ray_nor, ray_end, ray_start); + normalize_v3(ray_nor); bvhtree_from_mesh_looptri(&treeData, target, 0.0f, 4, 6); diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index d97233aad90..7f1d2e877ed 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -3290,10 +3290,9 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, if (brush->flags & MOD_DPAINT_PROX_PROJECT && brush->collision != MOD_DPAINT_COL_VOLUME) { mul_v3_fl(avg_brushNor, 1.0f / (float)numOfVerts); /* instead of null vector use positive z */ - if (!(MIN3(avg_brushNor[0], avg_brushNor[1], avg_brushNor[2]))) + if (UNLIKELY(normalize_v3(avg_brushNor) == 0.0f)) { avg_brushNor[2] = 1.0f; - else - normalize_v3(avg_brushNor); + } } /* check bounding box collision */ diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index e340a0ade94..8b925fff415 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -2594,7 +2594,7 @@ static int collision_detect(ParticleData *pa, ParticleCollision *col, BVHTreeRay sub_v3_v3v3(ray_dir, col->co2, col->co1); hit->index = -1; - hit->dist = col->original_ray_length = len_v3(ray_dir); + hit->dist = col->original_ray_length = normalize_v3(ray_dir); col->pce.inside = 0; /* even if particle is stationary we want to check for moving colliders */ diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index d6d0443893e..1b9b6e38208 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -1650,6 +1650,8 @@ int BLI_bvhtree_ray_cast(BVHTree *tree, const float co[3], const float dir[3], f BVHRayCastData data; BVHNode *root = tree->nodes[tree->totleaf]; + BLI_ASSERT_UNIT_V3(dir); + data.tree = tree; data.callback = callback; @@ -1659,8 +1661,6 @@ int BLI_bvhtree_ray_cast(BVHTree *tree, const float co[3], const float dir[3], f copy_v3_v3(data.ray.direction, dir); data.ray.radius = radius; - normalize_v3(data.ray.direction); - bvhtree_ray_cast_data_precalc(&data); if (hit) @@ -1713,6 +1713,8 @@ int BLI_bvhtree_ray_cast_all(BVHTree *tree, const float co[3], const float dir[3 BVHRayCastData data; BVHNode *root = tree->nodes[tree->totleaf]; + BLI_ASSERT_UNIT_V3(dir); + data.tree = tree; data.callback = callback; @@ -1722,8 +1724,6 @@ int BLI_bvhtree_ray_cast_all(BVHTree *tree, const float co[3], const float dir[3 copy_v3_v3(data.ray.direction, dir); data.ray.radius = radius; - normalize_v3(data.ray.direction); - bvhtree_ray_cast_data_precalc(&data); data.hit.index = -1; diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index da53d0a1005..d49deae6aac 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -1119,6 +1119,7 @@ typedef struct MeshDeformBind { typedef struct MeshDeformIsect { float start[3]; float vec[3]; + float vec_length; float lambda; bool isect; @@ -1225,7 +1226,7 @@ static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *r normal_tri_v3(no, UNPACK3(face)); } - dist = len_v3v3(ray->origin, co) / len_v3(isec->vec); + dist = len_v3v3(ray->origin, co) / isec->vec_length; if (dist < hit->dist) { hit->index = index; hit->dist = dist; @@ -1244,7 +1245,7 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, const mdb, &isect_mdef, }; - float end[3]; + float end[3], vec_normal[3]; // static float epsilon[3] = {1e-4, 1e-4, 1e-4}; /* happens binding when a cage has no faces */ @@ -1263,10 +1264,11 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, const copy_v3_v3(end, co2); #endif sub_v3_v3v3(isect_mdef.vec, end, isect_mdef.start); + isect_mdef.vec_length = normalize_v3_v3(vec_normal, isect_mdef.vec); hit.index = -1; hit.dist = FLT_MAX; - if (BLI_bvhtree_ray_cast(mdb->bvhtree, isect_mdef.start, isect_mdef.vec, + if (BLI_bvhtree_ray_cast(mdb->bvhtree, isect_mdef.start, vec_normal, 0.0, &hit, harmonic_ray_callback, &data) != -1) { const MLoop *mloop = mdb->cagedm_cache.mloop; diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index caafaf06e9e..787b79f0d6e 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -1809,13 +1809,14 @@ static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, float co[3], float float dist = KMAXDIST; float origin[3]; float origin_ofs[3]; - float ray[3]; + float ray[3], ray_normal[3]; /* unproject to find view ray */ knife_input_ray_segment(kcd, kcd->curr.mval, 1.0f, origin, origin_ofs); sub_v3_v3v3(ray, origin_ofs, origin); + normalize_v3_v3(ray_normal, ray); - f = BKE_bmbvh_ray_cast(kcd->bmbvh, origin, ray, 0.0f, NULL, co, cageco); + f = BKE_bmbvh_ray_cast(kcd->bmbvh, origin, ray_normal, 0.0f, NULL, co, cageco); if (f && kcd->only_select && BM_elem_flag_test(f, BM_ELEM_SELECT) == 0) { f = NULL; -- cgit v1.2.3