public void Init( TerrainOptions options )
{
this.options = options;
numMipMaps = options.maxMipmap;
size = options.size;
terrain = new VertexData();
terrain.vertexStart = 0;
terrain.vertexCount = options.size * options.size;
VertexDeclaration decl = terrain.vertexDeclaration;
VertexBufferBinding binding = terrain.vertexBufferBinding;
int offset = 0;
// Position/Normal
decl.AddElement( POSITION, 0, VertexElementType.Float3, VertexElementSemantic.Position );
decl.AddElement( NORMAL, 0, VertexElementType.Float3, VertexElementSemantic.Normal );
// TexCoords
decl.AddElement( TEXCOORD, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0 );
offset += VertexElement.GetTypeSize( VertexElementType.Float2 );
decl.AddElement( TEXCOORD, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 1 );
offset += VertexElement.GetTypeSize( VertexElementType.Float2 );
// TODO: Color
HardwareVertexBuffer buffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl.Clone( POSITION ), terrain.vertexCount, BufferUsage.StaticWriteOnly, true );
binding.SetBinding( POSITION, buffer );
buffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl.Clone( NORMAL ), terrain.vertexCount, BufferUsage.StaticWriteOnly, true );
binding.SetBinding( NORMAL, buffer );
buffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl.Clone( TEXCOORD ), terrain.vertexCount, BufferUsage.StaticWriteOnly, true );
binding.SetBinding( TEXCOORD, buffer );
minLevelDistSqr = new float[ numMipMaps ];
int endx = options.startx + options.size;
int endz = options.startz + options.size;
// TODO: name buffers different so we can unlock
HardwareVertexBuffer posBuffer = binding.GetBuffer( POSITION );
IntPtr pos = posBuffer.Lock( BufferLocking.Discard );
HardwareVertexBuffer texBuffer = binding.GetBuffer( TEXCOORD );
IntPtr tex = texBuffer.Lock( BufferLocking.Discard );
float min = 99999999, max = 0;
unsafe
{
float* posPtr = (float*)pos.ToPointer();
float* texPtr = (float*)tex.ToPointer();
int posCount = 0;
int texCount = 0;
for ( int j = options.startz; j < endz; j++ )
{
for ( int i = options.startx; i < endx; i++ )
{
float height = options.GetWorldHeight( i, j ) * options.scaley;
posPtr[ posCount++ ] = i * options.scalex;
posPtr[ posCount++ ] = height;
posPtr[ posCount++ ] = j * options.scalez;
texPtr[ texCount++ ] = (float)i / options.worldSize;
texPtr[ texCount++ ] = (float)j / options.worldSize;
texPtr[ texCount++ ] = ( (float)i / options.size ) * options.detailTile;
texPtr[ texCount++ ] = ( (float)j / options.size ) * options.detailTile;
if ( height < min )
{
min = height;
}
if ( height > max )
{
max = height;
}
} // for i
} // for j
} // unsafe
// unlock the buffers
posBuffer.Unlock();
texBuffer.Unlock();
box.SetExtents(
new Vector3( options.startx * options.scalex, min, options.startz * options.scalez ),
new Vector3( ( endx - 1 ) * options.scalex, max, ( endz - 1 ) * options.scalez ) );
center = new Vector3( ( options.startx * options.scalex + endx - 1 ) / 2,
( min + max ) / 2,
( options.startz * options.scalez + endz - 1 ) / 2 );
float C = CalculateCFactor();
CalculateMinLevelDist2( C );
}