diff options
author | Nicholas Bishop <nicholasbishop@gmail.com> | 2012-07-05 07:55:55 +0400 |
---|---|---|
committer | Nicholas Bishop <nicholasbishop@gmail.com> | 2012-07-05 07:55:55 +0400 |
commit | 0085c7110b9d4b42c55d00a241c0f47d8afba4c0 (patch) | |
tree | 696198919713b2ba20b04b9068afd5fe8a3ac7ad | |
parent | 2d5b9c4ae4a11f8b2671ca526f6ae3b2404a78b7 (diff) |
Code cleanup: move PBVH ray/AABB intersection test to BLI_math_geom
-rw-r--r-- | source/blender/blenlib/BLI_math_geom.h | 14 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_geom.c | 57 | ||||
-rw-r--r-- | source/blender/blenlib/intern/pbvh.c | 57 |
3 files changed, 77 insertions, 51 deletions
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index 93599dee63d..8ccc3159f78 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -159,6 +159,18 @@ void isect_point_quad_uv_v2(const float v0[2], const float v1[2], const float v2 void isect_point_face_uv_v2(const int isquad, const float v0[2], const float v1[2], const float v2[2], const float v3[2], const float pt[2], float r_uv[2]); +/* axis-aligned bounding box */ +int isect_aabb_aabb_v3(const float min1[3], const float max1[3], const float min2[3], const float max2[3]); + +typedef struct { + float ray_start[3]; + float ray_inv_dir[3]; + int sign[3]; +} IsectRayAABBData; + +void isect_ray_aabb_initialize(IsectRayAABBData *data, const float ray_start[3], const float ray_direction[3]); +int isect_ray_aabb(const IsectRayAABBData *data, const float bb_min[3], const float bb_max[3], float *tmin); + /* other */ int isect_sweeping_sphere_tri_v3(const float p1[3], const float p2[3], const float radius, const float v0[3], const float v1[3], const float v2[3], float *r_lambda, float ipoint[3]); @@ -166,8 +178,6 @@ int isect_sweeping_sphere_tri_v3(const float p1[3], const float p2[3], const flo int isect_axial_line_tri_v3(const int axis, const float co1[3], const float co2[3], const float v0[3], const float v1[3], const float v2[3], float *r_lambda); -int isect_aabb_aabb_v3(const float min1[3], const float max1[3], const float min2[3], const float max2[3]); - int clip_line_plane(float p1[3], float p2[3], const float plane[4]); void plot_line_v2v2i(const int p1[2], const int p2[2], int (*callback)(int, int, void *), void *userData); diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index e51d0d2645f..402aacf369a 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -1284,6 +1284,63 @@ int isect_aabb_aabb_v3(const float min1[3], const float max1[3], const float min min2[0] < max1[0] && min2[1] < max1[1] && min2[2] < max1[2]); } +void isect_ray_aabb_initialize(IsectRayAABBData *data, const float ray_start[3], const float ray_direction[3]) +{ + copy_v3_v3(data->ray_start, ray_start); + + data->ray_inv_dir[0] = 1.0f / ray_direction[0]; + data->ray_inv_dir[1] = 1.0f / ray_direction[1]; + data->ray_inv_dir[2] = 1.0f / ray_direction[2]; + + data->sign[0] = data->ray_inv_dir[0] < 0; + data->sign[1] = data->ray_inv_dir[1] < 0; + data->sign[2] = data->ray_inv_dir[2] < 0; +} + +/* Adapted from http://www.gamedev.net/community/forums/topic.asp?topic_id=459973 */ +int isect_ray_aabb(const IsectRayAABBData *data, const float bb_min[3], + const float bb_max[3], float *tmin_out) +{ + float bbox[2][3]; + float tmin, tmax, tymin, tymax, tzmin, tzmax; + + copy_v3_v3(bbox[0], bb_min); + copy_v3_v3(bbox[1], bb_max); + + tmin = (bbox[data->sign[0]][0] - data->ray_start[0]) * data->ray_inv_dir[0]; + tmax = (bbox[1 - data->sign[0]][0] - data->ray_start[0]) * data->ray_inv_dir[0]; + + tymin = (bbox[data->sign[1]][1] - data->ray_start[1]) * data->ray_inv_dir[1]; + tymax = (bbox[1 - data->sign[1]][1] - data->ray_start[1]) * data->ray_inv_dir[1]; + + if ((tmin > tymax) || (tymin > tmax)) + return FALSE; + + if (tymin > tmin) + tmin = tymin; + + if (tymax < tmax) + tmax = tymax; + + tzmin = (bbox[data->sign[2]][2] - data->ray_start[2]) * data->ray_inv_dir[2]; + tzmax = (bbox[1 - data->sign[2]][2] - data->ray_start[2]) * data->ray_inv_dir[2]; + + if ((tmin > tzmax) || (tzmin > tmax)) + return FALSE; + + if (tzmin > tmin) + tmin = tzmin; + + // XXX jwilkins: tmax does not need to be updated since we don't use it + // keeping this here for future reference + //if (tzmax < tmax) tmax = tzmax; + + if (tmin_out) + (*tmin_out) = tmin; + + return TRUE; +} + /* find closest point to p on line through l1,l2 and return lambda, * where (0 <= lambda <= 1) when cp is in the line segement l1,l2 */ diff --git a/source/blender/blenlib/intern/pbvh.c b/source/blender/blenlib/intern/pbvh.c index 409a9f88f39..14f9001814c 100644 --- a/source/blender/blenlib/intern/pbvh.c +++ b/source/blender/blenlib/intern/pbvh.c @@ -1424,56 +1424,21 @@ void BLI_pbvh_node_get_proxies(PBVHNode *node, PBVHProxyNode **proxies, int *pro /********************************* Raycast ***********************************/ typedef struct { - /* Ray */ - float start[3]; - int sign[3]; - float inv_dir[3]; + IsectRayAABBData ray; int original; } RaycastData; -/* Adapted from here: http://www.gamedev.net/community/forums/topic.asp?topic_id=459973 */ static int ray_aabb_intersect(PBVHNode *node, void *data_v) { - RaycastData *ray = data_v; - float bbox[2][3]; - float tmin, tmax, tymin, tymax, tzmin, tzmax; + RaycastData *rcd = data_v; + float bb_min[3], bb_max[3]; - if (ray->original) - BLI_pbvh_node_get_original_BB(node, bbox[0], bbox[1]); + if (rcd->original) + BLI_pbvh_node_get_original_BB(node, bb_min, bb_max); else - BLI_pbvh_node_get_BB(node, bbox[0], bbox[1]); - - tmin = (bbox[ray->sign[0]][0] - ray->start[0]) * ray->inv_dir[0]; - tmax = (bbox[1 - ray->sign[0]][0] - ray->start[0]) * ray->inv_dir[0]; - - tymin = (bbox[ray->sign[1]][1] - ray->start[1]) * ray->inv_dir[1]; - tymax = (bbox[1 - ray->sign[1]][1] - ray->start[1]) * ray->inv_dir[1]; - - if ((tmin > tymax) || (tymin > tmax)) - return 0; - - if (tymin > tmin) - tmin = tymin; - - if (tymax < tmax) - tmax = tymax; + BLI_pbvh_node_get_BB(node, bb_min, bb_max); - tzmin = (bbox[ray->sign[2]][2] - ray->start[2]) * ray->inv_dir[2]; - tzmax = (bbox[1 - ray->sign[2]][2] - ray->start[2]) * ray->inv_dir[2]; - - if ((tmin > tzmax) || (tzmin > tmax)) - return 0; - - if (tzmin > tmin) - tmin = tzmin; - - // XXX jwilkins: tmax does not need to be updated since we don't use it - // keeping this here for future reference - //if (tzmax < tmax) tmax = tzmax; - - node->tmin = tmin; - - return 1; + return isect_ray_aabb(&rcd->ray, bb_min, bb_max, &node->tmin); } void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data, @@ -1482,13 +1447,7 @@ void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data, { RaycastData rcd; - copy_v3_v3(rcd.start, ray_start); - rcd.inv_dir[0] = 1.0f / ray_normal[0]; - rcd.inv_dir[1] = 1.0f / ray_normal[1]; - rcd.inv_dir[2] = 1.0f / ray_normal[2]; - rcd.sign[0] = rcd.inv_dir[0] < 0; - rcd.sign[1] = rcd.inv_dir[1] < 0; - rcd.sign[2] = rcd.inv_dir[2] < 0; + isect_ray_aabb_initialize(&rcd.ray, ray_start, ray_normal); rcd.original = original; BLI_pbvh_search_callback_occluded(bvh, ray_aabb_intersect, &rcd, cb, data); |