B3D (формат файлов): различия между версиями

Материал из RnR Wiki
Перейти к навигации Перейти к поиску
м (Обозреватель (01))
Строка 73: Строка 73:
  
 
=Структуры и описания объектов=
 
=Структуры и описания объектов=
Структуры даны в синтаксисе C++.
+
Структуры даны в синтаксисе C++. Важно! Параметр nodePosition у объектов никак не влияет на их позицию! Скорее всего, он нужен лишь для оптимизации отрисовки.
 
==Некоторые используемые структуры==
 
==Некоторые используемые структуры==
 
  struct Vector3{
 
  struct Vector3{
Строка 79: Строка 79:
 
     float y;
 
     float y;
 
     float z;
 
     float z;
 +
};
 +
struct Vector3fi{
 +
    float x;
 +
    float y;
 +
    float z;
 +
    int  var;
 
  };
 
  };
 
  struct Vector4{
 
  struct Vector4{
Строка 85: Строка 91:
 
     float z;
 
     float z;
 
     float w;
 
     float w;
 +
};
 +
struct vertsSimple{
 +
    float x;
 +
    float y;
 +
    float z;
 +
    float u;
 +
    float v;
 
  };
 
  };
  
Строка 108: Строка 121:
  
 
==Контейнер (02)==
 
==Контейнер (02)==
  Vector4 position;
+
  Vector4 nodePosition;
 
  Vector4 unknown;
 
  Vector4 unknown;
 
  int    childCount;
 
  int    childCount;
Строка 115: Строка 128:
 
Контейнер с неизвестными параметрами.
 
Контейнер с неизвестными параметрами.
 
==Контейнер (03)==
 
==Контейнер (03)==
  Vector4 position;
+
  Vector4 nodePosition;
 
  int    childCount;
 
  int    childCount;
 
  <блоки[childCount]>
 
  <блоки[childCount]>
Строка 121: Строка 134:
 
Простой контейнер.
 
Простой контейнер.
 
==Контейнер (04)==
 
==Контейнер (04)==
  Vector4  position;
+
  Vector4  nodePosition;
 
  char[32] spaceObject;
 
  char[32] spaceObject;
 
  char[32] linkedObject;
 
  char[32] linkedObject;
Строка 129: Строка 142:
 
Контейнер с возможностью его прямой привязки к другому объекту: в spaceObject можно задать имя локатора типа 24, и тогда данный контейнер будет привязан к позиции локатора. В linkedObject задаётся подключенный объект (например, коллизия).
 
Контейнер с возможностью его прямой привязки к другому объекту: в spaceObject можно задать имя локатора типа 24, и тогда данный контейнер будет привязан к позиции локатора. В linkedObject задаётся подключенный объект (например, коллизия).
 
==Контейнер (05)==
 
==Контейнер (05)==
  Vector4  position;
+
  Vector4  nodePosition;
 
  char[32] linkedObject;
 
  char[32] linkedObject;
 
  int      childCount;
 
  int      childCount;
Строка 135: Строка 148:
  
 
Контейнер. Параметр linkedObject аналогично типу 04.
 
Контейнер. Параметр linkedObject аналогично типу 04.
==Блок типа 06==
+
==Контейнер-блок вершин (06)==
==Блок вершин (07)==
+
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)==
 
==Блок геометрии (08)==
 +
Vector4  nodePosition;
 +
int      faceStructsNum;
 +
<faceStruct[faceStructsNum]>
 +
 +
Блок, хранящий в себе информацию о треугольниках 3D-модели. Вся геометрия, образованная блоком типа 08, при отрисовке имеет плоское затенение ("flat shading").
 
==Контейнер (09)==
 
==Контейнер (09)==
 +
Vector4  nodePosition;
 +
Vector4  eventBorder;
 +
int      childCount;
 +
<блоки[childCount]>
 +
 +
Контейнер события. Плоскость eventBorder задаётся нормальным вектором и его длиной (она может быть отрицательной). Внутри контейнера данного типа могут быть и другие объекты типа 09. Границей события является сумма всех границ eventBorder родительских контейнеров по отношению к триггеру типа 13.
 
==Контейнер-переключатель LOD (10)==
 
==Контейнер-переключатель LOD (10)==
 +
Vector4  nodePosition;
 +
Vector4  LOD_xyzw;
 +
int      childCount;
 +
<блоки[childCount]>
 +
 +
Контейнер LOD. Имеет две переключаемые группы. В первой расположены объекты, отрисовываемые в том случае, когда расстояние от LOD_xyz до наблюдателя меньше w. В противном случае будет отображаться вторая группа.
 
==Контейнер (11)==
 
==Контейнер (11)==
 +
Vector4  nodePosition;
 +
Vector4  some_vector1;
 +
Vector4  some_vector2;
 +
int      childCount;
 +
<блоки[childCount]>
 +
 +
Контейнер неизвестного назначения. Встречается в старых b3d, например, в MirDemo.
 
==Плоскость коллизии (12)==
 
==Плоскость коллизии (12)==
  Vector4  position;
+
  Vector4  nodePosition;
 
  Vector4  collisionPlane;
 
  Vector4  collisionPlane;
 
  int      unknown;
 
  int      unknown;
Строка 151: Строка 205:
 
Плоскость коллизии (аналогична CollisionPlane из tech-файла). Определяется нормальным вектором и его длиной (она может быть отрицательной). Границей данной коллизии являются точки пересечений с другими объектами коллизии.
 
Плоскость коллизии (аналогична CollisionPlane из tech-файла). Определяется нормальным вектором и его длиной (она может быть отрицательной). Границей данной коллизии являются точки пересечений с другими объектами коллизии.
 
==Триггер (13)==
 
==Триггер (13)==
  Vector4  position;
+
  Vector4  nodePosition;
 
  int      eventType;
 
  int      eventType;
 
  int      eventValue;
 
  int      eventValue;
Строка 319: Строка 373:
 
  int      unknown_var;
 
  int      unknown_var;
 
  int      lightType;
 
  int      lightType;
  Vector3D lightPosition;
+
  Vector3  lightPosition;
  Vector3D lightDirection;
+
  Vector3  lightDirection;
 
  float    falloff;
 
  float    falloff;
 
  float    attenuation0;
 
  float    attenuation0;
Строка 358: Строка 412:
  
 
==Блок типа 34==
 
==Блок типа 34==
 +
Vector4  nodePosition;
 +
int      some_value;
 +
int      dataCount;
 +
<Vector3fi[dataCount]>
 +
 +
Назначение неизвестно.
 
==Блок геометрии (35)==
 
==Блок геометрии (35)==
==Блок типа 36==
+
Vector4  nodePosition;
==Блок вершин (37)==
+
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, и другие данные).
 
==Блок типа 38==
 
==Блок типа 38==
 
==Блок типа 39==
 
==Блок типа 39==
 
==Генератор объектов (40)==
 
==Генератор объектов (40)==
 +
 +
= Технические ограничения (Дальнобойщики II) =
 +
* На одну отрисовываемую 3D-модель должно приходиться не более 1023 вершин;
 +
* Число одновременно активных источников света не должно быть более 8 (?), в противном случае игра будет их отключать, пока количество сократится до допустимого.
  
 
{{Дб2}}
 
{{Дб2}}
  
 
= Примечания =
 
= Примечания =

Версия 16:17, 22 сентября 2025

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

Содержание

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

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

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

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

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

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

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

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

Заголовок

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

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

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

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

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

Структуры даны в синтаксисе C++. Важно! Параметр nodePosition у объектов никак не влияет на их позицию! Скорее всего, он нужен лишь для оптимизации отрисовки.

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

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;
};

Блок (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

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

Блок типа 15

Блок типа 16

Блок типа 17

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

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

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

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

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

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

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

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

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

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

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

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

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

Блок типа 26

Блок типа 27

Блок типа 28

Блок типа 29

Портал (30)

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

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

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

Важно!

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

Блок типа 31

Блок типа 32

Источник света (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, и другие данные).

Блок типа 38

Блок типа 39

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

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

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


Примечания