Формат файлов *.object (формат объектов SDK) — различия между версиями — S.T.A.L.K.E.R. Inside Wiki

Формат файлов *.object (формат объектов SDK) — различия между версиями

Материал из S.T.A.L.K.E.R. Inside Wiki

Перейти к: навигация, поиск
 
 
(не показана 21 промежуточная версия 5 участников)
Строка 1: Строка 1:
'''Формат разобрал excid'''
 
 
 
== О формате ==
 
== О формате ==
 
Формат *.object используется в качестве основного формата хранения моделей на этапе редактирования (включая экспорт из Maya или 3ds Max и хранение моделей до компиляции уровня)
 
Формат *.object используется в качестве основного формата хранения моделей на этапе редактирования (включая экспорт из Maya или 3ds Max и хранение моделей до компиляции уровня)
  
== Описание структуры ==
+
== Описание формата(из кода xrFSL) ==
Формат бинарный. Файл состоит из вложенных друг в друга блоков. Весь файл представляет собой единый блок.
+
 
 +
const uint16 ''EOBJ_VERSION'' = 0x10;
 +
 
 +
'''EObjectChunkIDs:'''
 +
 
 +
''EOBJ_CHUNK_MAIN'' = 0x7777,
 +
 
 +
''EOBJ_CHUNK_VERSION'' = 0x0900,
 +
 
 +
''EOBJ_CHUNK_FLAGS'' = 0x0903,
 +
 
 +
''EOBJ_CHUNK_SURFACES_0'' = 0x0905, // old format
 +
 
 +
''EOBJ_CHUNK_SURFACES_1'' = 0x0906, // old format
 +
 
 +
''EOBJ_CHUNK_SURFACES_2'' = 0x0907,
 +
 
 +
''EOBJ_CHUNK_MESHES'' = 0x0910,
 +
 
 +
''EOBJ_CHUNK_0911'' = 0x0911, // '''ignored by AE(Actor Editor)'''
 +
 
 +
''EOBJ_CHUNK_USERDATA'' = 0x0912,
 +
 
 +
''EOBJ_CHUNK_BONES_0'' = 0x0913, // old format
  
=== Структура блока ===
+
''EOBJ_CHUNK_MOTIONS'' = 0x0916,
Блок имеет 3 обязательные части:
+
{| class="standard"
+
|-
+
!Часть||Тип(размер)||Подробнее
+
|-
+
|Идентификатор типа блока||(4)||2 байта идентификатора и 2 нулевых байта<br />
+
|-
+
|Размер блока||uint(4)||без учета этих частей — только то, что идет дальше
+
|-
+
|Данные||(Размер блока)||Данные могут быть представлены вложенными блоками
+
|}
+
  
=== Типы данных ===
+
''EOBJ_CHUNK_SHADERS_0'' = 0x0918, // old format
Особое внимание стоит обратить на то, как хранятся строки: они нуль-терминальные, то есть в конце обязательно содержат нулевой байт.
+
  
== Структура ==
+
''EOBJ_CHUNK_PARTITIONS_0'' = 0x0919, // old format
В заголовке последующих пунктов в скобках содержатся идентификаторы типа блока в шестнадцатиричной форме, при этом байты представлены в обратном порядке (то есть так, как числа задаются в исходниках), поэтому идентификатор 0x0912 в файле будет выглядеть как 09 12 00 00.
+
  
== Файл (0x7777) ==
+
''EOBJ_CHUNK_TRANSFORM'' = 0x0920,
=== Неизвестные данные (0x0900) ===
+
Возможно, это версия.
+
{| class="standard"
+
|-
+
!Название||Тип(размер)||Значение||Подробнее
+
|-
+
|Неизвестно||(2)||0x10 0x00||
+
|}
+
  
=== Пользовательские информация — User Data (0x0912) ===
+
''EOBJ_CHUNK_BONES_1'' = 0x0921,
В редакторе Game options > User Data.
+
{| class="standard"
+
|-
+
!Название||Тип(размер)||Значение||Подробнее
+
|-
+
|Данные||строка||||Произвольная строка
+
|}
+
  
=== Уровень детализации — LOD (0x0925) ===
+
''EOBJ_CHUNK_REVISION'' = 0x0922, // file revision
В редакторе LOD > Reference.
+
{| class="standard"
+
|-
+
!Название||Тип(размер)||Значение||Подробнее
+
|-
+
|Ссылка||строка||||Путь к модели, содержащей следующий уровень детализации
+
|}
+
  
=== Тип объекта — Object Type (0x0903) ===
+
''EOBJ_CHUNK_PARTITIONS_1'' = 0x0923,
В редакторе Object Type.
+
{| class="standard"
+
|-
+
!Название||Тип(размер)||Значение||Подробнее
+
|-
+
|Тип||(4)||||Значение 0x00 для статической модели (тип Static)
+
|}
+
  
=== Данные о геометрии — Geometry (0x0910) ===
+
''EOBJ_CHUNK_MOTION_REFS'' = 0x0924,
В редакторе Geometry.
+
Все представленные ниже данные описывают 1 подобъект.
+
  
==== Неизвестные данные (0x1000) ====
+
''EOBJ_CHUNK_LOD_REF'' = 0x0925 // '''LOD\Reference'''
{| class="standard"
+
|-
+
!Название||Тип(размер)||Значение||Подробнее
+
|-
+
|Неизвестно||(2)||0x11 0x00||
+
|}
+
  
==== Название подобъекта — Name (0x1000) ====
+
'''EObjectClipChunkIDs:'''
{| class="standard"
+
|-
+
!Название||Тип(размер)||Значение||Подробнее
+
|-
+
|Название||строка||||
+
|}
+
  
==== Ограничивающий параллелепипед — Bounding Box (0x1004) ====
+
''EOBJ_CLIP_VERSION_CHUNK'' = 0x9000,
В редакторе Transform > BBox Min/Max
+
{| class="standard"
+
|-
+
!Название||Тип(размер)||Значение||Подробнее
+
|-
+
|Минимум||float(4)[3]||||Минимальные значения вершин по x, y, z
+
|-
+
|Максимум||float(4)[3]||||Максимальные значения вершин по x, y, z
+
|}
+
  
==== Неизвестные данные (0x1002) ====
+
''EOBJ_CLIP_DATA_CHUNK'' = 0x9001
{| class="standard"
+
|-
+
!Название||Тип(размер)||Значение||Подробнее
+
|-
+
|Неизвестно||(1)||0x05||
+
|}
+
  
==== Неизвестные данные (0x1010) ====
+
const uint16 ''EMESH_VERSION'' = 0x11;
{| class="standard"
+
|-
+
!Название||Тип(размер)||Значение||Подробнее
+
|-
+
|Неизвестно||(8)||0x00||Все нули
+
|}
+
  
==== Вершины — Vertices (0x1005) ====
+
'''EMeshChunkID:'''
{| class="standard"
+
|-
+
!Название||Тип(размер)||Значение||Подробнее
+
|-
+
|Количество вершин n||uint(4)||||
+
|-
+
|Координаты||float(4)[n * 3]||||Координаты x, y, z для каждой вершины
+
|}
+
  
==== Грани — Faces (0x1006) ====
+
''EMESH_CHUNK_VERSION'' = 0x1000,
{| class="standard"
+
|-
+
!Название||Тип(размер)||Значение||Подробнее
+
|-
+
|Количество граней m||uint(4)||||
+
|-
+
|Координаты||uint(4)[m * 6]||||Троки пар индекс вершины + индекс текстурной координаты
+
|}
+
  
==== Группы сглаживания — Smoothing Groups (0x1013) ====
+
''EMESH_CHUNK_MESHNAME'' = 0x1001,
{| class="standard"
+
|-
+
!Название||Тип(размер)||Значение||Подробнее
+
|-
+
|Группы||uint(4)[m]||||32-битная маска групп сглаживания для каждой грани
+
|}
+
  
==== Словарь текстурных координат — UVs map (0x1008) ====
+
''EMESH_CHUNK_FLAGS'' = 0x1002,
Логика формирования и назначение этого и блока «Текстурные координаты» доконца не понятна.
+
Предположительный вариант представлен ниже.
+
{| class="standard"
+
|-
+
!Название||Тип(размер)||Значение||Подробнее
+
|-
+
|Количество записей k||uint(4)||||
+
|-
+
|Данные||(9)[k]||||Предположительная структура в следующей таблице
+
|}
+
<br />
+
{| class="standard"
+
|-
+
!Название||Тип(размер)||Значение||Подробнее
+
|-
+
|Неизвестно||byte(1)||0x1||
+
|-
+
|Индекс таблицы текстурных координат||uint(4)||0x0 или 0x1||Возможно, только первый байт содержит эти данные,<br /> остальные выполняют другие функции<br />Встречались «некорректные» данные (например, 0x1 0x90 0xdb 0x11 0x7), но они не использовались
+
|-
+
|Индекс текстурных координаты||uint(4)||0x0 или 0x1||Индекс в таблице, определяемой предыдущим значением.
+
|}
+
  
==== Материалы объекта — Object Materials (0x1009) ====
+
''EMESH_CHUNK_BBOX'' = 0x1004,
{| class="standard"
+
|-
+
!Название||Тип(размер)||Значение||Подробнее
+
|-
+
|Количество материалов p||ushort(2)||||
+
|-
+
|Материалы||[p]||||Cтруктура в следующей таблице
+
|}
+
  
<br />
+
''EMESH_CHUNK_VERTS'' = 0x1005,
{| class="standard"
+
|-
+
!Название||Тип(размер)||Значение||Подробнее
+
|-
+
|Название материала||строка||||
+
|-
+
|Количество граней q||uint(4)||||Количество граней, имеющих этот материал
+
|-
+
|Индексы граней||uint(4)[q]||||
+
|}
+
  
==== Текстурные координаты — UVs (0x1008) ====
+
''EMESH_CHUNK_FACES'' = 0x1006,
Количество таблиц, которое встречалось в тестовых файлах — 2.
+
{| class="standard"
+
|-
+
!Название||Тип(размер)||Значение||Подробнее
+
|-
+
|Количество таблиц t||uint(4)||0x2||
+
|-
+
|Таблицы||[t]||||Структура в следующей таблице
+
|}
+
  
<br />
+
''EMESH_CHUNK_VMAPS_0'' = 0x1007,
{| class="standard"
+
|-
+
!Название||Тип(размер)||Значение||Подробнее
+
|-
+
|Неизвестно||строка||Texture||
+
|-
+
|Неизвестно||ubyte(1)||0x2||Возможно, количество компонентов в текс. координате?
+
|-
+
|Номер таблицы||ushort(1)||||
+
|-
+
|Количество текстурных координат s||uint(4)||||
+
|-
+
|Текстурные координаты||float(4)[s * 2]||||Пары значения текстурных координат u и v
+
|-
+
|Неизвестно||uint(4)[s]||||Какие-то индексы, не превышающие s
+
|-
+
|Неизвестно<br />(только для второй таблицы)||uint(4)[s]||||Какие-то индексы, не превышающие s, отсорированные по возрастанию
+
|}
+
  
 +
''EMESH_CHUNK_VMREFS'' = 0x1008,
  
=== Материалы — Materials (0x0907) ===
+
''EMESH_CHUNK_SFACE'' = 0x1009,
{| class="standard"
+
|-
+
!Название||Тип(размер)||Значение||Подробнее
+
|-
+
|Количество материалов r||uint(4)||||
+
|-
+
|Материалы||[r]||||Структура в следующей таблице
+
|}
+
  
<br />
+
''EMESH_CHUNK_OPTIONS'' = 0x1010,
{| class="standard"
+
|-
+
!Название||Тип(размер)||Значение||Подробнее
+
|-
+
|Название||строка||||
+
|-
+
|Характеристика для движка||строка||||Например, default
+
|-
+
|Характеристика для компилятора||строка||||Например, default
+
|-
+
|Характеристика для игры||строка||||Например, default
+
|-
+
|Путь к текстуре||строка||||
+
|-
+
|Неизвестно||строка||Texture||Значение Texture используется в блоке <br />Текстурные координаты — UVs (0x1008)
+
|-
+
|Флаги||uint(4)||||0x1, если материал двустронний, иначе 0x0
+
|-
+
|Неизвестно||(4)||0x12 0x1 0x0 0x0 0x1 0x0 0x0 0x0||
+
|}
+
  
 +
''EMESH_CHUNK_VMAPS_1'' = 0x1011,
  
=== Автор — Author (0x0907) ===
+
''EMESH_CHUNK_VMAPS_2'' = 0x1012,
{| class="standard"
+
|-
+
!Название||Тип(размер)||Значение||Подробнее
+
|-
+
|Создатель||строка||||Вид \\компьютер\пользователь (например, \\NAPALI\excid)
+
|-
+
|Дата создания||(4)||||
+
|-
+
|Последний модифицирующий||строка||||Вид \\компьютер\пользователь (например, \\NAPALI\excid)
+
|-
+
|Дата модификации||(4)||||
+
|}
+
  
 +
''EMESH_CHUNK_SG'' = 0x1013
  
== Скрипт разбора файла ==
+
const uint16 ''BONE_VERSION_1'' = 0x1;
Написан на Python. Не реализован полностью, завершение не планируется, так как свою миссию он выполнил.<br />
+
Если запускать из Blender, то импортирует объект (без материалов).<br />
+
Не рекомендуется запускать для больших файлов, так как выводится вся информация из файла.
+
  
=== Код ===
+
const uint16 ''BONE_VERSION_2'' = 0x2;
<code>
+
#                                          #
+
#    XRay Engine (S.T.A.L.K.E.R.) object    #
+
#      test import plugin for Blender      #
+
#                                          #
+
#          Anton 'excid' Gorenko            #
+
#              excid@mail.ru                #
+
#                                          #
+
#              (2007 June)                #
+
#                                          #
+
  
from struct import *
+
const uint16 ''BONE_VERSION'' = ''BONE_VERSION_2'';
import datetime
+
  
useBlender = True
+
'''EboneChunkID:'''
try:
+
    from Blender import *
+
    from Blender.Mathutils import *
+
except:
+
    useBlender = False
+
  
 +
''BONE_CHUNK_VERSION'' = 0x0001,
  
f = open('X:\\rawdata\\objects\\detail\\det_list_05.object', 'rb')
+
''BONE_CHUNK_DEF'' = 0x0002,
s = f.read()
+
f.close()
+
  
 +
''BONE_CHUNK_BIND_POSE''= 0x0003,
  
def parseMeshData(s):
+
''BONE_CHUNK_MATERIAL'' = 0x0004,
   
+
    p = 0
+
    print '\nunknown block =', hex(int(unpack('I', s[p : p + 4])[0]))
+
    p += 4
+
    size = unpack('I', s[p : p + 4])[0]
+
    print 'unknown block size =', size
+
    p += 4
+
    print 'unknown data =', map(hex, unpack('%dB' % (size,), s[p : p + size]))
+
    p += size
+
   
+
    print '\nname block =', hex(int(unpack('I', s[p : p + 4])[0]))
+
    p += 4
+
    nameSize = unpack('I', s[p : p + 4])[0]
+
    print 'name block size =', nameSize
+
    p += 4
+
    name = unpack('%ds' % (nameSize,), s[p : p + nameSize])[0][:-1]
+
    p += int(nameSize)
+
    print 'name =', name
+
   
+
    if useBlender:
+
        obj = Object.New('Mesh', name)
+
        mesh = Mesh.New(name)
+
        obj.link(mesh)
+
        scene = Scene.GetCurrent()
+
        scene.objects.link(obj)
+
   
+
    print '\nbbox block =', hex(int(unpack('I', s[p : p + 4])[0]))
+
    p += 4
+
    print 'bbox block size =', unpack('I', s[p : p + 4])[0]
+
    p += 4
+
    print 'bbox min = ', unpack('3f', s[p : p + 12])
+
    p += 12
+
    print 'bbox max = ', unpack('3f', s[p : p + 12])
+
    p += 12
+
   
+
    print '\nunknown block =', hex(int(unpack('I', s[p : p + 4])[0]))
+
    p += 4
+
    size = unpack('I', s[p : p + 4])[0]
+
    print 'unknown block size =', size
+
    p += 4
+
    print 'unknown data =', map(hex, unpack('%dB' % (size,), s[p : p + size]))
+
    p += size
+
   
+
    print '\nunknown block =', hex(int(unpack('I', s[p : p + 4])[0]))
+
    p += 4
+
    size = unpack('I', s[p : p + 4])[0]
+
    print 'unknown block size =', size
+
    p += 4
+
    print 'unknown data =', map(hex, unpack('%dB' % (size,), s[p : p + size]))
+
    p += size
+
   
+
    print '\nvertices block =', hex(int(unpack('I', s[p : p + 4])[0]))
+
    p += 4 
+
    print 'vertices block size =', unpack('I', s[p : p + 4])[0]
+
    p += 4 
+
    verticesCount = unpack('I', s[p : p + 4])[0]
+
    p += 4
+
    print 'vertices count =', verticesCount
+
    for i in range(verticesCount):
+
        coords = unpack('3f', s[p : p + 12])
+
        print 'vertex%d =' % (i,), coords
+
        p += 12
+
       
+
        if useBlender:
+
            mesh.verts.extend([coords])
+
   
+
    print '\ntriangles block =', hex(int(unpack('I', s[p : p + 4])[0]))
+
    p += 4
+
    print 'triangles block size =', unpack('I', s[p : p + 4])[0]
+
    p += 4
+
   
+
    trianglesCount = unpack('I', s[p : p + 4])[0]
+
    p += 4
+
    print 'triangles count =', trianglesCount 
+
   
+
    faces = []
+
    for i in range(trianglesCount):
+
        vertices = unpack('6I', s[p : p + 24])
+
        print 'triangle%d =' % (i,), vertices
+
        p += 24
+
       
+
        faces.append(vertices)
+
       
+
    print '\nsmoothgroups block =', hex(int(unpack('I', s[p : p + 4])[0]))
+
    p += 4
+
    size = unpack('I', s[p : p + 4])[0]
+
    p += 4
+
    print 'smoothgroups block size =', size
+
    for i in range(size / 4):
+
        x = unpack('I', s[p : p + 4])[0]
+
        print 'triangle%d =' % (i,), hex(int(x))
+
        p += 4
+
   
+
    print '\nuv map block =', hex(int(unpack('I', s[p : p + 4])[0]))
+
    p += 4
+
    size = unpack('I', s[p : p + 4])[0]
+
    p += 4
+
    print 'uv map block size =', size
+
    count = unpack('I', s[p : p + 4])[0]
+
    p += 4
+
    print 'count =', count
+
   
+
    layerIndices = []
+
    uvIndices = []
+
    for i in range(count):
+
        unknown = unpack('5B', s[p : p + 5])
+
        p += 5
+
       
+
        uvIndex = int(unpack('I', s[p : p + 4])[0])
+
        p += 4
+
       
+
        print 'uv index =', map(hex, unknown), uvIndex
+
       
+
        layerIndices.append(unknown[1])
+
        uvIndices.append(uvIndex)
+
       
+
   
+
    print '\nmaterials block =', hex(int(unpack('I', s[p : p + 4])[0]))
+
    p += 4
+
    size = unpack('I', s[p : p + 4])[0]
+
    p += 4
+
    print 'materials block size =', size
+
    materialsCount = unpack('H', s[p : p + 2])[0]
+
    p += 2
+
    print 'materials count =', materialsCount
+
   
+
    for i in range(materialsCount):
+
        materialName = ''
+
        b = unpack('B', s[p : p + 1])[0]
+
        p += 1
+
        while b != 0:
+
            materialName = materialName + chr(b)
+
            b = unpack('B', s[p : p + 1])[0]
+
            p += 1
+
        print 'material%d name =' % (i,), materialName
+
       
+
        trianglesCount = unpack('I', s[p : p + 4])[0]
+
        p += 4
+
        print 'triangles count =', trianglesCount
+
       
+
        print 'triangles indices =', map(int, unpack('%dI' % (trianglesCount,), s[p : p + 4 * trianglesCount]))
+
        p += 4 * trianglesCount
+
       
+
    print '\ntexcoords block =', hex(int(unpack('I', s[p : p + 4])[0]))
+
    p += 4
+
    size = unpack('I', s[p : p + 4])[0]
+
    p += 4
+
    print 'texcoords block size =', size
+
    uvTablesCount = unpack('I', s[p : p + 4])[0]
+
    p += 4
+
    print 'uv tables count =', uvTablesCount
+
   
+
   
+
    uvs = []
+
    for i in range(uvTablesCount):
+
        currentUv = []
+
        chanelName = ''
+
        b = unpack('B', s[p : p + 1])[0]
+
        p += 1
+
        while b != 0:
+
            chanelName = chanelName + chr(b)
+
            b = unpack('B', s[p : p + 1])[0]
+
            p += 1
+
        print 'name =', chanelName
+
       
+
        x = unpack('B', s[p : p + 1])[0]
+
        p += 1
+
        print 'unknown =', x
+
        layerIndex = unpack('H', s[p : p + 2])[0]
+
        p += 2
+
        print 'layer index =', layerIndex 
+
        count = unpack('I', s[p : p + 4])[0]
+
        p += 4
+
        print 'uvs count =', count
+
       
+
        for j in range(count):
+
            uv = unpack('2f', s[p : p + 8])
+
            print 'uv%d =' % (j,), uv
+
            p += 8
+
           
+
            currentUv.append(uv)
+
        uvs.append(currentUv)
+
           
+
        for j in range(count):
+
            x = unpack('I', s[p : p + 4])[0]
+
            print 'index%d =' % (j,), int(x)
+
            p += 4
+
  
    i = 0
+
''BONE_CHUNK_SHAPE'' = 0x0005,
    while len(s) > p:
+
        x = unpack('I', s[p : p + 4])[0]
+
        print 'unknown index%d =' % (i,), int(x)
+
        p += 4 
+
        i += 1
+
   
+
    if useBlender:
+
        faceIndex = 0
+
        for faceInfo in faces:
+
            if faceInfo[4] == 0:
+
                faceInfo = faceInfo[2:] + faceInfo[:2]
+
            mesh.faces.extend(faceInfo[::2])
+
            face = mesh.faces[-1]
+
  
            faceUvs = []
+
''BONE_CHUNK_IK_JOINT'' = 0x0006,
            for i in faceInfo[1::2]:
+
                faceUvs.append(Vector(uvs[layerIndices[i]][uvIndices[i]]))
+
            face.uv = faceUvs
+
   
+
def parseString(s, p):
+
    string = ''
+
    b = unpack('B', s[p : p + 1])[0]
+
    p += 1
+
    while b != 0:
+
        string = string + chr(b)
+
        b = unpack('B', s[p : p + 1])[0]
+
        p += 1
+
    return string, p
+
   
+
  
   
+
''BONE_CHUNK_MASS_PARAMS'' = 0x0007,
def parseGeometryBlock(s):
+
    print '\ngeometry\n'
+
    p = 0
+
    while p < len(s):
+
        i = unpack('I', s[p : p + 4])[0]   
+
        p += 4
+
        dataSize = unpack('I', s[p : p + 4])[0]
+
        print 'mesh%d data size = %d' % (i, dataSize)
+
        p += 4
+
        parseMeshData(s[p : p + dataSize])
+
        p += dataSize 
+
  
 +
''BONE_CHUNK_IK_FLAGS'' = 0x0008,
  
def parseMaterialBlock(s):
+
''BONE_CHUNK_BREAK_PARAMS'' = 0x0009,
    print '\nmaterials\n'
+
    p = 0
+
    materialsCount = unpack('I', s[p : p + 4])[0]
+
    p += 4
+
    print 'materials count =', materialsCount
+
  
    for i in range(materialsCount):
+
''BONE_CHUNK_FRICTION'' = 0x0010
        print '\n'
+
        materialName, p = parseString(s, p)
+
        print 'material%d name =' % (i,), materialName
+
       
+
        engineShader, p = parseString(s, p)
+
        print 'engine shader =', engineShader
+
       
+
        compilerShader, p = parseString(s, p)
+
        print 'compiler shader =', compilerShader
+
  
        gameMaterial, p = parseString(s, p)
+
==Game Materials Library(из кода xrFSL)==
        print 'game material =', gameMaterial 
+
       
+
        texturePath, p = parseString(s, p)
+
        print 'texture path =', texturePath
+
       
+
        texture, p = parseString(s, p)
+
        print 'texture =', texture
+
  
        print 'flags (2 sided, etc) =', hex(int(unpack('I', s[p : p + 4])[0]))
+
const uint16 ''GAMEMTLS_VERSION'' = 1;
        p += 4 
+
       
+
        size = 8
+
        print 'unknown data =', map(hex, unpack('%dB' % (size,), s[p : p + size]))
+
        p += size 
+
   
+
   
+
def parseAuthorBlock(s):
+
    print '\nauthor\n'
+
    p = 0
+
    authorName, p = parseString(s, p)
+
    print 'author name =', authorName
+
   
+
    size = 4
+
    print 'creation date =', map(hex, unpack('%dB' % (size,), s[p : p + size]))
+
    p += size 
+
  
   
+
''GAMEMTLS_CHUNK_VERSION'' = 0x1000,
    modifierName, p = parseString(s, p)
+
    print 'modifier name =', modifierName
+
   
+
    print 'modification date =', map(hex, unpack('%dB' % (size,), s[p : p + size]))
+
    p += size 
+
   
+
   
+
def parseUserDataBlock(s):
+
    print '\nuser data\n'
+
    p = 0
+
    userData, p = parseString(s, p)
+
    print 'user data =', userData
+
  
   
+
''GAMEMTLS_CHUNK_AUTOINC'' = 0x1001,
def parseLODBlock(s):
+
    print '\nlod\n'
+
    p = 0
+
    reference, p = parseString(s, p)
+
    print 'lod reference =', reference 
+
   
+
  
def parseFlagsBlock(s):
+
GAMEMTLS_CHUNK_MATERIALS'' = 0x1002,
    print '\nflags (model type)\n'
+
    p = 0
+
    flags = unpack('I', s[p : p + 4])[0]
+
    print 'model type =', hex(int(flags))
+
  
   
+
''GAMEMTLS_CHUNK_MATERIAL_PAIRS'' = 0x1003,
print '\n' * 3
+
  
p = 0
+
''GAMEMTL_CHUNK_MAIN'' = 0x1000,
header = unpack('I', s[p : p + 4])[0] 
+
print 'header =', hex(int(header))
+
p += 4
+
  
dataSize = unpack('I', s[p : p + 4])[0]
+
''GAMEMTL_CHUNK_FLAGS'' = 0x1001,
print 'data size =', dataSize
+
p += 4
+
  
while p < len(s):
+
''GAMEMTL_CHUNK_PHYSICS'' = 0x1002,
    print '\n'
+
    print '=' * 79
+
    block = unpack('I', s[p : p + 4])[0]
+
    print 'block =', hex(int(block))
+
    p += 4
+
   
+
    blockSize = unpack('I', s[p : p + 4])[0]
+
    print 'block size =', blockSize
+
    p += 4 
+
  
    if block == 0x0910:
+
''GAMEMTL_CHUNK_FACTORS'' = 0x1003,
        parseGeometryBlock(s[p : p + blockSize])
+
    elif block == 0x0907:
+
        parseMaterialBlock(s[p : p + blockSize])
+
    elif block == 0x0922:
+
        parseAuthorBlock(s[p : p + blockSize])
+
    elif block == 0x0912:
+
        parseUserDataBlock(s[p : p + blockSize])
+
    elif block == 0x0925:
+
        parseLODBlock(s[p : p + blockSize])
+
    elif block == 0x0903:
+
        parseFlagsBlock(s[p : p + blockSize])     
+
    else:
+
        print 'unknown data =', map(hex, unpack('%dB' % (blockSize,), s[p : p + blockSize]))
+
    p += blockSize
+
</code>
+
  
=== Результат ===
+
''GAMEMTL_CHUNK_FLOTATION'' = 0x1004,
<code>
+
header = 0x7777
+
data size = 1113
+
  
 +
''GAMEMTL_CHUNK_DESC'' = 0x1005,
  
===============================================================================
+
''GAMEMTL_CHUNK_INJURY'' = 0x1006,
block = 0x900
+
block size = 2
+
unknown data = ['0x10', '0x0']
+
  
  
===============================================================================
+
''GAMEMTLPAIR_CHUNK_PAIR'' = 0x1000,
block = 0x912
+
block size = 1
+
  
user data
+
''GAMEMTLPAIR_CHUNK_BREAKING'' = 0x1002,
  
user data =
+
''GAMEMTLPAIR_CHUNK_STEP'' = 0x1003,
  
 +
''GAMEMTLPAIR_CHUNK_COLLIDE'' = 0x1005,
  
===============================================================================
 
block = 0x925
 
block size = 1
 
  
lod
+
'''SGameMaterial:'''
  
lod reference =
+
''MF_BREAKABLE'' = 0x00000001,
  
 +
''MF_BOUNCEABLE'' = 0x00000004,
  
===============================================================================
+
''MF_SKIDMARK'' = 0x00000008,
block = 0x903
+
block size = 4
+
  
flags (model type)
+
''MF_BLOODMARK'' = 0x00000010,
  
model type = 0x0
+
''MF_CLIMABLE'' = 0x00000020,
  
 +
''MF_PASSABLE'' = 0x00000080,
  
===============================================================================
+
''MF_DYNAMIC'' = 0x00000100,
block = 0x910
+
block size = 929
+
  
geometry
+
''MF_LIQUID'' = 0x00000200,
  
mesh0 data size = 921
+
''MF_SUPPRESS_SHADOWS'' = 0x00000400,
  
unknown block = 0x1000
+
''MF_SUPPRESS_WALLMARKS'' = 0x00000800,
unknown block size = 2
+
unknown data = ['0x11', '0x0']
+
  
name block = 0x1001
+
''MF_ACTOR_OBSTACLE'' = 0x00001000,
name block size = 8
+
name = Plane10
+
  
bbox block = 0x1004
+
''MF_INJURIOUS'' = 0x10000000,
bbox block size = 24
+
bbox min =  (-0.089013084769248962, 0.00091872771736234426, -0.05408264324069023
+
1)
+
bbox max =  (0.064492635428905487, 0.017687048763036728, 0.050194162875413895)
+
  
unknown block = 0x1002
+
''MF_SHOOTABLE'' = 0x20000000,
unknown block size = 1
+
unknown data = ['0x5']
+
  
unknown block = 0x1010
+
''MF_TRANSPARENT'' = 0x40000000,
unknown block size = 8
+
unknown data = ['0x0', '0x0', '0x0', '0x0', '0x0', '0x0', '0x0', '0x0']
+
  
vertices block = 0x1005
+
''MF_SLOW_DOWN'' = 0x80000000,
vertices block size = 88
+
vertices count = 7
+
vertex0 = (-0.0019903033971786499, 0.001169001217931509, 0.0068940594792366028)
+
vertex1 = (-0.089013084769248962, 0.00091872771736234426, 0.045723527669906616)
+
vertex2 = (0.006468137726187706, 0.0094316964969038963, 0.050194162875413895)
+
vertex3 = (-0.039456427097320557, 0.0043633054010570049, -0.039133470505475998)
+
vertex4 = (0.023728765547275543, 0.0064991358667612076, -0.054082643240690231)
+
vertex5 = (0.031571760773658752, 0.0060988827608525753, 0.0041843997314572334)
+
vertex6 = (0.064492635428905487, 0.017687048763036728, -0.038134712725877762)
+
  
triangles block = 0x1006
 
triangles block size = 148
 
triangles count = 6
 
triangle0 = (0, 2, 1, 1, 2, 0)
 
triangle1 = (0, 8, 3, 7, 1, 6)
 
triangle2 = (0, 11, 4, 10, 3, 9)
 
triangle3 = (5, 14, 6, 13, 4, 12)
 
triangle4 = (0, 17, 2, 16, 5, 15)
 
triangle5 = (0, 20, 5, 19, 4, 18)
 
  
smoothgroups block = 0x1013
+
'''SGameMaterialPair:'''
smoothgroups block size = 24
+
triangle0 = 0x1
+
triangle1 = 0x1
+
triangle2 = 0x1
+
triangle3 = 0x1
+
triangle4 = 0x1
+
triangle5 = 0x1
+
  
uv map block = 0x1008
+
''MPF_BREAKING_SOUNDS'' = 0x02,
uv map block size = 193
+
count = 21
+
uv index = ['0x1', '0x0', '0x0', '0x0', '0x0'] 2
+
uv index = ['0x1', '0x0', '0x0', '0x0', '0x0'] 1
+
uv index = ['0x1', '0x0', '0x0', '0x0', '0x0'] 0
+
uv index = ['0x1', '0x90', '0xdb', '0x11', '0x7'] 12
+
uv index = ['0x1', '0x18', '0x87', '0x10', '0x7'] 12
+
uv index = ['0x1', '0x80', '0x8c', '0x10', '0x7'] 12
+
uv index = ['0x1', '0x1', '0x0', '0x0', '0x0'] 1
+
uv index = ['0x1', '0x0', '0x0', '0x0', '0x0'] 3
+
uv index = ['0x1', '0x1', '0x0', '0x0', '0x0'] 0
+
uv index = ['0x1', '0x1', '0x0', '0x0', '0x0'] 3
+
uv index = ['0x1', '0x0', '0x0', '0x0', '0x0'] 4
+
uv index = ['0x1', '0x1', '0x0', '0x0', '0x0'] 2
+
uv index = ['0x1', '0x1', '0x0', '0x0', '0x0'] 4
+
uv index = ['0x1', '0x0', '0x0', '0x0', '0x0'] 6
+
uv index = ['0x1', '0x0', '0x0', '0x0', '0x0'] 5
+
uv index = ['0x1', '0x1', '0x0', '0x0', '0x0'] 7
+
uv index = ['0x1', '0x1', '0x0', '0x0', '0x0'] 6
+
uv index = ['0x1', '0x1', '0x0', '0x0', '0x0'] 5
+
uv index = ['0x1', '0x1', '0x0', '0x0', '0x0'] 10
+
uv index = ['0x1', '0x1', '0x0', '0x0', '0x0'] 9
+
uv index = ['0x1', '0x1', '0x0', '0x0', '0x0'] 8
+
  
materials block = 0x1009
+
''MPF_STEP_SOUNDS'' = 0x04,
materials block size = 43
+
materials count = 1
+
material0 name = 01 - Default
+
triangles count = 6
+
triangles indices = [0, 1, 2, 3, 4, 5]
+
  
texcoords block = 0x1012
+
''MPF_COLLIDE_SOUNDS'' = 0x10,
texcoords block size = 294
+
uv tables count = 2
+
name = Texture
+
unknown = 2
+
layer index = 0
+
uvs count = 7
+
uv0 = (0.72911489009857178, 0.70259565114974976)
+
uv1 = (0.4648970365524292, 0.95080757141113281)
+
uv2 = (0.55649280548095703, 0.58906811475753784)
+
uv3 = (0.97081756591796875, 0.88250058889389038)
+
uv4 = (0.97814416885375977, 0.69620668888092041)
+
uv5 = (0.75604760646820068, 0.52614188194274902)
+
uv6 = (0.98893237113952637, 0.51763355731964111)
+
index0 = 0
+
index1 = 1
+
index2 = 2
+
index3 = 3
+
index4 = 4
+
index5 = 5
+
index6 = 6
+
name = Texture
+
unknown = 2
+
layer index = 1
+
uvs count = 11
+
uv0 = (0.72911489009857178, 0.70259565114974976)
+
uv1 = (0.4648970365524292, 0.95080757141113281)
+
uv2 = (0.72911489009857178, 0.70259565114974976)
+
uv3 = (0.97081756591796875, 0.88250058889389038)
+
uv4 = (0.97814416885375977, 0.69620668888092041)
+
uv5 = (0.72911489009857178, 0.70259565114974976)
+
uv6 = (0.5510140061378479, 0.58371180295944214)
+
uv7 = (0.75604760646820068, 0.52614188194274902)
+
uv8 = (0.72911489009857178, 0.70259565114974976)
+
uv9 = (0.75604760646820068, 0.52614188194274902)
+
uv10 = (0.97814416885375977, 0.69620668888092041)
+
index0 = 0
+
index1 = 1
+
index2 = 0
+
index3 = 3
+
index4 = 4
+
index5 = 0
+
index6 = 2
+
index7 = 5
+
index8 = 0
+
index9 = 5
+
index10 = 4
+
unknown index0 = 1
+
unknown index1 = 1
+
unknown index2 = 2
+
unknown index3 = 2
+
unknown index4 = 3
+
unknown index5 = 4
+
unknown index6 = 4
+
unknown index7 = 4
+
unknown index8 = 5
+
unknown index9 = 5
+
unknown index10 = 5
+
  
 +
''MPF_COLLIDE_PARTICLES'' = 0x20,
  
===============================================================================
+
''MPF_COLLIDE_MARKS'' = 0x40,
block = 0x907
+
block size = 82
+
  
materials
+
==Engine Shader Library==
 +
 +
// guessed names
  
materials count = 1
+
''SHADERS_CHUNK_CONSTANTS'' = 0,
  
 +
''SHADERS_CHUNK_MATRICES'' = 1,
  
material0 name = 01 - Default
+
''SHADERS_CHUNK_BLENDERS'' = 2,
engine shader = details\blend
+
compiler shader = default
+
game material = default
+
texture path = det\det_listya
+
texture = Texture
+
flags (2 sided, etc) = 0x0
+
unknown data = ['0x12', '0x1', '0x0', '0x0', '0x1', '0x0', '0x0', '0x0']
+
  
 +
''SHADERS_CHUNK_NAMES'' = 3
  
===============================================================================
+
====Разобрал bardak, Neo====
block = 0x922
+
block size = 38
+
  
author
+
===[[Попытка #1 от excid]]===
  
author name = \\SUSHKA\cy-27
+
===Ссылки===
creation date = ['0xf', '0x28', '0x98', '0x43']
+
Утилиты так или иначе связанные с импортом\экспортом object:
modifier name = \\SUSHKA\cy-27
+
*[http://stalkerin.gameru.net/modules.php?name=Downloads&d_op=getit&lid=318 xrFSL MaxTools 0.1.1] от '''Neo]['''
modification date = ['0xf', '0x28', '0x98', '0x43']
+
*[http://stalkerin.gameru.net/modules.php?name=Downloads&d_op=getit&lid=350 X-RAY Max Tools export beta 2] от '''bardak'''
</code>
+
*[http://stalkerin.gameru.net/modules.php?name=Downloads&d_op=getit&lid=287 X-RAY Tools src] от '''bardak'''
 +
*[http://stalkerin.gameru.net/modules.php?name=Downloads&d_op=getit&lid=348 X-RAY Tools update 2.0] от '''bardak'''
 +
*[http://stalkerin.gameru.net/modules.php?name=Downloads&d_op=getit&lid=288 X-RAY Tools] от '''bardak'''
 +
*[http://stalkerin.gameru.net/modules.php?name=Downloads&d_op=getit&lid=349 Maya 2009 plugin import/export] от '''bardak'''
 +
*[http://stalkerin.gameru.net/modules.php?name=Downloads&d_op=getit&lid=347 Maya 2008 plugin import/export] от '''bardak'''
 +
*[http://stalkerin.gameru.net/modules.php?name=Downloads&d_op=getit&lid=330 Object Format] от '''Neo][, bardak'''
 +
*[http://stalkerin.gameru.net/modules.php?name=Downloads&d_op=getit&lid=100 3DSMax 7 plugin export v.1.1] от '''GSC'''
 +
*[http://stalkerin.gameru.net/modules.php?name=Downloads&d_op=getit&lid=98 3DSMax 8 plugin export v.2.0] от '''GSC'''
 +
*[https://github.com/igelbox/blender-xray/releases Blender X-Ray Engine Tools] от '''igelbox'''
 +
*[https://github.com/PavelBlend/Blender_Stalker_Object Blender Import Object] от '''Pavel_Blend'''
 
[[Категория:Форматы файлов]]
 
[[Категория:Форматы файлов]]

Текущая версия на 12:24, 18 декабря 2016

О формате

Формат *.object используется в качестве основного формата хранения моделей на этапе редактирования (включая экспорт из Maya или 3ds Max и хранение моделей до компиляции уровня)

Описание формата(из кода xrFSL)

const uint16 EOBJ_VERSION = 0x10;

EObjectChunkIDs:

EOBJ_CHUNK_MAIN = 0x7777,

EOBJ_CHUNK_VERSION = 0x0900,

EOBJ_CHUNK_FLAGS = 0x0903,

EOBJ_CHUNK_SURFACES_0 = 0x0905, // old format

EOBJ_CHUNK_SURFACES_1 = 0x0906, // old format

EOBJ_CHUNK_SURFACES_2 = 0x0907,

EOBJ_CHUNK_MESHES = 0x0910,

EOBJ_CHUNK_0911 = 0x0911, // ignored by AE(Actor Editor)

EOBJ_CHUNK_USERDATA = 0x0912,

EOBJ_CHUNK_BONES_0 = 0x0913, // old format

EOBJ_CHUNK_MOTIONS = 0x0916,

EOBJ_CHUNK_SHADERS_0 = 0x0918, // old format

EOBJ_CHUNK_PARTITIONS_0 = 0x0919, // old format

EOBJ_CHUNK_TRANSFORM = 0x0920,

EOBJ_CHUNK_BONES_1 = 0x0921,

EOBJ_CHUNK_REVISION = 0x0922, // file revision

EOBJ_CHUNK_PARTITIONS_1 = 0x0923,

EOBJ_CHUNK_MOTION_REFS = 0x0924,

EOBJ_CHUNK_LOD_REF = 0x0925 // LOD\Reference

EObjectClipChunkIDs:

EOBJ_CLIP_VERSION_CHUNK = 0x9000,

EOBJ_CLIP_DATA_CHUNK = 0x9001

const uint16 EMESH_VERSION = 0x11;

EMeshChunkID:

EMESH_CHUNK_VERSION = 0x1000,

EMESH_CHUNK_MESHNAME = 0x1001,

EMESH_CHUNK_FLAGS = 0x1002,

EMESH_CHUNK_BBOX = 0x1004,

EMESH_CHUNK_VERTS = 0x1005,

EMESH_CHUNK_FACES = 0x1006,

EMESH_CHUNK_VMAPS_0 = 0x1007,

EMESH_CHUNK_VMREFS = 0x1008,

EMESH_CHUNK_SFACE = 0x1009,

EMESH_CHUNK_OPTIONS = 0x1010,

EMESH_CHUNK_VMAPS_1 = 0x1011,

EMESH_CHUNK_VMAPS_2 = 0x1012,

EMESH_CHUNK_SG = 0x1013

const uint16 BONE_VERSION_1 = 0x1;

const uint16 BONE_VERSION_2 = 0x2;

const uint16 BONE_VERSION = BONE_VERSION_2;

EboneChunkID:

BONE_CHUNK_VERSION = 0x0001,

BONE_CHUNK_DEF = 0x0002,

BONE_CHUNK_BIND_POSE= 0x0003,

BONE_CHUNK_MATERIAL = 0x0004,

BONE_CHUNK_SHAPE = 0x0005,

BONE_CHUNK_IK_JOINT = 0x0006,

BONE_CHUNK_MASS_PARAMS = 0x0007,

BONE_CHUNK_IK_FLAGS = 0x0008,

BONE_CHUNK_BREAK_PARAMS = 0x0009,

BONE_CHUNK_FRICTION = 0x0010

Game Materials Library(из кода xrFSL)

const uint16 GAMEMTLS_VERSION = 1;

GAMEMTLS_CHUNK_VERSION = 0x1000,

GAMEMTLS_CHUNK_AUTOINC = 0x1001,

GAMEMTLS_CHUNK_MATERIALS = 0x1002,

GAMEMTLS_CHUNK_MATERIAL_PAIRS = 0x1003,

GAMEMTL_CHUNK_MAIN = 0x1000,

GAMEMTL_CHUNK_FLAGS = 0x1001,

GAMEMTL_CHUNK_PHYSICS = 0x1002,

GAMEMTL_CHUNK_FACTORS = 0x1003,

GAMEMTL_CHUNK_FLOTATION = 0x1004,

GAMEMTL_CHUNK_DESC = 0x1005,

GAMEMTL_CHUNK_INJURY = 0x1006,


GAMEMTLPAIR_CHUNK_PAIR = 0x1000,

GAMEMTLPAIR_CHUNK_BREAKING = 0x1002,

GAMEMTLPAIR_CHUNK_STEP = 0x1003,

GAMEMTLPAIR_CHUNK_COLLIDE = 0x1005,


SGameMaterial:

MF_BREAKABLE = 0x00000001,

MF_BOUNCEABLE = 0x00000004,

MF_SKIDMARK = 0x00000008,

MF_BLOODMARK = 0x00000010,

MF_CLIMABLE = 0x00000020,

MF_PASSABLE = 0x00000080,

MF_DYNAMIC = 0x00000100,

MF_LIQUID = 0x00000200,

MF_SUPPRESS_SHADOWS = 0x00000400,

MF_SUPPRESS_WALLMARKS = 0x00000800,

MF_ACTOR_OBSTACLE = 0x00001000,

MF_INJURIOUS = 0x10000000,

MF_SHOOTABLE = 0x20000000,

MF_TRANSPARENT = 0x40000000,

MF_SLOW_DOWN = 0x80000000,


SGameMaterialPair:

MPF_BREAKING_SOUNDS = 0x02,

MPF_STEP_SOUNDS = 0x04,

MPF_COLLIDE_SOUNDS = 0x10,

MPF_COLLIDE_PARTICLES = 0x20,

MPF_COLLIDE_MARKS = 0x40,

Engine Shader Library

// guessed names

SHADERS_CHUNK_CONSTANTS = 0,

SHADERS_CHUNK_MATRICES = 1,

SHADERS_CHUNK_BLENDERS = 2,

SHADERS_CHUNK_NAMES = 3

Разобрал bardak, Neo

Попытка #1 от excid

Ссылки

Утилиты так или иначе связанные с импортом\экспортом object:

Другие места
LANGUAGE