// 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 ); } }