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


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

Yakim (Watco... : (неделю назад) КРУЗИИИС!!!11

Изображение
lz : (неделю назад) КРУЗИС!
lz : (неделю назад) ЗИС
lz : (неделю назад) КРУ
Yakim (Watco... : (неделю назад) Крузис и Королева тоже не в моем вкусе, а проигрывать нечего =D
lz : (неделю назад) Конечно, полюбить - так королеву, проиграть - так миллион, сделать - так крузис.
smt005 : (неделю назад) И от третьего лица тоже можно сделать простенькую игру. Простая игра это лучше чем ничего.
smt005 : (неделю назад) А, ты хочеш что-бы хит был, с "Crysis" графоном и контентом на 100500 часов игры?
Yakim (Watco... : (неделю назад) Ни топдовншутеры, ни стратежки)
Yakim (Watco... : (неделю назад) Не, спасибо, не в моем вкусе=)
smt005 : (неделю назад) Помнится за пару недель от скуки сделал. Делал по вечерам.
smt005 : (неделю назад)
smt005 : (неделю назад) Или например такое, только с моделями из игры -> https://youtu.be/RFDdN5dcX8s
smt005 : (неделю назад) Yakim, да сами себя пните... :) Сделайте что-то, хотя бы уровня "Scrolling TopDown Shooter".
Yakim (Watco... : (неделю назад) так что, думаю завтра с утреца стартану марафон)
Yakim (Watco... : (неделю назад) хе-хе, не сомневайся, я в чате по уе уже поинтересовался, сказали обалденный сериал)))
Yandersen : (неделю назад) Оооооо, поди ща залипнет на пару дней, стопудофф. :)
Yakim (Watco... : (неделю назад) Окей гляну)
Yandersen : (неделю назад) Сериал Пространство посмотри. Не по части Мехов, просто шикарен, авось ману доставит.
Yakim (Watco... : (неделю назад) Дуст и ты уже закаленные и пустые, надож где-то ману доставать)))
Yakim (Watco... : (неделю назад) Думаю, кого быть пнуть, что-бы тот пнул в ответ да по сильнее.
Yakim (Watco... : (неделю назад) Давненько и не маленько хе-хе, делать нечего, прокрастинирую =)
Yandersen : (неделю назад) Якимка, ты там шо, упоролсо маленько? Чиво картинами опспамилсо?
Yakim (Watco... : (неделю назад) Изображение
Yakim (Watco... : (2 недель назад) no, you are blind
Гость : (2 недель назад) Изображение
lz : (2 недель назад) Изображение
Yakim (Watco... : (2 недель назад) Изображение
Гость : (2 недель назад) Подкорректирую: скорее всего, Механоидов в названии уже не будет, кхм.
Гость : (3 недель назад) Не будет М3!.. :(
Yakim (Watco... : (3 недель назад) Нихуяшечки от нас не зависит)
Yandersen : (4 недель назад) Зависит от нас самих. От Скаев - надежды нет.
Гость : (4 недель назад) народ я тут хотел узнать есть шанс на меха 3 ?
Yakim (Watco... : (4 недель назад) точно? :huh: а если найду? :lol:
lz : (4 недель назад) да не, я не)
Yakim (Watco... : (4 недель назад) Егор, ты говоришь так. будто у тебя они есть, так вот, че по чем?))))
Гость : (4 недель назад) Вот бы сейчас, в 2018, читы на мехов гуглить...
lz : (4 недель назад) Ты просто без читов гоняешь.
Yandersen : (4 недель назад) Ниправда, этот сукасадист должен существовать, его не может не быть! Иначе на кого тяготы жизни сваливать?
Yakim (Watco... : (4 недель назад) Юморист от бога, которого нет)))
Гость : (4 недель назад) Бля, я думал это поиск
Гость : (4 недель назад) Читы
Yakim (Watco... : (16 Май 2018 - 22:49) Ну как-бы да, насколько я помню, Дуст и Сплайн основатели =) Кажется идея Дуста, реализация Сплайна.
lz : (16 Май 2018 - 21:10) Вон даже свалкер2 будет, а ты говоришь. И P4 будет)
Yandersen : (16 Май 2018 - 17:18) ессниошибаюсь. Якимка, подтверди?..

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

Локации из М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.






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

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