Advertisement
Guest User

Untitled

a guest
Dec 7th, 2011
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.76 KB | None | 0 0
  1.  
  2. void BVH4Traverser::intersect(const Ray& ray) const
  3. {
  4.     Hit hit;
  5.     /*! stack state */
  6.     size_t stackPtr = 1;                             //!< current stack pointer
  7.     int32 popCur  = bvh->root;                       //!< pre-popped top node from the stack
  8.     float popDist = neg_inf;                         //!< pre-popped distance of top node from the stack
  9.     StackItem stack[1+3*BVH4<Triangle4>::maxDepth];  //!< stack of nodes that still need to get traversed
  10.  
  11.     /*! offsets to select the side that becomes the lower or upper bound */
  12.     const size_t nearX = ray.dir.x >= 0 ? 0*sizeof(ssef) : 1*sizeof(ssef);
  13.     const size_t nearY = ray.dir.y >= 0 ? 2*sizeof(ssef) : 3*sizeof(ssef);
  14.     const size_t nearZ = ray.dir.z >= 0 ? 4*sizeof(ssef) : 5*sizeof(ssef);
  15.     const size_t farX  = nearX ^ 16;
  16.     const size_t farY  = nearY ^ 16;
  17.     const size_t farZ  = nearZ ^ 16;
  18.  
  19.     /*! load the ray into SIMD registers */
  20.     const sse3f norg(-ray.org.x,-ray.org.y,-ray.org.z);
  21.     const sse3f rdir(ray.rdir.x,ray.rdir.y,ray.rdir.z);
  22.     const ssef rayNear(ray.near);
  23.     ssef rayFar(ray.far);
  24.     const BVH4<Triangle4>::Node* nodes = bvh->nodes;
  25.  
  26.     while (true)
  27.     {
  28.       /*! pop next node */
  29.       if (__builtin_expect(stackPtr == 0, false)) break;
  30.       stackPtr--;
  31.       int32 cur = popCur;
  32.  
  33.     next:
  34.  
  35.       /*! we mostly go into the inner node case */
  36.       if (__builtin_expect(cur >= 0, true))
  37.       {
  38.         /*! single ray intersection with 4 boxes */
  39.         const BVH4<Triangle4>::Node& node = bvh->node(nodes,cur);
  40.         const ssef tNearX = (norg.x + *(ssef*)((const char*)nodes+BVH4<Triangle4>::offsetFactor*size_t(cur)+nearX)) * rdir.x;
  41.         const ssef tNearY = (norg.y + *(ssef*)((const char*)nodes+BVH4<Triangle4>::offsetFactor*size_t(cur)+nearY)) * rdir.y;
  42.         const ssef tNearZ = (norg.z + *(ssef*)((const char*)nodes+BVH4<Triangle4>::offsetFactor*size_t(cur)+nearZ)) * rdir.z;
  43.         const ssef tNear = max(tNearX,tNearY,tNearZ,rayNear);
  44.         const ssef tFarX = (norg.x + *(ssef*)((const char*)nodes+BVH4<Triangle4>::offsetFactor*size_t(cur)+farX)) * rdir.x;
  45.         const ssef tFarY = (norg.y + *(ssef*)((const char*)nodes+BVH4<Triangle4>::offsetFactor*size_t(cur)+farY)) * rdir.y;
  46.         const ssef tFarZ = (norg.z + *(ssef*)((const char*)nodes+BVH4<Triangle4>::offsetFactor*size_t(cur)+farZ)) * rdir.z;
  47.         popCur = stack[stackPtr-1].ofs;      //!< pre-pop of topmost stack item
  48.         popDist = stack[stackPtr-1].dist;    //!< pre-pop of distance of topmost stack item
  49.         const ssef tFar = min(tFarX,tFarY,tFarZ,rayFar);
  50.         size_t _hit = movemask(tNear <= tFar);
  51.  
  52.         /*! if no child is hit, pop next node */
  53.         if (__builtin_expect(_hit == 0, false))
  54.           continue;
  55.  
  56.         /*! one child is hit, continue with that child */
  57.         size_t r = __bsf(_hit); _hit = __btc(_hit,r);
  58.         if (__builtin_expect(_hit == 0, true)) {
  59.           cur = node.child[r];
  60.           goto next;
  61.         }
  62.  
  63.         /*! two children are hit, push all onto stack */
  64.         const int32 c0 = node.child[r];
  65.         const float d0 = tNear[r];
  66.         r = __bsf(_hit);
  67.         _hit = __btc(_hit,r);
  68.         const int32 c1 = node.child[r];
  69.         const float d1 = tNear[r];
  70.         if (__builtin_expect(_hit == 0, true)) {
  71.            stack[stackPtr].ofs = c0; stack[stackPtr++].dist = d0;
  72.            stack[stackPtr].ofs = c1; stack[stackPtr++].dist = d1;
  73.            cur = stack[stackPtr-1].ofs; stackPtr--;
  74.            goto next;
  75.         }
  76.  
  77.         /*! Here starts the slow path for 3 or 4 hit children. We push all nodes onto the stack */
  78.         stack[stackPtr].ofs = c0; stack[stackPtr++].dist = d0;
  79.         stack[stackPtr].ofs = c1; stack[stackPtr++].dist = d1;
  80.  
  81.         /*! three children are hit, push all onto stack */
  82.         r = __bsf(_hit);
  83.         _hit = __btc(_hit,r);
  84.         int32 c = node.child[r];
  85.         float d = tNear[r];
  86.         stack[stackPtr].ofs = c; stack[stackPtr++].dist = d;
  87.         if (__builtin_expect(_hit == 0, true)) {
  88.           cur = stack[stackPtr-1].ofs; stackPtr--;
  89.           goto next;
  90.         }
  91.  
  92.         /*! four children are hit, push all onto stack */
  93.         r = __bsf(_hit);
  94.         _hit = __btc(_hit,r);
  95.         c = node.child[r];
  96.         d = tNear[r];
  97.         stack[stackPtr].ofs = c; stack[stackPtr++].dist = d;
  98.         cur = stack[stackPtr-1].ofs; stackPtr--;
  99.         goto next;
  100.       }
  101.  
  102.       /*! this is a leaf node */
  103.       else {
  104.         cur ^= 0x80000000;
  105.         const size_t ofs = size_t(cur) >> 5;
  106.         const size_t num = size_t(cur) & 0x1F;
  107.  
  108.         for (size_t i=ofs; i<ofs+num; i++) {
  109.             hit.t = ray.far;
  110.             bvh->triangles[i].intersect(ray, hit);
  111.         }
  112.         popCur = stack[stackPtr-1].ofs;    //!< pre-pop of topmost stack item
  113.         popDist = stack[stackPtr-1].dist;  //!< pre-pop of distance of topmost stack item
  114.       }
  115.     }
  116. }
  117.  
  118.  
  119. void buildCube(vector_t<BuildTriangle>& triangles,
  120.                const Vec3f& center,
  121.                const float halfWidth,
  122.                const float halfHeight,
  123.                const float halfDepth) {
  124.  
  125.     Vec3f v0, v1, v2, v3, c;
  126.  
  127.     Vec3f xAxis(1.0f, 0.0f, 0.0f);
  128.     Vec3f yAxis(0.0f, 1.0f, 0.0f);
  129.     Vec3f zAxis(0.0f, 0.0f, 1.0f);
  130.  
  131.     c = center - zAxis * halfDepth;
  132.     v0 = c - halfWidth * xAxis - halfHeight * yAxis;
  133.     v1 = c + halfWidth * xAxis - halfHeight * yAxis;
  134.     v2 = c + halfWidth * xAxis + halfHeight * yAxis;
  135.     v3 = c - halfWidth * xAxis + halfHeight * yAxis;
  136.     triangles.push_back(BuildTriangle(v0, v1, v2));
  137.     triangles.push_back(BuildTriangle(v2, v3, v0));
  138.  
  139.     c = center + zAxis * halfDepth;
  140.     v0 = c - halfWidth * xAxis - halfHeight * yAxis;
  141.     v1 = c + halfWidth * xAxis - halfHeight * yAxis;
  142.     v2 = c + halfWidth * xAxis + halfHeight * yAxis;
  143.     v3 = c - halfWidth * xAxis + halfHeight * yAxis;
  144.     triangles.push_back(BuildTriangle(v0, v1, v2));
  145.     triangles.push_back(BuildTriangle(v2, v3, v0));
  146.  
  147.     c = center - xAxis * halfWidth;
  148.     v0 = c - halfDepth * zAxis - halfHeight * yAxis;
  149.     v1 = c + halfDepth * zAxis - halfHeight * yAxis;
  150.     v2 = c + halfDepth * zAxis + halfHeight * yAxis;
  151.     v3 = c - halfDepth * zAxis + halfHeight * yAxis;
  152.     triangles.push_back(BuildTriangle(v0, v1, v2));
  153.     triangles.push_back(BuildTriangle(v2, v3, v0));
  154.  
  155.     c = center + xAxis * halfWidth;
  156.     v0 = c - halfDepth * zAxis - halfHeight * yAxis;
  157.     v1 = c + halfDepth * zAxis - halfHeight * yAxis;
  158.     v2 = c + halfDepth * zAxis + halfHeight * yAxis;
  159.     v3 = c - halfDepth * zAxis + halfHeight * yAxis;
  160.     triangles.push_back(BuildTriangle(v0, v1, v2));
  161.     triangles.push_back(BuildTriangle(v2, v3, v0));
  162.  
  163.     c = center - yAxis * halfHeight;
  164.     v0 = c - halfWidth * xAxis - halfDepth * zAxis;
  165.     v1 = c + halfWidth * xAxis - halfDepth * zAxis;
  166.     v2 = c + halfWidth * xAxis + halfDepth * zAxis;
  167.     v3 = c - halfWidth * xAxis + halfDepth * zAxis;
  168.     triangles.push_back(BuildTriangle(v0, v1, v2));
  169.     triangles.push_back(BuildTriangle(v2, v3, v0));
  170.  
  171.     c = center + yAxis * halfHeight;
  172.     v0 = c - halfWidth * xAxis - halfDepth * zAxis;
  173.     v1 = c + halfWidth * xAxis - halfDepth * zAxis;
  174.     v2 = c + halfWidth * xAxis + halfDepth * zAxis;
  175.     v3 = c - halfWidth * xAxis + halfDepth * zAxis;
  176.     triangles.push_back(BuildTriangle(v0, v1, v2));
  177.     triangles.push_back(BuildTriangle(v2, v3, v0));
  178. }
  179.  
  180. int main(int argc, char *argv[]) {
  181.  
  182.     Ref<Intersector> bvh4;
  183.     vector_t<BuildTriangle> triangles;
  184.     Ray ray(Vec3f(-5.0f, 0.0f, 0.0f), Vec3f(1.0f, 0.0f, 0.0f));
  185.  
  186.     buildCube(triangles, Vec3f(0.0f, 0.0f, 0.0f), 1.0f, 1.0f, 1.0f);
  187.     TaskScheduler::init();
  188.     bvh4 = rtcCreateAccel("bvh4", triangles.begin(), triangles.size());
  189.     bvh4->intersect(ray);
  190.     TaskScheduler::cleanup();
  191.     return EXIT_SUCCESS;
  192. }
  193.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement