private IndexData GetIndexData()
{
int east = 0, west = 0, north = 0, south = 0;
int step = 1 << this.renderLevel;
int indexArray = 0;
int numIndexes = 0;
if ( this.neighbors[ (int)Neighbor.East ] != null && this.neighbors[ (int)Neighbor.East ].renderLevel > this.renderLevel )
{
east = step;
indexArray |= (int)Tile.East;
}
if ( this.neighbors[ (int)Neighbor.West ] != null && this.neighbors[ (int)Neighbor.West ].renderLevel > this.renderLevel )
{
west = step;
indexArray |= (int)Tile.West;
}
if ( this.neighbors[ (int)Neighbor.North ] != null && this.neighbors[ (int)Neighbor.North ].renderLevel > this.renderLevel )
{
north = step;
indexArray |= (int)Tile.North;
}
if ( this.neighbors[ (int)Neighbor.South ] != null && this.neighbors[ (int)Neighbor.South ].renderLevel > this.renderLevel )
{
south = step;
indexArray |= (int)Tile.South;
}
IndexData indexData = null;
if ( this.levelIndex[ this.renderLevel, indexArray ] != null )
{
indexData = this.levelIndex[ this.renderLevel, indexArray ];
}
else
{
int newLength = ( this.size / step ) * ( this.size / step ) * 2 * 2 * 2;
//this is the maximum for a level. It wastes a little, but shouldn't be a problem.
indexData = new IndexData();
indexData.indexBuffer =
HardwareBufferManager.Instance.CreateIndexBuffer(
IndexType.Size16,
newLength,
BufferUsage.StaticWriteOnly );
//indexCache.Add(indexData);
numIndexes = 0;
IntPtr idx = indexData.indexBuffer.Lock( BufferLocking.Discard );
unsafe
{
short* idxPtr = (short*)idx.ToPointer();
int count = 0;
for ( int j = north; j < this.size - 1 - south; j += step )
{
for ( int i = west; i < this.size - 1 - east; i += step )
{
//triangles
idxPtr[ count++ ] = this.GetIndex( i, j );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( i, j + step );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( i + step, j );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( i, j + step );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( i + step, j + step );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( i + step, j );
numIndexes++;
}
}
int substep = step << 1;
if ( west > 0 )
{
for ( int j = 0; j < this.size - 1; j += substep )
{
//skip the first bit of the corner if the north side is a different level as well.
if ( j > 0 || north == 0 )
{
idxPtr[ count++ ] = this.GetIndex( 0, j );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( step, j + step );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( step, j );
numIndexes++;
}
idxPtr[ count++ ] = this.GetIndex( step, j + step );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( 0, j );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( 0, j + step + step );
numIndexes++;
if ( j < this.options.size - 1 - substep || south == 0 )
{
idxPtr[ count++ ] = this.GetIndex( step, j + step );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( 0, j + step + step );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( step, j + step + step );
numIndexes++;
}
}
}
if ( east > 0 )
{
int x = this.options.size - 1;
for ( int j = 0; j < this.size - 1; j += substep )
{
//skip the first bit of the corner if the north side is a different level as well.
if ( j > 0 || north == 0 )
{
idxPtr[ count++ ] = this.GetIndex( x, j );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( x - step, j );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( x - step, j + step );
numIndexes++;
}
idxPtr[ count++ ] = this.GetIndex( x, j );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( x - step, j + step );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( x, j + step + step );
numIndexes++;
if ( j < this.options.size - 1 - substep || south == 0 )
{
idxPtr[ count++ ] = this.GetIndex( x, j + step + step );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( x - step, j + step );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( x - step, j + step + step );
numIndexes++;
}
}
}
if ( south > 0 )
{
int x = this.options.size - 1;
for ( int j = 0; j < this.size - 1; j += substep )
{
//skip the first bit of the corner if the north side is a different level as well.
if ( j > 0 || west == 0 )
{
idxPtr[ count++ ] = this.GetIndex( j, x - step );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( j, x );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( j + step, x - step );
numIndexes++;
}
idxPtr[ count++ ] = this.GetIndex( j + step, x - step );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( j, x );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( j + step + step, x );
numIndexes++;
if ( j < this.options.size - 1 - substep || east == 0 )
{
idxPtr[ count++ ] = this.GetIndex( j + step, x - step );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( j + step + step, x );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( j + step + step, x - step );
numIndexes++;
}
}
}
if ( north > 0 )
{
for ( int j = 0; j < this.size - 1; j += substep )
{
//skip the first bit of the corner if the north side is a different level as well.
if ( j > 0 || west == 0 )
{
idxPtr[ count++ ] = this.GetIndex( j, 0 );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( j, step );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( j + step, step );
numIndexes++;
}
idxPtr[ count++ ] = this.GetIndex( j, 0 );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( j + step, step );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( j + step + step, 0 );
numIndexes++;
if ( j < this.options.size - 1 - substep || east == 0 )
{
idxPtr[ count++ ] = this.GetIndex( j + step + step, 0 );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( j + step, step );
numIndexes++;
idxPtr[ count++ ] = this.GetIndex( j + step + step, step );
numIndexes++;
}
}
}
}
indexData.indexBuffer.Unlock();
indexData.indexCount = numIndexes;
indexData.indexStart = 0;
this.levelIndex[ this.renderLevel, indexArray ] = indexData;
}
return indexData;
}