//---- initialisation Stack.Push(kDTree.Root); //---- while there are some nodes in the stack or the query queue while (!Stack.Empty() $||$ !QueryQueue.Empty()) { //---- PART 1: processing finished occlusion queries while (!QueryQueue.Empty() && (ResultAvailable(QueryQueue.Front()) $||$ Stack.Empty())) { if (!ResultAvailable(QueryQueue.Front())) { //--- result is not available and the stack is empty //--- check if we can do some conservative decision N = QueryQueue.GetLeastCostNode(); if (N.renderingCost < MaxRenderCost) { RenderSubtree(N); QueryQueue.DequeLeastCostNode(); //-- we do not change N's visibility classfication - //-- N remains in the cut for the next frame } else //-- wait for the availability of the result while (!QueryQueue.ResultAvailable) Wait(); } else { N = QueryQueue.Dequeue(); //-- check the result of the query if ( N.visiblePixels $>$ VisibilityThreshold ) { N.visibility = VISIBLE; if (IsLeaf(N)) Render(N); else { //-- pull down Stack.Push(FarChild(N)); Stack.Push(CloseChild(N)); } } else { N.visibility = INVISIBLE; //-- pull up PullUpInvisibility(N); } } } //---- PART 2: kd-tree traversal if (!Stack.Empty()) { N = Stack.Pop(); N.lastVisited = frameID; if (InsideViewFrustum(N)) { //-- skip testing of all nodes above the cut if (!IsAboveTheCut(N)) { IssueOcclustionQuery(N); QueryQueue.Enqueue(N); if (WasVisible(N) $&&$ IsLeaf(N)) Render(N); else { //-- go down the kD-tree Stack.Push(FarChild(N)); Stack.Push(CloseChild(N)); } } } } }