/// <summary> /// Gets a normal vector for a given x, z coordinate and the corresponding heightmap /// </summary> /// <param name="heightMap"></param> /// <param name="x"></param> /// <param name="z"></param> /// <returns></returns> private static Vector4 GetNormalVector(HeightMap heightMap, int x, int z) { var currentP = new Vector3(x, heightMap.GetHeight(x, z), z); Vector3 p1; Vector3 p2; if (x == heightMap.Size - 1 && z == heightMap.Size - 1) // Bottom right pixel { p1 = new Vector3(x, heightMap.GetHeight(x, z - 1), z - 1); p2 = new Vector3(x - 1, heightMap.GetHeight(x - 1, z), z); } else if (x == heightMap.Size - 1) // Right border { p1 = new Vector3(x - 1, heightMap.GetHeight(x - 1, z), z); p2 = new Vector3(x, heightMap.GetHeight(x, z + 1), z + 1); } else if (z == heightMap.Size - 1) // Bottom border { p1 = new Vector3(x + 1, heightMap.GetHeight(x + 1, z), z); p2 = new Vector3(x, heightMap.GetHeight(x, z - 1), z - 1); } else // The rest of pixels { p1 = new Vector3(x, heightMap.GetHeight(x, z + 1), z + 1); p2 = new Vector3(x + 1, heightMap.GetHeight(x + 1, z), z); } return(new Vector4(Vector3.Normalize(Vector3.Cross(p1 - currentP, p2 - currentP)), 1)); }
/// <summary> /// Initializes Vertex buffer data by a given height map /// </summary> /// <param name="heightMap"></param> /// <param name="vertexBuffer"></param> private static unsafe void SetVertexDataFromHeightMap(HeightMap heightMap, IntPtr vertexBuffer) { var vb = (VertexNormalTexture *)vertexBuffer; var halfSize = heightMap.Size * 0.5f; for (var iZ = 0; iZ < heightMap.Size; ++iZ) { for (var iX = 0; iX < heightMap.Size; ++iX) { vb[iZ * heightMap.Size + iX] = new VertexNormalTexture { Position = new Vector4(iX - halfSize, heightMap.GetHeight(iX, iZ), -iZ + halfSize, 1), Normal = GetNormalVector(heightMap, iX, iZ), TextureCoordinate = new Vector2((float)iX / heightMap.Size, (float)iZ / heightMap.Size) }; } } }
/// <summary> /// Gets a normal vector for a given x, z coordinate and the corresponding heightmap /// </summary> /// <param name="heightMap"></param> /// <param name="x"></param> /// <param name="z"></param> /// <returns></returns> private static Vector4 GetNormalVector(HeightMap heightMap, int x, int z) { var currentP = new Vector3(x, heightMap.GetHeight(x, z), z); Vector3 p1; Vector3 p2; if (x == heightMap.Size - 1 && z == heightMap.Size - 1) // Bottom right pixel { p1 = new Vector3(x, heightMap.GetHeight(x, z - 1), z - 1); p2 = new Vector3(x - 1, heightMap.GetHeight(x - 1, z), z); } else if (x == heightMap.Size - 1) // Right border { p1 = new Vector3(x - 1, heightMap.GetHeight(x - 1, z), z); p2 = new Vector3(x, heightMap.GetHeight(x, z + 1), z + 1); } else if (z == heightMap.Size - 1) // Bottom border { p1 = new Vector3(x + 1, heightMap.GetHeight(x + 1, z), z); p2 = new Vector3(x, heightMap.GetHeight(x, z - 1), z - 1); } else // The rest of pixels { p1 = new Vector3(x, heightMap.GetHeight(x, z + 1), z + 1); p2 = new Vector3(x + 1, heightMap.GetHeight(x + 1, z), z); } return new Vector4(Vector3.Normalize(Vector3.Cross(p1 - currentP, p2 - currentP)), 1); }
/// <summary> /// Initializes Vertex buffer data by a given height map /// </summary> /// <param name="heightMap"></param> /// <param name="vertexBuffer"></param> private static unsafe void SetVertexDataFromHeightMap(HeightMap heightMap, IntPtr vertexBuffer) { var vb = (VertexNormalTexture*)vertexBuffer; var halfSize = heightMap.Size * 0.5f; for (var iZ = 0; iZ < heightMap.Size; ++iZ) for (var iX = 0; iX < heightMap.Size; ++iX) { vb[iZ * heightMap.Size + iX] = new VertexNormalTexture { Position = new Vector4(iX - halfSize, heightMap.GetHeight(iX, iZ), -iZ + halfSize, 1), Normal = GetNormalVector(heightMap, iX, iZ), TextureCoordinate = new Vector2((float)iX / heightMap.Size, (float)iZ / heightMap.Size) }; } }