public Result LoadFromFile(string filename) { try { _heightMap = new float[_size.X * _size.Y]; ReleaseCom(HeightMapTexture); HeightMapTexture = Texture.FromFile(_device, filename, _size.X, _size.Y, 1, Usage.Dynamic, Format.L8, Pool.Default, Filter.Default, Filter.Default, 0); var dr = HeightMapTexture.LockRectangle(0, LockFlags.None); for (var y = 0; y < _size.Y; y++) { for (var x = 0; x < _size.X; x++) { dr.Data.Seek(y * dr.Pitch + x, SeekOrigin.Begin); var b = dr.Data.Read <byte>(); _heightMap[x + y * _size.X] = b / 255.0f * _maxHeight; } } HeightMapTexture.UnlockRectangle(0); } catch (Exception ex) { Debug.Print("Error in {0} - {1}\n{2}", ex.TargetSite, ex.Message, ex.StackTrace); return(ResultCode.Failure); } return(ResultCode.Success); }
protected virtual void BuildData() { ClearData(); if (string.IsNullOrEmpty(HeightMap)) { HeightMapTexture = new Texture2D(Game.GraphicsDevice, 255, 255); List <Color> blankMap = new List <Color>(); for (int c = 0; c < 255 * 255; c++) { blankMap.Add(Color.TransparentBlack); } HeightMapTexture.SetData(blankMap.ToArray()); } else { HeightMapTexture = Game.Content.Load <Texture2D>(HeightMap); } if (Width != Height) { throw new Exception("Terrain height Map MUST be square and power of two..."); } Color[] mapHeightData = new Color[Width * Height]; HeightMapTexture.GetData(mapHeightData); // Find height map range float min, max; min = float.MaxValue; max = float.MinValue; heightData = new float[Width * Height]; for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { heightData[y + x * Width] = mapHeightData[y + x * Width].ToVector3().Y; if (heightData[y + x * Width] < min) { min = heightData[y + x * Width]; } if (heightData[y + x * Width] > max) { max = heightData[y + x * Width]; } } } // Average for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { heightData[y + x * Width] = (heightData[y + x * Width]) / ((max - min) + 1); } } int[] index = new int[(Width - 1) * (Height - 1) * 6]; Vector2 uv = Vector2.Zero; center = new Vector3(Width, (HeightMax - HeightMin) * .5f, Height) * .5f; float hmod = 1f / Width; for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { float h = MathHelper.Lerp(HeightMin, HeightMax, heightData[y + x * Width]);// + MathHelper.Lerp(-hmod, hmod, (float)rnd.NextDouble()); heightData[y + x * Width] = h; //h = data[y + x * Width]; uv = new Vector2(x, y) / (float)(Height - 1); VertexList.Add(new Vector3(x, h, y) - center); NormalList.Add(Vector3.Zero); TexCoordList.Add(uv); TangentList.Add(Vector3.Zero); ColorList.Add(Color.White); } } for (int x = 0; x < Width - 1; x++) { for (int y = 0; y < Height - 1; y++) { index[(x + y * (Width - 1)) * 6] = ((x + 1) + (y + 1) * Height); index[(x + y * (Width - 1)) * 6 + 1] = ((x + 1) + y * Height); index[(x + y * (Width - 1)) * 6 + 2] = (x + y * Height); index[(x + y * (Width - 1)) * 6 + 3] = ((x + 1) + (y + 1) * Height); index[(x + y * (Width - 1)) * 6 + 4] = (x + y * Height); index[(x + y * (Width - 1)) * 6 + 5] = (x + (y + 1) * Height); } } IndexList.AddRange(index); // Calculate tangents for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { if (x != 0 && x < Width - 1) { TangentList[x + y * Width] = VertexList[x - 1 + y * Width] - VertexList[x + 1 + y * Width]; } else if (x == 0) { TangentList[x + y * Width] = VertexList[x + y * Width] - VertexList[x + 1 + y * Width]; } else { TangentList[x + y * Width] = VertexList[x - 1 + y * Width] - VertexList[x + y * Width]; } } } // Calculate Normals for (int i = 0; i < NormalList.Count; i++) { NormalList[i] = new Vector3(0, 0, 0); } for (int i = 0; i < index.Length / 3; i++) { int index1 = index[i * 3]; int index2 = index[i * 3 + 1]; int index3 = index[i * 3 + 2]; Vector3 side1 = VertexList[index1] - VertexList[index3]; Vector3 side2 = VertexList[index1] - VertexList[index2]; Vector3 normal = Vector3.Cross(side1, side2); NormalList[index1] += normal; NormalList[index2] += normal; NormalList[index3] += normal; } for (int i = 0; i < NormalList.Count; i++) { NormalList[i] = Vector3.Normalize(NormalList[i]); } BuildSplatMap(); }