Загрузка карты высот из BMP

Программирование на Юнити.

Загрузка карты высот из BMP

Сообщение StalkerOnix 13 фев 2012, 12:37

Помогите, как открыть файл bmp с картой высот, чтобы затем с помощью функциии terrainData.SetHeights можно было посторить нужную местность.
StalkerOnix
UNец
 
Сообщения: 10
Зарегистрирован: 13 фев 2012, 10:28

Re: Загрузка карты высот из BMP

Сообщение StalkerOnix 13 фев 2012, 14:15

Пробовал считать побайтно, но строит ровную поверхность:
Синтаксис:
Используется csharp
        void Start () {
                Terrain t = GetComponent<Terrain>();
                Vector3 sz = new Vector3(2000, 100, 2000);
                t.terrainData.size=sz;
                t.terrainData.heightmapResolution=513;
        float[,] heights = new float[512, 512]; // Создаём участок поверхности размером 512x512
                byte[] byData = new byte [512];

                // чтение фала карты высот
                string filename="Maps\\mapheigth.bmp";
                FileInfo maps = new FileInfo(filename);
                FileStream fstr = maps.OpenRead();
                fstr.Seek (1024, SeekOrigin.Begin);

                for (int y=0; y<heights.GetLength(0); y++) {
                        fstr.Read(byData, 0, 512);
                for (int x = 0; x < heights.GetLength(1); x++) {
                    heights[y, x] = byData[x];

                        }      
                }
                fstr.Close();
         t.terrainData.SetHeights(0, 0, heights); // Засовываем этот участок в карту высот Terrain'а в позицию (0; 0)
 
StalkerOnix
UNец
 
Сообщения: 10
Зарегистрирован: 13 фев 2012, 10:28

Re: Загрузка карты высот из BMP

Сообщение DanielDem 13 фев 2012, 18:21

Как то ты странно считаешь файл BMP у него свой формат...
Чтот я сегодня добрый

Вот функция для загрузки из обычного RAW
Синтаксис:
Используется csharp
            //-------------------------------------------------------------------------------------
            /// <summary>
            /// Загрузка карты высоты с файла формата RAW.
            /// </summary>
            /// <param name="file_name">Имя файла</param>
            /// <param name="use_16bit">Кодировка файла</param>
            //-------------------------------------------------------------------------------------
            public void LoadHeightMapRAW(String file_name, Boolean use_16bit)
            {
                if (use_16bit)
                {
                    Byte[,] data = DispatcherFiles.ReadRawFile8Bit(file_name);

                    if (data != null)
                    {
                        Int32 size_h = data.GetUpperBound(0);

                        if (size_h != mTerrainData.heightmapResolution)
                        {
                            Debug.LogError("Ошибка в загрузке карты высот. Загружен размер <" +
                                size_h.ToString() + ">. Требуется размер <" + mTerrainData.heightmapResolution + ">");
                            return;
                        }

                        Single[,] heights = mTerrainData.GetHeights(0, 0, mTerrainData.heightmapResolution, mTerrainData.heightmapResolution);

                        for (Int32 y = 0; y < mTerrainData.heightmapResolution; y++)
                        {
                            for (Int32 x = 0; x < mTerrainData.heightmapResolution; x++)
                            {
                                heights[(mTerrainData.heightmapResolution - 1) - y, x] = (((Single)(data[x, y])) / 255.0f);
                            }
                        }

                        mTerrainData.SetHeights(0, 0, heights);
                    }
                }
                else
                {
                    UInt16[,] data = DispatcherFiles.ReadRawFile16Bit(file_name);

                    if (data != null)
                    {
                        Int32 size_h = data.GetUpperBound(0);

                        if (size_h != mTerrainData.heightmapResolution)
                        {
                            Debug.LogError("Ошибка в загрузке карты высот. Загружен размер <" +
                                size_h.ToString() + ">. Требуется размер <" + mTerrainData.heightmapResolution + ">");
                            return;
                        }

                        Single[,] heights = mTerrainData.GetHeights(0, 0, mTerrainData.heightmapResolution, mTerrainData.heightmapResolution);

                        for (Int32 y = 0; y < mTerrainData.heightmapResolution; y++)
                        {
                            for (Int32 x = 0; x < mTerrainData.heightmapResolution; x++)
                            {
                                heights[(mTerrainData.heightmapResolution - 1) - y, x] = (((Single)(data[x, y])) / 65535.0f);
                            }
                        }

                        mTerrainData.SetHeights(0, 0, heights);
                    }
                }
            }
 


При это загружается карта высот так что если на ландшафт смотреть сверху (Top) то будет полность сходится с картой высот
Собвенно методы загрузки данных
Синтаксис:
Используется csharp
            //-------------------------------------------------------------------------------------
            /// <summary>
            /// Чтение данных 8-битного формата RAW.
            /// </summary>
            /// <param name="file_name">Имя файла</param>
            /// <returns>Двухмерный массив байтов</returns>
            //-------------------------------------------------------------------------------------
            static public Byte[,] ReadRawFile8Bit(String file_name)
            {
                Byte[,] data = null;

                // Читаем файл
                try
                    {          
                            Byte[] data_file = File.ReadAllBytes(file_name);
                   
                    // Проверка на квадратичность
                    Int32 side = (Int32)Math.Sqrt(data_file.Length);
                    if(!(side == 257 || side == 513 || side == 1025 || side == 2049))
                    {
                        Debug.LogError("Файл <" + file_name + "> имеет неправильный размер. Текущий размер <" + side.ToString() + ">");
                        return (data);
                    }

                    // Преобразуем в двухмерный массив
                    data = new Byte[side, side];
                    for (Int32 y = 0; y < side; y++)
                    {
                        for (Int32 x = 0; x < side; x++)
                        {
                            data[x, y] = data_file[x + y * (side)];
                        }
                    }

                    return (data);
                   
                    }
                    catch (Exception exс)
                {
                    Debug.LogError("Ошибка чтения данных файла <" + file_name + ">. Исключение <" + exс.Message + ">");
                    }
               
                return (data);
            }

            //-------------------------------------------------------------------------------------
            /// <summary>
            /// Чтение данных 16-битного формата RAW.
            /// </summary>
            /// <param name="file_name">Имя файла</param>
            /// <returns>Двухмерный массив слов</returns>
            //-------------------------------------------------------------------------------------
            static public UInt16[,] ReadRawFile16Bit(String file_name)
            {
                UInt16[,] data = null;

                // Читаем файл
                try
                {
                    // Открываем поток
                    FileStream file_stream = new FileStream(file_name, FileMode.Open);
                    BinaryReader binary_reader = new BinaryReader(file_stream);

                    // Проверка на квадратичность
                    Int32 side = (Int32)Math.Sqrt(file_stream.Length / 2);
                    if (!(side == 257 || side == 513 || side == 1025 || side == 2049))
                    {
                        Debug.LogError("Файл <" + file_name + "> имеет неправильный размер. Текущий размер <" + side.ToString() + ">");

                        if (file_stream != null)
                        {
                            file_stream.Close();
                        }

                        if (binary_reader != null)
                        {
                            binary_reader.Close();
                        }

                        return (data);
                    }

                    // Преобразуем в двухмерный массив
                    data = new UInt16[side, side];
                    for (Int32 y = 0; y < side; y++)
                    {
                        for (Int32 x = 0; x < side; x++)
                        {
                            data[x, y] = binary_reader.ReadUInt16();
                        }
                    }

                    // Закрываем поток
                    file_stream.Close();
                    binary_reader.Close();

                    return (data);

                }
                catch (Exception exс)
                {
                    Debug.LogError("Ошибка чтения данных файла <" + file_name + ">. Исключение <" + exс.Message + ">");
                }

                return (data);
            }
 
Да прибудет с Вами сила...
Аватара пользователя
DanielDem
UNITрон
 
Сообщения: 174
Зарегистрирован: 07 янв 2010, 13:27
Откуда: Россия
  • ICQ

Re: Загрузка карты высот из BMP

Сообщение StalkerOnix 14 фев 2012, 08:46

Большое спасибо, всё работает, надо ещё поковырять чтобы можно было загружать из BMP
StalkerOnix
UNец
 
Сообщения: 10
Зарегистрирован: 13 фев 2012, 10:28

Re: Загрузка карты высот из BMP

Сообщение DanielDem 14 фев 2012, 12:00

Это сложный формат. Если просто то можно через System.Drawning
вот я код загрузки в Texture2D, но думаю принцип поймеш
Синтаксис:
Используется csharp
                        //-------------------------------------------------------------------------------------
                        /// <summary>
                        /// Загрузка текстуры из объекта типа System.Drawing.Bitmap.
                        /// </summary>
                        /// <param name="bitmap">Объект типа System.Drawing.Bitmap</param>
                        /// <returns>Текстура</returns>
                        //-------------------------------------------------------------------------------------
                        public static Texture2D LoadFromBitmap(System.Drawing.Bitmap bitmap)
                        {
                                Texture2D texture = new Texture2D(bitmap.Width, bitmap.Height);
                                for (Int32 y = 0; y < bitmap.Height; y++)
                                {
                                        for (Int32 x = 0; x < bitmap.Width; x++)
                                        {
                                                System.Drawing.Color cld = bitmap.GetPixel(x, y);
                                                Color cl = new Color(((Single)cld.R) / 255.0f,
                                                        ((Single)cld.G) / 255.0f,
                                                        ((Single)cld.B) / 255.0f,
                                                        ((Single)cld.A) / 255.0f);
                                                texture.SetPixel(x, y, cl);
                                        }
                                }

                                // Применяем изменения
                                texture.Apply();

                                return(texture);
                        }      
 
Да прибудет с Вами сила...
Аватара пользователя
DanielDem
UNITрон
 
Сообщения: 174
Зарегистрирован: 07 янв 2010, 13:27
Откуда: Россия
  • ICQ

Re: Загрузка карты высот из BMP

Сообщение StalkerOnix 03 апр 2012, 16:01

Использовал загрузку из BMP в редакторе всё работает, а при запуске скомпилнного проекта выдаётся ошибка:
TypeLoadException: Could not load type 'System.IO.InternalBufferOverflowException' from assembly 'System.Drawing'.
at System.Drawing.Bitmap..ctor (System.String filename, Boolean useIcm) [0x00000] in <filename unknown>:0
at System.Drawing.Bitmap..ctor (System.String filename) [0x00000] in <filename unknown>:0
at (wrapper remoting-invoke-with-check) System.Drawing.Bitmap:.ctor (string)
at Main.LoadFromBitmap (System.String bitname) [0x00000] in <filename unknown>:0
at Main.Start () [0x00000] in <filename unknown>:0

System.Drawing поместил в папку Plugins.
никак не пойму что такое
StalkerOnix
UNец
 
Сообщения: 10
Зарегистрирован: 13 фев 2012, 10:28

Re: Загрузка карты высот из BMP

Сообщение StalkerOnix 04 апр 2012, 07:11

Нашёл выход, правда не знаю корректно ли это, в настройках плеера перед билдом в "Other Settings" параметр "Api Compatibility Level" изменил с ".NET 2.0 Subset" на ".NET 2.0"
StalkerOnix
UNец
 
Сообщения: 10
Зарегистрирован: 13 фев 2012, 10:28


Вернуться в Скрипты

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 9