//-----------------------------------------------------------------------
 void PagingLandScapeOctree::_unref(const bool removeChildren)
 {
     --mNumNodes;
     if (removeChildren)
     {
         //remove null children
         PagingLandScapeOctree *child;
         for (unsigned int i = 0; i < 2; i++)
         {
             for (unsigned int j = 0; j < 2; j++)
             {
                 for (unsigned int k = 0; k < 2; k++)
                 {
                     child = mChildren[ i ][ j ][ k ];
                     if (child && !child->hasChildren())
                     {
                         mSceneMgr->deleteOctree(child);
                         mChildren[ i ][ j ][ k ] = 0;
                     }
                 }
             }
         }
     }
     if (mParent != 0)
     {
         mParent->_unref(mNumNodes == 0);
     }
 };
    //-----------------------------------------------------------------------
    void SWTraversal::onTree(PagingLandScapeOctree & n, VisibleObjectsBoundsInfo * const visibleBounds)
    {
        if(occlusion.mCurrentCam->isVisible(n.getCullBoundingBox ())) 
        {

		    #ifdef _VISIBILITYDEBUG
	            occlusion.traversed_nodes_cnt++; 
                n.getNodeData (occlusion.mCurrentCam)->viewFrustumVisible = true;
		    #endif //_VISIBILITYDEBUG    

            const bool isitVisible = isVisible(n);

		    if (isitVisible) 
            {
                traverseChildren (n, visibleBounds);
		    }

		    #ifdef _VISIBILITYDEBUG
		        n.getNodeData (occlusion.mCurrentCam)->queryVisible = isitVisible;
		    #endif //_VISIBILITYDEBUG    

	    }

		#ifdef _VISIBILITYDEBUG
	        else 
            {
	            occlusion.traversed_nodes_cnt++; 
                n.getNodeData (occlusion.mCurrentCam)->viewFrustumVisible = false;
		        occlusion.frustum_culled_nodes_cnt++;
	        }
		#endif //_VISIBILITYDEBUG    
    }
    //-----------------------------------------------------------------------
    void SWTraversal::traverseChildren(PagingLandScapeOctree & node, VisibleObjectsBoundsInfo * const visibleBounds)
    {
	    FrontToBackNodeSorterPriorityQueue myStack = FrontToBackNodeSorterPriorityQueue(FrontToBackNodeSorterOperator (camPos));
       
        //assert (node.getNodeData (occlusion.mCurrentCam)->viewFrustumVisible);
        if (!node.mNodes.empty())
        {
            PagingLandScapeOctreeNodeList::const_iterator it =  node.mNodes.begin();
            while (it != node.mNodes.end())
            {
                 myStack.push(*it);
                ++it;
            }
        }

        PagingLandScapeOctree *n = 
            node.mChildren[ 0 ][ 0 ][ 0 ];
        if (n && n->hasChildren())  
            myStack.push (n);
        n = node.mChildren[ 1 ][ 0 ][ 0 ];
        if (n && n->hasChildren())  
            myStack.push (n);
        n = node.mChildren[ 0 ][ 1 ][ 0 ];
        if (n && n->hasChildren())  
            myStack.push (n);
        n = node.mChildren[ 1 ][ 1 ][ 0 ];
        if (n && n->hasChildren())  
            myStack.push (n);
        n = node.mChildren[ 0 ][ 0 ][ 1 ];
        if (n && n->hasChildren())  
            myStack.push (n);
        n = node.mChildren[ 1 ][ 0 ][ 1 ];
        if (n && n->hasChildren())  
            myStack.push (n);
        n = node.mChildren[ 0 ][ 1 ][ 1 ];
        if (n && n->hasChildren())  
            myStack.push (n);
        n = node.mChildren[ 1 ][ 1 ][ 1 ];
        if (n && n->hasChildren())  
            myStack.push (n);

        //traverse nearer child first
        while (!myStack.empty ())
        {
	        OcclusionElement& nstacked = *myStack.top ();
	        myStack.pop ();
            nstacked.traversal(*this, visibleBounds);
        }
    }
    //-----------------------------------------------------------------------
    void CHCTraversal::onTree(PagingLandScapeOctree& node, VisibleObjectsBoundsInfo * const visibleBounds) const 
    {
    	#ifdef _VISIBILITYDEBUG
            assert (node.getNodeData (occlusion.mCurrentCam)->viewFrustumVisible);
		    occlusion.traversed_nodes_cnt++;       
        #endif //_VISIBILITYDEBUG    
                
        if (!node.mNodes.empty())
        {	
            PagingLandScapeOctreeNodeList::iterator it =  node.mNodes.begin();  
            while (it != node.mNodes.end())
            { 
                stack.push (*it);
                ++it;
            }
        }

        PagingLandScapeOctree *n = 
            node.mChildren[ 0 ][ 0 ][ 0 ];
        if (n && n->hasChildren())  
           stack.push(n);
        n = node.mChildren[ 1 ][ 0 ][ 0 ];
        if (n && n->hasChildren())  
            stack.push(n);
        n = node.mChildren[ 0 ][ 1 ][ 0 ];
        if (n && n->hasChildren())  
            stack.push(n);
        n = node.mChildren[ 1 ][ 1 ][ 0 ];
        if (n && n->hasChildren())  
            stack.push(n);
        n = node.mChildren[ 0 ][ 0 ][ 1 ];
        if (n && n->hasChildren())  
            stack.push(n);
        n = node.mChildren[ 1 ][ 0 ][ 1 ];
        if (n && n->hasChildren())  
            stack.push(n);
        n = node.mChildren[ 0 ][ 1 ][ 1 ];
        if (n && n->hasChildren())  
            stack.push(n);
        n = node.mChildren[ 1 ][ 1 ][ 1 ];
        if (n && n->hasChildren())  
            stack.push(n);
	}
        //-----------------------------------------------------------------------
        void TreeOverlayDebug::onTree(PagingLandScapeOctree& n, VisibleObjectsBoundsInfo * const visibleBounds) const 
		{    
			SimpleRenderable * const s = n.getRectangle2d(mScnMrg);
            if (n.getNodeData (occlusion.mCurrentCam)->viewFrustumVisible)
            {
			    if (n.getNodeData (occlusion.mCurrentCam)->queryVisible) 
                {
                    s->setMaterial ("BaseWhiteNoLightNoDepthCheck");
                    occlusion.mCurrentRenderQueue->addRenderable (s, s->getRenderQueueGroup ());

                    traverseChildren (n, visibleBounds);
			    }
			    else 
                {
                    s->setMaterial ("BaseRedNoLightNoDepthCheck");
                    occlusion.mCurrentRenderQueue->addRenderable (s, s->getRenderQueueGroup ());
			    }
		    }
		    else 
			{
                s->setMaterial ("BaseGreenNoLightNoDepthCheck");
                occlusion.mCurrentRenderQueue->addRenderable (s, s->getRenderQueueGroup ());
		    }       
        }
    //-----------------------------------------------------------------------
    void Traversal::traverseChildren(PagingLandScapeOctree& node, VisibleObjectsBoundsInfo * const visibleBounds)
    {                  
        // hasLocalChildren
        if (!node.mNodes.empty())
        {
            //Add stuff to be rendered;
			PagingLandScapeOctreeNodeList::iterator it = node.mNodes.begin();
			PagingLandScapeOctreeNodeList::iterator itEnd = node.mNodes.end();
            while (it != itEnd)
            {
                (*it)->traversal (*this, visibleBounds);
                ++it;
            }
        }
      
        PagingLandScapeOctree *n = 
            node.mChildren[ 0 ][ 0 ][ 0 ];
        if (n && n->hasChildren())  
            n->traversal (*this, visibleBounds);

        n = node.mChildren[ 1 ][ 0 ][ 0 ];
        if (n && n->hasChildren())  
            n->traversal (*this, visibleBounds);

        n = node.mChildren[ 0 ][ 1 ][ 0 ];
        if (n && n->hasChildren())  
            n->traversal (*this, visibleBounds);

        n = node.mChildren[ 1 ][ 1 ][ 0 ];
        if (n && n->hasChildren())  
            n->traversal (*this, visibleBounds);

        n = node.mChildren[ 0 ][ 0 ][ 1 ];
        if (n && n->hasChildren())  
            n->traversal (*this, visibleBounds);

        n = node.mChildren[ 1 ][ 0 ][ 1 ];
        if (n && n->hasChildren())  
            n->traversal (*this, visibleBounds);

        n = node.mChildren[ 0 ][ 1 ][ 1 ];
        if (n && n->hasChildren())  
            n->traversal (*this, visibleBounds);

        n = node.mChildren[ 1 ][ 1 ][ 1 ];
        if (n && n->hasChildren())  
            n->traversal (*this, visibleBounds);

	}
    //-----------------------------------------------------------------------
    PagingLandScapeOctree *PagingLandScapeOctree::_getChildWhereBoxFits(const AxisAlignedBox &box, 
                                                                        PagingLandScapeOctreeSceneManager *scn)
    { 
        /** It's assumed the the given box has already been proven to fit into
        * a child.  Since it's a loose PagingLandScapeOctree, only the centers need to be
        * compared to find the appropriate node.
        */
        const Vector3 &octantMax = mBox.getMaximum();
        const Vector3 &octantMin = mBox.getMinimum();
        const Vector3 octCenter = octantMin + mHalfSize;   

        const Vector3 ncenter = box.getMaximum().midPoint(box.getMinimum());

//ember change: We'll remove this assertion since it seems to trigger sometimes when stuff are placed really close to the boundaries, probably caused be precision issues
//         assert (octantMax.x >= ncenter.x && octantMax.y >= ncenter.y && octantMax.z >= ncenter.z &&
//                 octantMin.x <= ncenter.x && octantMin.y <= ncenter.y && octantMin.z <= ncenter.z);

        unsigned int x;
        if (ncenter.x > octCenter.x)
            x = 1;
        else
            x = 0;

        unsigned int y;
        if (ncenter.y > octCenter.y)
            y = 1;
        else
            y = 0;

        unsigned int z;
        if (ncenter.z > octCenter.z)
            z = 1;
        else
            z = 0;

        if (mChildren[ x ][ y ][ z ] == 0)
        {
            Vector3 min, max;

            if (x == 0)
            {
                min.x = octantMin.x;
                max.x = octCenter.x;
            }
            else
            {
                min.x = octCenter.x;
                max.x = octantMax.x;
            }

            if (y == 0)
            {
                min.y = octantMin.y;
                max.y = octCenter.y;
            }
            else
            {
                min.y = octCenter.y;
                max.y = octantMax.y;
            }

            if (z == 0)
            {
                min.z = octantMin.z;
                max.z = octCenter.z;
            }
            else
            {
                min.z = octCenter.z;
                max.z = octantMax.z;
            }

#ifdef _DEBUG
            std::cout << "new Child\n";
#endif

            PagingLandScapeOctree *newChild = scn->getNewOctree();
            newChild->setParent (this);
            newChild->setSceneManager(scn);
            newChild->setBoundingBox(min, max);

            assert (max.x >= ncenter.x && max.y >= ncenter.y && max.z >= ncenter.z &&
                    min.x <= ncenter.x && min.y <= ncenter.y && min.z <= ncenter.z);
          

            scn->registeredNodeInCamera (newChild);
            #ifdef _VISIBILITYDEBUG   
                newChild ->setDebugCorners(scn);
            #endif //_VISIBILITYDEBUG    
            mChildren[x][y][z] = newChild;
        }
        return mChildren[x][y][z];
            
    }
    //-----------------------------------------------------------------------
    PagingLandScapeOctree *PagingLandScapeOctree::_getCullChildWhereBoxFits(const AxisAlignedBox &box, 
                                                                            PagingLandScapeOctreeSceneManager *scn)
    { 
        /** It's assumed the the given box has already been proven to fit into
        * a child.  Since it's a loose PagingLandScapeOctree, only the centers need to be
        * compared to find the appropriate node.
        */
        const Vector3 octCenter = mCullBox.getMinimum() + mCullHalfSize;   
        const Vector3 ncenter = box.getMaximum().midPoint(box.getMinimum());
        
        unsigned int x;
        if (ncenter.x > octCenter.x)
            x = 1;
        else
            x = 0;

        unsigned int y;
        if (ncenter.y > octCenter.y)
            y = 1;
        else
            y = 0;

        unsigned int z;
        if (ncenter.z > octCenter.z)
            z = 1;
        else
            z = 0;

        if (mChildren[ x ][ y ][ z ] == 0)
        {
            const Vector3 &octantMax = mBox.getMaximum();
            const Vector3 &octantMin = mBox.getMinimum();

            Vector3 min, max;

            if (x == 0)
            {
                min.x = octantMin.x;
                max.x = octCenter.x;
            }
            else
            {
                min.x = octCenter.x;
                max.x = octantMax.x;
            }

            if (y == 0)
            {
                min.y = octantMin.y;
                max.y = octCenter.y;
            }
            else
            {
                min.y = octCenter.y;
                max.y = octantMax.y;
            }

            if (z == 0)
            {
                min.z = octantMin.z;
                max.z = octCenter.z;
            }
            else
            {
                min.z = octCenter.z;
                max.z = octantMax.z;
            }

            PagingLandScapeOctree *newChild = scn->getNewOctree();
            newChild->setParent (this);
            newChild->setSceneManager(scn);
            newChild ->setBoundingBox(min, max);
            scn->registeredNodeInCamera (newChild);
            #ifdef _VISIBILITYDEBUG   
                newChild ->setDebugCorners(scn);
            #endif //_VISIBILITYDEBUG    
            mChildren[x][y][z] = newChild;
        }
        return mChildren[x][y][z];
            
    }