public override void LoadWorldGeometry(string fileName)
{
var serializer = new XmlSerializer(typeof(TerrainOptions));
this.options = (TerrainOptions)serializer.Deserialize(ResourceGroupManager.Instance.OpenResource(fileName));
this.scale = new Vector3(this.options.scalex, this.options.scaley, this.options.scalez);
this.tileSize = this.options.size;
// load the heightmap
{
Image image = Image.FromStream(ResourceGroupManager.Instance.OpenResource(this.options.Terrain),
this.options.Terrain.Split('.')[1]);
worldSize = this.options.worldSize = image.Width;
var dest = new Real[(int)worldSize * (int)worldSize];
byte[] src = image.Data;
Real invScale;
//if ( image.Format != PixelFormat.L8 && image.Format != PixelFormat.L16 )
// throw new AxiomException( "Heightmap is not a grey scale image!" );
bool is16bit = (image.Format == PixelFormat.L16);
// Determine mapping from fixed to floating
ulong rowSize;
if (is16bit)
{
invScale = 1.0f / 65535.0f;
rowSize = (ulong)worldSize * 2;
}
else
{
invScale = 1.0f; // / 255.0f;
rowSize = (ulong)worldSize;
}
// Read the data
int srcIndex = 0;
int dstIndex = 0;
for (ulong j = 0; j < (ulong)worldSize; ++j)
{
for (ulong i = 0; i < (ulong)worldSize; ++i)
{
if (is16bit)
{
#if AXIOM_BIG_ENDIAN
ushort val = (ushort)(src[srcIndex++] << 8);
val += src[srcIndex++];
#else
ushort val = src[srcIndex++];
val += (ushort)(src[srcIndex++] << 8);
#endif
dest[dstIndex++] = new Real(val) * invScale;
}
else
{
dest[dstIndex++] = new Real(src[srcIndex++]); // *invScale;
#if (XBOX || XBOX360)
srcIndex += 3;
#endif
}
}
}
// get the data from the heightmap
this.options.data = dest;
}
float maxx = this.options.scalex * this.options.worldSize;
float maxy = 255 * this.options.scaley;
float maxz = this.options.scalez * this.options.worldSize;
Resize(new AxisAlignedBox(Vector3.Zero, new Vector3(maxx, maxy, maxz)));
this.terrainMaterial =
(Material)
(MaterialManager.Instance.CreateOrRetrieve(
!String.IsNullOrEmpty(this.options.MaterialName) ? this.options.MaterialName : "Terrain",
ResourceGroupManager.Instance.WorldResourceGroupName).First);
if (this.options.WorldTexture != "")
{
this.terrainMaterial.GetTechnique(0).GetPass(0).CreateTextureUnitState(this.options.WorldTexture, 0);
}
if (this.options.DetailTexture != "")
{
this.terrainMaterial.GetTechnique(0).GetPass(0).CreateTextureUnitState(this.options.DetailTexture, 1);
}
this.terrainMaterial.Lighting = this.options.isLit;
this.terrainMaterial.Load();
this.terrainRoot = (SceneNode)RootSceneNode.CreateChild("TerrainRoot");
this.numTiles = (this.options.worldSize - 1) / (this.options.size - 1);
this.tiles = new TerrainRenderable[this.numTiles, this.numTiles];
int p = 0, q = 0;
for (int j = 0; j < this.options.worldSize - 1; j += (this.options.size - 1))
{
p = 0;
for (int i = 0; i < this.options.worldSize - 1; i += (this.options.size - 1))
{
this.options.startx = i;
this.options.startz = j;
string name = string.Format("Tile[{0},{1}]", p, q);
var node = (SceneNode)this.terrainRoot.CreateChild(name);
var tile = new TerrainRenderable();
tile.Name = name;
tile.RenderQueueGroup = WorldGeometryRenderQueueId;
tile.SetMaterial(this.terrainMaterial);
tile.Init(this.options);
this.tiles[p, q] = tile;
node.AttachObject(tile);
p++;
}
q++;
}
int size1 = this.tiles.GetLength(0);
int size2 = this.tiles.GetLength(1);
for (int j = 0; j < size1; j++)
{
for (int i = 0; i < size2; i++)
{
if (j != size1 - 1)
{
this.tiles[i, j].SetNeighbor(Neighbor.South, this.tiles[i, j + 1]);
this.tiles[i, j + 1].SetNeighbor(Neighbor.North, this.tiles[i, j]);
}
if (i != size2 - 1)
{
this.tiles[i, j].SetNeighbor(Neighbor.East, this.tiles[i + 1, j]);
this.tiles[i + 1, j].SetNeighbor(Neighbor.West, this.tiles[i, j]);
}
}
}
if (this.options.isLit)
{
for (int j = 0; j < size1; j++)
{
for (int i = 0; i < size2; i++)
{
this.tiles[i, j].CalculateNormals();
}
}
}
}