void OLMeshTracker::UpdateSubNodes(Ogre::Node* regionNode, Ogre::Node* node, bool recurse, Ogre::MeshPtr meshP) {
	if (recurse && node->numChildren() > 0) {
		// if node has more children nodes, visit them recursivily
		Ogre::SceneNode::ChildNodeIterator nodeChildIterator = node->getChildIterator();
		while (nodeChildIterator.hasMoreElements()) {
			Ogre::Node* nodeChild = nodeChildIterator.getNext();
			// 'false' causes it to not visit sub-children which are included in parent and pos relative to parent
			UpdateSubNodes(regionNode, nodeChild, true, meshP);
		}
	}
	// children taken care of... check for attached objects to this node
	Ogre::SceneNode* snode = (Ogre::SceneNode*)node;
	Ogre::SceneNode::ObjectIterator snodeObjectIterator = snode->getAttachedObjectIterator();
	while (snodeObjectIterator.hasMoreElements()) {
		Ogre::MovableObject* snodeObject = snodeObjectIterator.getNext();
		if (snodeObject->getMovableType() == "Entity") {
			Ogre::Entity* snodeEntity = (Ogre::Entity*)snodeObject;
			Ogre::MeshPtr entityMesh = snodeEntity->getMesh();
			if (entityMesh == meshP) {
				snode->needUpdate(true);
				// LG::Log("OLMeshTracker::UpdateSubNodes: setting node update for %s", snode->getName().c_str());
			}
		}
	}
	return;
}
// BETWEEN FRAME OPERATION
void VisCalcFrustDist::calculateEntityVisibility(Ogre::Node* regionNode, Ogre::Node* node, bool recurse) {
	if (recurse && node->numChildren() > 0) {
		// if node has more children nodes, visit them recursivily
		Ogre::SceneNode::ChildNodeIterator nodeChildIterator = node->getChildIterator();
		while (nodeChildIterator.hasMoreElements()) {
			Ogre::Node* nodeChild = nodeChildIterator.getNext();
			// 'false' causes it to not visit sub-children which are included in parent and pos relative to parent
			calculateEntityVisibility(regionNode, nodeChild, false);
			visChildren++;
		}
	}
	visNodes++;
	// children taken care of... check fo attached objects to this node
	Ogre::SceneNode* snode = (Ogre::SceneNode*)node;
	// the camera needs to be made relative to the region
	// Ogre::Vector3 relCameraPos = LG::RendererOgre::Instance()->m_camera->getPosition() - regionNode->getPosition();
	// float snodeDistance = LG::RendererOgre::Instance()->m_camera->getPosition().distance(snode->_getWorldAABB().getCenter());
	// float snodeDistance = relCameraPos.distance(snode->getPosition());
	float snodeDistance = LG::RendererOgre::Instance()->m_camera->getDistanceFromCamera(regionNode, snode->getPosition());
	Ogre::SceneNode::ObjectIterator snodeObjectIterator = snode->getAttachedObjectIterator();
	while (snodeObjectIterator.hasMoreElements()) {
		Ogre::MovableObject* snodeObject = snodeObjectIterator.getNext();
		if (snodeObject->getMovableType() == "Entity") {
			visEntities++;
			Ogre::Entity* snodeEntity = (Ogre::Entity*)snodeObject;
			// check it's visibility if it's not world geometry (terrain and ocean)
			if ((snodeEntity->getQueryFlags() & Ogre::SceneManager::WORLD_GEOMETRY_TYPE_MASK) == 0) {
				// computation if it should be visible
				// Note: this call is overridden by derived classes that do fancier visibility rules
				bool shouldBeVisible = this->CalculateVisibilityImpl(LG::RendererOgre::Instance()->m_camera, snodeEntity, snodeDistance);
				if (snodeEntity->isVisible()) {
					// we currently think this object is visible. make sure it should stay that way
					if (shouldBeVisible) {
						// it should stay visible
						visVisToVis++;
					}
					else {
						// not visible any more... make invisible nad unload it`
						/*
						Ogre::Vector3 cPos = LG::RendererOgre::Instance()->m_camera->getPosition();
						Ogre::Vector3 rPos = regionNode->getPosition();
						Ogre::Vector3 sPos = snode->getPosition();
						LG::Log("VisToInVis: cPos=<%f,%f,%f>, rPos=<%f,%f,%f>, sPos(%s)=<%f,%f,%f>, d=%f", 
								cPos.x, cPos.y, cPos.z, 
								rPos.x, rPos.y, rPos.z, 
								snode->getName().c_str(),
								sPos.x, sPos.y, sPos.z, 
								snodeDistance);
								*/
						snodeEntity->setVisible(false);
						snode->needUpdate(true);
						visVisToInvis++;
						if (!snodeEntity->getMesh().isNull()) {
							queueMeshUnload(snodeEntity->getMesh());
						}
					}
				}
				else {
					// the entity currently thinks it's not visible.
					// check to see if it should be visible by checking a fake bounding box
					if (shouldBeVisible) {
						// it should become visible again
						if (!snodeEntity->getMesh().isNull()) {
							// queueMeshLoad(snodeEntity, snodeEntity->getMesh());
							LG::OLMeshTracker::Instance()->MakeLoaded(snodeEntity->getMesh()->getName(),
									Ogre::String(""), Ogre::String("visible"), snodeEntity);
						}
						// snodeEntity->setVisible(true);	// must happen after mesh loaded
						visInvisToVis++;
					}
					else {
						visInvisToInvis++;
					}
				}
			}
		}
	}
}