Index: GTP/trunk/App/Demos/Vis/KdTreeDemo/OGRE/src/TestKdTree.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/KdTreeDemo/OGRE/src/TestKdTree.cpp	(revision 1258)
+++ GTP/trunk/App/Demos/Vis/KdTreeDemo/OGRE/src/TestKdTree.cpp	(revision 1273)
@@ -181,5 +181,5 @@
 	cfDeath.load("testKdTree.cfg");
 
-	mSceneFiles = cfDeath.getSetting("scene");
+	mOptions.mSceneFiles = cfDeath.getSetting("scene");
 
 	tmp = cfDeath.getSetting("shadows");
@@ -236,4 +236,72 @@
 	createMaterials();
 
+	// load simple scene (planes & robots)
+	if (mOptions.mSceneFiles == "")
+	{
+		createSimpleScene();
+	}
+	// load terrain, but only if terrainscenemanager selected
+	else if (mOptions.mSceneFiles == TERRAIN_SCENE)
+	{
+		Plane waterPlane;
+
+		// Set ambient light
+		mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
+
+		// Create a light
+		Light* l = mSceneMgr->createLight("MainLight");
+		// Accept default settings: point light, white diffuse, just set position
+		// NB I could attach the light to a SceneNode if I wanted it to move automatically with
+		//  other objects, but I don't
+		l->setPosition(20,80,50);
+
+		// Fog
+		// NB it's VERY important to set this before calling setWorldGeometry 
+		// because the vertex program picked will be different
+		//ColourValue fadeColour(0.93, 0.86, 0.76);
+		//mSceneMgr->setFog( FOG_LINEAR, fadeColour, .001, 500, 1000);
+		//mWindow->getViewport(0)->setBackgroundColour(fadeColour);
+		mWindow->getViewport(0)->setBackgroundColour(ColourValue::Blue);
+
+		std::string terrain_cfg("terrain.cfg");
+
+		mSceneMgr -> setWorldGeometry( terrain_cfg );
+
+		// Define the required skyplane
+		Plane plane;
+		// 5000 world units from the camera
+		plane.d = 5000;
+		// Above the camera, facing down
+		plane.normal = -Vector3::UNIT_Y;
+
+		// add one robot
+		//Entity *robot = mSceneMgr->createEntity("TheRobot","robot.mesh");
+		//SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode("TheRobotNode");
+		//node->attachObject(robot);
+		// add stuff minus gound plane
+		mSelectEntities &= ~ENT_PLN;
+		createSimpleScene();
+
+		// Set a nice viewpoint
+		mCamNode->setPosition(707,2500,528);
+		mCamNode->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329));
+	}
+	// load scene from file
+	else
+	{
+		// don't load the other stuff
+		loadScene(mOptions.mSceneFiles);
+		// top view
+		mTopCam->setPosition(Vector3(1232, 3990, -1477));
+		// walkthrough view
+		mCamNode->setPosition(Vector3(827.885, 184.435, -524.984));
+		mCamNode->setOrientation(Quaternion(0.98935, 0.0348082, -0.141246, 0.00496945));
+
+		mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox", 5000, true);
+	}
+}
+
+void KdTreeApp::createSimpleScene()
+{
 	Entity *deaths;
 	SceneNode *nodes;
@@ -245,159 +313,125 @@
 	Real planeSixth = mPlaneDim / 6;
 
-	// load scene from file
-	if (mSceneFiles != "")
-	{
-		// don't load the other stuff
-		loadScene(mSceneFiles);
-		// top view
-		mTopCam->setPosition(Vector3(1232, 3990, -1477));
-		// walkthrough view
-		mCamNode->setPosition(Vector3(827.885, 184.435, -524.984));
-		mCamNode->setOrientation(Quaternion(0.98935, 0.0348082, -0.141246, 0.00496945));
-
-		mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox", 5000, true);
-	}
-	else
-	{
-		mCamNode->setPosition(Vector3(1280,600,1666));
-		mCamNode->setOrientation(Quaternion(0.936893, -0.124586, 0.323813, 0.04306));
-		//mCamera->lookAt(Vector3(-20,30,10));
-
-		SceneNode *anchor = mSceneMgr->getRootSceneNode()->createChildSceneNode("AnchorNode");
-		//SceneNode *grndan = anchor->createChildSceneNode("GroundAnchor");
-		SceneNode *grndan = mSceneMgr->getRootSceneNode();
-
-		if (mSelectEntities & ENT_GRID)
+	mCamNode->setPosition(Vector3(1280,600,1666));
+	mCamNode->setOrientation(Quaternion(0.936893, -0.124586, 0.323813, 0.04306));
+
+	SceneNode *anchor = mSceneMgr->getRootSceneNode()->createChildSceneNode("AnchorNode");
+	//SceneNode *grndan = anchor->createChildSceneNode("GroundAnchor");
+	SceneNode *grndan = mSceneMgr->getRootSceneNode();
+
+	if (mSelectEntities & ENT_GRID)
+	{
+		for (j = 0, z =  -(mModelCount / 2 * mModelSpacing); j < mModelCount; j++, z += mModelSpacing)
 		{
-			for (j = 0, z =  -(mModelCount / 2 * mModelSpacing); j < mModelCount; j++, z += mModelSpacing)
+			for (i = 0, x = -(mModelCount / 2 * mModelSpacing); i < mModelCount; i++, x += mModelSpacing) 
 			{
-				for (i = 0, x = -(mModelCount / 2 * mModelSpacing); i < mModelCount; i++, x += mModelSpacing) 
-				{
-					deaths = mSceneMgr->createEntity(cat(entName, i, j).c_str(),"robot.mesh");
-					if (mShadowsEnabled)
-						deaths->setCastShadows(true);
-					nodes = /*mSceneMgr->getRootSceneNode()*/anchor->createChildSceneNode(cat(nodeName, i, j).c_str(), Vector3(x, 0 , z));
-					nodes->attachObject(deaths);
-				}
-			}
-		}
-
-		if (mSelectEntities & ENT_RND)
-		{
-			entName = "randomdeath";
-			nodeName = "RandomDeathNode";
-			for (i = 0; i < mRandomCount; i++)
-			{
-				Vector3 pos(
-					Math::RangeRandom(-planeHalf,-planeSixth), 
-					0, 
-					Math::RangeRandom(-planeThreeEights, planeThreeEights));
-				deaths = mSceneMgr->createEntity(cat(entName,666,i),"robot.mesh");
+				deaths = mSceneMgr->createEntity(cat(entName, i, j).c_str(),"robot.mesh");
 				if (mShadowsEnabled)
 					deaths->setCastShadows(true);
-				nodes = /*mSceneMgr->getRootSceneNode()*/anchor->createChildSceneNode(cat(nodeName,666,i), pos,
-					Quaternion(Radian(Math::RangeRandom(-Math::PI, Math::PI)), Vector3::UNIT_Y));
+				nodes = /*mSceneMgr->getRootSceneNode()*/anchor->createChildSceneNode(cat(nodeName, i, j).c_str(), Vector3(x, 0 , z));
 				nodes->attachObject(deaths);
 			}
 		}
-
-		if (mSelectEntities & ENT_SPC)
+	}
+
+	if (mSelectEntities & ENT_RND)
+	{
+		entName = "randomdeath";
+		nodeName = "RandomDeathNode";
+		for (i = 0; i < mRandomCount; i++)
 		{
-			entName = "randomspaceship";
-			nodeName = "RandomSpaceshipNode";
-			for (i = 0; i < mRandomCount; i++)
-			{
-				Vector3 pos(
-					//Math::RangeRandom(-planeHalf,-planeSixth), 
-					Math::RangeRandom(planeSixth,planeHalf), 
-					Math::RangeRandom(planeHalf * 0.1, planeHalf), 
-					Math::RangeRandom(-planeThreeEights, planeThreeEights));
-				deaths = mSceneMgr->createEntity(cat(entName,666,i),"razor.mesh");
-				if (mShadowsEnabled)
-					deaths->setCastShadows(true);
-				nodes = /*mSceneMgr->getRootSceneNode()*/anchor->createChildSceneNode(cat(nodeName,666,i), pos,
-					Quaternion(Radian(Math::RangeRandom(-Math::PI, Math::PI)), Vector3::UNIT_Y));
-				nodes->attachObject(deaths);
-			}
+			Vector3 pos(
+				Math::RangeRandom(-planeHalf,-planeSixth), 
+				0, 
+				Math::RangeRandom(-planeThreeEights, planeThreeEights));
+			deaths = mSceneMgr->createEntity(cat(entName,666,i),"robot.mesh");
+			if (mShadowsEnabled)
+				deaths->setCastShadows(true);
+			nodes = /*mSceneMgr->getRootSceneNode()*/anchor->createChildSceneNode(cat(nodeName,666,i), pos,
+				Quaternion(Radian(Math::RangeRandom(-Math::PI, Math::PI)), Vector3::UNIT_Y));
+			nodes->attachObject(deaths);
 		}
-
-		if (mSelectEntities & ENT_MOV)
+	}
+
+	if (mSelectEntities & ENT_SPC)
+	{
+		entName = "randomspaceship";
+		nodeName = "RandomSpaceshipNode";
+		for (i = 0; i < mRandomCount; i++)
 		{
-			Entity *movingDeath = mSceneMgr->createEntity("movingDeath","robot.mesh");
+			Vector3 pos(
+				//Math::RangeRandom(-planeHalf,-planeSixth), 
+				Math::RangeRandom(planeSixth,planeHalf), 
+				Math::RangeRandom(planeHalf * 0.1, planeHalf), 
+				Math::RangeRandom(-planeThreeEights, planeThreeEights));
+			deaths = mSceneMgr->createEntity(cat(entName,666,i),"razor.mesh");
 			if (mShadowsEnabled)
-				movingDeath->setCastShadows( true );
-
-			SceneNode *deathPivotNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("deathPivotNode");
-			mMoveNode = deathPivotNode->createChildSceneNode("movingNode", Vector3(0, 0, mRotationRadius)/*,
-				Quaternion(Radian(Math::HALF_PI), Vector3::UNIT_Y)*/);
-			mMoveNode->attachObject(movingDeath);
-
-			Entity *ent_ball = mSceneMgr->createEntity("ball","sphere.mesh");
-			SceneNode *node_pivot = mMoveNode->createChildSceneNode("pivotNode");
-			SceneNode *node_ball = node_pivot->createChildSceneNode("orbitNode", Vector3(120, 40, 0));
-			node_ball->attachObject(ent_ball);
-			node_ball->scale(0.1, 0.1, 0.1);
-			
-
-			//mFollowCam->setAutoTracking(true, mMoveNode);
+				deaths->setCastShadows(true);
+			nodes = /*mSceneMgr->getRootSceneNode()*/anchor->createChildSceneNode(cat(nodeName,666,i), pos,
+				Quaternion(Radian(Math::RangeRandom(-Math::PI, Math::PI)), Vector3::UNIT_Y));
+			nodes->attachObject(deaths);
 		}
-		
-		if (mSelectEntities & ENT_PLN)
-		{
-			Plane ground(Vector3::UNIT_Y, 0);
-			MeshManager::getSingleton().createPlane("ground", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, 
-				ground, mPlaneDim * 4 / 3, mPlaneDim, 20, 20, true, 1, 20, 20, Vector3::UNIT_Z);
-			Entity *ent_ground = mSceneMgr->createEntity("GroundEntity", "ground");
-			ent_ground->setCastShadows(false);
-			ent_ground->setMaterialName("Examples/RustySteel");//("Examples/Rockwall");
-			SceneNode *node_ground = /*mSceneMgr->getRootSceneNode()*/grndan->createChildSceneNode("GroundNode", Vector3(0, 0, 0));
-			node_ground->attachObject(ent_ground);
-
-			//MeshManager::getSingleton().createPlane("ground2", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, 
-			//	ground, mPlaneDim/2, mPlaneDim, 10, 20, true, 1, 10, 20, Vector3::UNIT_Z);
-			//ent_ground = mSceneMgr->createEntity("GroundEntity2", "ground2");
-			//ent_ground->setCastShadows(false);
-			//ent_ground->setMaterialName("Examples/RustySteel");
-			//node_ground = /*mSceneMgr->getRootSceneNode()*/grndan->createChildSceneNode("GroundNode2", Vector3(-mPlaneDim/4, 0, 0));
-			//node_ground->attachObject(ent_ground);
-		}
-
-		// Lights
-		mSceneMgr->setAmbientLight(ColourValue(0.1,0.1,0.1));
-		Light *light = mSceneMgr->createLight("light");
+	}
+
+	if (mSelectEntities & ENT_MOV)
+	{
+		Entity *movingDeath = mSceneMgr->createEntity("movingDeath","robot.mesh");
 		if (mShadowsEnabled)
-		{
-			mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);
-			light->setType(Light::LT_POINT);
-			light->setPosition(Vector3(x, 300, z + 200));
-		}
-		else
-		{
-			light->setType(Light::LT_DIRECTIONAL);
-			light->setDirection(-1,-1,-1);
-		}
-		light->setDiffuseColour(ColourValue::White);
-		light->setSpecularColour(ColourValue(1, 1, 0.2));
-
-		// Skybox
-		mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", mPlaneDim * 2);
-	}
-
-	/* Some math tests
-	Plane planeX(Vector3::UNIT_X, Vector3(10,10,10));
-	Plane planeY(Vector3::UNIT_Y, Vector3(10,10,10));
-	Plane planeZ(Vector3::UNIT_Z, Vector3(10,10,10));
-	Vector3 vect(20,20,20);
-	Vector3 interX = planeX.projectVector(vect);
-	Vector3 interY = planeY.projectVector(vect);
-	Vector3 interZ = planeZ.projectVector(vect);
-	std::stringstream ssX, ssY, ssZ;
-	ssX << "The intersection of " << planeX << " and " << vect << " is at: " << interX;
-	ssY << "The intersection of " << planeY << " and " << vect << " is at: " << interY;
-	ssZ << "The intersection of " << planeZ << " and " << vect << " is at: " << interZ;
-	LogManager::getSingleton().logMessage(ssX.str());
-	LogManager::getSingleton().logMessage(ssY.str());
-	LogManager::getSingleton().logMessage(ssZ.str());
-	*/
+			movingDeath->setCastShadows( true );
+
+		SceneNode *deathPivotNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("deathPivotNode");
+		mMoveNode = deathPivotNode->createChildSceneNode("movingNode", Vector3(0, 0, mRotationRadius)/*,
+																									 Quaternion(Radian(Math::HALF_PI), Vector3::UNIT_Y)*/);
+																									 mMoveNode->attachObject(movingDeath);
+
+		Entity *ent_ball = mSceneMgr->createEntity("ball","sphere.mesh");
+		SceneNode *node_pivot = mMoveNode->createChildSceneNode("pivotNode");
+		SceneNode *node_ball = node_pivot->createChildSceneNode("orbitNode", Vector3(120, 40, 0));
+		node_ball->attachObject(ent_ball);
+		node_ball->scale(0.1, 0.1, 0.1);
+
+
+		//mFollowCam->setAutoTracking(true, mMoveNode);
+	}
+
+	if (mSelectEntities & ENT_PLN)
+	{
+		Plane ground(Vector3::UNIT_Y, 0);
+		MeshManager::getSingleton().createPlane("ground", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, 
+			ground, mPlaneDim * 4 / 3, mPlaneDim, 20, 20, true, 1, 20, 20, Vector3::UNIT_Z);
+		Entity *ent_ground = mSceneMgr->createEntity("GroundEntity", "ground");
+		ent_ground->setCastShadows(false);
+		ent_ground->setMaterialName("Examples/RustySteel");//("Examples/Rockwall");
+		SceneNode *node_ground = /*mSceneMgr->getRootSceneNode()*/grndan->createChildSceneNode("GroundNode", Vector3(0, 0, 0));
+		node_ground->attachObject(ent_ground);
+
+		//MeshManager::getSingleton().createPlane("ground2", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, 
+		//	ground, mPlaneDim/2, mPlaneDim, 10, 20, true, 1, 10, 20, Vector3::UNIT_Z);
+		//ent_ground = mSceneMgr->createEntity("GroundEntity2", "ground2");
+		//ent_ground->setCastShadows(false);
+		//ent_ground->setMaterialName("Examples/RustySteel");
+		//node_ground = /*mSceneMgr->getRootSceneNode()*/grndan->createChildSceneNode("GroundNode2", Vector3(-mPlaneDim/4, 0, 0));
+		//node_ground->attachObject(ent_ground);
+	}
+
+	// Lights
+	mSceneMgr->setAmbientLight(ColourValue(0.1,0.1,0.1));
+	Light *light = mSceneMgr->createLight("light");
+	if (mShadowsEnabled)
+	{
+		mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);
+		light->setType(Light::LT_POINT);
+		light->setPosition(Vector3(x, 300, z + 200));
+	}
+	else
+	{
+		light->setType(Light::LT_DIRECTIONAL);
+		light->setDirection(-1,-1,-1);
+	}
+	light->setDiffuseColour(ColourValue::White);
+	light->setSpecularColour(ColourValue(1, 1, 0.2));
+
+	// Skybox
+	mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", mPlaneDim * 2);
 }
 
@@ -418,5 +452,6 @@
 		"MySceneManager");
 	// set params for kdtree scene manager
-	if (mOptions.mSceneManager == KdTreeAppListener::SM_KDT)
+	if (mOptions.mSceneManager == KdTreeAppListener::SM_KDT || 
+		mOptions.mSceneManager == KdTreeAppListener::SM_KTE)
 	{
 		mSceneMgr->setOption("BuildMethod", &mOptions.mBuildMethod);
@@ -530,5 +565,7 @@
 
 	// create play button
-	mat = MaterialManager::getSingleton().create("KdTree/DemoPlayButton", "General");
+	mat = MaterialManager::getSingleton().getByName("KdTree/DemoPlayButton");
+	if (mat.isNull())
+		mat = MaterialManager::getSingleton().create("KdTree/DemoPlayButton", "General");
 	mat->setLightingEnabled(false);
 	tech = mat->getTechnique(0);
@@ -540,5 +577,7 @@
 
 	// create record button
-	mat = MaterialManager::getSingleton().create("KdTree/DemoRecordButton", "General");
+	mat = MaterialManager::getSingleton().getByName("KdTree/DemoRecordButton");
+	if (mat.isNull())
+		mat = MaterialManager::getSingleton().create("KdTree/DemoRecordButton", "General");
 	mat->setLightingEnabled(false);
 	tech = mat->getTechnique(0);
Index: GTP/trunk/App/Demos/Vis/KdTreeDemo/OGRE/src/TestKdTreeAppListener.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/KdTreeDemo/OGRE/src/TestKdTreeAppListener.cpp	(revision 1265)
+++ GTP/trunk/App/Demos/Vis/KdTreeDemo/OGRE/src/TestKdTreeAppListener.cpp	(revision 1273)
@@ -18,10 +18,12 @@
 const String KdTreeAppListener::BUILDMETHOD[] = { "RE", "PQ" };
 const String KdTreeAppListener::BUILDMETHODCAPTION[] = { "Recursive", "Priority Queue" };
-const String KdTreeAppListener::SCENEMANAGER[] = { "KDT", "OCM", "OCT", "GEN" };
+const String KdTreeAppListener::SCENEMANAGER[] = { "KDT", "KTE", "OCM", "OCT", "TER", "GEN" };
 const String KdTreeAppListener::SCENEMANAGERNAME[] =
 {
 	"KdTreeSceneManager",
+	"KdTreeTerrainSceneManager",
 	"OcclusionCullingSceneManager",
 	"OctreeSceneManager",
+	"TerrainSceneManager",
 	"DefaultSceneManager"
 };
@@ -128,4 +130,5 @@
 mRotScale(0.0f),
 mDeathAngle(0.0f),
+mRaySceneQuery(0),
 // just to stop toggles flipping too fast
 mTimeUntilNextToggle(0.0f),
@@ -159,4 +162,6 @@
 	mTopCam = sm->getCamera("TopCam");
 	mCamNode = sm->getSceneNode("PlayerCamNode");
+
+	mRaySceneQuery = mSceneMgr->createRayQuery(Ray(mCamNode->getPosition(), Vector3::NEGATIVE_UNIT_Y));
 
 	mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");
@@ -404,5 +409,7 @@
 	if (mSceneMgr->getTypeName() == "OctreeSceneManager")
 		mSceneMgr->setOption("ShowOctree", &show);
-	else if (mSceneMgr->getTypeName() == "KdTreeSceneManager")
+	else if (
+		mSceneMgr->getTypeName() == "KdTreeSceneManager" ||
+		mSceneMgr->getTypeName() == "KdTreeTerrainSceneManager")
 		mSceneMgr->setOption("ShowKdTree", &show);
 
@@ -965,21 +972,41 @@
 	if (!mFreeMove)
 	{
-		Vector3 pos = mCamNode->getPosition();
-		RaySceneQuery * rsquery = mSceneMgr->createRayQuery(Ray(pos, Vector3::NEGATIVE_UNIT_Y));
-		RaySceneQueryResult& rsresult = rsquery->execute();
-
-		RaySceneQueryResult::iterator it = rsresult.begin();
-		RaySceneQueryResult::iterator end = rsresult.end();
-
-		while (it != end && it->movable)
-		{
-			if (it->movable->getName() != "PlayerCam")
+		if (mOptions.mSceneFiles == TERRAIN_SCENE)
+		{
+			static Vector3 pos;
+			static Ray updateRay;
+			pos = mCamNode->getPosition();
+			updateRay.setOrigin(pos);
+			updateRay.setDirection(Vector3::NEGATIVE_UNIT_Y);
+			mRaySceneQuery->setRay(updateRay);
+			RaySceneQueryResult& qryResult = mRaySceneQuery->execute();
+			RaySceneQueryResult::iterator i = qryResult.begin();
+			if (i != qryResult.end() && i->worldFragment)
 			{
-				mCamNode->setPosition(pos.x, it->movable->getWorldBoundingBox().getCenter().y + 2, pos.z);
-				break;
+				SceneQuery::WorldFragment* wf = i->worldFragment;
+				mCamNode->setPosition(pos.x, wf->singleIntersection.y + 10, pos.z);
 			}
-			it++;
-		}
-		OGRE_DELETE(rsquery);
+		}
+		else
+		{
+			static Vector3 pos;
+			static Ray updateRay;
+			pos = mCamNode->getPosition();
+			updateRay.setOrigin(pos);
+			updateRay.setDirection(Vector3::NEGATIVE_UNIT_Y);
+			mRaySceneQuery->setRay(updateRay);
+			RaySceneQueryResult& qryResult = mRaySceneQuery->execute();
+			RaySceneQueryResult::iterator i = qryResult.begin();
+			while (i != qryResult.end() && i->movable)
+			{
+				if (i->movable->getName() != "PlayerCam")
+				{
+					MovableObject *mov = i->movable;
+					mCamNode->setPosition(pos.x, mov->getWorldBoundingBox().getCenter().y + 2, pos.z);
+					break;
+				}
+				i++;
+			}
+		}
 	}
 }
