//    Correct normal calculations
        //http://www.gamedev.net/reference/articles/article2264.asp
        public unsafe void Build( TerrainPatchBuilder builder )
        {
            using ( IVertexBufferLock vbLock = m_VbRange.Lock( ) )
            {
                m_IndexBuffer = BuildIndexBuffer( );
                TerrainVertex* firstVertex = ( TerrainVertex* )vbLock.Bytes;
                TerrainVertex* curVertex = firstVertex;

                Vector3 xInc = m_PatchXDir * ( m_PatchWidth / ( m_Size - 1 ) );
                Vector3 zInc = m_PatchZDir * ( m_PatchHeight / ( m_Size - 1 ) );

                Point3 rowStart = m_TopLeft;
                for ( int row = 0; row < m_Size; ++row )
                {
                    Point3 curPt = rowStart;
                    for ( int col = 0; col < m_Size; ++col )
                    {
                        Vector3 rlVec = ( curPt - Point3.Origin ).MakeNormal( );
                        Point3 rlPt = Point3.Origin + rlVec * 2;
                        float ptHeight = ( TestNoisePlanetTerrainGenerator.TerrainHeight( rlPt.X, rlPt.Y, rlPt.Z ) - 0.5f ) * 16.0f;
                        rlPt = Point3.Origin + rlVec * ( PlanetRadius + ptHeight );

                        curVertex->SetPosition( rlPt.X, rlPt.Y, rlPt.Z );
                        ++curVertex;
                        curPt += xInc;
                    }

                    rowStart += zInc;
                }

                for ( int row = 0; row < m_Size - 1; ++row )
                {
                    curVertex = firstVertex + ( row * m_Size );
                    for ( int col = 0; col < m_Size - 1; ++col )
                    {
                        Point3 pt0 = curVertex->Position;
                        Point3 pt1 = ( curVertex + m_Size )->Position;
                        Point3 pt2 = ( curVertex + 1 )->Position;
                        Vector3 vec = Vector3.Cross( pt1 - pt0, pt2 - pt0 ).MakeNormal( );

                        //	TODO: Make correct normal calculation
                        curVertex->SetNormal( vec.X, vec.Y, vec.Z );
                        ++curVertex;
                    }
                }
            }
        }
 public void PreBuild( TerrainPatchBuilder builder )
 {
     DestroyIndexBuffer( );
     m_VbRange = builder.AllocatePatchVertices( m_Lod );
     m_Size = TerrainPatchBuilder.GetLevelSize( m_Lod );
     m_Offset = m_VbRange.FirstVertexOffset;
 }
 /// <summary>
 /// Pre-builds all terrain patches in this side
 /// </summary>
 public void PreBuild( TerrainPatchBuilder builder )
 {
     foreach ( TerrainPatch patch in TerrainPatches )
     {
         patch.PreBuild( builder );
     }
 }