private void _generateCurvedPlaneVertexData( HardwareVertexBuffer vbuf, int ySegments, int xSegments, float xSpace, float halfWidth, float ySpace, float halfHeight, Matrix4 transform, bool firstTime, bool normals, Matrix4 rotation, float curvature, int numTexCoordSets, float xTexCoord, float yTexCoord, SubMesh subMesh, ref Vector3 min, ref Vector3 max, ref float maxSquaredLength )
{
Vector3 vec;
unsafe
{
// lock the vertex buffer
IntPtr data = vbuf.Lock( BufferLocking.Discard );
float* pData = (float*)data.ToPointer();
for ( int y = 0; y <= ySegments; y++ )
{
for ( int x = 0; x <= xSegments; x++ )
{
// centered on origin
vec.x = ( x * xSpace ) - halfWidth;
vec.y = ( y * ySpace ) - halfHeight;
// Here's where curved plane is different from standard plane. Amazing, I know.
Real diff_x = ( x - ( (Real)xSegments / 2 ) ) / (Real)xSegments;
Real diff_y = ( y - ( (Real)ySegments / 2 ) ) / (Real)ySegments;
Real dist = Utility.Sqrt( diff_x * diff_x + diff_y * diff_y );
vec.z = ( -Utility.Sin( ( 1 - dist ) * ( Utility.PI / 2 ) ) * curvature ) + curvature;
// Transform by orientation and distance
Vector3 pos = transform.TransformAffine( vec );
*pData++ = pos.x;
*pData++ = pos.y;
*pData++ = pos.z;
// Build bounds as we go
if ( firstTime )
{
min = vec;
max = vec;
maxSquaredLength = vec.LengthSquared;
firstTime = false;
}
else
{
min.Floor( vec );
max.Ceil( vec );
maxSquaredLength = Utility.Max( maxSquaredLength, vec.LengthSquared );
}
if ( normals )
{
// This part is kinda 'wrong' for curved planes... but curved planes are
// very valuable outside sky planes, which don't typically need normals
// so I'm not going to mess with it for now.
// Default normal is along unit Z
//vec = Vector3::UNIT_Z;
// Rotate
vec = rotation.TransformAffine( vec );
*pData++ = vec.x;
*pData++ = vec.y;
*pData++ = vec.z;
}
for ( int i = 0; i < numTexCoordSets; i++ )
{
*pData++ = x * xTexCoord;
*pData++ = 1 - ( y * yTexCoord );
} // for texCoords
} // for x
} // for y
// unlock the buffer
vbuf.Unlock();
subMesh.useSharedVertices = true;
} // unsafe
}