void Octree::Query_Frustum(std::vector<OctreeOccupant*> &result, const Frustum &frustum) const
{
	// Query outside root elements - add them if they are visible
	for(std::unordered_set<OctreeOccupant*>::iterator it = m_outsideRoot.begin(); it != m_outsideRoot.end(); it++)
	{
		OctreeOccupant* pOc = *it;

		if(!frustum.Test_AABB_Outside(pOc->m_aabb))
		{
			// Visible, add to list
			result.push_back(pOc);
		}
	}

	std::list<OctreeNode*> open;

	open.push_back(m_pRootNode.get());

	while(!open.empty())
	{
		// Depth-first (results in less memory usage), remove objects from open list
		OctreeNode* pCurrent = open.back();
		open.pop_back();

		switch(frustum.Test_AABB(pCurrent->m_region))
		{
		case Frustum::inside:
			// Add all of this nodes occupants and those below, since all must be visibile
			pCurrent->GetAllOccupantsBelow(result);
			
			break;

		case Frustum::intersect:
			// Add occupants if they are visible
			for(std::unordered_set<OctreeOccupant*>::iterator it = pCurrent->m_pOccupants.begin(); it != pCurrent->m_pOccupants.end(); it++)
			{
				OctreeOccupant* pOc = *it;

				if(!frustum.Test_AABB_Outside(pOc->m_aabb))
				{
					// Visible, add to list
					result.push_back(pOc);
				}
			}

			// Add children to open list
			if(pCurrent->m_hasChildren)
			{
				for(int x = 0; x < 2; x++)
					for(int y = 0; y < 2; y++)
						for(int z = 0; z < 2; z++)
						{
							if((*pCurrent->m_children)[x][y][z].GetNumOccupantsBelow() != 0)
								open.push_back(&(*pCurrent->m_children)[x][y][z]);
						}
			}

			break;

			// Outside case is ignored
		}
	}
}