B3D (формат файлов)

Материал из RnR Wiki
Перейти к навигации Перейти к поиску

Описание формата *.b3d игр Дальнобойщики: Путь к победе и Дальнобойщики 2. Данный формат представляет собой трёхмерную сцену с различными типами объектов: контейнерами, переключателями, триггерами, источниками освещения, геометрией и т.п.[1]. Инструменты для работы с B3D представлены на странице с утилитами. Сам формат, предположительно, создан в первой половине 90-х годов ХХ века.

Содержание

Общее описание структуры файла

Формат b3d разделен на 3 основные секции:

<заголовок>
<список материалов>
<блоки данных>

Общее описание блока данных

тип данных описание
int32 Идентификатор начала блока
char[32] Имя блока
int32 Тип блока
<данные> Данные блока
int32 Идентификатор конца блока

Числовые идентификаторы

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

значение int32 строковый вид в кодировке 1251 описание
111 "o..." Начало секции с блоками данных
222 "Ю..." Конец секции с блоками данных
333 "M .." Начало одного блока
444 "j .." Разделитель переключаемых блоков (маркер окончания переключаемой группы)
555 "+_.." Конец одного блока

Заголовок

тип данных описание значение по умолчанию
char[4] сигнатура файла "b3d"
int32 [ Размер файла в байтах ] / 4
int32 [ Смещение секции со списком используемых материалов ] / 4 6
int32 [ Размер секции со списком материалов (1ая секция) ] / 4
int32 [ Смещение секции с блоками данных (третья секция) ] / 4
int32 [ Размер секции с блоками данных (третья секция) в байтах ] / 4

Список материалов

Представляет собой массив имён материалов из RES-файла. Порядок и имена должны соответствовать RES.

тип данных описание
int32 количество материалов
массив char[32] имя материала

Структуры и описания объектов

Структуры даны в синтаксисе C++.

Некоторые используемые структуры

struct Vector3{
    float x;
    float y;
    float z;
};
struct Vector3fi{
    float x;
    float y;
    float z;
    int   var;
};
struct Vector4{
    float x;
    float y;
    float z;
    float w;
};
struct vertsSimple{
    float x;
    float y;
    float z;
    float u;
    float v;
};

Терминология и пояснения

Группа переключаемого контейнера

Переключаемые группы - это дочерние объекты у переключаемого контейнера, разделённые идентификатором int32=444 (в текстовом виде - "j .."). Например, в некотором контейнере в B3D записаны следующие объекты:

object0_0
object0_1
<j ..>
object1_0
<j ..>
object2_0

В таком случае, первой переключаемой группой будут object0_0 и object0_1, второй группой object1_0, а третьей группой object2_0.

  • В конце последней группы идентификатор 333 не ставится. Кроме того, группы могут быть пустыми, то есть не содержать никаких объектов.
  • Переключаемые группы есть только у объектов типа 10, 21 и (возможно) 24.

Замечания по структурам

  • Параметр nodePosition у объектов никак не влияет на их позицию! Скорее всего, он нужен лишь для оптимизации отрисовки.
  • В игре «Дальнобойщики: Путь к победе» было только 30 типов объектов. К выходу «Дальнобойщиков 2» количество увеличилось до 40.

Блок (00)

char[32] some_name
Vector3  some_position

Назначение неизвестно. Обычно расположен сразу после списка материалов в любом b3d-файле.

Обозреватель (01)

char[32] start_space
char[32] start_room

Обозреватель (Viewer).

параметр описание
start_space имя локатора типа 24, задаёт начальные позицию и вращение обозревателя
start_room имя комнаты типа 19, в которой будет создан обозреватель

Контейнер (02)

Vector4 nodePosition;
Vector4 unknown;
int     childCount;
<блоки[childCount]>

Контейнер с неизвестными параметрами.

Контейнер (03)

Vector4 nodePosition;
int     childCount;
<блоки[childCount]>

Простой контейнер.

Контейнер (04)

Vector4  nodePosition;
char[32] spaceObject;
char[32] linkedObject;
int      childCount;
<блоки[childCount]>

Контейнер с возможностью его прямой привязки к другому объекту: в spaceObject можно задать имя локатора типа 24, и тогда данный контейнер будет привязан к позиции локатора. В linkedObject задаётся подключенный объект (например, коллизия).

Контейнер (05)

Vector4  nodePosition;
char[32] linkedObject;
int      childCount;
<блоки[childCount]>

Контейнер. Параметр linkedObject аналогично типу 04.

Контейнер-блок вершин (06)

Vector4  nodePosition;
char[32] eventObject?;
char[32] parentObject;
int      vertexCount;
<vertsSimple[vertexCount]>
int      childCount;
<блоки[childCount]>

Блок-контейнер вершин. Хранит в себе простые вершины (XYZ+UV). Скорее всего, как-то используется в связке с блоками событий.

Контейнер-блок вершин (07)

Vector4  nodePosition;
char[32] spaceObject;
int      vertexCount;
<vertsSimple[vertexCount]>
int      childCount;
<блоки[childCount]>

Блок-контейнер вершин. Хранит в себе простые вершины (XYZ+UV). Параметр spaceObject задаёт локатор, к которому привязан данный 3D-объект.

Блок геометрии (08)

Vector4  nodePosition;
int      faceStructsNum;
<faceStruct[faceStructsNum]>

Блок, хранящий в себе информацию о треугольниках 3D-модели. Вся геометрия, образованная блоком типа 08, при отрисовке имеет плоское затенение ("flat shading").

Контейнер (09)

Vector4  nodePosition;
Vector4  eventBorder;
int      childCount;
<блоки[childCount]>

Контейнер события. Плоскость eventBorder задаётся нормальным вектором и его длиной (она может быть отрицательной). Внутри контейнера данного типа могут быть и другие объекты типа 09. Границей события является сумма всех границ eventBorder родительских контейнеров по отношению к триггеру типа 13.

Контейнер-переключатель LOD (10)

Vector4  nodePosition;
Vector4  LOD_xyzw;
int      childCount;
<блоки[childCount]>

Контейнер LOD. Имеет две переключаемые группы. В первой расположены объекты, отрисовываемые в том случае, когда расстояние от LOD_xyz до наблюдателя меньше w. В противном случае будет отображаться вторая группа.

Контейнер (11)

Vector4  nodePosition;
Vector4  some_vector1;
Vector4  some_vector2;
int      childCount;
<блоки[childCount]>

Контейнер неизвестного назначения. Встречается в старых b3d, например, в MirDemo.

Плоскость коллизии (12)

Vector4  nodePosition;
Vector4  collisionPlane;
int      unknown;
int      collisionType;
int      childCount;
<блоки[childCount]>

Плоскость коллизии (аналогична CollisionPlane из tech-файла). Определяется нормальным вектором и его длиной (она может быть отрицательной). Границей данной коллизии являются точки пересечений с другими объектами коллизии.

Триггер (13)

Vector4  nodePosition;
int      eventType;
int      eventValue;
int      paramsNum;
<данные_события[paramsNum]>

Блок-триггер.

Типы триггера

no_rain_no_sun (22)

Параметры блока:

параметр значение
eventType 22
eventValue 0
paramsNum 0

Параметры события: отсутствуют.

weather_change (23)

Параметры блока:

параметр значение
eventType 23
eventValue индекс варианта погоды из weather.ini
paramsNum 4

Параметры события: плоскость, заданная нормальным вектором и длиной, определяющая границу смены погоды.

тип параметр значение
Vector3 direction нормальный вектор
float length длина вектора

Загрузка модуля (4095)

Параметры блока:

параметр значение
eventType 4095
eventValue 0
paramsNum 1

Параметры события:

тип параметр значение
char[2] moduleName имя модуля из папки ENV
byte нулевой байт 0x00
byte закрывающий байт 0xCD

Событие (14)

Vector4  nodePosition;
Vector4  eventPosition;
int      eventType;
int      eventValue;
int      paramsNum;
<данные_события[paramsNum]>

Обработчик событий.

Типы событий

sell_<vehicle> (18)

Как-то связан с продажей автомобиля. Имеется только у автомобилей, доступных для заказа по рации(?) Расположен внутри главного контейнера автомобиля. Параметры блока:

параметр значение
eventType 18
eventValue 0
paramsNum 0

Параметры события: отсутствуют.

Nek_<vehicle> (25)

Без него сцепка полуприцепа неработоспособна. Значение eventPosition должно соответствовать параметру topSaddle данного полуприцепа в vehicle.tech! Расположен внутри главного контейнера полуприцепа. Параметры блока:

параметр значение
eventType 25
eventValue 0
paramsNum 0

Параметры события: отсутствуют.

Блок типа 16

Блок типа 17

Блок-связка (18)

Vector4  nodePosition;
char[32] spaceObject;
char[32] linkedObject;

Используется для добавления копий объектов. В spaceObject указывается имя блока-локатора типа 24, в linkedObject - имя подключаемого объекта. После загрузки сцены копия linkedObject будет расположена в позиции spaceObject, причём эта связь не единоразовая - при изменении позиции spaceObject изменится и позиция копии linkedObject.

Контейнер комнаты (19)

int    childCount;
<блоки[childCount]>

Используется для хранения комнат игрового мира.

Ломанная линия коллизии (20)

Контейнер-переключатель (21)

Vector4  nodePosition;
int      groupsCount;
int      defaultGroupIndex;
int      childCount;
<блоки[childCount]>

Контейнер с переключаемым содержимым. По умолчанию отображается группа под индексом defaultGroupIndex (если состояние переключателя не задаётся постоянно кодом игры).
Если у контейнера есть префикс "refer_" в названии, то значение активной группы привязывается к такому же контейнеру, у которого нет такого префикса в имени. Например, отображаемая группа контейнера "refer_DashboardGlowKey" будет зависеть от состояния контейнера "DashboardGlowKey".

Геометрия коллизии (23)

Локатор-контейнер (24)

Vector3 matrix0;
Vector3 matrix1;
Vector3 matrix2;
Vector3 position;
int     caseState?;
int     childCount;
<блоки[childCount]>

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

Звуковой объект (25)

Блок типа 27

Блок типа 28

Блок типа 29

Портал (30)

Vector4  doorPosition;
char[32] targetRoom;
Vector3  doorLowVertex;
Vector3  doorTopVertex;

Портал (дверь) между комнатами.

параметр описание
doorPosition позиция портала
targetRoom имя комнаты, в которую ведёт портал. Если комната находится в другом модуле, то имя задаётся в формате <модуль>:<комната>
doorLowVertex крайняя нижняя левая точка портала
doorTopVertex крайняя верхняя правая точка портала

Важно!

  • Если портал ведёт в комнату другого модуля, то в одной комнате с этим порталом обязательно должен быть загрузчик модуля (блок типа 13)
  • Порталы соседних комнат должны иметь одинаковую позицию (doorPosition) и границы, в противном случае запрошенная комната не будет отображена

Блок типа 31

Источник света (33)

Vector4  nodePosition;
int      is_enabled; 
int      unknown_var;
int      lightType;
Vector3  lightPosition;
Vector3  lightDirection;
float    falloff;
float    attenuation0;
float    attenuation1;
float    attenuation1;
float    theta;
float    phi;
float    R; 
float    G; 
float    B; 
int      childCount;
<блоки[childCount]>

Источник света DirectX 8.

параметр описание[2]
lightType тип источника света: 1 - направленный (directional), 2 - точечный (point), 3 - зональный (spot)
lightPosition позиция источника света
lightDirection направление освещения (нормальный вектор)
falloff уменьшение освещения между внутренним конусом (theta) и внешним конусом (phi) источника света
attenuation0 постоянное затухание
attenuation1 линейное затухание
attenuation2 квадратичное затухание
theta угол внутреннего конуса в радианах, для нацеленного источника света. Это значение может принимать от 0 до значения Phi
phi угол внешнего конуса источника света. Т.е. вне этого конуса свет уже не освещает. Может принимать значения между 0 и числом Пи.

Блок типа 34

Vector4  nodePosition;
int      some_value;
int      dataCount;
<Vector3fi[dataCount]>

Назначение неизвестно.

Блок геометрии (35)

Vector4  nodePosition;
int      faceStructType;
int      materialIndex;
int      faceStructsNum;
<faceStruct[faceStructsNum]>

Блок, хранящий в себе информацию о треугольниках 3D-модели. Вся геометрия, образованная блоком типа 35, при отрисовке имеет затенение по Гуро ("Gourand shading"). В отличие от типа 08, может иметь только один используемый материал и один тип faceStruct. Индекс материала, заданный внутри faceStruct, игнорируется.

Контейнер-блок вершин (36)

Vector4  nodePosition;
char[32] spaceObject;
char[32] linkedObject;
int      vertsStructType;
int      vertsStructsNum;
<vertsStruct[vertsStructsNum]>
int      childCount;
<блоки[childCount]>

Блок-контейнер вершин. Хранит в себе сложные вершины (тип определяется vertsStructType - могут быть и нормали, и несколько слоёв UV, и другие данные). В spaceObject можно задать имя локатора типа 24, и тогда данный контейнер будет привязан к позиции локатора. В linkedObject задаётся подключенный объект (например, коллизия).

Контейнер-блок вершин (37)

Vector4  nodePosition;
char[32] linkedObject;
int      vertsStructType;
int      vertsStructsNum;
<vertsStruct[vertsStructsNum]>
int      childCount;
<блоки[childCount]>

Блок-контейнер вершин. Хранит в себе сложные вершины (тип определяется vertsStructType - могут быть и нормали, и несколько слоёв UV, и другие данные).

Блок типа 39

Генератор объектов (40)

Vector4  nodePosition;
char[32] some_string;
char[32] generatorClass;
int      generatorType;
int      some_value;
int      paramsNum;
<данные_генератора[paramsNum]>

Генератор объектов. До конца не изучен.

Типы генераторов

generatorClass описание
$$TreeGenerator Генератор деревьев. Использовался в версиях 4.0 - 5.5. Использование в более поздних версиях игры возможно, но приводит к сообщениям в warn.log.
$$TreeGenerator1 Генератор сбиваемых деревьев. Используется в версиях игры, начиная с 6.6.
$$People Создаёт модели людей и животных в определённое время суток в указанных локациях.
$$GeneratorOfTerrain Генератор ландшафта в Алмазном.
$$CollisionOfTerrain Генератор коллизии в Алмазном.
$$StaticGlow неизвестно, не встречается в игре
$$DynamicGlow Создаёт блики от источников света, изменяющиеся от расстояния до наблюдателя. Есть во многих b3d-файлах игрового мира.
$$WeldingSparkles Излучатель искр. Используется в bb.b3d.
$$SeaGenerator неизвестно, не встречается в игре

Технические ограничения (Дальнобойщики II)

  • На одну отрисовываемую 3D-модель должно приходиться не более 1023 вершин;
  • Число одновременно активных источников света не должно быть более 8 (?), в противном случае игра будет их отключать, пока количество сократится до допустимого.
Дальнобойщики 2
Игровое наполнение Игровой регионАвтопаркСаундтрекВступительный роликРацияМилицияВертолёт
Дб2t.jpg
Моддинг МодификацииУтилитыgame.cnfsch-файлыvehicle.techtruck.ini
Разное История версийСоветы и секретыБонусный дискУправлениеАвторы


Примечания