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; }
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); }
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); } }
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); } }
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; }
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; }