Пример #1
0
SpatialMarkup
SpatialConvex::triangleTest(uint64 id)
{
  SpatialMarkup mark;
//
// do the face test on the triangle

  mark =  testNode(V(NV(0)),V(NV(1)),V(NV(2)));

// do we have a final result code?
// if rEJECT, fULL then return

  if(mark > fULL) return mark;

  if(mark == fULL) {
      fillChildren(id); // propagate final result to children
      return mark;
  }

// if pARTIAL or dONTKNOW, then continue, test children,
//    but do not reach beyond the leaf nodes.
//    If Convex is fully contained within one (sWALLOWED),
//    we can stop looking further in another child

  if (NC(id,0)!=0) {
    triangleTest(NC(id,0));
    triangleTest(NC(id,1));
    triangleTest(NC(id,2));
    triangleTest(NC(id,3));
// we are at the leafnodes
// If we have to recurse further, calculate intersections one by one
// If not, just set the proper bit in partial_ or append id to plist_.
  } else {
    if(addlevel_) {
      // from now on, continue to build the triangles dynamically.
      // until maxlevel_ levels depth.
      testPartial(addlevel_, N(id).id_, V(NV(0)), V(NV(1)), V(NV(2)));

    } else {
      if(bitresult_)
	partial_->set((uint32)index_->leafNumberById(N(id).id_),true);
      else
	plist_->append(N(id).id_);
    }
  }

  return mark;
}
Пример #2
0
void VoxelTree::fillChildren(const Surface &sur, const SpacialHash &faceHash, const SpacialHash &faceHashHiRes, int levelNum, int pX, int pY, int pZ, const Array<int> &tris, int numLevels, const Point3D &PMIN, float eL){
  //  for each voxel
  for (int x = 0; x < 2; x++){
    int cX = pX*2 + x;

    for (int y = 0; y < 2; y++){  
      int cY = pY*2 + y;

      for (int z = 0; z < 2; z++){
        int cZ = pZ*2 + z;

        Point3D pMin;
        pMin.x = PMIN.x + cX * eL;
        pMin.y = PMIN.y + cY * eL;
        pMin.z = PMIN.z + cZ * eL;

        //  test if the cell is an edge cell
        Array<int> subTris;
        filterTriangles(&subTris, tris, sur, pMin, eL);
        if (subTris.getSize()){
          if (levelNum == numLevels-1)
            level.setFlag(cX, cY, cZ, VL_FLAG_EDGE);
          else
            fillChildren(sur, faceHash, faceHashHiRes, levelNum+1, cX, cY, cZ, subTris, numLevels, PMIN, eL/2.0);
          }
        else{
          //  test if the cell is inside the object
          Point3D pMid;
          pMid.x = PMIN.x + (cX + 0.5)* eL;
          pMid.y = PMIN.y + (cY + 0.5)* eL;
          pMid.z = PMIN.z + (cZ + 0.5)* eL;

          bool in = ::insideSurface(pMid, sur, faceHash, faceHashHiRes);
          char flag = in? VL_FLAG_INTERNAL : VL_FLAG_OUTSIDE;
          if (levelNum == numLevels-1)
            level.setFlag(cX, cY, cZ, flag);
          else
            fillFlags(levelNum+1, cX, cY, cZ, flag, numLevels);
          }
        }
      }
    }
}
Пример #3
0
/////////////FILLCHILDREN/////////////////////////////////
// fillChildren: mark children as full
//
void
SpatialConvex::fillChildren(uint64 id) {
  if(range_)
    plist_->append(N(id).id_);
  else {
    if(NC(id,0)!=0) {
      for(size_t i = 0; i < 4; i++) {
	fillChildren(NC(id,i));
      }
    } else {
      // we are at the leaf. If we still have levels to recurse,
      // fill them. If not, just set the full_ bitlist's or flist_ list's
      // value correctly.
      if(addlevel_)
	setfull(N(id).id_,addlevel_);
      else {
	if(bitresult_)
	  full_->set((uint32)index_->leafNumberById(N(id).id_), true);
	else
	  flist_->append(N(id).id_);
      }
    }
  }
}
Пример #4
0
void VoxelTree::setup(const Surface &sur, const SpacialHash &faceHash, const SpacialHash &faceHashHiRes, int numLevels){
  this->sur = &sur;
  this->faceHash = &faceHash;
  this->faceHashHiRes = &faceHashHiRes;

  //  work out the bounding box
  Point3D pMin = sur.pMin;
  float lX = sur.pMax.x - sur.pMin.x;
  float lY = sur.pMax.y - sur.pMin.y;
  float lZ = sur.pMax.z - sur.pMin.z;
  float l = lX;
  if (lY > l)
    l = lY;
  if (lZ > l)
    l = lZ;

  //  create the levels
  int d = pow(2, numLevels);
  level.setup(pMin, l, d);

  //  initialise the list of triangle
  Array<int> tris;
  int numTris = sur.triangles.getSize();
  tris.resize(numTris);
  for (int i = 0; i < numTris; i++)
    tris.index(i) = i;

  //  fill the levels
  fillChildren(sur, faceHash, faceHashHiRes, 0, 0, 0, 0, tris, numLevels, pMin, l/2.0);

  //  verify lowest set of cells
/*{
  const VoxelLevel *vl = &level;
  float eL = vl->getLength();
  int d = vl->getD();
  OUTPUTINFO("d = %d\n", d);
  for (int i = 0; i < d; i++){
    for (int j = 0; j < d; j++){
      for (int k = 0; k < d; k++){
        char flag = vl->getFlag(i, j, k);

        Point3D pMin;
        vl->getMinPt(&pMin, i, j, k);
        Point3D pMid;
        vl->getMidPt(&pMid, i, j, k);

        char flag1 = vl->getFlag(pMid);
        if (flag1 != flag)
          OUTPUTINFO("Test Fail : %d %d\n", flag, flag1);

        Array<int> selTri;
        filterTriangles(&selTri, tris, sur, pMin, eL);
        OUTPUTINFO("%d Triangles\n", selTri.getSize());
        if (selTri.getSize()){
          //  EDGE
          if (flag != VL_FLAG_EDGE)
            OUTPUTINFO("Should be VL_FLAG_EDGE was (%d)\n", flag);
          }
        else{
          //  IN/OUT
          bool in = ::insideSurface(pMid, sur, sh);

          if (in && flag != VL_FLAG_INTERNAL)
            OUTPUTINFO("Should be VL_FLAG_INTERNAL was (%d)\n", flag);
          else if (!in && flag != VL_FLAG_OUTSIDE)
            OUTPUTINFO("Should be VL_FLAG_INTERNAL was (%d)\n", flag);
          }
        }
      }
    }
  }*/
}