Beispiel #1
0
/////////////TESTPARTIAL//////////////////////////////////
// testPartial: test a triangle's subtriangle whether they are partial.
// if level is nonzero, recurse.
//
void
RangeConvex::testPartial(size_t level, uint64 id,
			   const SpatialVector & v0,
			   const SpatialVector & v1,
			 const SpatialVector & v2, int PPrev)
{
  uint64 ids[4], id0;
  SpatialMarkup m[4];
  int P, F;// count number of partials and fulls

  SpatialVector w0 = v1 + v2; w0.normalize();
  SpatialVector w1 = v0 + v2; w1.normalize();
  SpatialVector w2 = v1 + v0; w2.normalize();

  ids[0] = id0 = id << 2;
  ids[1] = id0 + 1;
  ids[2] = id0 + 2;
  ids[3] = id0 + 3;

  m[0] = testNode(v0, w2, w1);
  m[1] = testNode(v1, w0, w2);
  m[2] = testNode(v2, w1, w0);
  m[3] = testNode(w0, w1, w2);

  F  = (m[0] == fULL)  + (m[1] == fULL)  + (m[2] == fULL)  + (m[3] == fULL);
  P = (m[0] == pARTIAL) + (m[1] == pARTIAL) + (m[2] == pARTIAL) + (m[3] == pARTIAL);

  //
  // Several interesting cases for saving this (the parent) trixel.
  // Case P==4, all four children are partials, so pretend parent is full, we save and return
  // Case P==3, and F==1, most of the parent is in, so pretend that parent is full again
  // Case P==2 or 3, but the previous testPartial had three partials, so parent was in an arc
  // as opposed to previous partials being fewer, so parent was in a tiny corner...
  

  if ((level-- <= 0) || ((P == 4) || (F >= 2) || (P == 3 && F == 1) || (P > 1 && PPrev == 3))){
    saveTrixel(id);
    return;
  } else {
    // look at each child, see if some need saving;
    for(int i=0; i<4; i++){
      if (m[i] == fULL){
	saveTrixel(ids[i]);
      }
    }
    // look at the four kids again, for partials
    
    if (m[0] == pARTIAL) testPartial(level, ids[0], v0, w2, w1, P);
    if (m[1] == pARTIAL) testPartial(level, ids[1], v1, w0, w2, P);
    if (m[2] == pARTIAL) testPartial(level, ids[2], v2, w1, w0, P);
    if (m[3] == pARTIAL) testPartial(level, ids[3], w0, w1, w2, P);
  }
}
DOMXPathResult* DOMXPathExpressionImpl::evaluate(const DOMNode *contextNode,
                                                 DOMXPathResult::ResultType type,
                                                 DOMXPathResult* result) const
{
    if(type!=DOMXPathResult::FIRST_ORDERED_NODE_TYPE && type!=DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE &&
       type!=DOMXPathResult::ANY_UNORDERED_NODE_TYPE && type!=DOMXPathResult::UNORDERED_NODE_SNAPSHOT_TYPE)
        throw DOMXPathException(DOMXPathException::TYPE_ERR, 0, fMemoryManager);

    if(contextNode==NULL || contextNode->getNodeType()!=DOMNode::ELEMENT_NODE)
        throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, fMemoryManager);

    JanitorMemFunCall<DOMXPathResultImpl> r_cleanup (
      0, &DOMXPathResultImpl::release);
    DOMXPathResultImpl* r=(DOMXPathResultImpl*)result;
    if(r==NULL)
    {
      r=new (fMemoryManager) DOMXPathResultImpl(type, fMemoryManager);
      r_cleanup.reset (r);
    }
    else
        r->reset(type);

    XPathMatcher matcher(fParsedExpression, fMemoryManager);
    matcher.startDocumentFragment();

    if(fMoveToRoot)
    {
        contextNode=contextNode->getOwnerDocument();
        if(contextNode==NULL)
            throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, fMemoryManager);

        QName qName(contextNode->getNodeName(), 0, fMemoryManager);
        SchemaElementDecl elemDecl(&qName);
        RefVectorOf<XMLAttr> attrList(0, true, fMemoryManager);
        matcher.startElement(elemDecl, 0, XMLUni::fgZeroLenString, attrList, 0);
        DOMNode* child=contextNode->getFirstChild();
        while(child)
        {
            if(child->getNodeType()==DOMNode::ELEMENT_NODE)
                testNode(&matcher, r, (DOMElement*)child);
            child=child->getNextSibling();
        }
        matcher.endElement(elemDecl, XMLUni::fgZeroLenString);
    }
    else
        testNode(&matcher, r, (DOMElement*)contextNode);

    r_cleanup.release ();
    return r;
}
Beispiel #3
0
int main()
{
    testNode();
    testMutex();
    std::cout << "End of program." << std::endl;
    return 0;
}
Beispiel #4
0
INLINE void cacheArchive(NODEI index, const Node* data)
{
	testNode(data, index, "Archiving");
	NODEI cindex = index / ARCHIVE_CLUSTER_SIZE;
	assert(cindex < ARCHIVE_CLUSTERS);
	if (archive[cindex]==NULL)
		archive[cindex] = new Node[ARCHIVE_CLUSTER_SIZE];
	archive[cindex][index % ARCHIVE_CLUSTER_SIZE] = *data;
}
Beispiel #5
0
TEST(NodeTests, EmptyNodeTest) {
    std::shared_ptr<Node> d1(nullptr);
    std::shared_ptr<Node> d2(nullptr);
    std::shared_ptr<Node> a(nullptr);
    Node testNode(1, a, d1, d2);
    EXPECT_EQ(testNode.anc, nullptr);
    EXPECT_EQ(testNode.desc1, nullptr);
    EXPECT_EQ(testNode.desc2, nullptr);
    EXPECT_EQ(testNode.get_id(), 1);
}
Beispiel #6
0
// computes the energy if the node returned by testNode() is moved
// to position testPos().
void PlanarityGrid::compCandEnergy()
{
	delete m_candidateGrid;
	node v = testNode();
	const DPoint& newPos = testPos();
	if(m_currentGrid->newGridNecessary(v,newPos))
		m_candidateGrid = new UniformGrid(m_layout,v,newPos);
	else
		m_candidateGrid = new UniformGrid(*m_currentGrid,v,newPos);
	m_candidateEnergy = m_candidateGrid->numberOfCrossings();
}
Beispiel #7
0
// this test checks if the classes provided are correctly stored
void run_class_test() {
	const std::string classString = "test classes are fun";
	CTML::Node testNode("a#test.test.classes.are.fun");
	std::cout << testNode.GetAttribute("hehhehtest") << std::endl;
	// get the test node's classlist.
	const std::string classList = testNode.GetAttribute("class");
	bool test = assert_strings_equal(classString, classList);
	std::cout << "Class Test " << ((test) ? "passed!" : "failed!") << std::endl <<
		"Class Output: " << classList << std::endl <<
		// use a double end line at the end for spacing between tests
		"Expected Output: " << classString << std::endl << std::endl;
}
Beispiel #8
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;
}
bool DOMXPathExpressionImpl::testNode(XPathMatcher* matcher, DOMXPathResultImpl* result, DOMElement *node) const
{
    int uriId=fStringPool->addOrFind(node->getNamespaceURI());
    QName qName(node->getNodeName(), uriId, fMemoryManager);
    SchemaElementDecl elemDecl(&qName);
    DOMNamedNodeMap* attrMap=node->getAttributes();
    XMLSize_t attrCount = attrMap->getLength();
    RefVectorOf<XMLAttr> attrList(attrCount, true, fMemoryManager);
    for(XMLSize_t i=0;i<attrCount;i++)
    {
        DOMAttr* attr=(DOMAttr*)attrMap->item(i);
        attrList.addElement(new (fMemoryManager) XMLAttr(fStringPool->addOrFind(attr->getNamespaceURI()),
                                                         attr->getNodeName(),
                                                         attr->getNodeValue(),
                                                         XMLAttDef::CData,
                                                         attr->getSpecified(),
                                                         fMemoryManager,
                                                         NULL,
                                                         true));
    }
    matcher->startElement(elemDecl, uriId, node->getPrefix(), attrList, attrCount);
    unsigned char nMatch=matcher->isMatched();
    if(nMatch!=0 && nMatch!=XPathMatcher::XP_MATCHED_DP)
    {
        result->addResult(node);
        if(result->getResultType()==DOMXPathResult::ANY_UNORDERED_NODE_TYPE || result->getResultType()==DOMXPathResult::FIRST_ORDERED_NODE_TYPE)
            return true;    // abort navigation, we found one result
    }

    if(nMatch==0 || nMatch==XPathMatcher::XP_MATCHED_D || nMatch==XPathMatcher::XP_MATCHED_DP)
    {
        DOMNode* child=node->getFirstChild();
        while(child)
        {
            if(child->getNodeType()==DOMNode::ELEMENT_NODE)
                if(testNode(matcher, result, (DOMElement*)child))
                    return true;
            child=child->getNextSibling();
        }
    }
    matcher->endElement(elemDecl, XMLUni::fgZeroLenString);
    return false;
}
Beispiel #10
0
void Planarity::printInternalData() const {
	cout << "\nCrossing Matrix:";
	int e_num = m_nonSelfLoops.size();
	for(int i = 1; i < e_num; i++) {
		cout << "\n Edge " << i << " crosses: ";
		for(int j = i+1; j <= e_num; j++)
			if((*m_crossingMatrix)(i,j)) cout << j << " ";
	}
	cout << "\nChanged crossings:";
	if(testNode() == NULL) cout << " None.";
	else {
		ListConstIterator<ChangedCrossing> it;
		for(it = m_crossingChanges.begin(); it.valid(); ++it) {
			ChangedCrossing cc = *(it);
			cout << " (" << cc.edgeNum1 << "," << cc.edgeNum2 << ")" << cc.cross;
		}
	}

}
Beispiel #11
0
/////////////TESTSUBTRIANGLE////////////////////////////////
// testSubTriangle: call full or partial depending on result of testNode.
//
void
SpatialConvex::testSubTriangle(size_t level, uint64 id,
			   const SpatialVector & v0, 
			   const SpatialVector & v1, 
			   const SpatialVector & v2) {

  // test this triangle.
  SpatialMarkup mark = testNode(v0, v1, v2);

  // if it is full, set all fulls below this level, too
  // else if it is partial or unknown or swallowed call testpartial
  // with this new level.
  if(mark == fULL) {
    if(range_)
      plist_->append(id);
    else
      setfull(id , level);
  } else if(mark < fULL)
    testPartial(level, id, v0, v1, v2);
}
Beispiel #12
0
	// computes the energy if the node returned by testNode() is moved
	// to position testPos().
	void Planarity::compCandEnergy()
	{
		node v = testNode();
		m_candidateEnergy = energy();
		edge e;
		m_crossingChanges.clear();

		forall_adj_edges(e,v) if(!e->isSelfLoop()) {
			// first we compute the two endpoints of e if v is on its new position
			node s = e->source();
			node t = e->target();
			DPoint p1 = testPos();
			DPoint p2 = (s==v)? currentPos(t) : currentPos(s);
			int e_num = (*m_edgeNums)[e];
			edge f;
			// now we compute the crossings of all other edges with e
			ListIterator<edge> it;
			for(it = m_nonSelfLoops.begin(); it.valid(); ++it) if(*it != e) {
				f = *it;
				node s2 = f->source();
				node t2 = f->target();
				if(s2 != s && s2 != t && t2 != s && t2 != t) {
					bool cross = lowLevelIntersect(p1,p2,currentPos(s2),currentPos(t2));
					int f_num = (*m_edgeNums)[f];
					bool priorIntersect = (*m_crossingMatrix)(min(e_num,f_num),max(e_num,f_num));
					if(priorIntersect != cross) {
						if(priorIntersect) m_candidateEnergy --; // this intersection was saved
						else m_candidateEnergy ++; // produced a new intersection
						ChangedCrossing cc;
						cc.edgeNum1 = min(e_num,f_num);
						cc.edgeNum2 = max(e_num,f_num);
						cc.cross = cross;
						m_crossingChanges.pushBack(cc);
					}
				}
			}
		}
	}
void testTree( const Path::NameNode& rootNode ) {
   // first, the rootNode should have four children:
   // a, b, e and g
   testNode( rootNode, "eval", 4 );

   Path::NameNode::const_iterator it = rootNode.begin();
   MC2_TEST_REQUIRED( (*it)->getName() == "a" );
   ++it;
   MC2_TEST_REQUIRED( (*it)->getName() == "b" );
   ++it;
   MC2_TEST_REQUIRED( (*it)->getName() == "e" );
   ++it;
   MC2_TEST_REQUIRED( (*it)->getName() == "g" );

   //
   // Test the "a"-tree
   //
   it = rootNode.begin();
   // should have 3 elements
   testNode( **it, "a", 3 );

   //
   // test sub node of "b" of "a"
   //
   it = (*it)->begin();
   testNode( **it, "b", 2 );

   Path::NameNode::const_iterator subIt = (*it)->begin();
   // first subnode must be "c"
   testNode( **subIt, "c", 0 );

   ++subIt;
   // second subnode must be "d" and empty
   testNode( **subIt, "d", 0 );

   //
   // test sub node "c" of "a"
   //
   it = rootNode.begin();
   it = (*it)->begin();
   ++it;
   testNode( **it, "c", 1 );
   // the subnode's name should be "d" and empty
   testNode( *(*(*it)->begin()), "d", 0 );

   //
   // test sub node "g" of "a"
   //
   it = rootNode.begin();
   it = (*it)->begin();
   ++it;
   ++it;
   // "g" should be empty
   testNode( **it, "g", 0 );

   //
   // Now test the "b" tree of the root node
   //
   it = rootNode.begin();
   ++it;
   // "b" should have one element
   testNode( **it, "b", 1 );

   // test "c" of "b"
   it = (*it)->begin();
   // should also have one element
   testNode( **it, "c", 1 );

   // test "d" of "c" of "b"
   it = (*it)->begin();
   // it should be empty
   testNode( **it, "d", 0 );

   //
   // Now test "e" tree of the root node
   //
   it = rootNode.begin();
   ++it;
   ++it;
   testNode( **it, "e", 1 );

   // test "f" of "e" of root node
   it = (*it)->begin();
   testNode( **it, "f", 0 );

   it = rootNode.begin();
   ++it;
   ++it;
   ++it;
   testNode( **it, "g", 0 );

}
Beispiel #14
0
 intrusive_list() : intrusive_list_base() {
   intrusive_list_node* testNode((T*)0);
   static_cast<void>(sizeof(testNode));
 }
Beispiel #15
0
/////////////TRIANGLETEST/////////////////////////////////
// testTrixel: this is the main test of a triangle vs a Convex.  It
// will properly mark up the flags for the triangular node[index], and
// all its children
SpatialMarkup
RangeConvex::testTrixel(uint64 id)
{
  SpatialMarkup mark;
  uint64 childID;
  uint64 tid;

  // const struct SpatialIndex::QuadNode &indexNode = index_->nodes_[id];
  const struct SpatialIndex::QuadNode *indexNode = &index_->nodes_[id];

  //
  // do the face test on the triangle

  // was: mark =  testNode(V(NV(0)),V(NV(1)),V(NV(2)));
  // changed to by Gyorgy Fekete. Overall Speedup approx. 2%

  mark = testNode(id); // was:(indexNode or  id);


  switch(mark){
  case fULL:
    tid = N(id).id_;

    saveTrixel(tid);  //was:  plist_->push_back(tid);
    // fillChildren(id); // [ed:NEW]

    return mark;
  case rEJECT:
    tid = N(id).id_;
    return mark;
  default:
    // 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

    // #define NC(n,m)	index_->nodes_[(n)].childID_[(m)]	// the children n->m
    // childID = index_->nodes_[id].childID_[0];

    // Test how many of the four children are rejected?
    //
    // [ed:algo]
    //
    break;
  }

  // NEW NEW algorithm  Disabled when enablenew is 0
  //
  {
    childID = indexNode->childID_[0];
    if ( childID != 0){
      ////////////// [ed:split]
      tid = N(id).id_;
      childID = indexNode->childID_[0];  testTrixel(childID);
      childID = indexNode->childID_[1];  testTrixel(childID);
      childID = indexNode->childID_[2];  testTrixel(childID);
      childID = indexNode->childID_[3];  testTrixel(childID);
    } else { /// No children...
      if (addlevel_){
	testPartial(addlevel_, N(id).id_, V(NV(0)), V(NV(1)), V(NV(2)), 0);
      } else {
	saveTrixel(N(id).id_); // was: plist_->push_back(N(id).id_);
      }
    }
  } ///////////////////////////// END OF NEW ALGORITHM returns mark below;



  /* NEW NEW NEW
     If rejected, then we return [done]
     If full, then we list the id (propagate to children) [done]

     If partial, then we look ahead to see how many children are rejected.
     But ah, next iteration could benefit from having computed this already.

     If two chidlren are rejected, then we stop
     If one or 0 nodes are rejected, then we
  */
  return mark;
}
Beispiel #16
0
INLINE void cacheUnarchive(NODEI index, Node* data)
{
	assert(index < nodeCount);
	*data = archive[index / ARCHIVE_CLUSTER_SIZE][index % ARCHIVE_CLUSTER_SIZE];
	testNode(data, index, "Unarchiving");
}
void OcclusionCullingTreeBuilder::draw(DrawEnv             &denv,
                                       RenderPartitionBase *part)
{
#if 1 //CHECK_ENV_ACTION
    //std::cout << "Frame Start" << std::endl;
    Window* win = denv.getWindow();

    if(_sortMode == ModeAdaptiveBucket)
    {
        // Merge all the buckets to a tree
        for(UInt32 i = 0; i < _numBuckets; ++i)
        {
            if(_buckets[i] != NULL)
            {
                _pRoot->addChild(_buckets[i]);
            }
        }
    }

    if(!win->hasExtension(_extOcclusionQuery))
    {
        // Don't have it, just draw the whole tree.
        SLOG << "Missing OCC GL extensions!!" << endLog;

        _uiActiveMatrix = 0;
        Inherited::drawNode(_pRoot, denv, part);

        return;
    }

//SETUP
// done in add, action should never change
//    _ract = dynamic_cast<RenderAction*>(denv.getAction());

    if(!_ract)
    {
        FFATAL(("OcclusionCullingTreeBuilder::draw: Action in denv is not a "
                "RenderAction!\n"));
        return;
    }

    _uiActiveMatrix = 0;
    Real32 screenCoveredPercentage = 0.f;
    if(_ract->getOcclusionCullingQueryBufferSize() != _numTestSamples || !_occInitialized)
    {
        _numTestSamples = _ract->getOcclusionCullingQueryBufferSize();
        //std::cout << "Buf size: " << _numTestSamples << std::endl;
        _testSamples.resize(_numTestSamples);
        //std::cout << "Performing OCC on " << _numNodes << " nodes." << std::endl;

        GenQueryT genquer = reinterpret_cast<GenQueryT>(
            win->getFunction(_funcGenQueriesARB));
        genquer(_numTestSamples, &(_testSamples.front()));
        _occInitialized = true;
    }

    if(!_isOccStateCreated)
    {
        _isOccStateCreated = true;

        // register an exit function to clean up the State object
        addPreFactoryExitFunction(&releaseTestingState);

        // Create an empty state to render test nodes.
        _testingStatePtr = State::create();

        DepthChunkUnrecPtr dc = DepthChunk::create();
        dc->setReadOnly(true);
        _testingStatePtr->addChunk(dc);

        ColorMaskChunkUnrecPtr cc = ColorMaskChunk::create();
        cc->setMaskR(false);
        cc->setMaskG(false);
        cc->setMaskB(false);
        cc->setMaskA(false);
        _testingStatePtr->addChunk(cc);

        PolygonChunkUnrecPtr pc = PolygonChunk::create();
        pc->setCullFace(GL_BACK);
        _testingStatePtr->addChunk(pc);

        commitChanges();
    }

    //glGenQueriesARB(_numNodes, queries);
    //std::cout << "Calculated Pixels" << std::endl;

    _vpWidth  = denv.getPixelWidth();
    _vpHeight = denv.getPixelHeight();

    _worldToScreen = denv.getVPWorldToScreen();

    _testingState = &*_testingStatePtr;


    _minFeatureSize = _ract->getOcclusionCullingMinimumFeatureSize();
    _visPixelThreshold = _ract->getOcclusionCullingVisibilityThreshold();
    _coveredProbThreshold = _ract->getOcclusionCullingCoveredThreshold();
    _minTriangleCount = _ract->getOcclusionCullingMinimumTriangleCount();
    _inTesting = false;

    _currSample = 0;
//DRAW / TEST / RE-DRAW ON BUFFER FULL
    testNode(_pRoot, denv, part, screenCoveredPercentage);

    StatCollector *sc = _ract->getStatCollector();
    if(sc != NULL)
        sc->getElem(statNOccNodes)->add(_numNodes);
    _numNodes=0;
    _uiActiveMatrix = 0;

    leaveTesting(denv, part);

//RESULTS / RE-DRAW
    while( !_testPendingNodes.empty() )
    {
        drawTestResults(denv, part);
    }

    //std::cout << "Calc Pixels" << std::endl;


    if(sc != NULL)
    {
        Real32 percentage =
            Real32(sc->getElem(statNOccInvisible)->get()) /
            Real32(sc->getElem(statNOccTests)->get());
        sc->getElem(statNOccSuccessTestPer)->set(percentage);
    }

    //std::cout << "Real pixels " << std::endl;
    //std::cout << std::endl;

   // screen_covered_percentage = 1.0;
   // drawNode(_pRoot, denv, part, screen_covered_percentage);
    _numNodes=0;
    _currSample = 0;
    //std::cout << "Frame End" << std::endl;
#endif
}
Beispiel #18
0
 void nodePf(std::stringstream & stream)
 {
     testNode(stream);
 }
void OcclusionCullingTreeBuilder::testNode(OCRenderTreeNode   *pNode,
                                           DrawEnv             &denv,
                                           RenderPartitionBase *part,
                                           Real32              &scr_percent)
{
    while (pNode != NULL)
    {
    //MATRIX SETUP
        UInt32 uiNextMatrix = pNode->getMatrixStore().first;

        if(uiNextMatrix != 0 && uiNextMatrix != _uiActiveMatrix)
        {
            glLoadMatrixf(pNode->getMatrixStore().second.getValues());

            _uiActiveMatrix = uiNextMatrix;

            _currMatrix.second = pNode->getMatrixStore().second;

            updateTopMatrix(denv);

            denv.setObjectToWorld(_accMatrix);

            ++part->_uiNumMatrixChanges;
        }

        const BoxVolume &volume = pNode->getVolume();
        Pnt3f min,max;

        volume.getBounds(min, max);
        Pnt3f p[8];
        p[0].setValues(min[0],min[1],min[2]);
        p[1].setValues(max[0],min[1],min[2]);
        p[2].setValues(min[0],max[1],min[2]);
        p[3].setValues(min[0],min[1],max[2]);
        p[4].setValues(max[0],max[1],min[2]);
        p[5].setValues(max[0],min[1],max[2]);
        p[6].setValues(min[0],max[1],max[2]);
        p[7].setValues(max[0],max[1],max[2]);

        //std::cout << "OtoW:" << std::endl;
        //std::cout << denv.getObjectToWorld() << std::endl;
        //std::cout << "WtoC:" << std::endl;
        //std::cout << worldToCam << std::endl;
        for(UInt32 i = 0; i<8;i++)
        {
           // std::cout << p[i] << "=>";
            denv.getObjectToWorld().mult    (p[i], p[i]);
            _worldToScreen         .multFull(p[i], p[i]);
            //std::cout << p[i] << "  ";
        }
        min=p[0];
        max=p[0];
        for(UInt32 i = 0; i<8; i++)
        {
           for(UInt32 j=0; j<2; j++)
           {
              if(p[i][j] < min[j])
              {
                min[j] = p[i][j];
              }
              if(p[i][j] > max[j])
              {
                max[j] = p[i][j];
              }
           }
        }
        max[0] = osgClamp(-1.f, max[0], 1.f);
        max[1] = osgClamp(-1.f, max[1], 1.f);
        min[0] = osgClamp(-1.f, min[0], 1.f);
        min[1] = osgClamp(-1.f, min[1], 1.f);

        // cbb is the percent of the screen real estate this would cover
        Real32 cbb = (max[0] - min[0]) * (max[1] - min[1]) / 4.f;

        //std::cout << cur_node << ":" << pix << " ";
        //std::cout << pNode->getScalar() << std::endl;

//Make decision

        if(pNode->hasFunctor() == false) //Nothing to do
        {
            //renderNode
            drawNode(pNode, denv, part);
        }
        else
        {
            //make decision
            //if(0 > 1)
            if(cbb > scr_percent) // Rendering major occluders
            {
                drawNode(pNode, denv, part);
                //scr_percent+=cbb;
            }
            else
            {

                Real32 pcov;
                pcov = sqrt(scr_percent) - sqrt(cbb);
                pcov *= pcov;
                //std::cout << "cbb:" << cbb << " scr_percent:" << scr_percent <<" pcov:" << pcov << std::endl;
                //if(scr_percent - pcov > 0.001)
                if(pcov > _coveredProbThreshold || cbb < 0.001) // If within threshold or reall small
                {
                    //Get triangles
                    DrawableStatsAttachment *st =
                        DrawableStatsAttachment::get(pNode->getNode()->getCore());
                    st->validate();
                    UInt32 triangles = st->getTriangles();

                    if(cbb * _vpWidth * _vpHeight < _minFeatureSize) //small feature culling
                    {
                        StatCollector *sc = _ract->getStatCollector();
                        if(sc != NULL)
                            sc->getElem(statNOccTriangles)->
                                add(triangles);
                        if(_ract->getOcclusionCullingDebug() && pNode->getNode())
                        {
                            pNode->getNode()->setTravMask(
                                pNode->getNode()->getTravMask() |
                                _ract->getOcclusionCulledDebugMask()
                                );
                        }
                        pNode->setIsRendered(true);
                    }
                    else if( triangles <= _minTriangleCount )
                    {
                        drawNode(pNode, denv, part);
                    }
                    else if((_testPendingNodes.size() == _numTestSamples - 1)) // Make sure we have room to draw a test
                    {
                        drawTestResults(denv, part);
                        if(_testPendingNodes.size() == _numTestSamples - 1) // If we are waiting on a result, draw a node
                        {
                            drawNode(pNode, denv, part);
                        }
                        else
                        {
                            drawTestNode(pNode, denv, part); // Made room, go ahead and draw a test node
                        }
                    }
                    else
                    {
                        drawTestNode(pNode, denv, part); //Plenty of room in buffer to draw a test node
                    }
                }
                else
                {
                    drawNode(pNode, denv, part); // Probably not being covered up...draw the real node
                    //scr_percent+=cbb;
                }
            }
            scr_percent += ((1.0 - scr_percent) * cbb);
        }

//DRAW CHILDREN OR GO TO TOP AND DO IT AGAIN
        if(pNode->getFirstChild() != NULL)
        {
            OCRenderTreeNode *child =
                static_cast<OCRenderTreeNode *>(pNode->getFirstChild());

            testNode(child, denv, part, scr_percent);
        }

        pNode = static_cast<OCRenderTreeNode *>(pNode->getBrother());
    }
}