Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Bishop <nicholasbishop@gmail.com>2012-07-05 07:55:55 +0400
committerNicholas Bishop <nicholasbishop@gmail.com>2012-07-05 07:55:55 +0400
commit0085c7110b9d4b42c55d00a241c0f47d8afba4c0 (patch)
tree696198919713b2ba20b04b9068afd5fe8a3ac7ad /source/blender/blenlib
parent2d5b9c4ae4a11f8b2671ca526f6ae3b2404a78b7 (diff)
Code cleanup: move PBVH ray/AABB intersection test to BLI_math_geom
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r--source/blender/blenlib/BLI_math_geom.h14
-rw-r--r--source/blender/blenlib/intern/math_geom.c57
-rw-r--r--source/blender/blenlib/intern/pbvh.c57
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);