public float GetHeightAt( float x, float z )
{
Vector3 start, end;
start.x = GetVertex( 0, 0, 0 );
start.y = GetVertex( 0, 0, 1 );
start.z = GetVertex( 0, 0, 2 );
end.x = GetVertex( options.size - 1, options.size - 1, 0 );
end.y = GetVertex( options.size - 1, options.size - 1, 1 );
end.z = GetVertex( options.size - 1, options.size - 1, 2 );
// safety catch. if the point asked for is outside of this tile, ask a neighbor
if ( x < start.x )
{
if ( GetNeighbor( Neighbor.West ) != null )
{
return GetNeighbor( Neighbor.West ).GetHeightAt( x, z );
}
else
{
x = start.x;
}
}
if ( x > end.x )
{
if ( GetNeighbor( Neighbor.East ) != null )
{
return GetNeighbor( Neighbor.East ).GetHeightAt( x, z );
}
else
{
x = end.x;
}
}
if ( z < start.z )
{
if ( GetNeighbor( Neighbor.North ) != null )
{
return GetNeighbor( Neighbor.North ).GetHeightAt( x, z );
}
else
{
z = start.z;
}
}
if ( z > end.z )
{
if ( GetNeighbor( Neighbor.South ) != null )
{
return GetNeighbor( Neighbor.South ).GetHeightAt( x, z );
}
else
{
z = end.z;
}
}
float xPct = ( x - start.x ) / ( end.x - start.x );
float zPct = ( z - start.z ) / ( end.z - start.z );
float xPt = xPct * (float)( options.size - 1 );
float zPt = zPct * (float)( options.size - 1 );
int xIndex = (int)xPt;
int zIndex = (int)zPt;
xPct = xPt - xIndex;
zPct = zPt - zIndex;
// bilinear interpolcation to find the height
float t1 = GetVertex( xIndex, zIndex, 1 );
float t2 = GetVertex( xIndex + 1, zIndex, 1 );
float b1 = GetVertex( xIndex, zIndex + 1, 1 );
float b2 = GetVertex( xIndex + 1, zIndex + 1, 1 );
float midpoint = ( b1 + b2 ) / 2;
if ( ( xPct + zPct ) <= 1 )
{
b2 = midpoint + ( midpoint - t1 );
}
else
{
t1 = midpoint + ( midpoint - b2 );
}
float t = ( t1 * ( 1 - xPct ) ) + ( t2 * ( xPct ) );
float b = ( b1 * ( 1 - xPct ) ) + ( b2 * ( xPct ) );
float h = ( t * ( 1 - zPct ) ) + ( b * ( zPct ) );
return h;
}