Terrain Grid

MrChris

07-03-2011 19:33:07

As part of my learning experience of Mogre I modified the existing Grid example posted in the WIKI to create a grid over a terrain created with the Terain Scene Manager. I figured I would share it with all the other newbies out there.


CreateGrid(float unitsize, float height, float terrainwidth, float terraindepth, float terrainsize, SceneManager mSMgr)
unitsize: grid line spacing
height: height to place the grid above the terrain
terrainwidth, terraindepth: the Pageworldx and pageworldz terrain sizes used in the terrain.cfg file. There appears to be a method to get these values programmtically but I cannot get them to work.
terrainsize: the terrain page size from the terrain.cfg file
mSMgr: Scenemanager that will have the grid attached to it.

USAGE Information
-----------------

Helper.TGrid mGrid;
mGrid = new Helper.TGrid();

//example that will generate a gid over the terrain with the following properties
// Grid pacing of 100 ogre units
//Grid height above terrain 1 ogre unit
//The terrain pageworldsizex and pageworldsizez are 3000 and 3000
//terrain pagesize is 513
//the scene manager is mSceneManager
mGrid.CreateGrid( 100, 1,3000,3000,513,mSceneManager);


TGrid Class

using System;
using System.Collections.Generic;
using System.Text;
using Mogre;

namespace Helper
{
class TGrid
{
ManualObject grid;
SceneManager mSceneMgr;

public void CreateGrid(float unitsize, float height, float terrainwidth, float terraindepth, float terrainsize, SceneManager mSMgr)
{
mSceneMgr = mSMgr;

grid = mSceneMgr.CreateManualObject("grid2");

grid.Begin("VTCore/TGrid", RenderOperation.OperationTypes.OT_LINE_LIST);

float verspacingwidth = terraindepth / (terrainsize-1);
float verspacingdepth = terrainwidth / (terrainsize-1);
float numrows = terrainwidth / unitsize;
float numcols = terraindepth / unitsize;
float previousheight;

//Use this to Center at 0,0,0) - since uses corner - not needed since cannot move TSM
//Vector3 center = new Vector3(-width / 2.0f, 0, -depth / 2.0f);

//Use this to Corner at 0,0,0) - since uses corner - not needed in TSM since corners at 0 0 0 by default
// Vector3 corner = new Vector3(0, 0, 0);


for (int k = 0; k < numrows; ++k)
{
previousheight = 0;

for (int i = 0; i < terrainsize; ++i)
{
Vector3 s, e;

s.x = verspacingdepth * i;
s.z = k * unitsize;
if (i == 0)
{
s.y = getTerrainHeight(s.x, s.z) + height;
}
else
{
s.y = previousheight;
}

e.x = verspacingdepth * (i + 1);
e.z = k * unitsize;
e.y = getTerrainHeight(e.x, e.z) + height;
previousheight = e.y;

grid.Position(s);
grid.Position(e);
}

}

for (int k = 0; k < numcols; ++k)
{
previousheight = 0;

for (int i = 0; i < terrainsize; ++i)
{
Vector3 s, e;

s.z = verspacingwidth * i;
s.x = k * unitsize;
if (i == 0)
{
s.y = getTerrainHeight(s.x, s.z) + height;
}
else
{
s.y = previousheight;
}

e.z = verspacingwidth * (i + 1);
e.x = k * unitsize;
e.y = getTerrainHeight(e.x, e.z) + height;
previousheight = e.y;

grid.Position(s);
grid.Position(e);
}

}
grid.End();

mSceneMgr.RootSceneNode.AttachObject(grid);
}

float getTerrainHeight(float x, float z)
{

Ray mRay = new Ray(new Vector3(x, 5000, z), Vector3.NEGATIVE_UNIT_Y);
RaySceneQuery mRaySceneQuery;
mRaySceneQuery = mSceneMgr.CreateRayQuery(mRay);

RaySceneQueryResult mResult = mRaySceneQuery.Execute();

if (mResult.Count != 0 && mResult.Front.worldFragment != null)
{
Vector3 destination = mResult.Front.worldFragment.singleIntersection;
return destination.y;
}
else
{
return 0;
}
}


public void ToggleView()
{
if (grid.Visible == false)
{
grid.Visible = true;
}
else
{
grid.Visible = false;
}


}


}
}