Пример #1
0
        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();
        }