Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTree.h
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTree.h	(revision 1183)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTree.h	(revision 1187)
@@ -207,4 +207,7 @@
 			virtual bool isEmpty() const = 0;
 			virtual bool hasGeometry() const = 0;
+
+			virtual void queueVisibleObjects(unsigned long currentFrame, 
+				Camera* cam, RenderQueue* queue, bool onlyShadowCasters, bool showBoxes) = 0;
 			
 			// consider using typesafe callback functions
@@ -288,10 +291,10 @@
 			int mLevel;
 			AxisAlignedBox mAABB;
-		protected:
-			WireBoundingBox * mWBB;
 
 			// for the CHC hierarchy interface
 			/** the real extent of the node. */
 			AxisAlignedBox mWorldAABB;
+		protected:
+			WireBoundingBox * mWBB;
 			
 			unsigned int mLastRendered;
@@ -327,4 +330,15 @@
 			virtual bool hasGeometry() const { return false; };
 
+			virtual void queueVisibleObjects(unsigned long currentFrame, 
+				Camera* cam, RenderQueue* queue, bool onlyShadowCasters, bool showBoxes)
+			{
+				if (showBoxes)
+				{
+					WireBoundingBox * wbb = getWireBoundingBox();
+					if (wbb)
+						queue->addRenderable(wbb);
+				}
+			}
+
 			// branches do not posses geometry => just merge child aabbs
 			virtual void _updateBounds(bool recurse = true)
@@ -334,7 +348,7 @@
 
 				if (mLeft)
-					mWorldAABB.merge(mLeft->_getWorldAABB());
+					mWorldAABB.merge(mLeft->mWorldAABB);
 				if (mRight)
-					mWorldAABB.merge(mRight->_getWorldAABB());
+					mWorldAABB.merge(mRight->mWorldAABB);
 
 				// update parent recursively
@@ -367,4 +381,7 @@
 			virtual bool hasGeometry() const { return !mKdRenderables.empty(); };
 
+			virtual void queueVisibleObjects(unsigned long currentFrame, 
+				Camera* cam, RenderQueue* queue, bool onlyShadowCasters, bool showBoxes);
+
 			// update the world aabb based on the contained geometry
 			virtual void _updateBounds(bool recurse = true);
@@ -430,4 +447,6 @@
 		typedef KdTree::Branch * BranchPtr;
 		typedef KdTree::Leaf * LeafPtr;
+
+		typedef std::list<NodePtr> NodeList;
 		typedef std::set<LeafPtr> LeafSet;
 
@@ -484,6 +503,5 @@
 
 		// test visibility of objects and add to render	queue
-		void queueVisibleObjects(Camera* cam, RenderQueue* queue, bool onlyShadowCasters, 
-			RenderMethod renderMethod, bool showBoxes = false);
+		void queueVisibleObjects(Camera* cam, RenderQueue* queue, bool onlyShadowCasters, bool showBoxes = false);
 
 		// self-explanatory ...
Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTreeSceneManager.h
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTreeSceneManager.h	(revision 1185)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTreeSceneManager.h	(revision 1187)
@@ -16,5 +16,5 @@
 #include "OgreKdTree.h"
 
-#define KDTREE_MAX_DEPTH 20
+#define KDTREE_MAX_DEPTH 12
 
 namespace Ogre
@@ -134,5 +134,7 @@
 	/** Render a list of scenenodes
 	*/
-	virtual void _renderNodes(const KdRenderableList& nodelist, Camera * cam,
+	//virtual void _renderNodes(const KdRenderableList& nodelist, Camera * cam,
+	//	bool onlyShadowCasters, int leavePassesInQueue);
+	virtual void _renderNode(KdTree::NodePtr node, Camera * cam,
 		bool onlyShadowCasters, int leavePassesInQueue);
 
@@ -227,5 +229,6 @@
 
 	// remember visited scene nodes for viz
-	KdRenderableList mVisibleNodes;
+	//KdRenderableList mVisibleNodes;
+	KdTree::NodeList mVisibleNodes;
 
 	/************************************************************************/
Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTreeSceneNode.h
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTreeSceneNode.h	(revision 1173)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTreeSceneNode.h	(revision 1187)
@@ -43,4 +43,7 @@
 		virtual AxisAlignedBox getBoundingBox() const;
 
+		// custom render op, show bounding box instead of axes
+		//virtual void getRenderOperation(RenderOperation& op);
+
 		//virtual void _findVisibleObjects(Camera* cam, RenderQueue* queue, 
 		//	bool includeChildren = true, bool displayNodes = false, bool onlyShadowCasters = false);
Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneManager.cpp	(revision 1185)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneManager.cpp	(revision 1187)
@@ -61,6 +61,6 @@
 
 // test
-//String chc = "CHC";
-//setOption("RenderMethod", &chc);
+String chc = "CHC";
+setOption("RenderMethod", &chc);
 }
 
@@ -557,5 +557,5 @@
 		getRenderQueue()->clear();
 		if (mKdTree)
-			mKdTree->queueVisibleObjects(cam, getRenderQueue(), onlyShadowCasters, mRenderMethod, mShowBoxes);
+			mKdTree->queueVisibleObjects(cam, getRenderQueue(), onlyShadowCasters, mShowBoxes);
 	}
 	else
@@ -578,5 +578,5 @@
 				getRenderQueue()->clear();
 				if (mKdTree)
-					mKdTree->queueVisibleObjects(cam, getRenderQueue(), onlyShadowCasters, mRenderMethod, mShowBoxes);
+					mKdTree->queueVisibleObjects(cam, getRenderQueue(), onlyShadowCasters, mShowBoxes);
 			}
 
@@ -697,13 +697,19 @@
 			if (mUseDepthPass)
 			{
-				KdRenderableList::const_iterator it, it_end = mVisibleNodes.end();
-
-				//getRenderQueue()->clear();
-				for (it = mVisibleNodes.begin(); it != it_end; ++ it)
+				//KdRenderableList::const_iterator it, it_end = mVisibleNodes.end();
+
+				////getRenderQueue()->clear();
+				//for (it = mVisibleNodes.begin(); it != it_end; ++ it)
+				//{
+				//	(*it)->queueObjects(mCameraInProgress, getRenderQueue(), false);
+				//}
+				KdTree::NodeList::const_iterator it, end = mVisibleNodes.end();
+				for (it = mVisibleNodes.begin(); it != end; it++)
 				{
-					(*it)->queueObjects(mCameraInProgress, getRenderQueue(), false);
+					(*it)->queueVisibleObjects(mHierarchyInterface->GetFrameId(), mCameraInProgress,
+						getRenderQueue(), false, mShowBoxes);
 				}
 			}
-#endif	
+#endif
 			//-- now we can render all remaining queue objects
 			//-- used for depth pass, transparents, overlay
@@ -724,25 +730,28 @@
 }
 
-void KdTreeSceneManager::_renderNodes(const KdRenderableList& nodelist, Camera * cam, 
-	bool onlyShadowCasters, int leavePassesInQueue)
-{
-#ifdef GTP_VISIBILITY_MODIFIED_OGRE
+//void KdTreeSceneManager::_renderNodes(const KdRenderableList& nodelist, Camera * cam, 
+//	bool onlyShadowCasters, int leavePassesInQueue)
+void KdTreeSceneManager::_renderNode(KdTree::NodePtr node, Camera * cam, 
+									 bool onlyShadowCasters, int leavePassesInQueue)
+{
 	RenderQueueGroup *currentGroup = 
 		getRenderQueue()->getQueueGroup(getRenderQueue()->getDefaultQueueGroup());
 	currentGroup->clear(leavePassesInQueue);
-#else
-	getRenderQueue()->clear();
-#endif
-	KdRenderableList::const_iterator it = nodelist.begin();
-	KdRenderableList::const_iterator end = nodelist.end();
-	while (it != end)
-	{
-		if (!(*it)->isQueued(mHierarchyInterface->GetFrameId(), cam))
-		{
-			mVisibleNodes.push_back(*it);
-			(*it)->queueObjects(cam, getRenderQueue(), onlyShadowCasters);
-		}
-		it++;
-	}
+
+	node->queueVisibleObjects(mHierarchyInterface->GetFrameId(), cam, getRenderQueue(),
+		onlyShadowCasters, mShowBoxes);
+	mVisibleNodes.push_back(node);
+
+	//KdRenderableList::const_iterator it = nodelist.begin();
+	//KdRenderableList::const_iterator end = nodelist.end();
+	//while (it != end)
+	//{
+	//	if (!(*it)->isQueued(mHierarchyInterface->GetFrameId(), cam))
+	//	{
+	//		mVisibleNodes.push_back(*it);
+	//		(*it)->queueObjects(cam, getRenderQueue(), onlyShadowCasters);
+	//	}
+	//	it++;
+	//}
 
 	_renderQueueGroupObjects(currentGroup, QueuedRenderableCollection::OM_PASS_GROUP);
@@ -957,17 +966,20 @@
 		nodeMat->getTechnique(0)->getPass(0)->removeAllTextureUnitStates();
 
-		for (KdRenderableList::iterator it = mVisibleNodes.begin(); it != mVisibleNodes.end(); ++it)
+		for (KdTree::NodeList::iterator it = mVisibleNodes.begin(); it != mVisibleNodes.end(); ++it)
 		{
 			if (mRenderNodesForViz)
 			{
-				KdTreeSceneNode * node = static_cast<KdTreeSceneNode *>(*it);
-				// render the leaf nodes
-				if (node->numAttachedObjects() && 
-					!node->numChildren() && 
-					(node->getAttachedObject(0)->getMovableType() == "Entity") &&
-					node->getAttachedObject(0)->isVisible())
-				{
-					getRenderQueue()->addRenderable(node);
-				}
+				//KdTreeSceneNode * node = static_cast<KdTreeSceneNode *>(*it);
+				//// render the leaf nodes
+				//if (node->numAttachedObjects() && 
+				//	!node->numChildren() && 
+				//	(node->getAttachedObject(0)->getMovableType() == "Entity") &&
+				//	node->getAttachedObject(0)->isVisible())
+				//{
+				//	//getRenderQueue()->addRenderable(node);
+				//	node->_addBoundingBoxToQueue(getRenderQueue());
+				//}
+
+				/*** TODO: fix this ... maybe revert to original state, not quite happy now! ***/
 
 				// addbounding boxes instead of node itself
@@ -977,5 +989,7 @@
 			if (mRenderNodesContentForViz) 
 			{
-				(*it)->queueObjects(cam, getRenderQueue(), false);
+				//(*it)->queueObjects(cam, getRenderQueue(), false);
+				(*it)->queueVisibleObjects(mHierarchyInterface->GetFrameId(), 
+					cam, getRenderQueue(), false, mShowBoxes);
 			}
 		}
Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeHierarchyInterface.cpp
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeHierarchyInterface.cpp	(revision 1173)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeHierarchyInterface.cpp	(revision 1187)
@@ -58,10 +58,5 @@
 		KdTreeSceneManager * ksm = static_cast<KdTreeSceneManager *>(mSceneManager);
 
-		// render only if the node is a leaf
-		if (kdnode->isLeaf())
-		{
-			ksm->_renderNodes(KDLEAFPTR_CAST(node)->mKdRenderables, mCamera, 
-				mOnlyShadowCasters, mLeavePassesInQueue);
-		}	
+		ksm->_renderNode(kdnode, mCamera, mOnlyShadowCasters, mLeavePassesInQueue);
 
 		mVisibleNodes.push_back(node);
Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneNode.cpp
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneNode.cpp	(revision 1183)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneNode.cpp	(revision 1187)
@@ -108,5 +108,6 @@
 			// Tell attached objects about camera position (incase any extra processing they want to do)
 			iobj->second->_notifyCurrentCamera(cam);
-			if (!onlyShadowCasters || iobj->second->getCastShadows())
+			if (iobj->second->isVisible() &&
+				(!onlyShadowCasters || iobj->second->getCastShadows()))
 			{
 				iobj->second->_updateRenderQueue(queue);
@@ -175,4 +176,15 @@
 	}
 
+	//void KdTreeSceneNode::getRenderOperation(RenderOperation& op)
+	//{
+	//	if (mWireBoundingBox == NULL) 
+	//	{
+	//		mWireBoundingBox = new WireBoundingBox();
+	//	}
+
+	//	mWireBoundingBox->setupBoundingBox(mWorldAABB);
+	//	mWireBoundingBox->getRenderOperation(op);
+	//}
+
 	// DEBUG
 	String KdTreeSceneNode::dumpToString()
Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTree.cpp	(revision 1183)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTree.cpp	(revision 1187)
@@ -22,4 +22,5 @@
 
 #define KDTREE_LOGNAME "KdTreeBuild.log"
+#define PLT_SIZE 101
 
 namespace Ogre
@@ -28,4 +29,6 @@
 	Real PlaneEvent::KI = 1.0;
 
+	//----------------------------------------------------------------------------
+	// determine if this event is left or right of the reference event
 	void PlaneEvent::classify(const PlaneEvent& e, PlaneEvent::Side side)
 	{
@@ -57,4 +60,6 @@
 	}
 
+	//----------------------------------------------------------------------------
+	// clip this event to an aabb (move it so that the plane on one of the box planes)
 	PlaneEvent PlaneEvent::clip(AxisAlignedBox& box, PlaneEvent::Dimension dim)
 	{
@@ -68,29 +73,11 @@
 	}
 
+	//----------------------------------------------------------------------------
+	// the surface area heuristic to determine the cost of splitting the parent aabb
+	// along the plane represented by this event
 	void PlaneEvent::SAH(const AxisAlignedBox& parent, int nLeft, int nPlane, int nRight, SplitInfo& split)
 	{
-
-#ifdef KDTREE_DEBUG_OFF
 		Real mu = splitBox(parent, split.bleft, split.bright);
-		Real sav = surfaceArea(parent); // optimize?? called several times for the same box
-		Real savl = surfaceArea(split.bleft);
-		Real savr = surfaceArea(split.bright);
-		Real pl = savl / sav;
-		Real pr = savr / sav;
-		Real costl = splitCost(pl, pr, nLeft + nPlane, nRight, mu);
-		Real costr = splitCost(pl, pr, nLeft, nPlane + nRight, mu);
-
-		Log * log = LogManager::getSingleton().getLog(KDTREE_LOGNAME);
-		log->logMessage("SAH: SA-parent=" + StringConverter::toString(sav) + 
-			"\n\tSA-left=" + StringConverter::toString(savl) + 
-			" SA-right=" + StringConverter::toString(savr) + 
-			"\n\tp-left=" + StringConverter::toString(pl) + 
-			" p-right=" + StringConverter::toString(pr) +
-			"\n\tmu=" + StringConverter::toString(mu) +
-			"\n\tcost-left=" + StringConverter::toString(costl) +
-			" cost-right=" + StringConverter::toString(costr));
-#else
-		Real mu = splitBox(parent, split.bleft, split.bright);
-		Real sav = surfaceArea(parent); // optimize?? called several times for the same box
+		Real sav = surfaceArea(parent);
 		Real pl = surfaceArea(split.bleft) / sav;
 		Real pr = surfaceArea(split.bright) / sav;
@@ -98,5 +85,4 @@
 		Real costr = splitCost(pl, pr, nLeft, nPlane + nRight, mu);
 
-#endif
 		if (costl < costr)
 		{
@@ -117,20 +103,14 @@
 	}
 
+	//----------------------------------------------------------------------------
+	// split the parent aabb with the plane in this event
 	Real PlaneEvent::splitBox(const AxisAlignedBox& parent, AxisAlignedBox& left, AxisAlignedBox& right)
 	{
 		Vector3 bmin = parent.getMinimum();
 		Vector3 bmax = parent.getMaximum();
-#ifdef KDTREE_DEBUG_OFF
-		if(bmin[mDimension] > mPosition[mDimension] || bmax[mDimension] < mPosition[mDimension])
-		{
-			Log * log = LogManager::getSingleton().getLog(KDTREE_LOGNAME);
-			log->logMessage("SPLITBOX SNAFU in event " + print() +
-				"\n\tmin=" + StringConverter::toString(bmin[mDimension]) + 
-				" split=" + StringConverter::toString(mPosition[mDimension]) + 
-				" max=" + StringConverter::toString(bmax[mDimension]));
-		}
-#endif
 		// calculate the penalty for spliting the box that way
-		Real mu = lookupPenalty((mPosition[mDimension] - bmin[mDimension]) / (bmax[mDimension] - bmin[mDimension]));
+		Real mu = lookupPenalty(
+			(mPosition[mDimension] - bmin[mDimension]) / 
+			(bmax[mDimension] - bmin[mDimension]));
 		// set corners which are the same as parent AABB
 		left.setMinimum(bmin);
@@ -146,8 +126,51 @@
 	}
 
+	//----------------------------------------------------------------------------
+	// compute surface area of a box ... DUH!
+	Real PlaneEvent::surfaceArea(const AxisAlignedBox& box)
+	{
+		Vector3 sides = box.getMaximum() - box.getMinimum();
+		return	2 * sides.x * sides.y +
+			2 * sides.y * sides.z +
+			2 * sides.z * sides.x;
+	}
+
+	//----------------------------------------------------------------------------
+	// lookup the penalty for placing the splitting plane near to the edge of the AABB
+	// 0.0 <= p <= 1.0, p = 0.5 means the plane divides the aabb in half
+	Real PlaneEvent::lookupPenalty(Real p)
+	{
+		// precomputed table of {x^6 + 1|0 <= x <= 1}
+		static Real mPenaltyLookupTable[PLT_SIZE];
+		static bool init_done = false;
+
+		if (!init_done)
+		{
+			Real step = 1.0  / (PLT_SIZE - 1);
+			Real x = 0.0; 
+			//LogManager::getSingleton().logMessage("### Calculating Lookup Table ###");
+			for (int i = 0; i < PLT_SIZE; i++)
+			{
+				mPenaltyLookupTable[i] = Math::Pow(x, 6) + 1.0;
+				x += step;
+				//LogManager::getSingleton().logMessage("### mPenaltyLookupTable[" + StringConverter::toString(i,3) + "]=" + StringConverter::toString(mPenaltyLookupTable[i]));
+			}
+			init_done = true;
+			//LogManager::getSingleton().logMessage("### Lookup Table Calculated ###");
+		}
+
+		// normalize p to [0,1]
+		Real x = Math::Abs(p * 2 - 1);
+		// compute index
+		int i = Math::IFloor(x * (PLT_SIZE - 1));
+
+		return mPenaltyLookupTable[i];
+	}
+
+	//----------------------------------------------------------------------------
+	// compute cost of the split, reward splitting of empty space (lambda, const),
+	// penalize splitting off 'thin' slices (mu, const)
 	Real PlaneEvent::splitCost(Real pLeft, Real pRight, int nLeft, int nRight)
 	{
-		//assert(pLeft <= 1.0 && pRight <= 1.0);
-
 		// reward splitting off chunks of empty space
 		Real lambda = 1.0;
@@ -157,5 +180,5 @@
 		}
 
-		// penalize splitting off small chunks
+		// penalize splitting off small chunks (thin slices)
 		Real mu = 1.0;
 		if (pLeft < 0.1 || pRight < 0.1 || pLeft > 0.9 || pRight > 0.9)
@@ -164,12 +187,11 @@
 		}
 		return lambda * mu * (KT + (KI * (pLeft*nLeft + pRight*nRight)));
-		
-		//return lambda * (KT + (KI * (pLeft*nLeft + pRight*nRight)));
-	}
-
+	}
+
+	//----------------------------------------------------------------------------
+	// compute cost of the split, reward splitting of empty space (lambda, const),
+	// penalize splitting off 'thin' slices (mu, parameter)
 	Real PlaneEvent::splitCost(Real pLeft, Real pRight, int nLeft, int nRight, Real mu)
 	{
-		//assert(pLeft <= 1.0 && pRight <= 1.0);
-
 		// reward splitting off chunks of empty space
 		Real lambda = 1.0;
@@ -182,22 +204,9 @@
 	}
 
-	Real PlaneEvent::surfaceArea(const AxisAlignedBox& box)
-	{
-		Vector3 sides = box.getMaximum() - box.getMinimum();
-#ifdef KDTREE_DEBUG_OFF
-		if(sides.x < 0 || sides.y < 0 || sides.z < 0)
-		{
-			Log * log = LogManager::getSingleton().getLog(KDTREE_LOGNAME);
-			log->logMessage("AABB SNAFU: x=" + StringConverter::toString(sides.x) + 
-				" y=" + StringConverter::toString(sides.y) + " z=" + StringConverter::toString(sides.z) +
-				" BOX=" + StringConverter::toString(box.getMinimum()) + "," + StringConverter::toString(box.getMaximum()));
-		}
-#endif
-		return	2 * sides.x * sides.y +
-				2 * sides.y * sides.z +
-				2 * sides.z * sides.x;
-	}
-
-	void PlaneEvent::pqSAH(Real globalSA, Real parentSA, int nLeft, int nPlane, int nRight, AxisAlignedBox& parentBox, SplitInfo& split)
+	//----------------------------------------------------------------------------
+	// surface area heuristic modified for the priority queue method of building
+	// the probabilities (p, pl, pr) are relative to the global (all enclosing) aabb
+	void PlaneEvent::pqSAH(Real globalSA, Real parentSA, int nLeft, int nPlane, int nRight, 
+		AxisAlignedBox& parentBox, SplitInfo& split)
 	{
 		Real mu = splitBox(parentBox, split.bleft, split.bright);
@@ -226,48 +235,12 @@
 	}
 
+	//----------------------------------------------------------------------------
+	// compute split cost without any penalties
 	Real PlaneEvent::pqSplitCost(Real pParent, Real pLeft, Real pRight, int nLeft, int nRight, Real mu)
 	{
-		// reward splitting off chunks of empty space
-		//Real lambda = 1.0;
-		//if (nLeft == 0 || nRight == 0)
-		//{
-		//	lambda = 0.8;
-		//}
-
-		return /* lambda * mu * */ (pParent*KT + (KI * (pLeft*nLeft + pRight*nRight)));
-	}
-
-#define PLT_SIZE 101
-
-	// lookup the penalty for placing the splitting plane near to the edge of the AABB
-	// 0.0 <= p <= 1.0, p = 0.5 means the plane divides the aabb in half
-	Real PlaneEvent::lookupPenalty(Real p)
-	{
-		// precomputed table of {x^6 + 1|0 <= x <= 1}
-		static Real mPenaltyLookupTable[PLT_SIZE];
-		static bool init_done = false;
-
-		if (!init_done)
-		{
-			Real step = 1.0  / (PLT_SIZE - 1);
-			Real x = 0.0; 
-			//LogManager::getSingleton().logMessage("### Calculating Lookup Table ###");
-			for (int i = 0; i < PLT_SIZE; i++)
-			{
-				mPenaltyLookupTable[i] = Math::Pow(x, 6) + 1.0;
-				x += step;
-				//LogManager::getSingleton().logMessage("### mPenaltyLookupTable[" + StringConverter::toString(i,3) + "]=" + StringConverter::toString(mPenaltyLookupTable[i]));
-			}
-			init_done = true;
-			//LogManager::getSingleton().logMessage("### Lookup Table Calculated ###");
-		}
-
-		// normalize p to [0,1]
-		Real x = Math::Abs(p * 2 - 1);
-		int i = Math::IFloor(x * (PLT_SIZE - 1));
-
-		return mPenaltyLookupTable[i];
-	}
-
+		return pParent * KT + (KI * (pLeft * nLeft + pRight * nRight));
+	}
+
+	//----------------------------------------------------------------------------
 	// DEBUG
 	String PlaneEvent::print()
@@ -290,4 +263,5 @@
 	};
 
+	//----------------------------------------------------------------------------
 	String SplitInfo::print()
 	{
@@ -308,4 +282,5 @@
 	};
 
+	//----------------------------------------------------------------------------
 	String KdTree::SplitCandidate::print()
 	{		
@@ -361,4 +336,8 @@
 	}
 
+	/************************************************************************/
+	/* KdTree insert/delete functions                                       */
+	/************************************************************************/
+
 	void KdTree::remove(KdRenderable * rend)
 	{
@@ -640,11 +619,12 @@
 	}
 
+	/************************************************************************/
+	/* KdTree build functions                                               */
+	/************************************************************************/
+
 	void KdTree::build(KdRenderable * sceneRoot)
 	{
-		// DEBUG
-		//LogManager *lm = LogManager::getSingletonPtr();
 		Timer *timer = Root::getSingleton().getTimer();
 		unsigned long t1, t2, t3, t4;
-		//AxisAlignedBox aabb;
 
 		mStats.clear();
@@ -662,12 +642,4 @@
 
 		mStats.mNumSceneNodes = nObjects;
-		// <DEBUG>
-		//lm->logMessage("# of perfect splits " + StringConverter::toString(events.size()));
-		//PlaneEventList::iterator it;
-		//for (it = events.begin(); it != events.end(); it++)
-		//{
-		//	lm->logMessage(it->print());
-		//}
-		// </DEBUG>
 
 		assert(! aabb.isNull() && "Teh stubid worldAABB iz NULL ... waht now?");
@@ -702,4 +674,5 @@
 		mBuildLog->logMessage("Time for tree build: " + StringConverter::toString(t4 - t3) + "µs");
 		mBuildLog->logMessage("Total time: " + StringConverter::toString(t4 - t1) + "µs");
+		mBuildLog->logMessage("Tree Depth: " + StringConverter::toString(mMaxDepth));
 		mBuildLog->logMessage("Number of Objects: " + StringConverter::toString(mStats.mNumSceneNodes));
 		mBuildLog->logMessage("Number of Leaves: " + StringConverter::toString(mStats.mNumLeaves));
@@ -723,18 +696,12 @@
 			it++;
 		}
+
 		events.sort();
+		
 		// HACK
 		if (aabb.isNull())
 		{
-			//LogManager::getSingleton().logMessage("AABB empty, using node AABB.");
 			aabb = nodeaabb;
 		}
-
-		// this must never happen!!
-		//AxisAlignedBox isect = aabb.intersection(nodeaabb);
-		//if (isect.getMinimum() != nodeaabb.getMinimum() || isect.getMaximum() != nodeaabb.getMaximum())
-		//{
-		//	LogManager::getSingleton().logMessage("#+#+#+#+#+ SceneNodes outside of node AABB.");
-		//}
 
 		if (mBuildMethod == KDBM_RECURSIVE)
@@ -760,23 +727,10 @@
 		}
 
-#ifdef KDTREE_DEBUG_OFF
-		mBuildLog->logMessage("events.size()=" + StringConverter::toString(events.size()));
-#endif
-#ifdef KDTREE_DEBUG_OFF
-		PlaneEventList::iterator xit, xbegin, xend;
-		xbegin = events.begin();
-		xend = events.end();
-		xit = xbegin;
-		while (xit != xend)
-		{
-			mBuildLog->logMessage(xit->print());
-			xit++;
-		}
-#endif
-
 		/************************************************/
 		/**************** BEGIN FINDPLANE ***************/
 		/************************************************/
 		// find optimal split plane and split node accordingly
+
+		// initialize
 		const int dim = 3;
 		int pStart, pOn, pEnd;
@@ -789,5 +743,4 @@
 		SplitInfo split, best;
 		best.cost = Math::POS_INFINITY;
-
 
 		PlaneEventList::iterator begin = events.begin();
@@ -821,24 +774,4 @@
 		}
 
-#ifdef KDTREE_DEBUG_OFF
-		Real lvol = best.bleft.volume();
-		Real rvol = best.bright.volume();
-
-		if (lvol == 0 || rvol == 0)
-		{
-			mBuildLog->logMessage("WARNING INVALID SPLIT!!!");
-			String side;
-			if (best.side == PlaneEvent::PES_LEFT)
-				side = "left";
-			else
-				side = "right";
-
-			mBuildLog->logMessage("Splitting node on level " + StringConverter::toString(level) + 
-				"\n\tcost=" + StringConverter::toString(best.cost) + " term=" + StringConverter::toString(PlaneEvent::KI*nObjects) +
-				" side=" + side +
-				"\n\tVolume: left=" + StringConverter::toString(lvol) +
-				" right=" + StringConverter::toString(rvol));
-		}
-#endif
 		/************************************************/
 		/**************** BEGIN TERMINATE ***************/
@@ -858,5 +791,4 @@
 				{
 					leaf->insert(rend);
-					//LogManager::getSingleton().logMessage("++ Adding SceneNode: " + (static_cast<KdTreeSceneNode *>(rend))->getName());
 				}
 				it++;
@@ -873,4 +805,5 @@
 		/**************** BEGIN CLASSIFY ****************/
 		/************************************************/
+		// split the event list in left and right sub-lists
 		else
 		{
@@ -896,5 +829,5 @@
 			while (it != end)
 			{
-				// right-only nodes get moved
+				// right-only nodes go in right list
 				if (it->getRenderable()->getSide() == PlaneEvent::PES_RIGHT)
 				{
@@ -904,23 +837,8 @@
 						nRightS++;
 					}
-
 					eventsRight.push_back(*it);
 				}
-				// both-only nodes get copied
-				// must clip AABBs to child AABB !!!
-				else if (it->getRenderable()->getSide() == PlaneEvent::PES_BOTH)
-				{
-					if (!it->getRenderable()->isClassified())
-					{
-						it->getRenderable()->setClassified(true);
-						nBothS++;
-					}
-
-					//eventsRight.push_back(*it);
-					//eventsLeft.push_back(*it);
-					eventsRight.push_back(it->clip(best.bright, best.event.getDimension()));
-					eventsLeft.push_back(it->clip(best.bleft, best.event.getDimension()));
-				}
-				else
+				// left-only nodes go in left list
+				else if (it->getRenderable()->getSide() == PlaneEvent::PES_LEFT)
 				{
 					if (!it->getRenderable()->isClassified())
@@ -931,12 +849,20 @@
 					eventsLeft.push_back(*it);
 				}
+				// remaining nodes go in both lists, bust must be clipped to prevent
+				// events from lying outside the new nodes aabb
+				else
+				{
+					if (!it->getRenderable()->isClassified())
+					{
+						it->getRenderable()->setClassified(true);
+						nBothS++;
+					}
+					eventsRight.push_back(it->clip(best.bright, best.event.getDimension()));
+					eventsLeft.push_back(it->clip(best.bleft, best.event.getDimension()));
+				}
 				it++;
 			}
 
-#ifdef KDTREE_DEBUG_OFF
-			mBuildLog->logMessage("Splitting on " + best.event.print());
-			mBuildLog->logMessage("eventsLeft.size()=" + StringConverter::toString(eventsLeft.size()));
-			mBuildLog->logMessage("eventsRight.size()=" + StringConverter::toString(eventsRight.size()));
-#endif
+			// create a new branch node and continue recursion
 			KdTree::Branch * branch = new KdTree::Branch(level, aabb, parent, best.event.getSplitPlane(), best.side);
 
@@ -956,7 +882,4 @@
 			// update bounding box
 			branch->_updateBounds(false);
-
-
-			//assert(branch->mRight || branch->mLeft);
 
 			return branch;
@@ -979,12 +902,7 @@
 		// inital split candidate
 		SplitInfo * best = pqFindPlane(e, nObjects, aabb, globalSA);
-		SplitCandidate splitcandidate(e, nObjects, aabb, parent, globalTreeCost, globalTreeCost - best->cost, best, PlaneEvent::PES_BOTH);
+		SplitCandidate splitcandidate(e, nObjects, aabb, parent, globalTreeCost, 
+			globalTreeCost - best->cost, best, PlaneEvent::PES_BOTH);
 		pqueue.push(splitcandidate);
-
-#ifdef KDTREE_DEBUG_OFF
-		//mBuildLog->logMessage("best.pevent=" + best->event.print() + 
-		//	" events.size()=" + StringConverter::toString(events.size()));
-		mBuildLog->logMessage("New split on " + splitcandidate.print());
-#endif
 
 
@@ -1001,10 +919,4 @@
 				level = sc.parent->mLevel + 1;
 			}
-
-#ifdef KDTREE_DEBUG_OFF
-			//mBuildLog->logMessage("Splitting on " + sc.best->event.print() +
-			//	" sc.events.size()=" + StringConverter::toString(sc.events->size()));
-			mBuildLog->logMessage("Splitting on " + sc.print());
-#endif
 
 			/************************************************/
@@ -1012,5 +924,4 @@
 			/************************************************/
 			// check terminating condition
-			//if (best.cost > PlaneEvent::KI*sc.nObjects || level >= mMaxDepth)
 			if (sc.decrease < 0.0 || level >= mMaxDepth)
 			{
@@ -1028,5 +939,4 @@
 					{
 						leaf->insert(rend);
-						//LogManager::getSingleton().logMessage("++ Adding SceneNode: " + (static_cast<KdTreeSceneNode *>(rend))->getName());
 					}
 					it++;
@@ -1053,36 +963,16 @@
 				while (it != end)
 				{
-#ifdef KDTREE_DEBUG_OFF
-					mBuildLog->logMessage(it->print());
-#endif
 					it->getRenderable()->setSide(PlaneEvent::PES_BOTH);
 					it->getRenderable()->setClassified(false);
 					it++;
 				}
+
 				// now classify all renderables. do they belong to the left child, the right child or both?
-#ifdef KDTREE_DEBUG_OFF
-				bool bla = true;
 				it = begin;
 				while (it != end)
 				{
 					it->classify(sc.best->event, sc.best->side);
-					if (*it == sc.best->event)
-					{
-						mBuildLog->logMessage("YEEPEE classified against valid event");
-						bla = false;
-					}
 					it++;
 				}
-				if (bla)
-					mBuildLog->logMessage("FUCKIT! Invalid classification");
-#else
-				it = begin;
-				while (it != end)
-				{
-					it->classify(sc.best->event, sc.best->side);
-					it++;
-				}
-#endif
-
 
 				// divide the event lists
@@ -1091,4 +981,5 @@
 				while (it != end)
 				{
+					// right-only events go in the right list
 					if (it->getRenderable()->getSide() == PlaneEvent::PES_RIGHT)
 					{
@@ -1101,16 +992,6 @@
 						eventsRight->push_back(*it);
 					}
-					else if (it->getRenderable()->getSide() == PlaneEvent::PES_BOTH)
-					{
-						if (!it->getRenderable()->isClassified())
-						{
-							it->getRenderable()->setClassified(true);
-							nBothS++;
-						}
-
-						eventsRight->push_back(it->clip(sc.best->bright, sc.best->event.getDimension()));
-						eventsLeft->push_back(it->clip(sc.best->bleft, sc.best->event.getDimension()));
-					}
-					else
+					// left-only events go in the left list
+					else if (it->getRenderable()->getSide() == PlaneEvent::PES_LEFT)
 					{
 						if (!it->getRenderable()->isClassified())
@@ -1121,64 +1002,28 @@
 						eventsLeft->push_back(*it);
 					}
+					// the rest goes in both lists after being clipped
+					else
+					{
+						if (!it->getRenderable()->isClassified())
+						{
+							it->getRenderable()->setClassified(true);
+							nBothS++;
+						}
+
+						eventsRight->push_back(it->clip(sc.best->bright, sc.best->event.getDimension()));
+						eventsLeft->push_back(it->clip(sc.best->bleft, sc.best->event.getDimension()));
+					}
 					it++;
 				}
 
-#ifdef KDTREE_DEBUG_OFF
-				mBuildLog->logMessage("#### Splitting node on level " + StringConverter::toString(level));
-				Plane * vplane;
-				int count = 0;
-				PlaneEventList::iterator vit, vbegin, vend;
-				vbegin = eventsLeft->begin();
-				vend = eventsLeft->end();
-				vit = vbegin;
-				while (vit != vend)
-				{
-					vplane = vit->getSplitPlane();
-					if (!sc.best.bleft.intersects(*vplane))
-					{
-						mBuildLog->logMessage("Invalid event classification! Plane: " + 
-						StringConverter::toString(vplane->normal) + ", " + StringConverter::toString(-vplane->d) +
-						" Box: |" + StringConverter::toString(sc.best.bleft.getMinimum()) + "|" +
-						StringConverter::toString(sc.best.bleft.getMaximum()) + "|");
-						count++;
-					}
-					OGRE_DELETE(vplane);
-					vit++;
-				}
-				mBuildLog->logMessage("@@@@ Number of invalid events on the left: " + 
-					StringConverter::toString(count) +
-					" Number of events on both sides: " + StringConverter::toString(nBothS));
-				count = 0;
-				vbegin = eventsRight->begin();
-				vend = eventsRight->end();
-				vit = vbegin;
-				while (vit != vend)
-				{
-					vplane = vit->getSplitPlane();
-					if (!sc.best.bright.intersects(*vplane))
-					{
-						mBuildLog->logMessage("Invalid event classification! Plane: " + 
-						StringConverter::toString(vplane->normal) + ", " + StringConverter::toString(-vplane->d) +
-						" Box: |" + StringConverter::toString(sc.best.bright.getMinimum()) + "|" +
-						StringConverter::toString(sc.best.bright.getMaximum()) + "|");
-						count++;
-					}
-					OGRE_DELETE(vplane);
-					vit++;
-				}
-				mBuildLog->logMessage("@@@@ Number of invalid events on the right: " + 
-					StringConverter::toString(count) +
-					" Number of events on both sides: " + StringConverter::toString(nBothS));
-#endif
-
+				// create a new branch node
 				KdTree::Branch * branch = 
 					new KdTree::Branch(level, sc.aabb, sc.parent, sc.best->event.getSplitPlane(), sc.best->side);
 
-				//Real decr = (PlaneEvent::surfaceArea(sc.aabb)/globalSA*PlaneEvent::KI*sc.nObjects) - sc.best.cost;
 				globalTreeCost -= sc.decrease;
 
-				//mBuildLog->logMessage("Splitting, cost is now " + StringConverter::toString(globalTreeCost) + "");
-
-				// now create the child nodes and continue recursion
+
+				// now for each potential child node, compute the split plane and the cost decrease
+				// and place them in the queue
 				if (eventsLeft->size() > 0)
 				{
@@ -1188,17 +1033,4 @@
 						branch, old, old - best->cost, best, PlaneEvent::PES_LEFT);
 					pqueue.push(scleft);
-
-#ifdef KDTREE_DEBUG_OFF
-					//mBuildLog->logMessage("best.pevent: " + best->event.print() + 
-					//	" eventsLeft.size()=" + StringConverter::toString(eventsLeft->size()));
-					mBuildLog->logMessage("New split on " + scleft.print());
-					Plane * plane = best->event.getSplitPlane();
-					if (!sc.best->bleft.intersects(*plane))
-					{
-						mBuildLog->logMessage("Best plane outside parent box on level " + 
-							StringConverter::toString(level));
-					}
-					OGRE_DELETE(plane);
-#endif
 				}
 				// cleanup
@@ -1207,4 +1039,5 @@
 					delete eventsLeft;
 				}
+
 				if (eventsRight->size() > 0)
 				{
@@ -1214,17 +1047,4 @@
 						branch, old, old - best->cost, best, PlaneEvent::PES_RIGHT);
 					pqueue.push(scright);
-
-#ifdef KDTREE_DEBUG_OFF
-					//mBuildLog->logMessage("best.pevent: " + best->event.print() + 
-					//	" eventsRight.size()=" + StringConverter::toString(eventsRight->size()));
-					mBuildLog->logMessage("New split on " + scright.print());
-					Plane * plane = best->event.getSplitPlane();
-					if (!sc.best->bright.intersects(*plane))
-					{
-						mBuildLog->logMessage("Best plane outside parent box on level " + 
-							StringConverter::toString(level));
-					}
-					OGRE_DELETE(plane);
-#endif
 				}
 				// cleanup
@@ -1273,4 +1093,5 @@
 	}
 
+	//-------------------------------------------------------------------------
 	SplitInfo * KdTree::pqFindPlane(PlaneEventList * events, int nObjects, AxisAlignedBox& aabb, Real globalSA)
 	{
@@ -1320,15 +1141,17 @@
 	}
 
-	void KdTree::queueVisibleObjects(Camera* cam, RenderQueue* queue, bool onlyShadowCasters, 
-		KdTree::RenderMethod renderMethod, bool showBoxes)
-	{
-		// for now only recurse or stack render methods
+	/************************************************************************/
+	/* KdTree rendering functions                                           */
+	/************************************************************************/
+
+	//-------------------------------------------------------------------------
+	void KdTree::queueVisibleObjects(Camera* cam, RenderQueue* queue, bool onlyShadowCasters, bool showBoxes)
+	{
 		if (mKdRoot)
-		{
 			recQueueVisibleObjects(mKdRoot, Root::getSingleton().getCurrentFrameNumber(),
 				cam, queue, onlyShadowCasters, showBoxes);
-		}
-	}
-
+	}
+
+	//-------------------------------------------------------------------------
 	void KdTree::recQueueVisibleObjects(KdTree::Node * node, unsigned long currentFrame, 
 		Camera* cam, RenderQueue* queue, bool onlyShadowCasters, bool showBoxes)
@@ -1383,4 +1206,9 @@
 	}
 
+	/************************************************************************/
+	/* KdTree debug & helper functions                                      */
+	/************************************************************************/
+
+	//-------------------------------------------------------------------------
 	void KdTree::dump()
 	{
@@ -1390,4 +1218,5 @@
 	}
 
+	//-------------------------------------------------------------------------
 	void KdTree::dump(KdTree::Node * node)
 	{
@@ -1411,5 +1240,6 @@
 			{
 				scenenode = dynamic_cast<KdTreeSceneNode *>(*it);
-				log->logMessage(pad + "# Leaf   level " + StringConverter::toString(node->mLevel) + 
+				log->logMessage(pad + "# Leaf   level " + 
+					StringConverter::toString(node->mLevel) + 
 					" SceneNode " + scenenode->getName());
 				log->logMessage(pad + "## Objects: " + scenenode->dumpToString());
@@ -1422,10 +1252,12 @@
 			if (branch->mLeft)
 			{
-				log->logMessage(pad + "# Branch level " + StringConverter::toString(node->mLevel) + " Left Child");
+				log->logMessage(pad + "# Branch level " + 
+					StringConverter::toString(node->mLevel) + " Left Child");
 				dump(branch->mLeft);
 			}
 			if (branch->mRight)
 			{
-				log->logMessage(pad + "# Branch level " + StringConverter::toString(node->mLevel) + " Right Child");
+				log->logMessage(pad + "# Branch level " + 
+					StringConverter::toString(node->mLevel) + " Right Child");
 				dump(branch->mRight);
 			}
@@ -1433,4 +1265,5 @@
 	}
 
+	//-------------------------------------------------------------------------
 	Real KdTree::calcCost()
 	{
@@ -1441,4 +1274,5 @@
 	}
 
+	//-------------------------------------------------------------------------
 	Real KdTree::calcCost(KdTree::Node * node, Real vs)
 	{
@@ -1449,13 +1283,20 @@
 		{
 			KdTree::Leaf * leaf = KDLEAFPTR_CAST(node);
-			return (PlaneEvent::surfaceArea(node->mAABB)/vs)*PlaneEvent::KI*leaf->mKdRenderables.size();
+			return (PlaneEvent::surfaceArea(node->mAABB)/vs) *
+				PlaneEvent::KI * leaf->mKdRenderables.size();
 		}
 		else
 		{
 			KdTree::Branch * branch = KDBRANCHPTR_CAST(node);
-			return (PlaneEvent::surfaceArea(node->mAABB)/vs)*PlaneEvent::KT + calcCost(branch->mLeft, vs) + calcCost(branch->mRight, vs);
-		}
-	}
-
+			return (PlaneEvent::surfaceArea(node->mAABB)/vs) * PlaneEvent::KT + 
+				calcCost(branch->mLeft, vs) + calcCost(branch->mRight, vs);
+		}
+	}
+
+	/************************************************************************/
+	/* KdTree::Node/Branch/Leaf functions                                   */
+	/************************************************************************/
+
+	//-------------------------------------------------------------------------
 	KdTree::Leaf::~Leaf()
 	{
@@ -1472,4 +1313,27 @@
 	}
 
+	void KdTree::Leaf::queueVisibleObjects(unsigned long currentFrame, 
+		Camera* cam, RenderQueue* queue, bool onlyShadowCasters, bool showBoxes)
+	{
+		KdRenderableList::iterator it  = mKdRenderables.begin();
+		KdRenderableList::iterator end = mKdRenderables.end();
+		while (it != end)
+		{			
+			if (!(*it)->isQueued(currentFrame, cam))
+			{
+				(*it)->queueObjects(cam, queue, onlyShadowCasters);
+			}
+			it++;
+		}
+
+		if (showBoxes)
+		{
+			WireBoundingBox * wbb = getWireBoundingBox();
+			if (wbb)
+				queue->addRenderable(wbb);
+		}
+	}
+
+	//-------------------------------------------------------------------------
 	// update the world aabb based on the contained geometry
 	void KdTree::Leaf::_updateBounds(bool recurse)
