Beispiel #1
0
    int BVHModel<BV>::recursiveBuildTree(int bv_id, int first_primitive, int num_primitives)
    {
      BVHModelType type = getModelType();
      BVNode<BV>* bvnode = bvs + bv_id;
      unsigned int* cur_primitive_indices = primitive_indices + first_primitive;

      // constructing BV
      BV bv = bv_fitter.fit(cur_primitive_indices, num_primitives);
      bv_splitter.computeRule(bv, cur_primitive_indices, num_primitives);


      bvnode->bv = bv;
      bvnode->first_primitive = first_primitive;
      bvnode->num_primitives = num_primitives;

      if(num_primitives == 1)
      {
        bvnode->first_child = -((*cur_primitive_indices) + 1);
      }
      else
      {
        bvnode->first_child = num_bvs;
        num_bvs += 2;

        int c1 = 0;
        for(int i = 0; i < num_primitives; ++i)
        {
          Vec3f p;
          if(type == BVH_MODEL_POINTCLOUD) p = vertices[cur_primitive_indices[i]];
          else if(type == BVH_MODEL_TRIANGLES)
          {
            const Triangle& t = tri_indices[cur_primitive_indices[i]];
            const Vec3f& p1 = vertices[t[0]];
            const Vec3f& p2 = vertices[t[1]];
            const Vec3f& p3 = vertices[t[2]];
            BVH_REAL x = (p1[0] + p2[0] + p3[0]) / 3;
            BVH_REAL y = (p1[1] + p2[1] + p3[1]) / 3;
            BVH_REAL z = (p1[2] + p2[2] + p3[2]) / 3;
            p = Vec3f(x, y, z);
          }
          else
          {
            std::cerr << "BVH Error: Model type not supported!" << std::endl;
            return BVH_ERR_UNSUPPORTED_FUNCTION;
          }


          // loop invariant: up to (but not including) index c1 in group 1,
          // then up to (but not including) index i in group 2
          //
          //  [1] [1] [1] [1] [2] [2] [2] [x] [x] ... [x]
          //                   c1          i
          //
          if(bv_splitter(p)) // in the right side
          {
            // do nothing
          }
          else
          {
            unsigned int temp = cur_primitive_indices[i];
            cur_primitive_indices[i] = cur_primitive_indices[c1];
            cur_primitive_indices[c1] = temp;
            c1++;
          }
        }


        if((c1 == 0) || (c1 == num_primitives)) c1 = num_primitives / 2;

        int num_first_half = c1;

        recursiveBuildTree(bvnode->leftChild(), first_primitive, num_first_half);
        recursiveBuildTree(bvnode->rightChild(), first_primitive + num_first_half, num_primitives - num_first_half);
      }

      return BVH_OK;
    }
Beispiel #2
0
int BVHModel<BV>::recursiveRefitTree_bottomup(int bv_id)
{
  BVNode<BV>* bvnode = bvs + bv_id;
  if(bvnode->isLeaf())
  {
    BVHModelType type = getModelType();
    int primitive_id = -(bvnode->first_child + 1);
    if(type == BVH_MODEL_POINTCLOUD)
    {
      BV bv;

      if(prev_vertices)
      {
        Vec3f v[2];
        v[0] = prev_vertices[primitive_id];
        v[1] = vertices[primitive_id];
        fit(v, 2, bv);
      }
      else
        fit(vertices + primitive_id, 1, bv);

      bvnode->bv = bv;
    }
    else if(type == BVH_MODEL_TRIANGLES)
    {
      BV bv;
      const Triangle& triangle = tri_indices[primitive_id];

      if(prev_vertices)
      {
        Vec3f v[6];
        for(int i = 0; i < 3; ++i)
        {
          v[i] = prev_vertices[triangle[i]];
          v[i + 3] = vertices[triangle[i]];
        }

        fit(v, 6, bv);
      }
      else
      {
        Vec3f v[3];
        for(int i = 0; i < 3; ++i)
        {
          v[i] = vertices[triangle[i]];
        }

        fit(v, 3, bv);
      }

      bvnode->bv = bv;
    }
    else
    {
      std::cerr << "BVH Error: Model type not supported!" << std::endl;
      return BVH_ERR_UNSUPPORTED_FUNCTION;
    }
  }
  else
  {
    recursiveRefitTree_bottomup(bvnode->leftChild());
    recursiveRefitTree_bottomup(bvnode->rightChild());
    bvnode->bv = bvs[bvnode->leftChild()].bv + bvs[bvnode->rightChild()].bv;
  }

  return BVH_OK;
}