Перейти к содержимому


Свернуть чат Чат Открыть чат во всплывающем окне

Yakim (Watco... : (4 дней назад) :D
Yakim (Watco... : (4 дней назад) nope
Yandersen : (4 дней назад) Айаяй. Поди Якимко заспамил чат стикерами. :)
Yandersen : (4 дней назад) Да лан, тут каждый день кто-нить из админов заглядывает. Как пропустили?
Nextovoy : (5 дней назад) Я писал
Гость : (неделю назад) Сорьки, что так у нас. Чего три года так и не попытался в чат писнуть? :)
Nextovoy : (неделю назад) Спасибо
lz : (неделю назад) Активировал.
Гость : (2 недель назад) Активируйте его.
Гость : (2 недель назад) Мой профиль - Nextovoy
Гость : (2 недель назад) Написать в чат. Профиль в ручную админы активируют.
Гость : (2 недель назад) Ох уж эта дурацкая привычка писать всё раздельно засоряя чат. Это всё классно, конечно, но ребята, одменестраторы, так называемые. Третий год пытаюсь зарегистрироваться (буквально, третий) на этом форуме, но ПИСЬМО С ПОДТВЕРЖДЕНИЕМ НА ПОЧТУ ТАК И НЕ ПРИХОДИТ. Что делать?
Гость : (2 недель назад) Перешёл я всё же по ссылке Redoctor'a...
Гость : (2 недель назад) Пора уже M4
Гость : (2 недель назад) итак м3
lz : (2 недель назад) Мы тебе и тут передадим.
Гость : (2 недель назад) Зачем в телеграмме делать?!Я вот например не могу зайти,написать в чат,подписаться и не только у меня это.
Redoctor : (3 недель назад) https://vk.com/away....0_23001&cc_key=
Redoctor : (3 недель назад) Тогда в телеграмме в поисковике набери Механоиды 3
Гость : (3 недель назад) Не открывается.
Redoctor : (3 недель назад) https://t.me/mechanoids3 Для тех кто в танке.
Yakim (Watco... : (4 недель назад) КРУЗИИИС!!!11

Изображение
lz : (4 недель назад) КРУЗИС!
lz : (4 недель назад) ЗИС
lz : (4 недель назад) КРУ
Yakim (Watco... : (4 недель назад) Крузис и Королева тоже не в моем вкусе, а проигрывать нечего =D
lz : (4 недель назад) Конечно, полюбить - так королеву, проиграть - так миллион, сделать - так крузис.
smt005 : (4 недель назад) И от третьего лица тоже можно сделать простенькую игру. Простая игра это лучше чем ничего.
smt005 : (4 недель назад) А, ты хочеш что-бы хит был, с "Crysis" графоном и контентом на 100500 часов игры?
Yakim (Watco... : (4 недель назад) Ни топдовншутеры, ни стратежки)
Yakim (Watco... : (4 недель назад) Не, спасибо, не в моем вкусе=)
smt005 : (4 недель назад) Помнится за пару недель от скуки сделал. Делал по вечерам.
smt005 : (4 недель назад)
smt005 : (4 недель назад) Или например такое, только с моделями из игры -> https://youtu.be/RFDdN5dcX8s
smt005 : (4 недель назад) Yakim, да сами себя пните... :) Сделайте что-то, хотя бы уровня "Scrolling TopDown Shooter".
Yakim (Watco... : (12 Июнь 2018 - 22:17) так что, думаю завтра с утреца стартану марафон)
Yakim (Watco... : (12 Июнь 2018 - 22:15) хе-хе, не сомневайся, я в чате по уе уже поинтересовался, сказали обалденный сериал)))
Yandersen : (12 Июнь 2018 - 20:56) Оооооо, поди ща залипнет на пару дней, стопудофф. :)
Yakim (Watco... : (12 Июнь 2018 - 18:28) Окей гляну)
Yandersen : (12 Июнь 2018 - 16:23) Сериал Пространство посмотри. Не по части Мехов, просто шикарен, авось ману доставит.
Yakim (Watco... : (11 Июнь 2018 - 18:50) Дуст и ты уже закаленные и пустые, надож где-то ману доставать)))
Yakim (Watco... : (11 Июнь 2018 - 18:49) Думаю, кого быть пнуть, что-бы тот пнул в ответ да по сильнее.
Yakim (Watco... : (11 Июнь 2018 - 18:48) Давненько и не маленько хе-хе, делать нечего, прокрастинирую =)
Yandersen : (11 Июнь 2018 - 17:46) Якимка, ты там шо, упоролсо маленько? Чиво картинами опспамилсо?
Yakim (Watco... : (09 Июнь 2018 - 22:27) Изображение

Фотография
- - - - -

Локации из М2


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 30

#1 OFFLINE   Yandersen

Yandersen

    Диванный теоретик

  • Админ
  • 454 сообщений
  • Откуда:Canada
  • Настоящее имя:Ян

Отправлено 20 Июль 2014 - 17:24

Файлы игровых карт, использующиеся в М2, находятся в запакованном виде в архиве "AIM II//Data//AIMMMP.pak" (локации), "AIM II//Data//AIMMMM.pak" (миникарты локаций) и "AIM II//Data//AIMMMO.pak" (объекты на локации, настройки торговли, группы глайдеров и пр.).
Вот список карт и секторов, им соответствующих:

TRAINMAP - обучающий уровень
LOCATION1 - сектор Скал
LOCATION2 - сектор Тундры
LOCATION3 - сектор Арктики

LOCATION4 - сектор Вулканов
LOCATION5 - сектор Пустыни
LOCATION6 - сектор Холмов
LOCATION7 - сектор Болот (урезанная версия в М2)
LOCATION8 - Внешний Мир
LOCATION9 - Разрушенный сектор
LOCATION10 - Высотный сектор
LOCATION11 - сектор Ядовитых болот
LOCATION12 - Подземный сектор
LOCATION13 - Подземный завод
Вулканы и Внешний мир вырезаны из М2 полностью, а Упаковщик из меховского SDK не берёт архивы из первых Механоидов.

 

Файлы с расширением MMM - это миникарты. Файлы миникарт состоят из 16 байт шапки (int[4]={?.?,Width, Height}), а всё остальное - непрерывный массив сегментов миникарты (64 на 64 точки), каждый размером 4096 байт. Данные запакованы в формат DXT5.

 

Файлы с расширением ММО содержат в себе информацию об объектах карты, торговле, группах и пр.

 

Файл собственно карты (*.MMP) устроен следующим образом. Сначала идёт перечисление общих данных о карте - размеры, модель окружения, погодные режимы, описание воды и пр. Затем идёт массив описаний сегментов карты (76 байт на элемент). После этой "шапки" и до самого конца файла идёт собственно массив индивидуальных сегментов карты. Все сегменты имеют одинаковый размер (101928 байт на сегмент) и чёткую структуру данных. Каждый сегмент соответствует своему кусочку карты размером 64 на 64 квадратика, т.е. вершин в сегменте 65 на 65. Однако указанные в файле размеры карты не обязательно кратны числу "64*nSegments+1". Обычно указанные размеры карты немного меньше.

Вот такую структуру имеет каждый сегмент:

 

{4 byte} - UNKNOWN, always 0xFFFFFFFF;

{33*33*4*4 bytes} - data block #1 (offset=4), 4 images 33x33: 1st=heightmap, 2nd=color map, 3rd=UNKNOWN, 4th=UNKNOWN;

{65*65*4 bytes} - data block #2 (offset=17428), height map, float;

{65*65*4 bytes} - data block #3 (offset=34328), properties map, unsigned short[2] ([0] - tech info, [1] - texture index);

{65*65*4 bytes} - data block #4 (offset=51228), color map, unsigned char[4] (BGR, A not used);

{65*65*4 bytes} - data block #5 (offset=68128), shadow map, unsigned char[4];

{65*65*4 bytes} - data block #6 (offset=85028), normal map, signed short[2] (only 2 horizontal components);

 

Первый блок (block1) - это архаизм из М1, когда сегменты карты были в 2 раза меньше. Эти 4 карты размером 33х33 вершины не используются в М2, т.к. в новых картах block1 забит нулями или требухой.

 

Block2 - это карта высот в формате float.

 

Block3 хранит в себе 2 типа информации: первые 16 бит каждой точки являются bitfield'ом, биты которого являются флагами неких рендер-специфических аттрибутов. А вот вторые 16 бит (15 из них, т.к. верхний бит для вертикальных текстур выбирает одно из двух направлений проекции наложения) - это unsigned short int, идентификатор текстуры из db.dat. В базе данных указана картинка, тип наложения, камешки, травка и пр. В пример приведу идентификаторы, встречающиеся на карте Сектора Арктики и названия текстур из базы данных, которым эти идентификаторы соответствуют:

0 - нет текстуры
314 - LT_SNOW2
321 - LT_L3_SNOW_1
856 - LT_L4_ROAD
2034 - LT_L3_ROAD
2040 - LT_L3_SNOW_3
2044 - LT_L3_SNOW_2
2050 - LT_L3_ROCKS_V
2055 - LT_L3_SNOW_FOREST
2061 - LT_L3_ICE_BOLD
2065 - LT_L3_ICE_THIN
2070 - LT_L3_ICE_VERTICAL
2074 - LT_L3_LAND_DEAD
2076 - LT_L3_LAND_GRASS
2082 - LT_L3_LAND_GRASS_D
2091 - LT_L3_ROCKS_GAZER
2108 - LT_L3_LAND_DEAD_STONES
2155 - LT_L3_SNOW_MUSHROOM
2163 - LT_L3_SNOW_3_CHILLS
3390 - LT_UA_BASEMENT_WARNING
3398 - LT_UA_BRIDGE
3562 - LT_UA_BASEMENT_SIDE_SNOW
3570 - LT_UA_BASEMENT_TOP_SNOW

 

Block4 - это цветовая карта. Первый байт - интенсивность синего, второй байт - интенсивность зелёного, третий - красного, а вот четвёртый байт хранит требуху, гарантированно не используется.

 

Block5, карта теней, 4 канала. Интенсивность символизирует силу затенения. Каналы хранят в себе тени от ландшафта и объектов в разное время суток.

 

Block6 - две из трёх компонент вектора нормали (горизонтальные), в формате signed short int. Подразумевается, что третья компонента (вертикальная) всегда смотрит вверх.

 

 

 

Вот прога для экспорта данных из меховских карт в различных форматах (v0.7.0.1).

 

Вот её исходники для Borland Builder 6.

 

Прога позволяет вскрывать меховские *.MMP файлы карт и *.MMM файлы миникарт и экспортировать из них отдельные слои в оригинальном формате или конвертировать их в желаемый формат (*.* - данные сваливаются прямо в файл, *.bmp - в виде картинки, *.glt - текстура). Формат *.glt - это разработанный мною формат текстур для OpenGL. Тут для него можно скачать хеадер.



#2 OFFLINE   Yandersen

Yandersen

    Диванный теоретик

  • Админ
  • 454 сообщений
  • Откуда:Canada
  • Настоящее имя:Ян

Отправлено 21 Июль 2014 - 06:01

Вот как слои сектора Арктики выглядят в картиночной интерпретации:

LOCATION3_heightmap(normalized).jpg - Layer1, карта высот

LOCATION3_texturemap(translated).gif - Layer2, карта текстурных индексов

LOCATION3_colormap(24bpp).jpg - Layer3, карта цвета

LOCATION3_lightmap(shadowmap0).jpg - Layer4, карта теней (один из каналов)

LOCATION3_bumpmap.jpg - Layer3, карта нормалей

Сравнимо с миникартой из игры данные превьюшки выглядят кверху ногами, однако в этом виноват формат bmp, который по стандарту отображается снизу вверх. Ну и в любом случае это лишь превьюшки.  :)



#3 OFFLINE   Yakim (Watcover3396)

Yakim (Watcover3396)
  • Создатель
  • 167 сообщений
  • Откуда:Донецкая Народная Республика
  • Настоящее имя:Дмитрий

Отправлено 22 Июль 2014 - 05:51

Yandersen, ну поковырял я твою программку, экспортнул карту, она почему то вытягивалась постоянно с красным оттенком, но я в фотошопе это легко исправил.

Ютуб почему то качеством по жадничал, но думаю и так видно.

Скрытый текст

В движке круче смотрится, а если еще текстурки наложить, то вообще будет ништяк.

Прикрепленные изображения

  • asdsad.jpg


#4 OFFLINE   GranMinigun

GranMinigun

    Хранитель Форума

  • Админ
  • 170 сообщений
  • Откуда:Верхняя Салда
  • Настоящее имя:Александр

Отправлено 22 Июль 2014 - 14:00

Формат карты высот, который UDK точно ест, как, впрочем, и Unity, такой: RAW, один канал, 16 бит, без заголовка, IBM PC либо MAC, разницы нет.

 

UPD: UDK, похоже, понимает float, но не переваривает размеры, используемые в М. Т.е., требуется адаптация: либо увеличение размера карты, либо уменьшение. Точные значения нужно вычислять, если надо кому - займусь.


Mama Africa

#5 OFFLINE   SHW

SHW

    Разработчик

  • Создатель
  • 32 сообщений
  • Откуда:Самара
  • Настоящее имя:Слава

Отправлено 22 Июль 2014 - 17:35

<...>

Собственно, даже и не знаю, чем могу вам помочь, вы итак почти всю основную информацию вытащили. Да и с этим файлом я не особо знаком.

 

Помню, что загрузка была сделана в два или больше уровней, то есть тот первый блок с "мусором" скорее всего "младшие" лоды самого ландшафта. Высоты, цвет, карту самозатенения (тоже клёвая вещь, так как позволяла дёшево делать тени на ландшафте от самого себя) и нормалей в определили.

 

Третий слой на самом деле состоит из двух частей: два байта - маска лодов. В мехах использовалось что-то вроде Diamond-based ROAM. Он позволяет иерархически представлять ландшафт для постепенного уточнения в зависимости от кривизны поверхности. Отсюда такой странный паттерн на карте, повторяющий крутые склоны. Вторые два байта - идентификатор поверхности, ищите её в базе. Там не только текстуры, но и куча других свойств описана, включая объекты детализации (мелкие камешки, травинки и прочее не интерактивное барахло).

 

Не думаю, что те маленькие сегменты карты 33х33 вершины - это младшие ЛОДЫ. У них другой формат данных - для высот используется не float, а int. И слоёв там всего 4, а не 5. Так что всё же считаю, что это архаизмы со времён М1 остались.

Вначале - действительно младшие ЛОДы, не удивительно, что там используется short int вместо float, он же короче. Всё-таки, мехи вышли тогда, когда всю карту с диска не возможно было загрузить в память, так что экономили на всём. Дальние лоды занимали меньше места, чем основные, на них кажется даже текстура не накладывалась.

 

Размер карты должен быть где-то в самом начале файла. А вот смещения вполне возможно, что нет совсем. Загрузка была реализована через поток, то есть, как-только вся служебная информация по карте была загружена (включая произвольное количество погодных описаний), смещение запоминалось и дальше от этого места рандомно (по мере надобности) погружались сами ячейки.


Your mind is software. Program it.
Your body is a shell. Change it.
Death is a disease. Cure it.

#6 OFFLINE   Yandersen

Yandersen

    Диванный теоретик

  • Админ
  • 454 сообщений
  • Откуда:Canada
  • Настоящее имя:Ян

Отправлено 24 Июль 2014 - 02:29

Бинго! Нашёл, где размеры карты указаны - два int'а, начинаются с позиции 132, показывают количество вершин в карте. Вот что интересно, так это то, что в редакторе можно расширять карту на 1 сегмент со всех сторон, т.е. на 128 вершин в обоих измерениях. А игровые карты, похоже, квадратные не все. Впридачу, размеры карт кратны (64*х+1) вершине только для карт, созданных мною в редакторе. Для игровых карт они вовсе не такие. К примеру, размер секторов Арктики и Скал, согласно прочитанным в файле значениям, 2500 на 2500, а не 2561 х 2561, как по количеству сегментов выходит. Таким образом получается, что значения размеров карты в файле означает именно количество используемых вершин.

 

Апдэйт: поработал над кодом функции RipLayersFromMMP(), теперь вытягивает карты именно тех размеров, что в файле указаны, без лишних вершин на краях. Потестал на всех картах - работает идеально. Вот код:

#include <stdlib.h>      //Standard routines
#include <malloc.h>      //malloc, free
#include <sys/types.h>
#include <sys/stat.h>    //_S_IREAD
#include <fcntl.h>       //_O_RDONLY, _O_BINARY
#include <share.h>       //_SH_DENYWR, _SH_DENYRW
#include <io.h>          //_sopen_s, _filelength, _read, _close
#include <stdio.h>       //SEEK_SET, SEEK_END
#include <string.h>      //strlen, memcpy
//==============================================================================

//4 byte data structure
union dword{
 float f;
 int i;
 unsigned int ui;
 short s[2];
 unsigned short us[2];
 char c[4];
 unsigned char uc[4];
};

//Segment data structure

struct{
 dword MagicNumber;  //Always 0xFFFFFFFF
 dword Legacy[4356]; //4 minimaps [33x33], probably unused;
 dword Layer1[4225]; //Heightmap [65x65], float;
 dword Layer2[4225]; //Infomap [65x65], unsigned short[2] (second value masked
                     //with 0x7fff gives texture identifier);
 dword Layer3[4225]; //Colormap [65x65], unsigned char[4] (BGRA, but A not used)
 dword Layer4[4225]; //Shadowmap [65x65], unsigned char[4] (each channel carries
                     //shadow' intensity in different daytimes)
 dword Layer5[4225]; //Normalmap [65x65], signed short[2] (two horizontal
                     //components only)
}MMPSegment;

//Save given data as a 32bpp bitmap; returned value indicates success;
//NOTE: the extension .bmp must be included in the given file path; returned
//value indicates success
bool SaveBMP32bpp(const char* FilePath,int Width,int Height,const void* Pixels){
 //Check the input
 if(Width<=0||Height<=0||!Pixels)return false;
 //Try to open the specified file for writing
 int FileHandle=_open(FilePath,_O_BINARY|_O_CREAT|_O_TRUNC|_O_WRONLY,_S_IWRITE);
 if(FileHandle==-1)return false;
 //Write the bitmap header
 int Size = Width*Height*4;
 dword tmp;
 tmp.c[0]='B'; tmp.c[1]='M'; _write(FileHandle,&tmp,2);
 tmp.i = 54+Size; _write(FileHandle,&tmp,4);
 tmp.i = 0; _write(FileHandle,&tmp,4);
 tmp.i = 54; _write(FileHandle,&tmp,4);
 tmp.i = 40; _write(FileHandle,&tmp,4);
 tmp.i = Width; _write(FileHandle,&tmp,4);
 tmp.i = Height; _write(FileHandle,&tmp,4);
 tmp.s[0]=1; tmp.s[1]=32; _write(FileHandle,&tmp,4);
 tmp.i = 0; _write(FileHandle,&tmp,4);
 tmp.i = 0; _write(FileHandle,&tmp,4);
 tmp.i = 0; _write(FileHandle,&tmp,4);
 tmp.i = 0; _write(FileHandle,&tmp,4);
 tmp.i = 0; _write(FileHandle,&tmp,4);
 tmp.i = 0; _write(FileHandle,&tmp,4);
 //Write the pixel data, close the file and return true indicating the success
 _write(FileHandle,Pixels,Size);
 _close(FileHandle);
 return true;
}//SaveBMP32bpp-----------------------------------------------------------------

//Save given map layer as a file with specified name; if the file has extension
//.bmp then that layer will be saved as 32bpp bitmap; otherwise it will be saved
//as it is; returned value indicates success
bool SaveLayerOfMMP(const char* FilePath,int Width,int Height,const void* Data){
 //Check the input
 if(!FilePath||!Data)return false;
 int Size = Width*Height*4; if(Size<=0)return false;
 //Check the extension; save as bitmap if the extension is .bmp or .BMP
 int PathLength = strlen(FilePath); 
 if(PathLength>=4)if(FilePath[PathLength-4]=='.')
  if(FilePath[PathLength-3]=='b'||FilePath[PathLength-3]=='B')
   if(FilePath[PathLength-2]=='m'||FilePath[PathLength-2]=='M')
    if(FilePath[PathLength-1]=='p'||FilePath[PathLength-1]=='P')
     return SaveBMP32bpp(FilePath,Width,Height,Data);
 //Try to create or open the specified file and write the given data as it is
 int FileHandle=_open(FilePath,_O_BINARY|_O_CREAT|_O_TRUNC|_O_WRONLY,_S_IWRITE);
 if(FileHandle==-1)return false;
 _write(FileHandle,Data,Size);
 //Close the file and return true indicating the success
 _close(FileHandle);
 return true;
}//SaveLayerOfMMP---------------------------------------------------------------

//Rip the individual maps from the given MMP file and save them to the specified
//files; returned value indicates success;
//XmapFileName - path to the output file; the file has a raw structure:
//dword[Width*Height], points stored row-by-row;
//if XmapFileName is NULL, that layer will not be saved;
//NOTE: if the extension of 'XmapFileName' is ".bmp" then 54 bytes of Windows
//bitmap file header will be inserted at the beginning of the file to describe
//the data as 32 bpp image; the actual data, howether, left as it is
bool RipLayersFromMMP(const char* MMP_FilePath,
                      const char* HeightmapFileName,
                      const char* InfomapFileName,
                      const char* ColormapFileName,
                      const char* ShadowmapFileName,
                      const char* NormalmapFileName){
 //Try to open the MMP file for reading and check the parameters
 int FileHandle =
  _sopen(MMP_FilePath,_O_BINARY|_O_RDONLY|_O_SEQUENTIAL,_SH_DENYWR);
 if(FileHandle==-1)return false;
 int Size = _filelength(FileHandle); if(Size<140)return false;
 //Check the quantity of points and segments in both dimensions
 _lseek(FileHandle,132,SEEK_SET);
 int Width=0,Height=0;
 _read(FileHandle,&Width,4); _read(FileHandle,&Height,4);
 if(Width<1||Height<1)return false;
 int SegmentsInRow = (Width+62)/64,
     SegmentsInColumn = (Height+62)/64;
 //Calculate array size and seek to the start of the array
 int Segments = SegmentsInRow*SegmentsInColumn,
     ArraySize = Segments*sizeof(MMPSegment);
 if(ArraySize>=Size)return false;
 _lseek(FileHandle,-ArraySize,SEEK_END);
 //Try to allocate the buffer for the maps
 int MapPoints = Width*Height,
     MapSize = MapPoints*4;
 dword* Layer1 = (dword*)malloc(MapSize*5);
 dword* Layer2 = Layer1+MapPoints;
 dword* Layer3 = Layer2+MapPoints;
 dword* Layer4 = Layer3+MapPoints;
 dword* Layer5 = Layer4+MapPoints;
 if(!Layer1){ _close(FileHandle); return false; }
 //Cycle through the segments
 for(int s=0;s<Segments;s++){
  //Load the data
  _read(FileHandle,&MMPSegment,sizeof(MMPSegment));
  //Calculate coordinates of the segment origin
  int x = (s%SegmentsInRow)*64, y = (s/SegmentsInRow)*64;
  //Cycle through the lines of the segment; check the bounds
  for(int l=0;l<65&&(y+l)<Height;l++){
   int CopyWidth = Width-x;
   CopyWidth = (CopyWidth>65)?260:(CopyWidth<<2);
   memcpy(Layer1+((y+l)*Width+x),&(MMPSegment.Layer1[l*65]),CopyWidth);
   memcpy(Layer2+((y+l)*Width+x),&(MMPSegment.Layer2[l*65]),CopyWidth);
   memcpy(Layer3+((y+l)*Width+x),&(MMPSegment.Layer3[l*65]),CopyWidth);
   memcpy(Layer4+((y+l)*Width+x),&(MMPSegment.Layer4[l*65]),CopyWidth);
   memcpy(Layer5+((y+l)*Width+x),&(MMPSegment.Layer5[l*65]),CopyWidth);
  }
 }
 //Close the MMP file
 _close(FileHandle);
 //Try to open or create the files and write the layered data into them
 SaveLayerOfMMP(HeightmapFileName,Width,Height,Layer1);
 SaveLayerOfMMP(InfomapFileName,Width,Height,Layer2);
 SaveLayerOfMMP(ColormapFileName,Width,Height,Layer3);
 SaveLayerOfMMP(ShadowmapFileName,Width,Height,Layer4);
 SaveLayerOfMMP(NormalmapFileName,Width,Height,Layer5);
 //Release the buffer and return true indicating the success
 free(Layer1);
 return true;
}//RipLayersFromMMP-------------------------------------------------------------


#7 OFFLINE   Arсhangel

Arсhangel

    Главный админ

  • Админ
  • 44 сообщений
  • Откуда:Украина
  • Настоящее имя:Влад

Отправлено 24 Июль 2014 - 23:48

Безымянный2.png

Ловите Сектор Арктики в Unity - по нему можно побегать:

Прикрепленный файл  test.7z   29,53МБ   57 - Раз(а) скачано

 

Исходники (Unity package):

Прикрепленный файл  Арктика.7z   36,2МБ   41 - Раз(а) скачано



#8 OFFLINE   Yakim (Watcover3396)

Yakim (Watcover3396)
  • Создатель
  • 167 сообщений
  • Откуда:Донецкая Народная Республика
  • Настоящее имя:Дмитрий

Отправлено 25 Июль 2014 - 08:10

Да уж разница между 8битами и 16биткой существенная :lol:

asdasdasd.jpg - 16 бит на вершину

dfgdfjh.png - 8 бит на вершину



#9 OFFLINE   Yakim (Watcover3396)

Yakim (Watcover3396)
  • Создатель
  • 167 сообщений
  • Откуда:Донецкая Народная Республика
  • Настоящее имя:Дмитрий

Отправлено 28 Июль 2014 - 06:53

Yandersen, программка работает отлично, да уж это просто супер :)

fdgdfgfdh.jpg sdfsdfsdf.jpg



#10 OFFLINE   Yakim (Watcover3396)

Yakim (Watcover3396)
  • Создатель
  • 167 сообщений
  • Откуда:Донецкая Народная Республика
  • Настоящее имя:Дмитрий

Отправлено 28 Июль 2014 - 09:11

Yandersen, вытащил все основные карты, но проявилась парочка что то мне не очень знакомых, может просто провтыкал.

Вообщем вот они, правда вторая мне напоминает подземку

Прикрепленные изображения

  • hgjffd.png
  • jhjgf.png


#11 OFFLINE   GranMinigun

GranMinigun

    Хранитель Форума

  • Админ
  • 170 сообщений
  • Откуда:Верхняя Салда
  • Настоящее имя:Александр

Отправлено 28 Июль 2014 - 17:26

Твоя утилита прекрасно работает с МГ, к слову. И там тоже есть альфа (из примера в прикреплении удалена).

TRACK01_heightmap(normalized).png

TRACK01_colormap(original).png


Mama Africa

#12 OFFLINE   PA3UJIb

PA3UJIb

    Серый

  • Создатель
  • 171 сообщений

Отправлено 29 Июль 2014 - 12:54

Вот только я, увы, разочаровался в UDK... не дает эту карту импортировать
Сталкивался с подобными проблемами при работе с готовым двиглом, иногда думаешь, что быстрее сам напишешь код, чем с этим угробищем разбираться. Зато какой кайф когда наконец решишь всё! Так что, GranMinigun, не вешай нос и добивайся своего. Это только с одной стороны кажется, что уже всё, ничего не сделать, но решение есть! Надо искать

 


#13 OFFLINE   Yandersen

Yandersen

    Диванный теоретик

  • Админ
  • 454 сообщений
  • Откуда:Canada
  • Настоящее имя:Ян

Отправлено 01 Август 2014 - 16:03

Оказывается, в оригинальный меховский редактор локаций можно обратно выдернутые карты импортировать. Хотя, походу, только в битмапном формате. Ну вот попробовал сектор скал всунуть. Получилось примерно то же дискретное УГ, что Яким демонстрировал. Но не суть. Я установил размеры карты 2500 на 2500 и в окне 2Д карты измерил расстояние от одного края карты до другого. Вышло близко к 25000 метрам. Значит в файлах карт расстояние между вершинами считается равным 10 метрам. Это значит, что импортируя нормализованную карту высот в Юнити или куда там ещё, где расстояние между вершинами считается 1м, нам нужно выбирать масштаб высоты, равный "(Highest-Lowest)/10". Тогда получится один в один как в мехах. B)

 

Ну вот, к примеру, в секторе Скал мой экспортер пишет, что расстояние между высочайшей точкой и самой нижней составляет 3447.8134765625 единиц. Значит при экспорте в Юнити в формате Raw 16 bit нам нужен масштаб 344.78134765625. От-так-от.  :)

 

И ещё одно небольшое открытие. Определена ещё одна структура данных в шапке файла MMP. Непосредственно перед массивом сегментов идёт массив описаний всех этих сегментов. Каждое описание имеет размер 76 байт (19*4) и первое значение - это int32, хранящий смещение от начала файла, где располагается описываемый сегмент карты. После него идут 6 float'ов - т.н. boundbox, определяющий минимальные и максимальные значения вершинных координат карты. Интересно, что означают остальные 12 четырёхбайтных значений?..

 

Результаты моего декодирования:

 

struct SegmentInfo{

int Offset;

float Xmin;

float Ymin;

float Zmin; //Minimal height

float Xmax;

float Ymax;

float Zmax; //Maximal height

float ?;

float ?;

float ?;

float ?;

float ?;

dword ?;

dword ?;

dword ?;

dword ?;

dword ?;

dword ?;

dword ?;

};



#14 OFFLINE   Yandersen

Yandersen

    Диванный теоретик

  • Админ
  • 454 сообщений
  • Откуда:Canada
  • Настоящее имя:Ян

Отправлено 03 Август 2014 - 07:35

О, обнаружен ещё один массив в файлах MMP. Массив состоит из элементов размером 228 байт и начинается с оффсета 316. В оффсете 312, т.е. прямо перед массивом, находится 4-хбайтное число, указывающее размер данного массива в байтах.

Обнаружил я этот массив по периодически повторяющимся идентификаторам текстур (TEX_*), под каждый из которых отведено 32 байта пространства. По два идентификатора на элемент массива.



#15 OFFLINE   Yandersen

Yandersen

    Диванный теоретик

  • Админ
  • 454 сообщений
  • Откуда:Canada
  • Настоящее имя:Ян

Отправлено 03 Август 2014 - 23:43

Небольшое отступление в сторону МММ файлов. Как я понимаю, это миникарта. На вопрос "да кому она нужна" отвечу: нубам, которые впервые в руки взяли М2 и задают тупые вопросы в стиле "а где в секторе таком-то находится то-то?" - т.е. для составления качественных хелпов и факов к М2 миникарты в оригинальном виде пригодились бы.

 

Структура данных в этих файлах предельно простая: 16 байт шапки, а затем массив из 16-байтных элементов до самого конца файла.

 

Первые 4 байта (int32) шапки во всех минкартах несут значение 16, следующие 4 байта интерпретируются как 257. Затем идут, предположительно, полные размеры карты - два int32, равные 2560 и 2560 для сектора Скал. Эти числа получаются, если количество сегментов (40х40 для Скал) умножить на 64. Таким образом данные числа - количество квадратиков карты.

 

Однако количество 16-байтных элементов в массиве вовсе не равно 2560х2560, как хотелось бы ожидать. Это количество в 16 раз меньше:

nElements16 = SizeX*SizeY/16

 

Что особо странно, так это то, что первые 8 байт у всех элементов массива, во всех МММ картах всегда одинаковы: {255,255,0,0,0,0,0,0}.

Так что в МММ файлах находится, похоже, не просто картинка миникарты. Или же это какой-то сжатый формат?..

 

В общем, хз, сломал все зубы об МММ и так ничего и не добился. Пробовал экспортировать массив элементов с вырезанными первыми 8-ю и 12 байтами - никакие интерпретации не дают вразумительных изображений.

 

Требуется подсказка "помощь зала" или лучше "звонок другу". Может, SHW подскажет?  :rolleyes:



#16 OFFLINE   SHW

SHW

    Разработчик

  • Создатель
  • 32 сообщений
  • Откуда:Самара
  • Настоящее имя:Слава

Отправлено 04 Август 2014 - 18:58

В мехах, кажется, и мини карта была организована с ЛОДМИ (в зависимости от масштаба радара) и динамической подгрузкой блоками 64*64. И да, вполне мог использоваться один из видов аппаратного сжатия DXT*.

 

Судя по паттерну (255,255,0,0,0,0,0,0) - это DXT5 (4) формат, а сам паттерн - кодированный альфа канал (максимальное, минимальное значение и 3-битные индексы). Так как миникарта по факту непрозрачная, то альфа канал тупо всегда 255, что и выливается в эту фигню.

Остальное должно быть как в DXT1. Два 16-ти битных цвета и 16 двух-битных индекса.

Можно просто попробовать загрузить все данные как текстуру в DXT5 формате и не париться с ручным декодированием.


Your mind is software. Program it.
Your body is a shell. Change it.
Death is a disease. Cure it.

#17 OFFLINE   SHW

SHW

    Разработчик

  • Создатель
  • 32 сообщений
  • Откуда:Самара
  • Настоящее имя:Слава

Отправлено 06 Август 2014 - 19:41

Знаний по DirectX у меня - ноль целых ноль десятых, никогда не касался даже. Так что тут я руки вверх, Вадимка миникарту не получит.

Ну это зря. Во-первых, на сколько я знаю, такую текстуру можно загрузить и в OpenGL, так как DXT* формат видюхи поддерживают аппаратно.

Во-вторых, алгоритм сжатия довольно простой. Вам 10 минут хватит, чтобы написать декодер:

DXT сжатия (также иногда известный как сжатие S3 ) на самом деле очень простое. Вот как это работает:

- Изображение делится на блоки 4х4
- Для каждого блока, находится два самых важных цвета
- Получившиеся два цвета хранятся в первых 32-х битах в 16-ти битном формате RGB 5.6.5
- Для каждого из 16 пикселей в блоке, хранится 2 бита значения, указывающее, как далеко он находится между двумя основными цветами, то есть 00 - первый цвет, 01 - 76.6% первого цвета и 33.3% второго, 10 - 33.3% - первого и 76.6% второго, 11 - второй цвет.

Your mind is software. Program it.
Your body is a shell. Change it.
Death is a disease. Cure it.

#18 OFFLINE   SHW

SHW

    Разработчик

  • Создатель
  • 32 сообщений
  • Откуда:Самара
  • Настоящее имя:Слава

Отправлено 07 Август 2014 - 20:42

Вам 10 минут хватит, чтобы написать декодер

Ниправда не очевидно всё мне, головоломка же. Предлагаю вот что: заинтересованные товарищи напишут мне функциёвину, конвертирующую 16 байт блока сжатых данных в 16 несжатых пикселей, а я всуну эту функциёвину в конвертер.

Как-то так. Хотя где-то мог и накосячить. 

//Структура данных для хранения цвета одиночного пикселя в 32-битном формате:
struct SPixel32bit{
  unsigned char BGRA[4];
};

//Структура данных для хранения 16 пикселей в несжатом виде:
struct SPixels4x4{
  SPixel32bit Row1[4];
  SPixel32bit Row2[4];
  SPixel32bit Row3[4];
  SPixel32bit Row4[4];
};

// Конвертим 16-ти битный цвет в 32-х битный (альфа всегда 1)
SPixel32bit conv16_32(unsigned short int color_16) {
  SPixel32bit res;
  // Тут не совсем правильно, так как младшие биты получаются всегда 0
  res.BGRA[0] = (color_16 & 0x1F) << 3;         // B
  res.BGRA[1] = ((color_16 >> 5) & 0x3F) << 2;  // G
  res.BGRA[2] = ((color_16 >> 11) & 0x1F) << 3; // R
  res.BGRA[3] = 0xFF;                           // A
  return res;
}

// Интерполяция между двумя цветами
SPixel32bit color_lerp(const SPixel32bit& color1, const SPixel32bit& color2, const float val) {
  SPixel32bit res;
  for (int i = 0; i < 4; ++i) {
    res.BGRA[i] = color1.BGRA[i] * (1 - val) + color2.BGRA[i] * val;
  }
  return res;
}

//Функция декодирует 128-битный блок данных DXT-текстуры (DXTBlock128bit) и вычисляет
//цвета 16-ти пикселей в несжатом виде, заполняя структуру DecodedPixels:
void DecodeDXTBlock(const char* in_stream, SPixels4x4* out_pixels){
  char* cur_pos = (char *)in_stream;

  cur_pos += 8; // пропускаю альфа канал, так как лень, да и там и так одни единицы

  SPixel32bit palette[4];
  palette[0] = conv16_32(*((unsigned short int*)cur_pos));
  cur_pos += 2;
  palette[1] = conv16_32(*((unsigned short int*)cur_pos));
  cur_pos += 2;
  palette[2] = color_lerp(palette[0], palette[1], 1.0f / 3.0f);
  palette[3] = color_lerp(palette[0], palette[1], 2.0f / 3.0f);
  
  // Грязный хак для упрощения кода
  SPixel32bit* cur_pixel = (SPixel32bit*)out_pixels;
  for (int i = 0; i < 4; ++i) {
    unsigned char cur_byte = *cur_pos;
    for (int j = 0; j < 4; ++j) {
      *cur_pixel = palette[cur_byte & 3];
      cur_byte >>= 2;
      ++cur_pixel;
    }
    ++cur_pos;
  }
}


Your mind is software. Program it.
Your body is a shell. Change it.
Death is a disease. Cure it.

#19 OFFLINE   Yandersen

Yandersen

    Диванный теоретик

  • Админ
  • 454 сообщений
  • Откуда:Canada
  • Настоящее имя:Ян

Отправлено 08 Август 2014 - 16:16

Готово! Апгрэйднул MMP-риппер до просто Mechanoids map exporter'а (v0.7.0.1), забомбив поддержку MMM файлов и немного упорядочив интерфейс. Исходники залил сюда. Добавил ссылку в первый пост.

Ещё раз Большое спасибо SHW за помощь! ;)



#20 OFFLINE   Yakim (Watcover3396)

Yakim (Watcover3396)
  • Создатель
  • 167 сообщений
  • Откуда:Донецкая Народная Республика
  • Настоящее имя:Дмитрий

Отправлено 19 Сентябрь 2014 - 14:44

Было бы не плохо вытащить сектор Вулканов из М1.

Интересно какой алгоритм используется при упаковке паков с картами, сами карты думаю можно вытащить аналогичным способом как из М2.






Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных