Esempio n. 1
0
local void ball_search(smxptr sm, real r2ball, real *ri)
{
    kdnode *ntab = sm->kd->ntab;
    bodyptr *bptr = sm->kd->bptr;
    pqnode *pq = sm->pqhead;
    int cell, cp, ct, pj;
    real dist2;

    cell = KDROOT;                              /* start at root of tree    */
    while (cell < sm->kd->nsplit) {             /* descend to local bucket  */
        if (ri[ntab[cell].dim] < ntab[cell].split)
            cell = Lower(cell);
        else
            cell = Upper(cell);
    }
    for (pj = ntab[cell].first; pj <= ntab[cell].last; ++pj)
	if (! InQue(bptr[pj])) {		/* in bucket, but not que?  */
	    DISTSQV(dist2, ri, Pos(bptr[pj]));  /* compute dist^2 to center */
	    if (dist2 < r2ball) {		/* within current ball?     */
		ClrFlag(bptr[pq->pind], INQUE);	/* drop furthest from que   */
		SetFlag(bptr[pj], INQUE);	/* and add this one to que  */
		pq->pqkey = dist2;              /* store its distance       */
		pq->pind = pj;                  /* and its index            */
		PQReplace(pq);                  /* move to rightful place   */
		r2ball = pq->pqkey;             /* adopt new search radius  */
	    }
	}
    while (cell != KDROOT) {			/* scan back toward root    */
        cp = Sibling(cell);
        ct = cp;
        SetNext(ct);
	do {
            Intersect(ntab[cp], r2ball, ri, GetNextCell);
						/* got intersection to test */
            if (cp < sm->kd->nsplit) {          /* not yet down to bucket?  */
                cp = Lower(cp);
                continue;
            } else                              /* scan bucket for winners  */
                for (pj = ntab[cp].first; pj <= ntab[cp].last; ++pj)
		    if (! InQue(bptr[pj])) {	/* not already in the que?  */
			DISTSQV(dist2, ri, Pos(bptr[pj]));
			if (dist2 < r2ball) {	/* but within current ball? */
			    ClrFlag(bptr[pq->pind], INQUE);
			    SetFlag(bptr[pj], INQUE);
			    pq->pqkey = dist2;
			    pq->pind = pj;
			    PQReplace(pq);
			    r2ball = pq->pqkey;
			}
		    }
          GetNextCell:
            SetNext(cp);
        } while (cp != ct);
        cell = Parent(cell);			/* climb down towards root  */
    }
    sm->pqhead = pq;
}
Esempio n. 2
0
void
MTnode::Print(ostream& os) const
{
	if(obj!=NULL) os << *obj << " ";
//	else cout << "obj NULL...\n";
	os << ((MTnode *)this)->Path() << " #Entries: " << NumEntries() << ", Level " << Level();
	if(IsLeaf()) os << "(Leaf)";
	else os << "(Internal)";
	os << ", Sibling: " << Sibling() << ", Size: " << Size() << "/" << Tree()->Store()->PageSize() << endl;
	for(int i=0; i<NumEntries(); i++) (*this)[i]->Print(os);
}
Esempio n. 3
0
void
MTnode::Print (ostream& os) const
{
	if (obj) {
		os << *obj << " ";
	}
	os << ((MTnode *)this)->Path() << " #Entries: " << NumEntries() << ", Level " << Level();
	IsLeaf () ? os << "(Leaf)" : os << "(Internal)";
	os << ", Sibling: " << Sibling() << ", Size: " << Size() << "/" << Tree()->Store()->PageSize() << endl;
	for (int i=0; i<NumEntries(); i++) {
		(*this)[i]->Print(os);
	}
}
Esempio n. 4
0
void 
GiSTnode::Print (ostream& os) const
{
	os << path << " #Entries: " << NumEntries() << ", ";
	os << "Level " << Level();
	if (IsLeaf()) {
		os << "(Leaf)";
	} else {
		os << "(Internal)";
	}
	os << ", Sibling: " << Sibling();
	os << ", Size: " << Size() << "/" << tree->Store()->PageSize() << endl;
	for (int i=0; i<numEntries; i++) {
		(*this)[i]->Print(os);
	}
}
Esempio n. 5
0
void 
GiSTnode::Pack(char *page) const
{
  // Pack the header
  GiSTheader *h  = (GiSTheader *) page;
  h->level     = Level();
  h->numEntries = NumEntries();
  h->sibling    = Sibling();

  int fixlen = FixedLength();
  GiSTlte *ltable = (GiSTlte *) (page+tree->Store()->PageSize());
  GiSTlte ltptr = GIST_PAGE_HEADER_SIZE;

  for (int i=0; i<numEntries; i++) {
      GiSTcompressedEntry compressedEntry = (*this)[i]->Compress();

      if (fixlen)
	  assert(fixlen == compressedEntry.keyLen);

      // Copy the entry onto the page
      if (compressedEntry.keyLen > 0)
	  memcpy(page+ltptr,
		 compressedEntry.key,
		 compressedEntry.keyLen);

      memcpy(page+ltptr+compressedEntry.keyLen,
	     &compressedEntry.ptr,
	     sizeof(GiSTpage));

      // Be tidy
      if (compressedEntry.key)
	delete compressedEntry.key;

      // Enter a pointer to the entry in the line table
      if (!fixlen) *--ltable = ltptr;

      int entryLen = compressedEntry.keyLen + sizeof(GiSTpage);
      ltptr += entryLen;
  }

  // Store extra line table entry so we know last entry's length
  *--ltable = ltptr;
}
Esempio n. 6
0
TraversalState BVH::Traverse(TraversalState state, const SlimRay& ray, HitRecord* nearest,
 function<bool (uint32_t index, const SlimRay& ray, HitRecord* hit, bool* request_suspend)> intersector,
 bool resume) {
    // Precompute the inverse direction of the ray.
    vec3 inv_dir(1.0f / ray.direction.x,
                 1.0f / ray.direction.y,
                 1.0f / ray.direction.z);

    // Initialize traversal based on passed state.
    TraversalState traversal = state;
    bool request_suspend = false;

    if (resume) {
        if (traversal.state == TraversalState::State::FROM_PARENT) {
            goto resume_parent;
        } else if (traversal.state == TraversalState::State::FROM_SIBLING) {
            goto resume_sibling;
        } else {
            TERRLN("Must be in FROM_PARENT or FROM_SIBLING state to resume traversal!");
        }
    }

    while (true) {
        switch (traversal.state) {
            case TraversalState::State::FROM_PARENT:
                if (!BoundingHit(_nodes[traversal.current].bounds, ray, inv_dir, nearest->t)) {
                    // Ray missed the near child, try the far child.
                    traversal.current = Sibling(traversal.current);
                    traversal.state = TraversalState::State::FROM_SIBLING;
                } else if (_nodes[traversal.current].leaf) {
                    // Ray hit the near child and it's a leaf node.
                    request_suspend = false;
                    traversal.hit = intersector(_nodes[traversal.current].index, ray, nearest, &request_suspend) || traversal.hit;
                    if (request_suspend) goto suspend_traversal;
resume_parent:      traversal.current = Sibling(traversal.current);
                    traversal.state = TraversalState::State::FROM_SIBLING;
                } else {
                    // Ray hit the near child and it's an interior node.
                    traversal.current = NearChild(traversal.current, ray.direction);
                    traversal.state = TraversalState::State::FROM_PARENT;
                }
                break;

            case TraversalState::State::FROM_SIBLING:
                if (!BoundingHit(_nodes[traversal.current].bounds, ray, inv_dir, nearest->t)) {
                    // Ray missed the far child, backtrack to the parent.
                    traversal.current = _nodes[traversal.current].parent;
                    traversal.state = TraversalState::State::FROM_CHILD;
                } else if (_nodes[traversal.current].leaf) {
                    // Ray hit the far child and it's a leaf node.
                    request_suspend = false;
                    traversal.hit = intersector(_nodes[traversal.current].index, ray, nearest, &request_suspend) || traversal.hit;
                    if (request_suspend) goto suspend_traversal;
resume_sibling:     traversal.current = _nodes[traversal.current].parent;
                    traversal.state = TraversalState::State::FROM_CHILD;
                } else {
                    // Ray hit the far child and it's an interior node.
                    traversal.current = NearChild(traversal.current, ray.direction);
                    traversal.state = TraversalState::State::FROM_PARENT;
                }
                break;

            case TraversalState::State::FROM_CHILD:
                if (traversal.current == 0) {
                    // Traversal has finished.
                    return traversal;
                }
                if (traversal.current == NearChild(_nodes[traversal.current].parent, ray.direction)) {
                    // Coming back up through the near child, so traverse
                    // to the far child.
                    traversal.current = Sibling(traversal.current);
                    traversal.state = TraversalState::State::FROM_SIBLING;
                } else {
                    // Coming back up through the far child, so continue
                    // backtracking through the parent.
                    traversal.current = _nodes[traversal.current].parent;
                    traversal.state = TraversalState::State::FROM_CHILD;
                }
                break;

            default:
                TERRLN("BVH traversal in unknown state!");
                exit(EXIT_FAILURE);
                break;
        }
    }

    /// Shouldn't ever get here...
    TERRLN("Unexpected exit path in BVH traversal.");
    return TraversalState();

suspend_traversal:
    return traversal;
}