no need to calculate the exact nearest distance if we are not using any heuristic...
authorAndre Susano Pinto <andresusanopinto@gmail.com>
Wed, 5 Aug 2009 21:09:41 +0000 (21:09 +0000)
committerAndre Susano Pinto <andresusanopinto@gmail.com>
Wed, 5 Aug 2009 21:09:41 +0000 (21:09 +0000)
source/blender/render/intern/include/rayobject.h
source/blender/render/intern/raytrace/bvh.h
source/blender/render/intern/source/rayobject.c

index 8f0dbed31762c4ad03d37ceaae6e6f3e9a63806c..2c63c8ceae9140aabad79a9a7ace3767c8661dfc 100644 (file)
@@ -164,7 +164,8 @@ int RE_rayobject_intersect(RayObject *r, Isect *i);
  * Returns distance ray must travel to hit the given bounding box
  * BB should be in format [2][3]
  */
-float RE_rayobject_bb_intersect(const Isect *i, const float *bb);
+/* float RE_rayobject_bb_intersect(const Isect *i, const float *bb); */
+int RE_rayobject_bb_intersect_test(const Isect *i, const float *bb); /* same as bb_intersect but doens't calculates distance */
 
 /*
  * Returns the expected cost of raycast on this node, primitives have a cost of 1
index 8f7e611168479ed6935ee41aac5b93744a2ea5d6..56bb907acfc524c01c39bb35b3a79ca1ba632e94 100644 (file)
  *
  * ***** END GPL LICENSE BLOCK *****
  */
+/* 
+template<int SIZE>
+struct BBGroup
+{
+       float bb[6][SIZE];
+};
+
+
+static inline int test_bb_group(BBGroup<4> *bb_group, Isect *isec)
+{
+       const float *bb = _bb;
+       __m128 tmin={0}, tmax = {isec->labda};
+
+       tmin = _mm_max_ps(tmin, _mm_mul_ps( _mm_sub_ps( group->bb[isec->bv_index[0]], isec->sse_start[0] ), isec->sse_idot_axis[0]) );
+       tmax = _mm_min_ps(tmax, _mm_mul_ps( _mm_sub_ps( group->bb[isec->bv_index[1]], isec->sse_start[0] ), isec->sse_idot_axis[0]) );  
+       tmin = _mm_max_ps(tmin, _mm_mul_ps( _mm_sub_ps( group->bb[isec->bv_index[2]], isec->sse_start[1] ), isec->sse_idot_axis[1]) );
+       tmax = _mm_min_ps(tmax, _mm_mul_ps( _mm_sub_ps( group->bb[isec->bv_index[3]], isec->sse_start[1] ), isec->sse_idot_axis[1]) );
+       tmin = _mm_max_ps(tmin, _mm_mul_ps( _mm_sub_ps( group->bb[isec->bv_index[4]], isec->sse_start[2] ), isec->sse_idot_axis[2]) );
+       tmax = _mm_min_ps(tmax, _mm_mul_ps( _mm_sub_ps( group->bb[isec->bv_index[5]], isec->sse_start[2] ), isec->sse_idot_axis[2]) );
+       
+       return _mm_movemask_ps(_mm_cmpge_ps(tmax, tmin));
+}
+
+static inline int test_bb_group(BBGroup<1> *bb_group, Isect *isec)
+{
+       float t1x = (bb[isec->bv_index[0]] - isec->start[0]) * isec->idot_axis[0];
+       float t2x = (bb[isec->bv_index[1]] - isec->start[0]) * isec->idot_axis[0];
+       float t1y = (bb[isec->bv_index[2]] - isec->start[1]) * isec->idot_axis[1];
+       float t2y = (bb[isec->bv_index[3]] - isec->start[1]) * isec->idot_axis[1];
+       float t1z = (bb[isec->bv_index[4]] - isec->start[2]) * isec->idot_axis[2];
+       float t2z = (bb[isec->bv_index[5]] - isec->start[2]) * isec->idot_axis[2];
+
+       RE_RC_COUNT(isec->raycounter->bb.test);
+       if(t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) return 0;
+       if(t2x < 0.0 || t2y < 0.0 || t2z < 0.0) return 0;
+       if(t1x > isec->labda || t1y > isec->labda || t1z > isec->labda) return 0;
+
+       RE_RC_COUNT(isec->raycounter->bb.hit);
+       return 1;
+}
+*/
 
 /* bvh tree generics */
 template<class Tree> static int bvh_intersect(Tree *obj, Isect *isec);
@@ -68,7 +109,7 @@ static float bvh_cost(Tree *obj)
 /* bvh tree nodes generics */
 template<class Node> static inline int bvh_node_hit_test(Node *node, Isect *isec)
 {
-       return RE_rayobject_bb_intersect(isec, (const float*)node->bb) != FLT_MAX;
+       return RE_rayobject_bb_intersect_test(isec, (const float*)node->bb);
 }
 
 
index 7316120e4777a10aa2c202aa4c74492f620727cb..5639080c40632d588364eb92997db59db4365ff6 100644 (file)
@@ -42,6 +42,7 @@
  * Based on Tactical Optimization of Ray/Box Intersection, by Graham Fyffe
  *  [http://tog.acm.org/resources/RTNews/html/rtnv21n1.html#art9]
  */
+/*
 float RE_rayobject_bb_intersect(const Isect *isec, const float *_bb)
 {
        const float *bb = _bb;
@@ -67,6 +68,27 @@ float RE_rayobject_bb_intersect(const Isect *isec, const float *_bb)
     if (t1z > dist) dist = t1z;
        return dist;
 }
+*/
+int RE_rayobject_bb_intersect_test(const Isect *isec, const float *_bb)
+{
+       const float *bb = _bb;
+       
+       float t1x = (bb[isec->bv_index[0]] - isec->start[0]) * isec->idot_axis[0];
+       float t2x = (bb[isec->bv_index[1]] - isec->start[0]) * isec->idot_axis[0];
+       float t1y = (bb[isec->bv_index[2]] - isec->start[1]) * isec->idot_axis[1];
+       float t2y = (bb[isec->bv_index[3]] - isec->start[1]) * isec->idot_axis[1];
+       float t1z = (bb[isec->bv_index[4]] - isec->start[2]) * isec->idot_axis[2];
+       float t2z = (bb[isec->bv_index[5]] - isec->start[2]) * isec->idot_axis[2];
+
+       RE_RC_COUNT(isec->raycounter->bb.test);
+       
+       if(t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) return 0;
+       if(t2x < 0.0 || t2y < 0.0 || t2z < 0.0) return 0;
+       if(t1x > isec->labda || t1y > isec->labda || t1z > isec->labda) return 0;
+       RE_RC_COUNT(isec->raycounter->bb.hit);  
+
+       return 1;
+}
 
 
 /* only for self-intersecting test with current render face (where ray left) */