public static void ExtrudeVertices( HardwareVertexBuffer vertexBuffer, int originalVertexCount, Vector4 lightPosition, float extrudeDistance )
{
unsafe
{
Debug.Assert( vertexBuffer.VertexSize == sizeof( float ) * 3, "Position buffer should contain only positions!" );
// Extrude the first area of the buffer into the second area
// Lock the entire buffer for writing, even though we'll only be
// updating the latter because you can't have 2 locks on the same
// buffer
IntPtr srcPtr = vertexBuffer.Lock( BufferLocking.Normal );
IntPtr destPtr = new IntPtr( srcPtr.ToInt64() + ( originalVertexCount * 3 * 4 ) );
float* pSrc = (float*)srcPtr.ToPointer();
float* pDest = (float*)destPtr.ToPointer();
int destCount = 0, srcCount = 0;
// Assume directional light, extrusion is along light direction
Vector3 extrusionDir = new Vector3( -lightPosition.x, -lightPosition.y, -lightPosition.z );
extrusionDir.Normalize();
extrusionDir *= extrudeDistance;
for ( int vert = 0; vert < originalVertexCount; vert++ )
{
if ( lightPosition.w != 0.0f )
{
// Point light, adjust extrusionDir
extrusionDir.x = pSrc[ srcCount + 0 ] - lightPosition.x;
extrusionDir.y = pSrc[ srcCount + 1 ] - lightPosition.y;
extrusionDir.z = pSrc[ srcCount + 2 ] - lightPosition.z;
extrusionDir.Normalize();
extrusionDir *= extrudeDistance;
}
pDest[ destCount++ ] = pSrc[ srcCount++ ] + extrusionDir.x;
pDest[ destCount++ ] = pSrc[ srcCount++ ] + extrusionDir.y;
pDest[ destCount++ ] = pSrc[ srcCount++ ] + extrusionDir.z;
}
}
vertexBuffer.Unlock();
}